0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * CDDL HEADER START
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * The contents of this file are subject to the terms of the
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * Common Development and Distribution License (the "License").
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * You may not use this file except in compliance with the License.
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * See the License for the specific language governing permissions
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * and limitations under the License.
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * When distributing Covered Code, include this CDDL HEADER in each
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * If applicable, add the following below this CDDL HEADER, with the
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * fields enclosed by brackets "[]" replaced with your own identifying
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * information: Portions Copyright [yyyy] [name of copyright owner]
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * CDDL HEADER END
0c45178b5714d692c44817c2235320c3f2b030abwl * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * Use is subject to license terms.
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * External function definitions
b1a03ab1e63a57c5b968c229e2f36c79d2fdd222Victor Liextern void vhci_mpapi_update_tpg_data(struct scsi_address *, char *, int);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphsstatic int vhci_tpgs_inquiry(struct scsi_address *ap, struct buf *bp,
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphsstatic int vhci_tpgs_page83(struct scsi_address *ap, struct buf *bp,
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphsstatic int vhci_tpgs_report_target_groups(struct scsi_address *ap,
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs struct buf *bp, int rel_tgt_port, int tgt_port, int *pstate,
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphsvhci_tpgs_set_target_groups(struct scsi_address *ap, int set_state,
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(1, (CE_WARN, NULL, "!vhci_tpgs_set_target_groups: "
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " failed getrbuf"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (1);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(1, (CE_WARN, NULL, "!vhci_tpgs_set_target_groups: "
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "request packet allocation for %d failed....", len));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (1);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_set_target_groups: scsi_init_pkt error\n"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (1);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * Sends 1 TPG descriptor only. Hence Parameter list length pkt_cdbp[9]
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * is set to 8 bytes - Refer SPC3 for details.
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs pkt->pkt_cdbp[1] = SSVC_ACTION_SET_TARGET_PORT_GROUPS;
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_set_target_groups: sending set target port group:"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " cdb[0/1/6/7/8/9]: %x/%x/%x/%x/%x/%x\n", pkt->pkt_cdbp[0],
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs pkt->pkt_cdbp[1], pkt->pkt_cdbp[6], pkt->pkt_cdbp[7],
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs if (rval == 0) {
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(1, (CE_NOTE, NULL, "!vhci_tpgs_set_target_groups:"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " vhci_do_scsi_cmd failed\n"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (-1);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_set_target_groups:"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " sense:%x, add_code: %x, qual_code:%x"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_set_target_groups:"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " sense:%x, add_code: %x, qual_code:%x"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_set_target_groups:"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " sense_key:%x, add_code: %x, qual_code:%x"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * At this point sns data may be for power-on-reset
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * UNIT ATTN hardware errors, vendor unqiue sense etc.
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * For all these cases, sense is unknown.
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_set_target_groups: "
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " sense UNKNOWN: sense key:%x, ASC:%x, ASCQ:%x\n",
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (0);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (1);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * get the failover mode, ownership and if it has extended failover
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * capability. The mode(bits5-4/byte5) is defined as implicit, explicit, or
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * both. The state is defined as online-optimized(0h),
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * online-nonoptimized(1h), standby(2h), offline(3h),
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * and transitioning(fh). Currently, there is online,
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * standby, and offline(defined in sunmdi.h).
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * Online-nonoptimized will be a mode of secondary
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * and an ownership of online. Thought about using a different mode but
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * it appears the states are really for the states for secondary mode.
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * We currently have IS_ONLINING, IS_OFFLINING - should we have TRANSITIONING
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * to mean from online-optimized to online-nonoptimized or does onlining
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * cover this?
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs/* ARGSUSED */
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphsvhci_tpgs_get_target_fo_mode(struct scsi_device *sd, int *mode,
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_get_target_fo_mode: enter\n"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(1, (CE_NOTE, NULL, "!vhci_tpgs_get_target_fo_mode: "
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " failed getrbuf\n"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (1);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(1, (CE_NOTE, NULL, "!vhci_tpgs_get_target_fo_mode: "
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " failed vhci_tpgs_inquiry\n"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs } else if (vhci_tpgs_page83(ap, bp, &rel_tgt_port, &tgt_port, &lu)) {
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(1, (CE_NOTE, NULL, "!vhci_tpgs_get_target_fo_mode: "
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " failed vhci_tpgs_page83\n"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs } else if (vhci_tpgs_report_target_groups(ap, bp, rel_tgt_port,
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(1, (CE_NOTE, NULL, "!vhci_tpgs_get_target_fo_mode: "
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " failed vhci_tpgs_report_target_groups\n"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(6, (CE_NOTE, NULL, "!vhci_tpgs_get_target_fo_mode: "
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "SUCCESS\n"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphsvhci_tpgs_inquiry(struct scsi_address *ap, struct buf *bp, int *mode)
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs sizeof (struct scsi_arq_status), 0, 0, SLEEP_FUNC, NULL);
d35e9352c203d3c67ed57186e0e8a6de000384abChris Liu "!vhci_tpgs_inquiry: Failure returned from scsi_init_pkt"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(1, (CE_WARN, NULL, "!vhci_tpgs_inquiry: Failure"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " returned from vhci_do_scsi_cmd"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (1);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_inquiry: zero tpgs_bits"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (1);
d91393a8e4d666dd6b6588c980c59cec667835f4Chris Horne } else if (inq.inq_tpgs == TPGS_FAILOVER_EXPLICIT) {
d91393a8e4d666dd6b6588c980c59cec667835f4Chris Horne } else if (inq.inq_tpgs == TPGS_FAILOVER_BOTH) {
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_inquiry: Illegal mode returned: %x mode: %x",
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphsvhci_tpgs_page83(struct scsi_address *ap, struct buf *bp,
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * lets start the buf size with 512 bytes. If this
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * if found to be insufficient, we can allocate
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * appropriate size in the next iteration.
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "request packet allocation for %d failed....",
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (1);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_page83: Failure returned from scsi_init_pkt"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (1);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs pkt->pkt_cdbp[3] = (unsigned char)((buf_len >> 8) & 0xff);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_page83: vhci_do_scsi_cmd failed\n"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (1);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * Now lets check if the size that was provided was
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * sufficient. If not, allocate the appropriate size
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * and retry the command again.
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs rx_bsize = (((bufp[2] & 0xff) << 8) | (bufp[3] & 0xff));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * Need to allocate more buf and retry again
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "bufsize: %d greater than allocated buf: %d\n",
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(1, (CE_NOTE, NULL, "Retrying for size %d\n",
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "desc[1/4/5/6/7]:%x %x %x %x %x\n",
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_page83: relative target port: %x\n",
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_page83: target port: %x\n", *tgt_port));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs ptr += ptr[3] + 4; /* next identification descriptor */
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (0);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs int i = 0, j;
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(4, (CE_NOTE, NULL, "!buf_size: %x loop: %x left: %x",
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs for (j = 0; j < loop; j++) {
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!buf[%d-%d]: %x %x %x %x %x %x %x %x",
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs for (j = 0; j < left; j++) {
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphsvhci_tpgs_report_target_groups(struct scsi_address *ap, struct buf *bp,
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs int rel_tgt_port, int tgt_port, int *pstate, int *preferred)
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * Start with buffer size of 512.
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * If this is found to be insufficient, required size
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * will be allocated and the command will be retried.
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(1, (CE_WARN, NULL, "!vhci_tpgs_report_target_groups:"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " request packet allocation for %d failed....", len));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (1);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_report_target_groups: scsi_init_pkt error\n"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (1);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs pkt->pkt_cdbp[1] = SSVC_ACTION_GET_TARGET_PORT_GROUPS;
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_report_target_groups: sending target port group:"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs pkt->pkt_cdbp[7], pkt->pkt_cdbp[8], pkt->pkt_cdbp[9]));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(4, (CE_NOTE, NULL, "!vhci_tpgs_report_target_groups:"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " vhci_do_scsi_cmd failed\n"));
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (1);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(6, (CE_NOTE, NULL, "!vhci_tpgs_report_target_groups:"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " returned from target"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " port group: buf[0/1/2/3]: %x/%x/%x/%x\n",
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(4, (CE_NOTE, NULL, "!vhci_tpgs_report_target_groups:"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " bufsize: %d greater than allocated buf: %d\n",
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(4, (CE_NOTE, NULL, "Retrying for size %d\n",
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs l_tgt_port = ((ptr[2] & 0xff) << 8) + (ptr[3] & 0xff);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(4, (CE_NOTE, NULL, "!vhci_tpgs_report_tgt_groups:"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " tpgs state: %x"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs for (i = 0; i < tgt_port_cnt; i++) {
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_report_tgt_groups:"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs " found tgt_port: %x rel_tgt_port:%x"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * once we have the preferred flag
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * and a non-optimized state flag
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * we will get preferred flag from the
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs * report target groups
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs } else if (tpgs_state ==
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (0);
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "!vhci_tpgs_report_tgt_groups:"
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs VHCI_DEBUG(1, (CE_NOTE, NULL, "!vhci_tpgs_report_tgt_groups: "
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs "NO rel_TGTPRT MATCH!!! Assigning Default: state: %x "
0205780bc43902d17f94f07ceacb0cd8d5eab20frralphs return (1);