stmf.c revision 91159e90831fc9243576f2ec1a483b3bb462bcf4
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
780c822c86101e82568fa9e357d13965b9f0cf81tim szeto * Lock order:
780c822c86101e82568fa9e357d13965b9f0cf81tim szeto * stmf_state_lock --> ilport_lock/iss_lockp --> ilu_task_lock
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte/* start messages at 1 */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int stmf_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int stmf_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int stmf_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int stmf_open(dev_t *devp, int flag, int otype, cred_t *credp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int stmf_close(dev_t dev, int flag, int otype, cred_t *credp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int stmf_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int stmf_get_stmf_state(stmf_state_desc_t *std);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int stmf_set_stmf_state(stmf_state_desc_t *std);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void stmf_abort_task_offline(scsi_task_t *task, int offline_lu,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic int stmf_set_alua_state(stmf_alua_state_desc_t *alua_state);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic void stmf_get_alua_state(stmf_alua_state_desc_t *alua_state);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_xfer_data_t *stmf_prepare_tpgs_data(uint8_t ilu_alua);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid stmf_svc_queue(int cmd, void *obj, stmf_state_change_info_t *info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_status_t stmf_lun_reset_poll(stmf_lu_t *lu, struct scsi_task *task,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid stmf_target_reset_poll(struct scsi_task *task);
91159e90831fc9243576f2ec1a483b3bb462bcf4John Fortevoid stmf_xd_to_dbuf(stmf_data_buf_t *dbuf, int set_rel_off);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoint stmf_load_ppd_ioctl(stmf_ppioctl_data_t *ppi, uint64_t *ppi_token,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint stmf_delete_ppd_ioctl(stmf_ppioctl_data_t *ppi);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetoint stmf_get_ppd_ioctl(stmf_ppioctl_data_t *ppi, stmf_ppioctl_data_t *ppi_out,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic void stmf_task_lu_free(scsi_task_t *task, stmf_i_scsi_session_t *iss);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic stmf_status_t stmf_ic_lu_reg(stmf_ic_reg_dereg_lun_msg_t *msg,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic stmf_status_t stmf_ic_lu_dereg(stmf_ic_reg_dereg_lun_msg_t *msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic stmf_status_t stmf_ic_rx_scsi_status(stmf_ic_scsi_status_msg_t *msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic stmf_status_t stmf_ic_rx_status(stmf_ic_status_msg_t *msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestatic stmf_status_t stmf_ic_rx_scsi_data(stmf_ic_scsi_data_msg_t *msg);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortevoid stmf_task_lu_killall(stmf_lu_t *lu, scsi_task_t *tm_task, stmf_status_t s);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte/* pppt modhandle */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte/* pppt modload imported functions */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_ic_reg_port_msg_alloc_func_t ic_reg_port_msg_alloc;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_ic_dereg_port_msg_alloc_func_t ic_dereg_port_msg_alloc;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_ic_reg_lun_msg_alloc_func_t ic_reg_lun_msg_alloc;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_ic_dereg_lun_msg_alloc_func_t ic_dereg_lun_msg_alloc;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_ic_lun_active_msg_alloc_func_t ic_lun_active_msg_alloc;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_ic_scsi_cmd_msg_alloc_func_t ic_scsi_cmd_msg_alloc;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_ic_scsi_data_xfer_done_msg_alloc_func_t ic_scsi_data_xfer_done_msg_alloc;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_ic_session_create_msg_alloc_func_t ic_session_reg_msg_alloc;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_ic_session_destroy_msg_alloc_func_t ic_session_dereg_msg_alloc;
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic void stmf_itl_task_start(stmf_i_scsi_task_t *itask);
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic void stmf_itl_lu_new_task(stmf_i_scsi_task_t *itask);
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic void stmf_itl_task_done(stmf_i_scsi_task_t *itask);
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic void stmf_lport_xfer_start(stmf_i_scsi_task_t *itask,
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic void stmf_lport_xfer_done(stmf_i_scsi_task_t *itask,
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szetostatic void stmf_update_kstat_lu_q(scsi_task_t *, void());
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szetostatic void stmf_update_kstat_lport_q(scsi_task_t *, void());
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szetostatic void stmf_update_kstat_lu_io(scsi_task_t *, stmf_data_buf_t *);
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szetostatic void stmf_update_kstat_lport_io(scsi_task_t *, stmf_data_buf_t *);
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic int stmf_irport_compare(const void *void_irport1,
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic stmf_i_remote_port_t *stmf_irport_create(scsi_devid_desc_t *rport_devid);
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic void stmf_irport_destroy(stmf_i_remote_port_t *irport);
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic stmf_i_remote_port_t *stmf_irport_lookup_locked(
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic void stmf_irport_deregister(stmf_i_remote_port_t *irport);
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic void stmf_teardown_itl_kstats(stmf_i_itl_kstat_t *ks);
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic void stmf_delete_itl_kstat_by_lport(char *);
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic void stmf_delete_itl_kstat_by_guid(char *);
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic int stmf_itl_kstat_compare(const void*, const void*);
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic stmf_i_itl_kstat_t *stmf_itl_kstat_lookup(char *kstat_nm);
427fcaf873956aad428be801380a44e59d38b8b5tim szetostatic stmf_i_itl_kstat_t *stmf_itl_kstat_create(stmf_itl_data_t *itl,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto char *nm, scsi_devid_desc_t *lport, scsi_devid_desc_t *lun);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* =====[ Tunables ]===== */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* Internal tracing */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevolatile int stmf_trace_buf_size = (1 * 1024 * 1024);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The reason default task timeout is 75 is because we want the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * host to timeout 1st and mostly host timeout is 60 seconds.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Setting this to one means, you are responsible for config load and keeping
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * things in sync with persistent database.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevolatile int stmf_allow_modunload = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* === [ Debugging and fault injection ] === */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevolatile int stmf_drop_task_counter = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevolatile int stmf_drop_buf_counter = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0xff };
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte { 0xff, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 };
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic enum {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int stmf_nworkers_cur; /* # of workers currently running */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int stmf_nworkers_needed; /* # of workers need to be running */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is equal to stmf_nworkers_cur while we are increasing # workers and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * stmf_nworkers_needed while we are decreasing the worker count.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte 0, /* streamtab */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace_buf = kmem_zalloc(stmf_trace_buf_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&trace_buf_lock, NULL, MUTEX_DRIVER, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* STMF service is off by default */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&stmf_state.stmf_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&stmf_state.stmf_cv, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_session_counter = (uint64_t)ddi_get_lbolt();
427fcaf873956aad428be801380a44e59d38b8b5tim szeto stmf_irport_compare, sizeof (stmf_i_remote_port_t),
427fcaf873956aad428be801380a44e59d38b8b5tim szeto id_space_create("lport-instances", 0, MAX_ILPORT);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto id_space_create("rport-instances", 0, MAX_IRPORT);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto stmf_itl_kstat_compare, sizeof (stmf_i_itl_kstat_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (stmf_state.stmf_config_state != STMF_CONFIG_NONE)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_nlps || stmf_state.stmf_npps) {
427fcaf873956aad428be801380a44e59d38b8b5tim szeto while ((irport = avl_destroy_nodes(&stmf_state.stmf_irportlist,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto id_space_destroy(stmf_state.stmf_ilport_inst_space);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto id_space_destroy(stmf_state.stmf_irport_inst_space);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto while ((ks_itl = avl_destroy_nodes(&stmf_state.stmf_itl_kstat_list,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto (void *)(uintptr_t)ddi_get_instance(stmf_state.stmf_dip);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_create_minor_node(dip, "admin", S_IFCHR, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_open(dev_t *devp, int flag, int otype, cred_t *credp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_close(dev_t dev, int flag, int otype, cred_t *credp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (stmf_state.stmf_config_state != STMF_CONFIG_INIT_DONE)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_copyin_iocdata(intptr_t data, int mode, stmf_iocdata_t **iocd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *iocd = kmem_zalloc(sizeof (stmf_iocdata_t), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = ddi_copyin((void *)data, *iocd, sizeof (stmf_iocdata_t), mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *ibuf = kmem_zalloc((*iocd)->stmf_ibuf_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = ddi_copyin((void *)((unsigned long)(*iocd)->stmf_ibuf),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *obuf = kmem_zalloc((*iocd)->stmf_obuf_size, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_copyout_iocdata(intptr_t data, int mode, stmf_iocdata_t *iocd, void *obuf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = ddi_copyout(obuf, (void *)(unsigned long)iocd->stmf_obuf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = ddi_copyout(iocd, (void *)data, sizeof (stmf_iocdata_t), mode);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = stmf_copyin_iocdata(data, mode, &iocd, &ibuf, &obuf);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto /* retrieves both registered/unregistered */
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto for (i = 0; i < n; i++) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto bcopy(id_entry->id_data, luid_list[i].lu_guid, 16);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto for (ilu = stmf_state.stmf_ilulist; ilu; ilu = ilu->ilu_next) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto if (stmf_lookup_id(id_list, 16, id + 4) == NULL) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto if (i < n) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iocd->stmf_obuf_max_nentries = stmf_state.stmf_nlus;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < n; i++) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto for (i = 0; i < n; i++) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto bcopy(id_entry->id_data, luid_list[i].lu_guid, 16);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iocd->stmf_obuf_max_nentries = stmf_state.stmf_nlports;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < n; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((p_id == NULL) || (iocd->stmf_ibuf_size < 4) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ilport = stmf_state.stmf_ilportlist; ilport; ilport =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iocd->stmf_obuf_max_nentries = ilport->ilport_nsessions;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_obuf_size)/sizeof (slist_scsi_session_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < n; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_obuf_size < sizeof (sioc_lu_props_t)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (p_id[0] == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ilu = stmf_state.stmf_ilulist; ilu; ilu = ilu->ilu_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bcmp(p_id, ilu->ilu_lu->lu_id->ident, 16) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(ilu->ilu_lu->lu_id->ident, lup->lu_guid, 16);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ilport = stmf_state.stmf_ilportlist; ilport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(ilport->ilport_lport->lport_id, lportp->tgt_id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilport->ilport_lport->lport_id->ident_length + 4);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_ibuf_size < sizeof (stmf_state_desc_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = stmf_set_stmf_state((stmf_state_desc_t *)ibuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_obuf_size < sizeof (stmf_state_desc_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = stmf_get_stmf_state((stmf_state_desc_t *)obuf);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (iocd->stmf_ibuf_size < sizeof (stmf_alua_state_desc_t))) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ret = stmf_set_alua_state((stmf_alua_state_desc_t *)ibuf);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (iocd->stmf_obuf_size < sizeof (stmf_alua_state_desc_t))) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_get_alua_state((stmf_alua_state_desc_t *)obuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_ibuf_size < sizeof (stmf_state_desc_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ilu = stmf_state.stmf_ilulist; ilu; ilu = ilu->ilu_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bcmp(p_id, ilu->ilu_lu->lu_id->ident, 16) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmd = (std->state == STMF_STATE_ONLINE) ? STMF_CMD_LU_ONLINE :
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ctl_ret = stmf_ctl(cmd, (void *)ilu->ilu_lu, &ssi);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_ibuf_size < sizeof (stmf_state_desc_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ilport = stmf_state.stmf_ilportlist; ilport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ctl_ret = stmf_ctl(cmd, (void *)ilport->ilport_lport, &ssi);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_config_state == STMF_CONFIG_NONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iocd->stmf_error = STMF_IOCERR_UPDATE_NEED_CFG_INIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_ibuf_size < sizeof (stmf_group_op_data_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break; /* not allowed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = stmf_add_group_member(grp_entry->group.name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_config_state == STMF_CONFIG_NONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iocd->stmf_error = STMF_IOCERR_UPDATE_NEED_CFG_INIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_ibuf_size < sizeof (stmf_group_op_data_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break; /* not allowed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = stmf_remove_group_member(grp_entry->group.name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_config_state == STMF_CONFIG_NONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iocd->stmf_error = STMF_IOCERR_UPDATE_NEED_CFG_INIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_ibuf_size < sizeof (stmf_group_name_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break; /* not allowed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_config_state == STMF_CONFIG_NONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iocd->stmf_error = STMF_IOCERR_UPDATE_NEED_CFG_INIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_ibuf_size < sizeof (stmf_group_name_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break; /* not allowed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_config_state == STMF_CONFIG_NONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iocd->stmf_error = STMF_IOCERR_UPDATE_NEED_CFG_INIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_ibuf_size < sizeof (stmf_view_op_entry_t))) {
63ed874a56e20df7e4ec98ba42582352d87386c5tim szeto } else { /* STMF_IOCTL_VALIDATE_VIEW */
63ed874a56e20df7e4ec98ba42582352d87386c5tim szeto ret = stmf_validate_lun_ve(ve->ve_host_group.name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (!ve->ve_ndx_valid || !ve->ve_lu_number_valid) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iocd->stmf_obuf_size >= sizeof (stmf_view_op_entry_t)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_config_state == STMF_CONFIG_NONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iocd->stmf_error = STMF_IOCERR_UPDATE_NEED_CFG_INIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_ibuf_size < sizeof (stmf_view_op_entry_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = stmf_remove_ve_by_id(ve->ve_guid, ve->ve_ndx,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iocd->stmf_obuf_max_nentries = id_list->id_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_obuf_size)/sizeof (stmf_group_name_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < n; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* FALLTHROUGH */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_ibuf_size < sizeof (stmf_group_name_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte id_entry = stmf_lookup_id(id_list, grpname->name_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte id_list = (stmf_id_list_t *)id_entry->id_impl_specific;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iocd->stmf_obuf_max_nentries = id_list->id_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < n; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte n = iocd->stmf_obuf_size/sizeof (stmf_view_op_entry_t);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto for (id_entry = stmf_state.stmf_luid_list.idl_head;
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto (iocd->stmf_obuf_size < sizeof (stmf_view_op_entry_t))) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto n = iocd->stmf_obuf_size/sizeof (stmf_view_op_entry_t);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto for (id_entry = stmf_state.stmf_luid_list.idl_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_config_state == STMF_CONFIG_NONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iocd->stmf_error = STMF_IOCERR_UPDATE_NEED_CFG_INIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_ibuf_size < sizeof (stmf_ppioctl_data_t))) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto /* returned token */
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto ret = stmf_load_ppd_ioctl(ppi, ppi_token, &iocd->stmf_error);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto if (stmf_state.stmf_config_state == STMF_CONFIG_NONE) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto iocd->stmf_error = STMF_IOCERR_UPDATE_NEED_CFG_INIT;
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto (iocd->stmf_ibuf_size < sizeof (stmf_ppioctl_data_t))) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto (iocd->stmf_obuf_size < sizeof (stmf_ppioctl_data_t))) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto ret = stmf_get_ppd_ioctl(ppi, ppi_out, &iocd->stmf_error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_config_state == STMF_CONFIG_NONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iocd->stmf_error = STMF_IOCERR_UPDATE_NEED_CFG_INIT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (iocd->stmf_ibuf_size < sizeof (stmf_ppioctl_data_t))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((iocd->stmf_obuf_size == 0) || (iocd->stmf_ibuf_size < 4)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i = *((int *)ibuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((i > trace_buf_size) || ((i + iocd->stmf_obuf_size) >
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(stmf_trace_buf + i, obuf, iocd->stmf_obuf_size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = stmf_copyout_iocdata(data, mode, iocd, obuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) stmf_copyout_iocdata(data, mode, iocd, obuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else if (ilport->ilport_state == STMF_STATE_ONLINE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else if (ilport->ilport_state == STMF_STATE_ONLINING)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else if (ilport->ilport_state == STMF_STATE_OFFLINING)
5dfbf9be7aa351a2746b8259a906f60caf81fdcfSue Gleeson if ((stmf_state.stmf_config_state == STMF_CONFIG_INIT) ||
5dfbf9be7aa351a2746b8259a906f60caf81fdcfSue Gleeson (stmf_state.stmf_config_state == STMF_CONFIG_NONE)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (std->config_state != STMF_CONFIG_INIT_DONE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_state.stmf_config_state = STMF_CONFIG_INIT_DONE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_config_state == STMF_CONFIG_INIT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilport->ilport_prev_state != STMF_STATE_ONLINE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) stmf_ctl(STMF_CMD_LU_ONLINE, ilu->ilu_lu, &ssi);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* svc_state is STMF_STATE_ONLINE here */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) stmf_ctl(STMF_CMD_LU_OFFLINE, ilu->ilu_lu, &ssi);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte std->config_state = stmf_state.stmf_config_state;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * handles registration message from pppt for a logical unit
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_ic_lu_reg(stmf_ic_reg_dereg_lun_msg_t *msg, uint32_t type)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte for (ilp = stmf_state.stmf_ilplist; ilp != NULL; ilp = ilp->ilp_next) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte lp->lp_proxy_msg(msg->icrl_lun_id, msg->icrl_cb_arg,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * handles de-registration message from pppt for a logical unit
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_ic_lu_dereg(stmf_ic_reg_dereg_lun_msg_t *msg)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte for (ilp = stmf_state.stmf_ilplist; ilp != NULL; ilp = ilp->ilp_next) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * helper function to find a task that matches a task_msgid
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortefind_task_from_msgid(uint8_t *lu_id, stmf_ic_msgid_t task_msgid)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte for (ilu = stmf_state.stmf_ilulist; ilu != NULL; ilu = ilu->ilu_next) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (bcmp(lu_id, ilu->ilu_lu->lu_id->ident, 16) == 0) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* task not found. Likely already aborted. */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * message received from pppt/ic
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (msg->ics_msg_type != STMF_ICM_REGISTER_PROXY_PORT) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* for now, ignore other message status */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (msg->ics_msgid == ilport->ilport_reg_msgid) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * handles scsi status message from pppt
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_ic_rx_scsi_status(stmf_ic_scsi_status_msg_t *msg)
cbdc6dc775d8961a464fa0e1ca1bc234719c6e0dJohn Forte /* is this a task management command */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte task = find_task_from_msgid(msg->icss_lun_id, msg->icss_task_msgid);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (void) stmf_send_scsi_status(task, STMF_IOF_LU_DONE);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * handles scsi data message from pppt
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_ic_rx_scsi_data(stmf_ic_scsi_data_msg_t *msg)
cbdc6dc775d8961a464fa0e1ca1bc234719c6e0dJohn Forte /* is this a task management command */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte task = find_task_from_msgid(msg->icsd_lun_id, msg->icsd_task_msgid);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * send xfer done status to pppt
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * for now, set the session id to 0 as we cannot
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * ascertain it since we cannot find the task
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ic_xfer_done_msg = ic_scsi_data_xfer_done_msg_alloc(
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte msg->icsd_task_msgid, 0, STMF_FAILURE, data_msg_id);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte itask = (stmf_i_scsi_task_t *)task->task_stmf_private;
91159e90831fc9243576f2ec1a483b3bb462bcf4John Forte task->task_cmd_xfer_length += msg->icsd_data_len;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte xd = (stmf_xfer_data_t *)kmem_zalloc(asz, KM_NOSLEEP);
91159e90831fc9243576f2ec1a483b3bb462bcf4John Forte dbuf->db_relative_offset = task->task_nbytes_transferred;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_proxy_scsi_cmd(scsi_task_t *task, stmf_data_buf_t *dbuf)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (stmf_i_local_port_t *)task->task_lport->lport_stmf_private;
437be37266d159c6a27c02e61710a578bef3d15fJohn Forte * stmf will now take over the task handling for this task
437be37266d159c6a27c02e61710a578bef3d15fJohn Forte * but it still needs to be treated differently from other
cbdc6dc775d8961a464fa0e1ca1bc234719c6e0dJohn Forte * default handled tasks, hence the ITASK_PROXY_TASK.
cbdc6dc775d8961a464fa0e1ca1bc234719c6e0dJohn Forte * If this is a task management function, we're really just
cbdc6dc775d8961a464fa0e1ca1bc234719c6e0dJohn Forte * duping the command to the peer. Set the TM bit so that
cbdc6dc775d8961a464fa0e1ca1bc234719c6e0dJohn Forte * we can recognize this on return since we won't be completing
cbdc6dc775d8961a464fa0e1ca1bc234719c6e0dJohn Forte * the proxied task in that case.
cbdc6dc775d8961a464fa0e1ca1bc234719c6e0dJohn Forte itask->itask_flags |= ITASK_DEFAULT_HANDLING | ITASK_PROXY_TASK;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ic_cmd_msg = ic_scsi_cmd_msg_alloc(itask->itask_proxy_msg_id,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte task, dbuf->db_data_size, dbuf->db_sglist[0].seg_addr,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ic_cmd_msg = ic_scsi_cmd_msg_alloc(itask->itask_proxy_msg_id,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ddi_modopen("drv/pppt", KRTLD_MODE_FIRST, &error)) == NULL)) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (ic_reg_port_msg_alloc == NULL && ((ic_reg_port_msg_alloc =
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ddi_modsym(pppt_mod, "stmf_ic_reg_port_msg_alloc",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte "Unable to find symbol - stmf_ic_reg_port_msg_alloc");
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (ic_dereg_port_msg_alloc == NULL && ((ic_dereg_port_msg_alloc =
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ddi_modsym(pppt_mod, "stmf_ic_dereg_port_msg_alloc",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte "Unable to find symbol - stmf_ic_dereg_port_msg_alloc");
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (ic_reg_lun_msg_alloc == NULL && ((ic_reg_lun_msg_alloc =
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ddi_modsym(pppt_mod, "stmf_ic_reg_lun_msg_alloc",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte "Unable to find symbol - stmf_ic_reg_lun_msg_alloc");
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (ic_lun_active_msg_alloc == NULL && ((ic_lun_active_msg_alloc =
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ddi_modsym(pppt_mod, "stmf_ic_lun_active_msg_alloc",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte "Unable to find symbol - stmf_ic_lun_active_msg_alloc");
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (ic_dereg_lun_msg_alloc == NULL && ((ic_dereg_lun_msg_alloc =
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ddi_modsym(pppt_mod, "stmf_ic_dereg_lun_msg_alloc",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte "Unable to find symbol - stmf_ic_dereg_lun_msg_alloc");
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (ic_scsi_cmd_msg_alloc == NULL && ((ic_scsi_cmd_msg_alloc =
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ddi_modsym(pppt_mod, "stmf_ic_scsi_cmd_msg_alloc",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte "Unable to find symbol - stmf_ic_scsi_cmd_msg_alloc");
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ddi_modsym(pppt_mod, "stmf_ic_scsi_data_xfer_done_msg_alloc",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte "Unable to find symbol -"
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte "stmf_ic_scsi_data_xfer_done_msg_alloc");
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ddi_modsym(pppt_mod, "stmf_ic_session_create_msg_alloc",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte "Unable to find symbol -"
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte "stmf_ic_session_create_msg_alloc");
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ddi_modsym(pppt_mod, "stmf_ic_session_destroy_msg_alloc",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte "Unable to find symbol -"
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte "stmf_ic_session_destroy_msg_alloc");
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (stmf_ic_tx_msg_func_t)ddi_modsym(pppt_mod, "stmf_ic_tx_msg",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte cmn_err(CE_WARN, "Unable to find symbol - stmf_ic_tx_msg");
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (stmf_ic_msg_free_func_t)ddi_modsym(pppt_mod, "stmf_ic_msg_free",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte cmn_err(CE_WARN, "Unable to find symbol - stmf_ic_msg_free");
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_get_alua_state(stmf_alua_state_desc_t *alua_state)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte alua_state->alua_node = stmf_state.stmf_alua_node;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte alua_state->alua_state = stmf_state.stmf_alua_state;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_set_alua_state(stmf_alua_state_desc_t *alua_state)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (alua_state->alua_state > 1 || alua_state->alua_node > 1) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* reset existing rtpids to new base */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_state.stmf_alua_node = alua_state->alua_node;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* register existing local ports with ppp */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
cd36db67f9470c74ed7f5bbd57ec6eeb84f71fcdJohn Forte /* skip standby ports and non-alua participants */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte "error on port registration "
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte "port - %s",
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* register existing logical units */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* register with proxy module */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (lu->lu_lp && lu->lu_lp->lp_lpif_rev == LPIF_REV_2 &&
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* allocate the register message */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* send the message */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortetypedef struct {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void *bp; /* back pointer from internal struct to main struct */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortetypedef struct {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte} stmf_sizes[] = { { 0, 0 },
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_alloc(stmf_struct_id_t struct_id, int additional_size, int flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((struct_id == 0) || (struct_id >= STMF_MAX_STRUCT_IDS))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((curthread->t_flag & T_INTR_THREAD) || (flags & AF_FORCE_NOSLEEP)) {
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore sh = (__stmf_t *)kmem_alloc(stmf_size, kmem_flag);
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore sh = (__stmf_t *)kmem_zalloc(stmf_size, kmem_flag);
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * In principle, the implementation inside stmf_alloc should not
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * be changed anyway. But the original order of framework private
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * data and caller private data does not support sglist in the caller
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * private data.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * To work around this, the memory segments of framework private
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * data and caller private data are re-ordered here.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * A better solution is to provide a specific interface to allocate
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * the sglist, then we will not need this workaround any more.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * But before the new interface is available, the memory segment
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang * ordering should be kept as is.
2a8164df8a5f42c8a00f10c67d7bc84f80ae9c41Zhong Wang sh->cp = GET_BYTE_OFFSET(sh, stmf_sizes[struct_id].shared);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Just store the total size instead of storing additional size */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * So far we dont need any struct specific processing. If such
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a need ever arises, then store the struct id in the framework
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * private section and get it here as sh->fp->struct_id.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Given a pointer to stmf_lu_t, verifies if this lu is registered with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * framework and returns a pointer to framework private data for the lu.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns NULL if the lu was not found.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ilu = stmf_state.stmf_ilulist; ilu != NULL; ilu = ilu->ilu_next) {
1b7fc709228029b3f29f1c3de6d817a476f7c583tim szeto * Given a pointer to stmf_local_port_t, verifies if this lport is registered
1b7fc709228029b3f29f1c3de6d817a476f7c583tim szeto * with the framework and returns a pointer to framework private data for
1b7fc709228029b3f29f1c3de6d817a476f7c583tim szeto * the lport.
1b7fc709228029b3f29f1c3de6d817a476f7c583tim szeto * Returns NULL if the lport was not found.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_lu_provider_t *ilp = (stmf_i_lu_provider_t *)lp->lp_stmf_private;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (lp->lp_lpif_rev != LPIF_REV_1 && lp->lp_lpif_rev != LPIF_REV_2)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* See if we need to do a callback */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ppd = stmf_state.stmf_ppdlist; ppd != NULL; ppd = ppd->ppd_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_config_state == STMF_CONFIG_INIT)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lp->lp_cb(lp, STMF_PROVIDER_DATA_UPDATED, ppd->ppd_nv, cb_flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_deregister_lu_provider(stmf_lu_provider_t *lp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_lu_provider_t *ilp = (stmf_i_lu_provider_t *)lp->lp_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ppilp = &stmf_state.stmf_ilplist; *ppilp != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_register_port_provider(stmf_port_provider_t *pp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* See if we need to do a callback */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ppd = stmf_state.stmf_ppdlist; ppd != NULL; ppd = ppd->ppd_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_config_state == STMF_CONFIG_INIT)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pp->pp_cb(pp, STMF_PROVIDER_DATA_UPDATED, ppd->ppd_nv, cb_flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_deregister_port_provider(stmf_port_provider_t *pp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ppipp = &stmf_state.stmf_ipplist; *ppipp != NULL;
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetostmf_load_ppd_ioctl(stmf_ppioctl_data_t *ppi, uint64_t *ppi_token,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ppi->ppi_lu_provider + ppi->ppi_port_provider) != 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ppd = stmf_state.stmf_ppdlist; ppd != NULL; ppd = ppd->ppd_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strncmp(ppi->ppi_name, ppd->ppd_name, 254) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* New provider */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (s > 254) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* See if this provider already exists */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Link this ppd in */
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto * User is requesting that the token be checked.
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto * If there was another set after the user's get
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto * it's an error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (size_t)ppi->ppi_data_size, &nv, KM_NOSLEEP)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Free any existing lists and add this one to the ppd */
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto /* set the token for writes */
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto /* return token to caller */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* If there is a provider registered, do the notifications */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_config_state == STMF_CONFIG_INIT)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_PROVIDER_DATA_UPDATED, ppd->ppd_nv, cb_flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ipp = (stmf_i_port_provider_t *)ppd->ppd_provider;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_PROVIDER_DATA_UPDATED, ppd->ppd_nv, cb_flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (pppd = &stmf_state.stmf_ppdlist; *pppd != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ppi->ppi_lu_provider + ppi->ppi_port_provider) != 1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ppd = stmf_state.stmf_ppdlist; ppd != NULL; ppd = ppd->ppd_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strncmp(ppi->ppi_name, ppd->ppd_name, 254) == 0)
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetostmf_get_ppd_ioctl(stmf_ppioctl_data_t *ppi, stmf_ppioctl_data_t *ppi_out,
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto if ((ppi->ppi_lu_provider + ppi->ppi_port_provider) != 1) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto for (ppd = stmf_state.stmf_ppdlist; ppd != NULL; ppd = ppd->ppd_next) {
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto if (strncmp(ppi->ppi_name, ppd->ppd_name, 254) == 0)
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto if ((ret = nvlist_pack(ppd->ppd_nv, &bufp, &req_size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ppd = stmf_state.stmf_ppdlist; ppd != NULL; ppd = nppd) {
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto * 16 is the max string length of a protocol_ident, increase
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto * the size if needed.
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto#define STMF_KSTAT_LU_SZ (STMF_GUID_INPUT + 1 + 256)
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto * This array matches the Protocol Identifier in stmf_ioctl.h
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto "Fibre Channel",
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto "Parallel SCSI",
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto "IEEE_1394",
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto * Update the lun wait/run queue count
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szetostmf_update_kstat_lu_q(scsi_task_t *task, void func())
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto * Update the target(lport) wait/run queue count
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szetostmf_update_kstat_lport_q(scsi_task_t *task, void func())
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto ilp = (stmf_i_local_port_t *)task->task_lport->lport_stmf_private;
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto if (ilp != NULL && ilp->ilport_kstat_io != NULL) {
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szetostmf_update_kstat_lport_io(scsi_task_t *task, stmf_data_buf_t *dbuf)
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto ilp = (stmf_i_local_port_t *)task->task_lport->lport_stmf_private;
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto if (ilp != NULL && ilp->ilport_kstat_io != NULL) {
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szetostmf_update_kstat_lu_io(scsi_task_t *task, stmf_data_buf_t *dbuf)
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto /* create kstat lun info */
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto ks_lu = (stmf_kstat_lu_info_t *)kmem_zalloc(STMF_KSTAT_LU_SZ,
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto (void) sprintf(ks_nm, "stmf_lu_%"PRIxPTR"", (uintptr_t)ilu);
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto if ((ilu->ilu_kstat_info = kstat_create(STMF_MODULE_NAME, 0,
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto sizeof (stmf_kstat_lu_info_t) / sizeof (kstat_named_t),
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto ilu->ilu_kstat_info->ks_data_size = STMF_KSTAT_LU_SZ;
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto kstat_named_init(&ks_lu->i_lun_alias, "lun-alias",
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto /* convert guid to hex string */
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto bzero(ilu->ilu_ascii_hex_guid, sizeof (ilu->ilu_ascii_hex_guid));
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto (void) sprintf(&ilu->ilu_ascii_hex_guid[i * 2], "%02x", p[i]);
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto /* create kstat lun io */
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto (void) sprintf(ks_nm, "stmf_lu_io_%"PRIxPTR"", (uintptr_t)ilu);
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto if ((ilu->ilu_kstat_io = kstat_create(STMF_MODULE_NAME, 0,
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto cmn_err(CE_WARN, "STMF: kstat_create lu_io failed");
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto mutex_init(&ilu->ilu_kstat_lock, NULL, MUTEX_DRIVER, 0);
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto ilu->ilu_kstat_io->ks_lock = &ilu->ilu_kstat_lock;
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szetostmf_create_kstat_lport(stmf_i_local_port_t *ilport)
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto /* create kstat lport info */
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto ks_tgt = (stmf_kstat_tgt_info_t *)kmem_zalloc(STMF_KSTAT_TGT_SZ,
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto (void) sprintf(ks_nm, "stmf_tgt_%"PRIxPTR"", (uintptr_t)ilport);
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto if ((ilport->ilport_kstat_info = kstat_create(STMF_MODULE_NAME,
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto sizeof (stmf_kstat_tgt_info_t) / sizeof (kstat_named_t),
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto cmn_err(CE_WARN, "STMF: kstat_create target failed");
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto ilport->ilport_kstat_info->ks_data_size = STMF_KSTAT_TGT_SZ;
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto kstat_named_init(&ks_tgt->i_tgt_name, "target-name",
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto kstat_named_init(&ks_tgt->i_tgt_alias, "target-alias",
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto /* ident might not be null terminated */
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto len = ilport->ilport_lport->lport_id->ident_length;
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto /* protocol */
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto if ((id = ilport->ilport_lport->lport_id->protocol_id) > PROTOCOL_ANY) {
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto cmn_err(CE_WARN, "STMF: protocol_id out of bound");
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto kstat_named_setstr(&ks_tgt->i_protocol, protocol_ident[id]);
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto /* create kstat lport io */
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto (void) sprintf(ks_nm, "stmf_tgt_io_%"PRIxPTR"", (uintptr_t)ilport);
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto if ((ilport->ilport_kstat_io = kstat_create(STMF_MODULE_NAME, 0,
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto cmn_err(CE_WARN, "STMF: kstat_create target_io failed");
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto mutex_init(&ilport->ilport_kstat_lock, NULL, MUTEX_DRIVER, 0);
034d83c4b3be1c9bbe03552a652ebb90d4d66885tim szeto ilport->ilport_kstat_io->ks_lock = &ilport->ilport_kstat_lock;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * set the asymmetric access state for a logical unit
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * caller is responsible for establishing SCSI unit attention on
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * state change
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_set_lu_access(stmf_lu_t *lu, uint8_t access_state)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte for (ilu = stmf_state.stmf_ilulist; ilu != NULL; ilu = ilu->ilu_next) {
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * We're changing access state on an existing logical unit
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * Send the proxy registration message for this logical unit
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * if we're in alua mode.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * If the requested state is STMF_LU_ACTIVE, we want to register
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * this logical unit.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * If the requested state is STMF_LU_STANDBY, we're going to
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * abort all tasks for this logical unit.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_status_t ic_ret = STMF_IC_MSG_SUCCESS;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (lu->lu_lp && lu->lu_lp->lp_lpif_rev == LPIF_REV_2 &&
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* allocate the register message */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* send the message */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* abort all tasks for this lu */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ilu = stmf_state.stmf_ilulist; ilu != NULL; ilu = ilu->ilu_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte luid = stmf_lookup_id(&stmf_state.stmf_luid_list,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * register with proxy module if available and logical unit
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * is in active state
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_status_t ic_ret = STMF_IC_MSG_SUCCESS;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (lu->lu_lp && lu->lu_lp->lp_lpif_rev == LPIF_REV_2 &&
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* allocate the register message */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (uint8_t *)lu->lu_proxy_reg_arg, stmf_proxy_msg_id);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* send the message */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX we should probably check if this lu can be brought online */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX: Generate event */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_wait(&stmf_state.stmf_cv, &stmf_state.stmf_lock);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* de-register with proxy if available */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* de-register with proxy module */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_ic_msg_status_t ic_ret = STMF_IC_MSG_SUCCESS;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte if (lu->lu_lp && lu->lu_lp->lp_lpif_rev == LPIF_REV_2 &&
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* allocate the de-register message */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* send the message */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_state.stmf_svc_ilu_draining = ilu->ilu_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((stmf_id_data_t *)ilu->ilu_luid)->id_pt_to_object =
427fcaf873956aad428be801380a44e59d38b8b5tim szeto stmf_delete_itl_kstat_by_guid(ilu->ilu_ascii_hex_guid);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_set_port_standby(stmf_local_port_t *lport, uint16_t rtpid)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte (stmf_i_local_port_t *)lport->lport_stmf_private;
cd36db67f9470c74ed7f5bbd57ec6eeb84f71fcdJohn Forte (stmf_i_local_port_t *)lport->lport_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_register_local_port(stmf_local_port_t *lport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilport = (stmf_i_local_port_t *)lport->lport_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rw_init(&ilport->ilport_lock, NULL, RW_DRIVER, NULL);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto id_alloc_nosleep(stmf_state.stmf_ilport_inst_space);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilport->ilport_next = stmf_state.stmf_ilportlist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_lookup_group_for_target(lport->lport_id->ident,
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * rtpid will/must be set if this is a standby port
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * only register ports that are not standby (proxy) ports
cd36db67f9470c74ed7f5bbd57ec6eeb84f71fcdJohn Forte * and ports that are alua participants (ilport_alua == 1)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ilport->ilport_rtpid = atomic_add_16_nv(&stmf_rtpid_counter, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_EVENT_ALLOC_HANDLE(ilport->ilport_event_hdl);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_workers_state == STMF_WORKERS_DISABLED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX we should probably check if this lport can be brought online */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) stmf_ctl(STMF_CMD_LPORT_ONLINE, lport, &ssci);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX: Generate event */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_deregister_local_port(stmf_local_port_t *lport)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilport = (stmf_i_local_port_t *)lport->lport_stmf_private;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * deregister ports that are not standby (proxy)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilport->ilport_next->ilport_prev = ilport->ilport_prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilport->ilport_prev->ilport_next = ilport->ilport_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_state.stmf_ilportlist = ilport->ilport_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_EVENT_FREE_HANDLE(ilport->ilport_event_hdl);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto stmf_delete_itl_kstat_by_lport(ilport->ilport_kstat_tgt_name);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * Rport id/instance mappings remain valid until STMF is unloaded
427fcaf873956aad428be801380a44e59d38b8b5tim szetostmf_irport_compare(const void *void_irport1, const void *void_irport2)
427fcaf873956aad428be801380a44e59d38b8b5tim szeto const stmf_i_remote_port_t *irport1 = void_irport1;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto const stmf_i_remote_port_t *irport2 = void_irport2;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto /* Sort by code set then ident */
427fcaf873956aad428be801380a44e59d38b8b5tim szeto return (-1);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto /* Next by ident length */
427fcaf873956aad428be801380a44e59d38b8b5tim szeto return (-1);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto /* Code set and ident length both match, now compare idents */
427fcaf873956aad428be801380a44e59d38b8b5tim szeto return (-1);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto } else if (result > 0) {
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * Lookup will bump the refcnt if there's an existing rport
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * context for this identifier.
427fcaf873956aad428be801380a44e59d38b8b5tim szeto alloc_len = sizeof (*irport) + sizeof (scsi_devid_desc_t) +
427fcaf873956aad428be801380a44e59d38b8b5tim szeto id_alloc_nosleep(stmf_state.stmf_irport_inst_space);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto (struct scsi_devid_desc *)(irport + 1); /* Ptr. Arith. */
427fcaf873956aad428be801380a44e59d38b8b5tim szeto sizeof (scsi_devid_desc_t) + rport_devid->ident_length - 1);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto mutex_init(&irport->irport_mutex, NULL, MUTEX_DEFAULT, NULL);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto id_free(stmf_state.stmf_irport_inst_space, irport->irport_instance);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kmem_free(irport, sizeof (*irport) + sizeof (scsi_devid_desc_t) +
427fcaf873956aad428be801380a44e59d38b8b5tim szetostmf_irport_register(scsi_devid_desc_t *rport_devid)
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * Lookup will bump the refcnt if there's an existing rport
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * context for this identifier.
427fcaf873956aad428be801380a44e59d38b8b5tim szeto if ((irport = stmf_irport_lookup_locked(rport_devid)) != NULL) {
427fcaf873956aad428be801380a44e59d38b8b5tim szetostmf_irport_lookup_locked(scsi_devid_desc_t *rport_devid)
427fcaf873956aad428be801380a44e59d38b8b5tim szeto irport = avl_find(&stmf_state.stmf_irportlist, &tmp_irport, NULL);
427fcaf873956aad428be801380a44e59d38b8b5tim szetostmf_irport_deregister(stmf_i_remote_port_t *irport)
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * If we were actually going to remove unreferenced remote ports
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * we would want to acquire stmf_state.stmf_lock before getting
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * the irport mutex.
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * Instead we're just going to leave it there even if unreferenced.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Port provider has to make sure that register/deregister session and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * port are serialized calls.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_register_scsi_session(stmf_local_port_t *lport, stmf_scsi_session_t *ss)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_local_port_t *ilport = (stmf_i_local_port_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Port state has to be online to register a scsi session. It is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * possible that we started an offline operation and a new SCSI
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * session started at the same time (in that case also we are going
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to fail the registeration). But any other state is simply
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a bad port provider implementation.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilport->ilport_state != STMF_STATE_OFFLINING) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(lport->lport_alias, "Port is trying to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "register a session while the state is neither "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "online nor offlining");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto if ((iss->iss_irport = stmf_irport_register(ss->ss_rport_id)) == NULL) {
427fcaf873956aad428be801380a44e59d38b8b5tim szeto stmf_trace(lport->lport_alias, "Could not register "
427fcaf873956aad428be801380a44e59d38b8b5tim szeto "remote port during session registration");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* sessions use the ilport_lock. No separate lock is required */
780c822c86101e82568fa9e357d13965b9f0cf81tim szeto cmn_err(CE_PANIC, "create lun map called with non NULL map");
780c822c86101e82568fa9e357d13965b9f0cf81tim szeto iss->iss_sm = (stmf_lun_map_t *)kmem_zalloc(sizeof (stmf_lun_map_t),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ss->ss_session_id = atomic_add_64_nv(&stmf_session_counter, 1);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* XXX should we remove ISS_LUN_INVENTORY_CHANGED on new session? */
e17f3b2227c590f1d761b9ec4613cfb05982e6abtim szeto DTRACE_PROBE2(session__online, stmf_local_port_t *, lport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_deregister_scsi_session(stmf_local_port_t *lport, stmf_scsi_session_t *ss)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_local_port_t *ilport = (stmf_i_local_port_t *)
e17f3b2227c590f1d761b9ec4613cfb05982e6abtim szeto DTRACE_PROBE2(session__offline, stmf_local_port_t *, lport,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* dereg proxy session if not standby port */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ppss = &ilport->ilport_ss_list; *ppss != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_PANIC, "Deregister session called for non existent"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " session");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) stmf_session_destroy_lun_map(ilport, iss);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_session_id_to_issptr(uint64_t session_id, int stay_locked)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
427fcaf873956aad428be801380a44e59d38b8b5tim szetostmf_itl_kstat_compare(const void *itl_kstat_1, const void *itl_kstat_2)
427fcaf873956aad428be801380a44e59d38b8b5tim szeto const stmf_i_itl_kstat_t *kstat_nm1 = itl_kstat_1;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto const stmf_i_itl_kstat_t *kstat_nm2 = itl_kstat_2;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto ret = strcmp(kstat_nm1->iitl_kstat_nm, kstat_nm2->iitl_kstat_nm);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto return (-1);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto } else if (ret > 0) {
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itl_kstat = avl_find(&stmf_state.stmf_itl_kstat_list, &tmp, NULL);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto ks_itl = avl_first(&stmf_state.stmf_itl_kstat_list);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto next = AVL_NEXT(&stmf_state.stmf_itl_kstat_list, ks_itl);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto avl_remove(&stmf_state.stmf_itl_kstat_list, ks_itl);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto ks_itl = avl_first(&stmf_state.stmf_itl_kstat_list);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto next = AVL_NEXT(&stmf_state.stmf_itl_kstat_list, ks_itl);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto avl_remove(&stmf_state.stmf_itl_kstat_list, ks_itl);
427fcaf873956aad428be801380a44e59d38b8b5tim szetostmf_itl_kstat_create(stmf_itl_data_t *itl, char *nm,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto bcopy(lport->ident, ks_itl->iitl_kstat_lport, lport->ident_length);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto ks_itl->iitl_kstat_lport[lport->ident_length] = '\0';
427fcaf873956aad428be801380a44e59d38b8b5tim szeto (void) sprintf(&ks_itl->iitl_kstat_guid[i * 2], "%02x",
427fcaf873956aad428be801380a44e59d38b8b5tim szeto lun->ident[i]);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto ks_itl->iitl_kstat_strbuf = itl->itl_kstat_strbuf;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto ks_itl->iitl_kstat_strbuflen = itl->itl_kstat_strbuflen;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto ks_itl->iitl_kstat_lu_xfer = itl->itl_kstat_lu_xfer;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto ks_itl->iitl_kstat_lport_xfer = itl->itl_kstat_lport_xfer;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * Allocate enough memory in the ITL to hold the relevant
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * identifiers.
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * rport and lport identifiers come from the stmf_scsi_session_t.
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * ident might not be null terminated.
427fcaf873956aad428be801380a44e59d38b8b5tim szeto iss->iss_irport->irport_instance, ilport->ilport_instance,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto (void) snprintf(ks_itl_nm, KSTAT_STRLEN, "itl_%s", ks_itl_id);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * let's verify this itl_kstat already exist
427fcaf873956aad428be801380a44e59d38b8b5tim szeto if ((tmp_kstat = stmf_itl_kstat_lookup(ks_itl_nm)) != NULL) {
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itl->itl_kstat_strbuf = tmp_kstat->iitl_kstat_strbuf;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itl->itl_kstat_strbuflen = tmp_kstat->iitl_kstat_strbuflen;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itl->itl_kstat_taskq = tmp_kstat->iitl_kstat_taskq;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itl->itl_kstat_lu_xfer = tmp_kstat->iitl_kstat_lu_xfer;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itl->itl_kstat_lport_xfer = tmp_kstat->iitl_kstat_lport_xfer;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto /* New itl_kstat */
427fcaf873956aad428be801380a44e59d38b8b5tim szeto lport_alias = (ss->ss_lport->lport_alias == NULL) ?
427fcaf873956aad428be801380a44e59d38b8b5tim szeto lu_alias = (itl->itl_ilu->ilu_lu->lu_alias == NULL) ?
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itl->itl_kstat_strbuflen = (ss->ss_rport_id->ident_length + 1) +
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itl->itl_kstat_strbuf = kmem_zalloc(itl->itl_kstat_strbuflen,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto ks_itl = (stmf_kstat_itl_info_t *)kmem_zalloc(sizeof (*ks_itl),
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kmem_free(itl->itl_kstat_strbuf, itl->itl_kstat_strbuflen);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto if ((itl->itl_kstat_info = kstat_create(STMF_MODULE_NAME,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto sizeof (stmf_kstat_itl_info_t) / sizeof (kstat_named_t),
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itl->itl_kstat_info->ks_data_size += itl->itl_kstat_strbuflen;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_init(&ks_itl->i_rport_name, "rport-name",
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_init(&ks_itl->i_rport_alias, "rport-alias",
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_init(&ks_itl->i_lport_name, "lport-name",
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_init(&ks_itl->i_lport_alias, "lport-alias",
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_init(&ks_itl->i_lu_number, "lu-number",
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_init(&ks_itl->i_task_waitq_elapsed, "task-waitq-elapsed",
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_init(&ks_itl->i_task_read_elapsed, "task-read-elapsed",
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_init(&ks_itl->i_task_write_elapsed, "task-write-elapsed",
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_init(&ks_itl->i_lu_read_elapsed, "lu-read-elapsed",
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_init(&ks_itl->i_lu_write_elapsed, "lu-write-elapsed",
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_init(&ks_itl->i_lport_read_elapsed, "lport-read-elapsed",
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_init(&ks_itl->i_lport_write_elapsed, "lport-write-elapsed",
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_setstr(&ks_itl->i_rport_name, strbuf - len);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_setstr(&ks_itl->i_rport_alias, strbuf);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto bcopy(ss->ss_lport->lport_id->ident, strbuf, len);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_setstr(&ks_itl->i_lport_name, strbuf - len);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_setstr(&ks_itl->i_lport_alias, strbuf);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto id = (ss->ss_lport->lport_id->protocol_id > PROTOCOL_ANY) ?
427fcaf873956aad428be801380a44e59d38b8b5tim szeto PROTOCOL_ANY : ss->ss_lport->lport_id->protocol_id;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_named_setstr(&ks_itl->i_protocol, protocol_ident[id]);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto /* Now create the I/O kstats */
427fcaf873956aad428be801380a44e59d38b8b5tim szeto (void) snprintf(ks_nm, KSTAT_STRLEN, "itl_tasks_%s", ks_itl_id);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto if ((itl->itl_kstat_taskq = kstat_create(STMF_MODULE_NAME, 0,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto (void) snprintf(ks_nm, KSTAT_STRLEN, "itl_lu_%s", ks_itl_id);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto if ((itl->itl_kstat_lu_xfer = kstat_create(STMF_MODULE_NAME, 0,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto (void) snprintf(ks_nm, KSTAT_STRLEN, "itl_lport_%s", ks_itl_id);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto if ((itl->itl_kstat_lport_xfer = kstat_create(STMF_MODULE_NAME, 0,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto /* Install all the kstats */
427fcaf873956aad428be801380a44e59d38b8b5tim szeto /* Add new itl_kstat to stmf_itl_kstat_list */
427fcaf873956aad428be801380a44e59d38b8b5tim szeto if (stmf_itl_kstat_create(itl, ks_itl_nm, ss->ss_lport->lport_id,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kmem_free(itl->itl_kstat_strbuf, itl->itl_kstat_strbuflen);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto cmn_err(CE_WARN, "STMF: kstat_create itl failed");
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kmem_free(ks->iitl_kstat_info->ks_data, sizeof (stmf_kstat_itl_info_t));
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kmem_free(ks->iitl_kstat_strbuf, ks->iitl_kstat_strbuflen);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_release_itl_handle(stmf_lu_t *lu, stmf_itl_data_t *itl)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(itl->itl_flags & STMF_ITL_BEING_TERMINATED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (itlpp = &ilu->ilu_itl_list; (*itlpp) != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lu->lu_abort(lu, STMF_LU_ITL_HANDLE_REMOVED, itl->itl_handle,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_register_itl_handle(stmf_lu_t *lu, uint8_t *lun,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_scsi_session_t *ss, uint64_t session_id, void *itl_handle)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
a8e2ef8ffd76e062a138e86bdafe5484f62f6b5btim szeto * Acquire stmf_lock for stmf_itl_kstat_lookup.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte n = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((lun_map_ent == NULL) || (lun_map_ent->ent_lu != lu)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte itl = (stmf_itl_data_t *)kmem_zalloc(sizeof (*itl), KM_NOSLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_do_itl_dereg(stmf_lu_t *lu, stmf_itl_data_t *itl, uint8_t hdlrm_reason)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_8(&itl->itl_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Something changed, start all over */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(itl_list, nmaps * sizeof (stmf_itl_data_t *));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } /* lun table for a session */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } /* sessions */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } /* ports */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < nu; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(itl_list, nmaps * sizeof (stmf_itl_data_t *));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_deregister_itl_handle(stmf_lu_t *lu, uint8_t *lun,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_scsi_session_t *ss, uint64_t session_id, void *itl_handle)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte n = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (ent->ent_itl_datap->itl_handle == itl_handle)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_do_itl_dereg(lu, itl, STMF_ITL_REASON_DEREG_REQUEST);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_get_itl_handle(stmf_lu_t *lu, uint8_t *lun, stmf_scsi_session_t *ss,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte n = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *itl_handle_retp = ent->ent_itl_datap->itl_handle;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_alloc_dbuf(scsi_task_t *task, uint32_t size, uint32_t *pminsize,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ndx = stmf_first_zero[itask->itask_allocated_buf_map];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dbuf = itask->itask_dbufs[ndx] = lport->lport_ds->ds_alloc_data_buf(
3fb517f786391b507780c78aabb8d98bfea9efe9James Moorestmf_setup_dbuf(scsi_task_t *task, stmf_data_buf_t *dbuf, uint32_t flags)
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore ASSERT(task->task_additional_flags & TASK_AF_ACCEPT_LU_DBUF);
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore if ((task->task_additional_flags & TASK_AF_ACCEPT_LU_DBUF) == 0)
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore ndx = stmf_first_zero[itask->itask_allocated_buf_map];
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore ret = lport->lport_ds->ds_setup_dbuf(task, dbuf, flags);
3fb517f786391b507780c78aabb8d98bfea9efe9James Moorestmf_teardown_dbuf(scsi_task_t *task, stmf_data_buf_t *dbuf)
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore ASSERT(task->task_additional_flags & TASK_AF_ACCEPT_LU_DBUF);
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore ASSERT(lport->lport_ds->ds_teardown_dbuf != NULL);
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore itask->itask_allocated_buf_map &= ~(1 << dbuf->db_handle);
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore lport->lport_ds->ds_teardown_dbuf(lport->lport_ds, dbuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_free_dbuf(scsi_task_t *task, stmf_data_buf_t *dbuf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte itask->itask_allocated_buf_map &= ~(1 << dbuf->db_handle);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport->lport_ds->ds_free_data_buf(lport->lport_ds, dbuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte itask = (stmf_i_scsi_task_t *)task->task_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_task_alloc(struct stmf_local_port *lport, stmf_scsi_session_t *ss,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t *lun, uint16_t cdb_length_in, uint16_t ext_id)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We allocate 7 extra bytes for CDB to provide a cdb pointer which
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is guaranteed to be 8 byte aligned. Some LU providers like OSD
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * depend upon this alignment.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iss = (stmf_i_scsi_session_t *)ss->ss_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte luNbr = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (stmf_lun_map_ent_t *)stmf_get_ent_from_map(iss->iss_sm, luNbr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ppitask = &ilu->ilu_free_tasks; (*ppitask != NULL) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilu->ilu_ntasks_free < ilu->ilu_ntasks_min_free)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CONSTCOND */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (0);
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore * Save the task_cdb pointer and zero per cmd fields.
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore * We know the task_cdb_length is large enough by task
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore * selection process above.
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore bzero((void *)t_start, (size_t)(t_end - t_start));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte task = (scsi_task_t *)stmf_alloc(STMF_STRUCT_SCSI_TASK,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte task->task_cdb = (uint8_t *)task->task_port_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte itask = (stmf_i_scsi_task_t *)task->task_stmf_private;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itask->itask_lu_read_time = itask->itask_lu_write_time = 0;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itask->itask_lport_read_time = itask->itask_lport_write_time = 0;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itask->itask_read_xfer = itask->itask_write_xfer = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* kmem_zalloc automatically makes itask->itask_lu_prev NULL */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte itask->itask_ilu_task_cntr = ilu->ilu_cur_task_cntr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((lun_map_ent != NULL) && ((itask->itask_itl_datap =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_add_32(&itask->itask_itl_datap->itl_counter, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte task->task_lu_itl_handle = itask->itask_itl_datap->itl_handle;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Fortestmf_task_lu_free(scsi_task_t *task, stmf_i_scsi_session_t *iss)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_lu_t *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(ilu->ilu_ntasks_min_free <= ilu->ilu_ntasks_free);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* free half of the minimal free of the free tasks */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_to_release = (ilu->ilu_ntasks_min_free + 1) / 2;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Called with stmf_lock held
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clock_t endtime = ddi_get_lbolt() + drv_usectohz(10000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* stmf_svc_ilu_draining may get changed after stmf_lock is released */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((ilu = stmf_state.stmf_svc_ilu_draining) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_state.stmf_svc_ilu_draining = ilu->ilu_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we do not care about the accuracy of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ilu_ntasks_min_free, so we don't lock here
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Called with stmf_lock held
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte clock_t endtime = ddi_get_lbolt() + drv_usectohz(10000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* stmf_svc_ilu_timing may get changed after stmf_lock is released */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((ilu = stmf_state.stmf_svc_ilu_timing) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilu->ilu_cur_task_cntr == (&ilu->ilu_task_cntr1)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we are here then it means that there is some slowdown
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in tasks on this lu. We need to check.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Kills all tasks on a lu except tm_task
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_task_lu_killall(stmf_lu_t *lu, scsi_task_t *tm_task, stmf_status_t s)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_lu_t *ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_abort(STMF_QUEUE_TASK_ABORT, itask->itask_task, s, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_free_task_bufs(stmf_i_scsi_task_t *itask, stmf_local_port_t *lport)
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore if ((map = itask->itask_allocated_buf_map) == 0)
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore for (i = 0; i < 4; i++) {
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore * LU needs to clean up buffer.
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore * LU is required to free the buffer
3fb517f786391b507780c78aabb8d98bfea9efe9James Moore * in the xfer_done handler.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_scsi_task_t *itask = (stmf_i_scsi_task_t *)
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte stmf_i_scsi_session_t *iss = (stmf_i_scsi_session_t *)
427fcaf873956aad428be801380a44e59d38b8b5tim szeto DTRACE_PROBE2(stmf__task__end, scsi_task_t *, task,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itask->itask_done_timestamp - itask->itask_start_timestamp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (atomic_add_32_nv(&itask->itask_itl_datap->itl_counter,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_add_32(&itask->itask_worker->worker_ref_count, -1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * After calling stmf_task_lu_free, the task pointer can no longer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be trusted.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_post_task(scsi_task_t *task, stmf_data_buf_t *dbuf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_scsi_task_t *itask = (stmf_i_scsi_task_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_lu_t *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Latest value of currently running tasks */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Select the next worker using round robin */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nv = (int)atomic_add_32_nv((uint32_t *)&stmf_worker_sel_counter, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Its ok if this cas fails */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) atomic_cas_32((uint32_t *)&stmf_worker_sel_counter,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A worker can be pinned by interrupt. So select the next one
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if it has lower load.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (w1->worker_queue_depth < w->worker_queue_depth)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((w->worker_flags & STMF_WORKER_STARTED) == 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Maybe we are in the middle of a change. Just go to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the 1st worker.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Track max system load inside the worker as we already have the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * worker lock (no point implementing another lock). The service
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * thread will do the comparisons and figure out the max overall
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * system load.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new |= ITASK_KNOWN_TO_TGT_PORT | ITASK_IN_WORKER_QUEUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (task->task_cdb[0] == SCMD_REPORT_LUNS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (++(w->worker_queue_depth) > w->worker_max_qdepth_pu) {
427fcaf873956aad428be801380a44e59d38b8b5tim szeto /* Measure task waitq time */
427fcaf873956aad428be801380a44e59d38b8b5tim szeto if ((w->worker_flags & STMF_WORKER_ACTIVE) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This can only happen if during stmf_task_alloc(), ILU_RESET_ACTIVE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * was set between checking of ILU_RESET_ACTIVE and clearing of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ITASK_IN_FREE_LIST flag. Take care of these "sneaked-in" tasks here.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_abort(STMF_QUEUE_TASK_ABORT, task, STMF_ABORTED, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ++++++++++++++ ABORT LOGIC ++++++++++++++++++++
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Once ITASK_BEING_ABORTED is set, ITASK_KNOWN_TO_LU can be reset already
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * i.e. before ITASK_BEING_ABORTED being set. But if it was not, it cannot
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be reset until the LU explicitly calls stmf_task_lu_aborted(). Of course
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the LU will make this call only if we call the LU's abort entry point.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we will only call that entry point if ITASK_KNOWN_TO_LU was set.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Same logic applies for the port.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Also ITASK_BEING_ABORTED will not be allowed to set if both KNOWN_TO_LU
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and KNOWN_TO_TGT_PORT are reset.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * +++++++++++++++++++++++++++++++++++++++++++++++
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_xfer_data(scsi_task_t *task, stmf_data_buf_t *dbuf, uint32_t ioflags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto if (!(ioflags & STMF_IOF_STATS_ONLY) && stmf_drop_buf_counter > 0) {
5679c89fcd2facbb4334df8870d3d7a4d2b11673jv if (atomic_add_32_nv((uint32_t *)&stmf_drop_buf_counter, -1) ==
e17f3b2227c590f1d761b9ec4613cfb05982e6abtim szeto ret = task->task_lport->lport_xfer_data(task, dbuf, ioflags);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * Port provider may have already called the buffer callback in
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * which case dbuf->db_xfer_start_timestamp will be 0.
427fcaf873956aad428be801380a44e59d38b8b5tim szeto if ((ret != STMF_SUCCESS) && (dbuf->db_xfer_start_timestamp != 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_data_xfer_done(scsi_task_t *task, stmf_data_buf_t *dbuf, uint32_t iof)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte task->task_completion_status = dbuf->db_xfer_status;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the task is known to LU then queue it. But if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it is already queued (multiple completions) then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * just update the buffer information by grabbing the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * worker lock. If the task is not known to LU,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * completed/aborted, then see if we need to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * free this task.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint8_t cmd = (dbuf->db_handle << 5) | ITASK_CMD_DATA_XFER_DONE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte itask->itask_cmd_stack[itask->itask_ncmds++] = cmd;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto /* Measure task waitq time */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ITASK_KNOWN_TO_TGT_PORT | ITASK_IN_WORKER_QUEUE |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_send_scsi_status(scsi_task_t *task, uint32_t ioflags)
e17f3b2227c590f1d761b9ec4613cfb05982e6abtim szeto DTRACE_PROBE1(scsi__send__status, scsi_task_t *, task);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(itask->itask_flags & ITASK_KNOWN_TO_TGT_PORT)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (task->task_additional_flags & TASK_AF_NO_EXPECTED_XFER_LENGTH) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte task->task_resid = task->task_expected_xfer_length -
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (task->task_lport->lport_send_status(task, ioflags));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_send_status_done(scsi_task_t *task, stmf_status_t s, uint32_t iof)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the task is known to LU then queue it. But if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it is already queued (multiple completions) then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * just update the buffer information by grabbing the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * worker lock. If the task is not known to LU,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * completed/aborted, then see if we need to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * free this task.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " when task is already in worker queue "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto /* Measure task waitq time */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (++(w->worker_queue_depth) > w->worker_max_qdepth_pu) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ITASK_KNOWN_TO_TGT_PORT | ITASK_IN_WORKER_QUEUE |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_PANIC, "LU is done with the task but LPORT "
437be37266d159c6a27c02e61710a578bef3d15fJohn Forte " is not done, itask %p itask_flags %x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " when task is in worker queue "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ITASK_KNOWN_TO_TGT_PORT | ITASK_IN_WORKER_QUEUE |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_PANIC, "stmf_lu_done should be the last stage but "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " the task is still not done, task = %p", (void *)task);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_queue_task_for_abort(scsi_task_t *task, stmf_status_t s)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Queue it and get out */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (itask->itask_flags & ITASK_IN_WORKER_QUEUE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&itask->itask_flags, ITASK_IN_WORKER_QUEUE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (++(w->worker_queue_depth) > w->worker_max_qdepth_pu) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_abort(int abort_cmd, scsi_task_t *task, stmf_status_t s, void *arg)
e17f3b2227c590f1d761b9ec4613cfb05982e6abtim szeto DTRACE_PROBE2(scsi__task__abort, scsi_task_t *, task,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte itask = (stmf_i_scsi_task_t *)task->task_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((old & f) != f) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_task_lu_aborted(scsi_task_t *task, stmf_status_t s, uint32_t iof)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unsigned long long st;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((s != STMF_ABORT_SUCCESS) && (s != STMF_NOT_FOUND)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "task %p, lu failed to abort ret=%llx", (void *)task, st);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Task aborted but LU is not finished, task ="
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * LU abort successfully
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&itask->itask_flags, ~ITASK_KNOWN_TO_LU);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_task_lport_aborted(scsi_task_t *task, stmf_status_t s, uint32_t iof)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unsigned long long st;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((s != STMF_ABORT_SUCCESS) && (s != STMF_NOT_FOUND)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "task %p, tgt port failed to abort ret=%llx", (void *)task,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Task aborted but tgt port is not finished, "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "task=%p, s=%llx, iof=%x", (void *)task, st, iof);
554c2b163439bbe1231a5d9ff5b9b0045c510c69tim szeto * LPORT abort successfully
554c2b163439bbe1231a5d9ff5b9b0045c510c69tim szeto } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_task_poll_lu(scsi_task_t *task, uint32_t timeout)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_scsi_task_t *itask = (stmf_i_scsi_task_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (itask->itask_cmd_stack[i] == ITASK_CMD_POLL_LU) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte itask->itask_cmd_stack[itask->itask_ncmds++] = ITASK_CMD_POLL_LU;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((itask->itask_flags & ITASK_IN_WORKER_QUEUE) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (++(w->worker_queue_depth) > w->worker_max_qdepth_pu) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_or_32(&itask->itask_flags, ITASK_IN_WORKER_QUEUE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_task_poll_lport(scsi_task_t *task, uint32_t timeout)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_scsi_task_t *itask = (stmf_i_scsi_task_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(itask->itask_flags & ITASK_KNOWN_TO_TGT_PORT);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (itask->itask_cmd_stack[i] == ITASK_CMD_POLL_LPORT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte itask->itask_cmd_stack[itask->itask_ncmds++] = ITASK_CMD_POLL_LPORT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((itask->itask_flags & ITASK_IN_WORKER_QUEUE) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (++(w->worker_queue_depth) > w->worker_max_qdepth_pu) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unsigned long long ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((old & (ITASK_KNOWN_TO_LU | ITASK_LU_ABORT_CALLED)) ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((itask->itask_flags & ITASK_DEFAULT_HANDLING) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = lu->lu_abort(lu, STMF_LU_ABORT_TASK, task, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = dlun0->lu_abort(lu, STMF_LU_ABORT_TASK, task, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret == STMF_ABORT_SUCCESS) || (ret == STMF_NOT_FOUND)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_task_lu_aborted(task, ret, STMF_IOF_LU_DONE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Abort failed by LU %p, ret %llx", (void *)lu, ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (itask->itask_flags & ITASK_KNOWN_TO_LU) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lu->lu_abort_timeout : ITASK_DEFAULT_ABORT_TIMEOUT))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "lu abort timed out");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_abort_task_offline(itask->itask_task, 1, info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ITASK_TGT_PORT_ABORT_CALLED)) == ITASK_KNOWN_TO_TGT_PORT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
5679c89fcd2facbb4334df8870d3d7a4d2b11673jv ret = lport->lport_abort(lport, STMF_LPORT_ABORT_TASK, task, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret == STMF_ABORT_SUCCESS) || (ret == STMF_NOT_FOUND)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_task_lport_aborted(task, ret, STMF_IOF_LPORT_DONE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Abort failed by tgt port %p ret %llx",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (itask->itask_flags & ITASK_KNOWN_TO_TGT_PORT) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "lport abort timed out");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_abort_task_offline(itask->itask_task, 0, info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_state_change_info_t *ssci = (stmf_state_change_info_t *)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilport = stmf_lookup_lport((stmf_local_port_t *)obj);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_svc_queue(cmd, obj, (stmf_state_change_info_t *)arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((stmf_change_status_t *)arg)->st_completion_status ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_add_lu_to_active_sessions((stmf_lu_t *)obj);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* XXX: should throw a meesage an record more data */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_svc_queue(cmd, obj, (stmf_state_change_info_t *)arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((stmf_change_status_t *)arg)->st_completion_status ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_add_lu_to_active_sessions((stmf_lu_t *)obj);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * LPORT_ONLINE/OFFLINE has nothing to do with link offline/online.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It's related with hardware disable/enable.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Only user request can recover the port from the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * FORCED_OFFLINE state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilport->ilport_flags & ILPORT_FORCED_OFFLINE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(ssci->st_rflags & STMF_RFLAG_USER_REQUEST)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Avoid too frequent request to online
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ilport->ilport_avg_interval < STMF_AVG_ONLINE_INTERVAL) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(NULL, "stmf_ctl: too frequent request to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "online the port");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "stmf_ctl: too frequent request to "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "online the port, set FORCED_OFFLINE now");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilport->ilport_last_online_clock = ddi_get_lbolt();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Submit online service request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_svc_queue(cmd, obj, (stmf_state_change_info_t *)arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilport->ilport_state != STMF_STATE_ONLINING) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((stmf_change_status_t *)arg)->st_completion_status ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_svc_queue(cmd, obj, (stmf_state_change_info_t *)arg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ilport->ilport_state != STMF_STATE_OFFLINING) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((stmf_change_status_t *)arg)->st_completion_status ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "Invalid ctl cmd received %x", cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_info_impl(uint32_t cmd, void *arg1, void *arg2, uint8_t *buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_info(uint32_t cmd, void *arg1, void *arg2, uint8_t *buf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (stmf_info_impl(cmd, arg1, arg2, buf, bufsizep));
5679c89fcd2facbb4334df8870d3d7a4d2b11673jv return (((stmf_local_port_t *)arg1)->lport_info(cmd, arg1,
5679c89fcd2facbb4334df8870d3d7a4d2b11673jv return (((stmf_lu_t *)arg1)->lu_info(cmd, arg1, arg2, buf,
70c284ca5360ed73476d9e94223d4905dd80b1adPeter Cudhea - Sun Microsystems - Burlington, MA United States * Used by port providers. pwwn is 8 byte wwn, sdid is the devid used by
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * stmf to register local ports. The ident should have 20 bytes in buffer
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * space to convert the wwn to "wwn.xxxxxxxxxxxxxxxx" string.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_wwn_to_devid_desc(scsi_devid_desc_t *sdid, uint8_t *wwn,
70c284ca5360ed73476d9e94223d4905dd80b1adPeter Cudhea - Sun Microsystems - Burlington, MA United States char wwn_str[20+1];
70c284ca5360ed73476d9e94223d4905dd80b1adPeter Cudhea - Sun Microsystems - Burlington, MA United States
70c284ca5360ed73476d9e94223d4905dd80b1adPeter Cudhea - Sun Microsystems - Burlington, MA United States /* Convert wwn value to "wwn.XXXXXXXXXXXXXXXX" format */
70c284ca5360ed73476d9e94223d4905dd80b1adPeter Cudhea - Sun Microsystems - Burlington, MA United States (void) snprintf(wwn_str, sizeof (wwn_str),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "wwn.%02X%02X%02X%02X%02X%02X%02X%02X",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
70c284ca5360ed73476d9e94223d4905dd80b1adPeter Cudhea - Sun Microsystems - Burlington, MA United States bcopy(wwn_str, (char *)sdid->ident, 20);
70c284ca5360ed73476d9e94223d4905dd80b1adPeter Cudhea - Sun Microsystems - Burlington, MA United States
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte uint32_t sz, asz, nports = 0, nports_standby = 0;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* check if any ports are standby and create second group */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte for (ilport = stmf_state.stmf_ilportlist; ilport;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* The spec only allows for 255 ports to be reported per group */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte xd = (stmf_xfer_data_t *)kmem_zalloc(asz, KM_NOSLEEP);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte for (ilport = stmf_state.stmf_ilportlist; ilport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((uint16_t *)p)[1] = BE_16(ilport->ilport_rtpid);
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte for (ilport = stmf_state.stmf_ilportlist; ilport;
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ((uint16_t *)p)[1] = BE_16(ilport->ilport_rtpid);
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto scsi_devid_desc_t *id = ilport->ilport_lport->lport_id;
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szetostmf_scsilib_get_lport_rtid(struct scsi_devid_desc *devid)
8fe960854f0d52e2e8a80ba68e8621a5ac6a866dtim szeto (memcmp(devid->ident, id->ident, id->ident_length) == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_scsilib_uniq_lu_id(uint32_t company_id, scsi_devid_desc_t *lu_id)
fdcc480a6215c1e81d58d8e7af8c84fd6f1faa50John Forte return (stmf_scsilib_uniq_lu_id2(company_id, 0, lu_id));
fdcc480a6215c1e81d58d8e7af8c84fd6f1faa50John Fortestmf_scsilib_uniq_lu_id2(uint32_t company_id, uint32_t host_id,
fdcc480a6215c1e81d58d8e7af8c84fd6f1faa50John Forte if (hid == 0 && !localetheraddr((struct ether_addr *)NULL, &mac)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * saa is sense key, ASC, ASCQ
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_scsilib_send_status(scsi_task_t *task, uint8_t st, uint32_t saa)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) stmf_send_scsi_status(task, STMF_IOF_LU_DONE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_scsilib_prepare_vpd_page83(scsi_task_t *task, uint8_t *page,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uint32_t page_len, uint8_t byte0, uint32_t vpd_mask)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CONSTCOND */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte copysz = page_len > (n + sz) ? sz : page_len - n;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sz = task->task_lport->lport_id->ident_length + 4;
94d9b8e175557451537bf7b214abfc1cd7e52a90John Forte * If we're in alua mode, group 1 contains all alua
94d9b8e175557451537bf7b214abfc1cd7e52a90John Forte * participating ports and all standby ports
94d9b8e175557451537bf7b214abfc1cd7e52a90John Forte * > 255. Otherwise, if we're in alua mode, any local
94d9b8e175557451537bf7b214abfc1cd7e52a90John Forte * ports (non standby/pppt) are also in group 1 if the
94d9b8e175557451537bf7b214abfc1cd7e52a90John Forte * alua node is 1. Otherwise the group is 0.
94d9b8e175557451537bf7b214abfc1cd7e52a90John Forte (ilport->ilport_alua || ilport->ilport_standby) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_scsilib_handle_report_tpgs(scsi_task_t *task, stmf_data_buf_t *dbuf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For now we will abort all I/Os on the LU in case of ABORT_TASK_SET
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and ABORT_TASK. But unlike LUN_RESET we will not reset LU state
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in these cases. This needs to be changed to abort only the required
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* issue the reset to the proxy node as well */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We dont support this task mgmt function */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte itask = (stmf_i_scsi_task_t *)task->task_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * To sync with target reset, grab this lock. The LU is not going
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * anywhere as there is atleast one task pending (this task).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mark this task as the one causing LU reset so that we know who
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * was responsible for setting the ILU_RESET_ACTIVE. In case this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * task itself gets aborted, we will clear ILU_RESET_ACTIVE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte itask->itask_flags |= ITASK_DEFAULT_HANDLING | ITASK_CAUSING_LU_RESET;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Initiatiate abort on all commands on this LU except this one */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_abort(STMF_QUEUE_ABORT_LU, task, STMF_ABORTED, task->task_lu);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Start polling on this task */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_task_poll_lu(task, ITASK_DEFAULT_POLL_TIMEOUT)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_abort(STMF_QUEUE_TASK_ABORT, task, STMF_ALLOC_FAILURE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte itask = (stmf_i_scsi_task_t *)task->task_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iss = (stmf_i_scsi_session_t *)task->task_session->ss_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * To sync with LUN reset, grab this lock. The session is not going
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * anywhere as there is atleast one task pending (this task).
d6b3018d1023e158e4d4f1315056f98b55c6f590Sumit Gupta /* Grab the session lock as a writer to prevent any changes in it */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now go through each LUN in this session and make sure all of them
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * can be reset.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilu = (stmf_i_lu_t *)(lm_ent->ent_lu->lu_stmf_private);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&iss->iss_flags, ~ISS_RESET_ACTIVE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lf == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* No luns in this session */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&iss->iss_flags, ~ISS_RESET_ACTIVE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* ok, start the damage */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilu = (stmf_i_lu_t *)(lm_ent->ent_lu->lu_stmf_private);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_abort(STMF_QUEUE_ABORT_LU, task, STMF_ABORTED,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Start polling on this task */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_task_poll_lu(task, ITASK_DEFAULT_POLL_TIMEOUT)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_abort(STMF_QUEUE_TASK_ABORT, task, STMF_ALLOC_FAILURE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_handle_cmd_during_ic(stmf_i_scsi_task_t *itask)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_scsi_session_t *iss = (stmf_i_scsi_session_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (((iss->iss_flags & ISS_LUN_INVENTORY_CHANGED) == 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Make local copy of global tunables */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (stmf_worker_t) * stmf_i_max_nworkers, KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < stmf_i_max_nworkers; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&w->worker_lock, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_worker_mgmt_delay = drv_usectohz(20 * 1000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Workers will be started by stmf_worker_mgmt() */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Lets wait for atleast one worker to start */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_worker_mgmt_delay = drv_usectohz(3 * 1000 * 1000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_worker_mgmt_delay = drv_usectohz(20 * 1000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sb = ddi_get_lbolt() + drv_usectohz(10 * 1000 * 1000);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Wait for all the threads to die */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < stmf_i_max_nworkers; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(stmf_workers, sizeof (stmf_worker_t) * stmf_i_max_nworkers);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte w->worker_flags |= STMF_WORKER_STARTED | STMF_WORKER_ACTIVE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((w->worker_ref_count == 0) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CONSTCOND */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (wait_timer && (ddi_get_lbolt() >= wait_timer)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte curcmd = itask->itask_cmd_stack[itask->itask_ncmds - 1];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(itask->itask_flags & ITASK_BEING_ABORTED);
554c2b163439bbe1231a5d9ff5b9b0045c510c69tim szeto * set ITASK_KSTAT_IN_RUNQ, this flag
554c2b163439bbe1231a5d9ff5b9b0045c510c69tim szeto * will not reset until task completed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (atomic_cas_32(&itask->itask_flags, old, new) != old);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Decide if this task needs to go to a queue and/or if
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we can decrement the itask_cmd_stack.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is where the queue depth should go down by
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * one but we delay that on purpose to account for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the call into the provider. The actual decrement
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * happens after the worker has done its job.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* We made it here means we are going to call LU */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((itask->itask_flags & ITASK_DEFAULT_HANDLING) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dbuf = itask->itask_dbufs[ITASK_CMD_BUF_NDX(curcmd)];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (iss->iss_flags & ISS_LUN_INVENTORY_CHANGED) {
e17f3b2227c590f1d761b9ec4613cfb05982e6abtim szeto DTRACE_PROBE1(scsi__task__start, scsi_task_t *, task);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* case ITASK_CMD_XFER_DATA: */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((w->worker_flags & STMF_WORKER_TERMINATE) && (wait_timer == 0)) {
427fcaf873956aad428be801380a44e59d38b8b5tim szeto DTRACE_PROBE1(worker__timed__sleep, stmf_worker_t, w);
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni (void) cv_reltimedwait(&w->worker_cv, &w->worker_lock,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Check if we are trying to increase the # of threads */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = stmf_nworkers_cur; i < stmf_nworkers_needed; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_workers[i].worker_flags & STMF_WORKER_STARTED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Wait for transition to complete */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Check if we are trying to decrease the # of workers */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = (stmf_nworkers_cur - 1); i >= stmf_nworkers_needed; i--) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((stmf_workers[i].worker_flags & STMF_WORKER_STARTED) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * stmf_nworkers_accepting_cmds has already been
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * updated by the request to reduce the # of workers.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Wait for transition to complete */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Check if we are being asked to quit */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_workers_state != STMF_WORKERS_ENABLED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Check if we are starting */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < stmf_nworkers_accepting_cmds; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* still ramping up */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* max qdepth cannot be more than max tasks */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* See if we have more workers */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Since we dont reduce the worker count right away, monitor
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the highest load during the scale_down_delay.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ddi_get_lbolt() < stmf_worker_scale_down_timer) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Its time to reduce the workers */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_worker_scale_down_qd < stmf_i_min_nworkers)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_worker_scale_down_qd > stmf_i_max_nworkers)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_worker_scale_down_qd == stmf_nworkers_cur)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* NOTREACHED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = stmf_nworkers_cur; i < workers_needed; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte w->worker_tid = thread_create(NULL, 0, stmf_worker_task,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* At this point we know that we are decreasing the # of workers */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Signal the workers that its time to quit */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = (stmf_nworkers_cur - 1); i >= stmf_nworkers_needed; i--) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(w && (w->worker_flags & STMF_WORKER_STARTED));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fills out a dbuf from stmf_xfer_data_t (contained in the db_lu_private).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If all the data has been filled out, frees the xd and makes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * db_lu_private NULL.
91159e90831fc9243576f2ec1a483b3bb462bcf4John Fortestmf_xd_to_dbuf(stmf_data_buf_t *dbuf, int set_rel_off)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte s = min(xd->size_left, dbuf->db_sglist[i].seg_length);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_dlun0_new_task(scsi_task_t *task, stmf_data_buf_t *dbuf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (cdbp[0]) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Basic protocol checks. In addition, only reply to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * standard inquiry. Otherwise, the LU provider needs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to respond.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sz == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dbuf && (dbuf->db_sglist[0].seg_length < 36)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Ignore any preallocated dbuf if the size is less
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * than 36. It will be freed during the task_free.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((dbuf == NULL) || (dbuf->db_sglist[0].seg_length < sz)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Standard inquiry handling only.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte xd = stmf_session_prepare_report_lun_data(iss->iss_sm);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_scsilib_send_status(task, STATUS_CHECK, STMF_SAA_INVALID_OPCODE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_dlun0_dbuf_done(scsi_task_t *task, stmf_data_buf_t *dbuf)
91159e90831fc9243576f2ec1a483b3bb462bcf4John Forte task->task_nbytes_transferred += dbuf->db_data_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* There is more */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * If this is a proxy task, it will need to be completed from the
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * proxy port provider. This message lets pppt know that the xfer
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * is complete. When we receive the status from pppt, we will
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte * then relay that status back to the lport.
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* send xfer done status to pppt */
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte ic_xfer_done_msg = ic_scsi_data_xfer_done_msg_alloc(
450396635f70344c58b6b1e4db38cf17ff34445cJohn Forte /* task will be completed from pppt */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_dlun0_abort(struct stmf_lu *lu, int abort_cmd, void *arg, uint32_t flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_lu_t *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((task->task_mgmt_function) && (itask->itask_flags &
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (ITASK_CAUSING_LU_RESET | ITASK_CAUSING_TARGET_RESET))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&ilu->ilu_flags, ~ILU_RESET_ACTIVE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * OK so its not a task mgmt. Make sure we free any xd sitting
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * inside any dbuf.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((map = itask->itask_allocated_buf_map) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < 4; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Right now we only do this for handling task management functions */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) stmf_lun_reset_poll(task->task_lu, task, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_dlun0_ctl(struct stmf_lu *lu, int cmd, void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* This function will never be called */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN, "stmf_dlun0_ctl called with cmd %x", cmd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dlun0->lu_send_status_done = stmf_dlun0_status_done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_scsi_session_t *iss = (stmf_i_scsi_session_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilu = (stmf_i_lu_t *)lm_ent->ent_lu->lu_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&ilu->ilu_flags, ~ILU_RESET_ACTIVE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&iss->iss_flags, ~ISS_RESET_ACTIVE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The return value is only used by function managing target reset.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_lun_reset_poll(stmf_lu_t *lu, struct scsi_task *task, int target_reset)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_lu_t *ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ntasks_pending = ilu->ilu_ntasks - ilu->ilu_ntasks_free;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This function is also used during Target reset. The idea is that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * once all the commands are aborted, call the LU's reset entry
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * point (abort entry point with a reset flag). But if this Task
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mgmt is running on this LU then all the tasks cannot be aborted.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * one task (this task) will still be running which is OK.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ntasks_pending == 0) || ((task->task_lu == lu) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((task->task_mgmt_function == TM_LUN_RESET) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (task->task_mgmt_function == TM_TARGET_WARM_RESET) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (task->task_mgmt_function == TM_TARGET_COLD_RESET)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = lu->lu_abort(lu, STMF_LU_RESET_STATE, task, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&ilu->ilu_flags, ~ILU_RESET_ACTIVE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_abort(STMF_QUEUE_TASK_ABORT, task, ret, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Tell target reset polling code that we are not done */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_task_poll_lu(task, ITASK_DEFAULT_POLL_TIMEOUT)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_scsi_session_t *iss = (stmf_i_scsi_session_t *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilu = (stmf_i_lu_t *)lm_ent->ent_lu->lu_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = stmf_lun_reset_poll(lm_ent->ent_lu, task, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_task_poll_lu(task, ITASK_DEFAULT_POLL_TIMEOUT)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte atomic_and_32(&iss->iss_flags, ~ISS_RESET_ACTIVE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_lu_t *ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((eventid < 0) || (eventid >= STMF_MAX_NUM_EVENTS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_i_lu_t *ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((eventid < 0) || (eventid >= STMF_MAX_NUM_EVENTS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_lport_add_event(stmf_local_port_t *lport, int eventid)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((eventid < 0) || (eventid >= STMF_MAX_NUM_EVENTS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_EVENT_ADD(ilport->ilport_event_hdl, eventid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_lport_remove_event(stmf_local_port_t *lport, int eventid)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((eventid < 0) || (eventid >= STMF_MAX_NUM_EVENTS)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte STMF_EVENT_REMOVE(ilport->ilport_event_hdl, eventid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_generate_lu_event(stmf_i_lu_t *ilu, int eventid, void *arg, uint32_t flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (STMF_EVENT_ENABLED(ilu->ilu_event_hdl, eventid) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ilu->ilu_lu->lu_event_handler(ilu->ilu_lu, eventid, arg, flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_generate_lport_event(stmf_i_local_port_t *ilport, int eventid, void *arg,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (STMF_EVENT_ENABLED(ilport->ilport_event_hdl, eventid) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (ilport->ilport_lport->lport_event_handler != NULL)) {
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * With the possibility of having multiple itl sessions pointing to the
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * same itl_kstat_info, the ilu_kstat_lock mutex is used to synchronize
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * the kstat update of the ilu_kstat_io, itl_kstat_taskq and itl_kstat_lu_xfer
427fcaf873956aad428be801380a44e59d38b8b5tim szeto * statistics.
427fcaf873956aad428be801380a44e59d38b8b5tim szeto ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_waitq_enter(KSTAT_IO_PTR(itl->itl_kstat_taskq));
427fcaf873956aad428be801380a44e59d38b8b5tim szeto stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_enter);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto stmf_update_kstat_lport_q(itask->itask_task, kstat_waitq_enter);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto kstat_waitq_to_runq(KSTAT_IO_PTR(itl->itl_kstat_taskq));
427fcaf873956aad428be801380a44e59d38b8b5tim szeto stmf_update_kstat_lu_q(itask->itask_task, kstat_waitq_to_runq);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto stmf_update_kstat_lport_q(itask->itask_task, kstat_waitq_to_runq);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itli = (stmf_kstat_itl_info_t *)KSTAT_NAMED_PTR(itl->itl_kstat_info);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itli->i_task_waitq_elapsed.value.ui64 += itask->itask_waitq_time;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itask->itask_done_timestamp - itask->itask_start_timestamp;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itli->i_task_read_elapsed.value.ui64 += elapsed_time;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto itli->i_task_write_elapsed.value.ui64 += elapsed_time;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto stmf_update_kstat_lport_q(task, kstat_waitq_exit);
427fcaf873956aad428be801380a44e59d38b8b5tim szeto stmf_i_scsi_task_t *itask = task->task_stmf_private;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto stmf_i_lu_t *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
427fcaf873956aad428be801380a44e59d38b8b5tim szetostmf_lu_xfer_done(scsi_task_t *task, boolean_t read, uint64_t xfer_bytes,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto stmf_i_scsi_task_t *itask = task->task_stmf_private;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto stmf_i_lu_t *ilu = (stmf_i_lu_t *)task->task_lu->lu_stmf_private;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto atomic_add_64((uint64_t *)&itask->itask_lu_read_time,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto atomic_add_64((uint64_t *)&itask->itask_lu_write_time,
427fcaf873956aad428be801380a44e59d38b8b5tim szetostmf_lport_xfer_start(stmf_i_scsi_task_t *itask, stmf_data_buf_t *dbuf)
427fcaf873956aad428be801380a44e59d38b8b5tim szeto DTRACE_PROBE2(scsi__xfer__start, scsi_task_t *, itask->itask_task,
427fcaf873956aad428be801380a44e59d38b8b5tim szetostmf_lport_xfer_done(stmf_i_scsi_task_t *itask, stmf_data_buf_t *dbuf)
427fcaf873956aad428be801380a44e59d38b8b5tim szeto ilp = (stmf_i_local_port_t *)task->task_lport->lport_stmf_private;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto xfer_size = (dbuf->db_xfer_status == STMF_SUCCESS) ?
427fcaf873956aad428be801380a44e59d38b8b5tim szeto elapsed_time = gethrtime() - dbuf->db_xfer_start_timestamp;
427fcaf873956aad428be801380a44e59d38b8b5tim szeto atomic_add_64((uint64_t *)&itask->itask_lport_read_time,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto atomic_add_64((uint64_t *)&itask->itask_read_xfer,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto atomic_add_64((uint64_t *)&itask->itask_lport_write_time,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto atomic_add_64((uint64_t *)&itask->itask_write_xfer,
427fcaf873956aad428be801380a44e59d38b8b5tim szeto DTRACE_PROBE3(scsi__xfer__end, scsi_task_t *, itask->itask_task,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_svc_flags & STMF_SVC_STARTED)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_state.stmf_svc_taskq = ddi_taskq_create(0, "STMF_SVC_TASKQ", 1,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) ddi_taskq_dispatch(stmf_state.stmf_svc_taskq,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_svc_flags & STMF_SVC_STARTED) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Wait for 5 seconds */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < 500; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_svc_flags & STMF_SVC_STARTED)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (i == 500)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_state.stmf_svc_flags |= STMF_SVC_STARTED | STMF_SVC_ACTIVE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (stmf_state.stmf_svc_flags & STMF_SVC_TERMINATE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Fallthrough */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Fallthrough */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Nothing to do */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Remove all mappings of this LU */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_session_lu_unmapall((stmf_lu_t *)req->svc_obj);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Kill all the pending I/Os for this LU */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_task_lu_killall((stmf_lu_t *)req->svc_obj, NULL,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Put it in the wait queue */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* The waiting list is not going to be modified by anybody else */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (preq = &stmf_state.stmf_svc_waiting; (*preq) != NULL; ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Fallthrough */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lport->lport_ctl(lport, req->svc_cmd, &req->svc_info);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Do timeouts */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((!timing_next) || (ddi_get_lbolt() >= timing_next))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we are starting a new round */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we finished a complete round */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we still have some ilu items to check */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Check if there are free tasks to clear */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((!drain_next) || (ddi_get_lbolt() >= drain_next))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we are starting a new round */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we finished a complete round */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we still have some ilu items to check */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Check if we need to run worker_mgmt */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Check if any active session got its 1st LUN */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (ilport = stmf_state.stmf_ilportlist; ilport;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * scan all the ilports again as the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ilport list might have changed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* drop the lock if we are holding it. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Max 4 session at a time */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_svc_queue(int cmd, void *obj, stmf_state_change_info_t *info)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req->svc_info.st_additional_info = (char *)(GET_BYTE_OFFSET(req,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((stmf_state.stmf_svc_flags & STMF_SVC_ACTIVE) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len = snprintf(tbuf, 158, "%s:%07lu: ", ident ? ident : "",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte len += vsnprintf(tbuf + len, 158 - len, fmt, args);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bcopy(tbuf, &stmf_trace_buf[trace_buf_curndx], len+1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestmf_abort_task_offline(scsi_task_t *task, int offline_lu, char *info)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace("FROM STMF", "abort_task_offline called for %s: %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte offline_lu ? "LU" : "LPORT", info ? info : "no additional info");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte task->task_lport->lport_stmf_private)->ilport_state ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte stmf_trace(0, "Calling stmf_ctl to offline %s : %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "<no additional info>");