1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24 /*
25 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
26 * Copyright (c) 2016 by Delphix. All rights reserved.
27 */
28
29 /*
30 * Multiplexed I/O SCSI vHCI implementation
31 */
32
33 #include <sys/conf.h>
34 #include <sys/file.h>
35 #include <sys/ddi.h>
36 #include <sys/sunddi.h>
37 #include <sys/scsi/scsi.h>
38 #include <sys/scsi/impl/scsi_reset_notify.h>
39 #include <sys/scsi/impl/services.h>
40 #include <sys/sunmdi.h>
41 #include <sys/mdi_impldefs.h>
42 #include <sys/scsi/adapters/scsi_vhci.h>
43 #include <sys/disp.h>
44 #include <sys/byteorder.h>
45
46 extern uintptr_t scsi_callback_id;
47 extern ddi_dma_attr_t scsi_alloc_attr;
48
49 #ifdef DEBUG
50 int vhci_debug = VHCI_DEBUG_DEFAULT_VAL;
51 #endif
52
53 /* retry for the vhci_do_prout command when a not ready is returned */
54 int vhci_prout_not_ready_retry = 180;
55
56 /*
57 * These values are defined to support the internal retry of
58 * SCSI packets for better sense code handling.
59 */
60 #define VHCI_CMD_CMPLT 0
61 #define VHCI_CMD_RETRY 1
62 #define VHCI_CMD_ERROR -1
63
64 #define PROPFLAGS (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM)
65 #define VHCI_SCSI_PERR 0x47
66 #define VHCI_PGR_ILLEGALOP -2
67 #define VHCI_NUM_UPDATE_TASKQ 8
68 /* changed to 132 to accomodate HDS */
69
70 /*
71 * Version Macros
72 */
73 #define VHCI_NAME_VERSION "SCSI VHCI Driver"
74 char vhci_version_name[] = VHCI_NAME_VERSION;
75
76 int vhci_first_time = 0;
115 * functions exported by scsi_vhci struct dev_ops
116 */
117 static int vhci_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
118 static int vhci_attach(dev_info_t *, ddi_attach_cmd_t);
119 static int vhci_detach(dev_info_t *, ddi_detach_cmd_t);
120
121 /*
122 * functions exported by scsi_vhci scsi_hba_tran_t transport table
123 */
124 static int vhci_scsi_tgt_init(dev_info_t *, dev_info_t *,
125 scsi_hba_tran_t *, struct scsi_device *);
126 static void vhci_scsi_tgt_free(dev_info_t *, dev_info_t *, scsi_hba_tran_t *,
127 struct scsi_device *);
128 static int vhci_pgr_register_start(scsi_vhci_lun_t *, struct scsi_pkt *);
129 static int vhci_scsi_start(struct scsi_address *, struct scsi_pkt *);
130 static int vhci_scsi_abort(struct scsi_address *, struct scsi_pkt *);
131 static int vhci_scsi_reset(struct scsi_address *, int);
132 static int vhci_scsi_reset_target(struct scsi_address *, int level,
133 uint8_t select_path);
134 static int vhci_scsi_reset_bus(struct scsi_address *);
135 static int vhci_scsi_getcap(struct scsi_address *, char *, int);
136 static int vhci_scsi_setcap(struct scsi_address *, char *, int, int);
137 static int vhci_commoncap(struct scsi_address *, char *, int, int, int);
138 static int vhci_pHCI_cap(struct scsi_address *ap, char *cap, int val, int whom,
139 mdi_pathinfo_t *pip);
140 static struct scsi_pkt *vhci_scsi_init_pkt(struct scsi_address *,
141 struct scsi_pkt *, struct buf *, int, int, int, int, int (*)(), caddr_t);
142 static void vhci_scsi_destroy_pkt(struct scsi_address *, struct scsi_pkt *);
143 static void vhci_scsi_dmafree(struct scsi_address *, struct scsi_pkt *);
144 static void vhci_scsi_sync_pkt(struct scsi_address *, struct scsi_pkt *);
145 static int vhci_scsi_reset_notify(struct scsi_address *, int, void (*)(caddr_t),
146 caddr_t);
147 static int vhci_scsi_get_bus_addr(struct scsi_device *, char *, int);
148 static int vhci_scsi_get_name(struct scsi_device *, char *, int);
149 static int vhci_scsi_bus_power(dev_info_t *, void *, pm_bus_power_op_t,
150 void *, void *);
151 static int vhci_scsi_bus_config(dev_info_t *, uint_t, ddi_bus_config_op_t,
152 void *, dev_info_t **);
153 static int vhci_scsi_bus_unconfig(dev_info_t *, uint_t, ddi_bus_config_op_t,
154 void *);
1369 * fail for some other reason. There is not an
1370 * easy way how to recover though. Log a warning
1371 * and return.
1372 */
1373 p_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
1374 vhci_log(CE_WARN, vhci->vhci_dip, "!Sending "
1375 "RELEASE(6) to %s failed, a potential "
1376 "reservation conflict ahead.",
1377 ddi_pathname(mdi_pi_get_phci(pip), p_path));
1378 kmem_free(p_path, MAXPATHLEN);
1379
1380 if (restore_lbp)
1381 (void) mdi_set_lb_policy(cdip, lbp);
1382
1383 /* no need to check pkt_reserve_cmd here */
1384 vlun->svl_flags &= ~VLUN_QUIESCED_FLG;
1385 return (TRAN_FATAL_ERROR);
1386 }
1387
1388 rel_pkt->pkt_cdbp[0] = SCMD_RELEASE;
1389 rel_pkt->pkt_time = 60;
1390
1391 /*
1392 * Ignore the return value. If it will fail
1393 * then most likely it is no longer reserved
1394 * anyway.
1395 */
1396 (void) vhci_do_scsi_cmd(rel_pkt);
1397 VHCI_DEBUG(1, (CE_NOTE, NULL,
1398 "!vhci_scsi_start: path 0x%p, issued SCSI-2"
1399 " RELEASE\n", (void *)pip));
1400 scsi_destroy_pkt(rel_pkt);
1401 mdi_rele_path(pip);
1402 }
1403 }
1404
1405 VHCI_INCR_PATH_CMDCOUNT(svp);
1406
1407 /*
1408 * Ensure that no other IOs raced ahead, while a RESERVE cmd was
1409 * QUIESCING the same lun.
1518 /* Do not destroy phci packet information for PKT_DMA_PARTIAL */
1519 if ((vpkt->vpkt_flags & CFLAG_DMA_PARTIAL) == 0) {
1520 scsi_destroy_pkt(vpkt->vpkt_hba_pkt);
1521 vpkt->vpkt_hba_pkt = NULL;
1522 if (vpkt->vpkt_path) {
1523 MDI_PI_ERRSTAT(vpkt->vpkt_path, MDI_PI_TRANSERR);
1524 mdi_rele_path(vpkt->vpkt_path);
1525 vpkt->vpkt_path = NULL;
1526 }
1527 }
1528 return (TRAN_BUSY);
1529 }
1530
1531 /*
1532 * Function name : vhci_scsi_reset()
1533 *
1534 * Return Values : 0 - reset failed
1535 * 1 - reset succeeded
1536 */
1537
1538 /* ARGSUSED */
1539 static int
1540 vhci_scsi_reset(struct scsi_address *ap, int level)
1541 {
1542 int rval = 0;
1543
1544 cmn_err(CE_WARN, "!vhci_scsi_reset 0x%x", level);
1545 if ((level == RESET_TARGET) || (level == RESET_LUN)) {
1546 return (vhci_scsi_reset_target(ap, level, TRUE));
1547 } else if (level == RESET_ALL) {
1548 return (vhci_scsi_reset_bus(ap));
1549 }
1550
1551 return (rval);
1552 }
1553
1554 /*
1555 * vhci_recovery_reset:
1556 * Issues reset to the device
1557 * Input:
1558 * vlun - vhci lun pointer of the device
1559 * ap - address of the device
1560 * select_path:
1561 * If select_path is FALSE, then the address specified in ap is
1562 * the path on which reset will be issued.
1563 * If select_path is TRUE, then path is obtained by calling
1564 * mdi_select_path.
1565 *
1566 * recovery_depth:
1567 * Caller can specify the level of reset.
1568 * VHCI_DEPTH_LUN -
1569 * Issues LUN RESET if device supports lun reset.
1570 * VHCI_DEPTH_TARGET -
1571 * If Lun Reset fails or the device does not support
1597 recovery_depth--;
1598 }
1599
1600 if ((ret == 0) && recovery_depth) {
1601 (void) scsi_reset(ap, RESET_ALL);
1602 }
1603
1604 return (ret);
1605 }
1606
1607 /*
1608 * Note: The scsi_address passed to this routine could be the scsi_address
1609 * for the virtual device or the physical device. No assumptions should be
1610 * made in this routine about the contents of the ap structure.
1611 * Further, note that the child dip would be the dip of the ssd node regardless
1612 * of the scsi_address passed in.
1613 */
1614 static int
1615 vhci_scsi_reset_target(struct scsi_address *ap, int level, uint8_t select_path)
1616 {
1617 dev_info_t *vdip, *cdip;
1618 mdi_pathinfo_t *pip = NULL;
1619 mdi_pathinfo_t *npip = NULL;
1620 int rval = -1;
1621 scsi_vhci_priv_t *svp = NULL;
1622 struct scsi_address *pap = NULL;
1623 scsi_hba_tran_t *hba = NULL;
1624 int sps;
1625 struct scsi_vhci *vhci = NULL;
1626
1627 if (select_path != TRUE) {
1628 ASSERT(ap != NULL);
1629 if (level == RESET_LUN) {
1630 hba = ap->a_hba_tran;
1631 ASSERT(hba != NULL);
1632 return (hba->tran_reset(ap, RESET_LUN));
1633 }
1634 return (scsi_reset(ap, level));
1635 }
1636
1637 cdip = ADDR2DIP(ap);
1638 ASSERT(cdip != NULL);
1639 vdip = ddi_get_parent(cdip);
1640 ASSERT(vdip != NULL);
1641 vhci = ddi_get_soft_state(vhci_softstate, ddi_get_instance(vdip));
1642 ASSERT(vhci != NULL);
1643
1644 rval = mdi_select_path(cdip, NULL, MDI_SELECT_ONLINE_PATH, NULL, &pip);
1645 if ((rval != MDI_SUCCESS) || (pip == NULL)) {
1646 VHCI_DEBUG(2, (CE_WARN, NULL, "!vhci_scsi_reset_target: "
1647 "Unable to get a path, dip 0x%p", (void *)cdip));
1648 return (0);
1649 }
1650 again:
1651 svp = (scsi_vhci_priv_t *)mdi_pi_get_vhci_private(pip);
1652 if (svp == NULL) {
1653 VHCI_DEBUG(2, (CE_WARN, NULL, "!vhci_scsi_reset_target: "
1654 "priv is NULL, pip 0x%p", (void *)pip));
1655 mdi_rele_path(pip);
1656 return (0);
1657 }
1688 return (0);
1689 }
1690 mdi_rele_path(pip);
1691 pip = npip;
1692 goto again;
1693 }
1694 mdi_rele_path(pip);
1695 mutex_enter(&vhci->vhci_mutex);
1696 scsi_hba_reset_notify_callback(&vhci->vhci_mutex,
1697 &vhci->vhci_reset_notify_listf);
1698 mutex_exit(&vhci->vhci_mutex);
1699 VHCI_DEBUG(6, (CE_NOTE, NULL, "!vhci_scsi_reset_target: "
1700 "reset %d sent down pip:%p for cdip:%p\n", level,
1701 (void *)pip, (void *)cdip));
1702 return (1);
1703 }
1704 mdi_rele_path(pip);
1705 return (0);
1706 }
1707
1708
1709 /* ARGSUSED */
1710 static int
1711 vhci_scsi_reset_bus(struct scsi_address *ap)
1712 {
1713 return (1);
1714 }
1715
1716
1717 /*
1718 * called by vhci_getcap and vhci_setcap to get and set (respectively)
1719 * SCSI capabilities
1720 */
1721 /* ARGSUSED */
1722 static int
1723 vhci_commoncap(struct scsi_address *ap, char *cap,
1724 int val, int tgtonly, int doset)
1725 {
1726 struct scsi_vhci *vhci = ADDR2VHCI(ap);
1727 struct scsi_vhci_lun *vlun = ADDR2VLUN(ap);
1728 int cidx;
1729 int rval = 0;
1730
1731 if (cap == (char *)0) {
1732 VHCI_DEBUG(3, (CE_WARN, vhci->vhci_dip,
1733 "!vhci_commoncap: invalid arg"));
1734 return (rval);
1735 }
1736
3169 char *cpath;
3170
3171 ASSERT(vpkt != NULL);
3172 tpkt = vpkt->vpkt_tgt_pkt;
3173 ASSERT(tpkt != NULL);
3174 svp = (scsi_vhci_priv_t *)mdi_pi_get_vhci_private(vpkt->vpkt_path);
3175 ASSERT(svp != NULL);
3176 vlun = svp->svp_svl;
3177 ASSERT(vlun != NULL);
3178 lpath = vpkt->vpkt_path;
3179
3180 /*
3181 * sync up the target driver's pkt with the pkt that
3182 * we actually used
3183 */
3184 *(tpkt->pkt_scbp) = *(pkt->pkt_scbp);
3185 tpkt->pkt_resid = pkt->pkt_resid;
3186 tpkt->pkt_state = pkt->pkt_state;
3187 tpkt->pkt_statistics = pkt->pkt_statistics;
3188 tpkt->pkt_reason = pkt->pkt_reason;
3189
3190 /* Return path_instance information back to the target driver. */
3191 if (scsi_pkt_allocated_correctly(tpkt)) {
3192 if (scsi_pkt_allocated_correctly(pkt)) {
3193 /*
3194 * If both packets were correctly allocated,
3195 * return path returned by pHCI.
3196 */
3197 tpkt->pkt_path_instance = pkt->pkt_path_instance;
3198 } else {
3199 /* Otherwise return path of pHCI we used */
3200 tpkt->pkt_path_instance =
3201 mdi_pi_get_path_instance(lpath);
3202 }
3203 }
3204
3205 if (pkt->pkt_cdbp[0] == SCMD_PROUT &&
3206 ((pkt->pkt_cdbp[1] & 0x1f) == VHCI_PROUT_REGISTER) ||
3207 ((pkt->pkt_cdbp[1] & 0x1f) == VHCI_PROUT_R_AND_IGNORE)) {
3208 if ((SCBP_C(pkt) != STATUS_GOOD) ||
3940 }
3941
3942 /* Check for Reservation Conflict */
3943 bp = scsi_alloc_consistent_buf(
3944 &svp->svp_psd->sd_address, (struct buf *)NULL,
3945 DEV_BSIZE, B_READ, NULL, NULL);
3946 if (!bp) {
3947 VHCI_DEBUG(1, (CE_NOTE, NULL,
3948 "!vhci_update_pathstates: No resources "
3949 "(buf)\n"));
3950 mdi_rele_path(pip);
3951 goto done;
3952 }
3953 pkt = scsi_init_pkt(&svp->svp_psd->sd_address, NULL, bp,
3954 CDB_GROUP1, sizeof (struct scsi_arq_status), 0,
3955 PKT_CONSISTENT, NULL, NULL);
3956 if (pkt) {
3957 (void) scsi_setup_cdb((union scsi_cdb *)
3958 (uintptr_t)pkt->pkt_cdbp, SCMD_READ, 1, 1,
3959 0);
3960 pkt->pkt_time = 3*30;
3961 pkt->pkt_flags = FLAG_NOINTR;
3962 pkt->pkt_path_instance =
3963 mdi_pi_get_path_instance(pip);
3964
3965 if ((scsi_transport(pkt) == TRAN_ACCEPT) &&
3966 (pkt->pkt_reason == CMD_CMPLT) &&
3967 (SCBP_C(pkt) ==
3968 STATUS_RESERVATION_CONFLICT)) {
3969 VHCI_DEBUG(1, (CE_NOTE, NULL,
3970 "!vhci_update_pathstates: reserv. "
3971 "conflict to be resolved on 0x%p\n",
3972 (void *)pip));
3973 svp_conflict = svp;
3974 }
3975 scsi_destroy_pkt(pkt);
3976 }
3977 scsi_free_consistent_buf(bp);
3978 } else if ((opinfo.opinfo_path_state == SCSI_PATH_INACTIVE) &&
3979 !(MDI_PI_IS_STANDBY(pip))) {
3980 VHCI_DEBUG(1, (CE_NOTE, NULL,
5205 if ((vlun->svl_flags & VLUN_RESERVE_ACTIVE_FLG) == 0) {
5206 /*
5207 * Issue SCSI-2 RELEASE only for the first time on
5208 * a new path just in case the host rebooted and
5209 * a reservation is still pending on this path.
5210 * IBM Shark storage does not clear RESERVE upon
5211 * host reboot.
5212 */
5213 pkt = scsi_init_pkt(ap, NULL, NULL, CDB_GROUP0,
5214 sizeof (struct scsi_arq_status), 0, 0,
5215 SLEEP_FUNC, NULL);
5216 if (pkt == NULL) {
5217 VHCI_DEBUG(1, (CE_NOTE, NULL,
5218 "!vhci_pathinfo_online: "
5219 "Release init_pkt failed :%p\n",
5220 (void *)pip));
5221 rval = MDI_FAILURE;
5222 goto failure;
5223 }
5224 pkt->pkt_cdbp[0] = SCMD_RELEASE;
5225 pkt->pkt_time = 60;
5226
5227 VHCI_DEBUG(1, (CE_NOTE, NULL,
5228 "!vhci_path_online: path:%p "
5229 "Issued SCSI-2 RELEASE\n", (void *)pip));
5230
5231 /* Ignore the return value */
5232 (void) vhci_do_scsi_cmd(pkt);
5233 scsi_destroy_pkt(pkt);
5234 }
5235 }
5236
5237 rval = vhci_update_pathinfo(psd, pip, sfo, vlun, vhci);
5238 if (rval == MDI_FAILURE) {
5239 goto failure;
5240 }
5241
5242 /* Initialize MP-API data */
5243 vhci_update_mpapi_data(vhci, vlun, pip);
5244
5245 /*
6132
6133 case DEVCTL_DEVICE_RESET:
6134 /*
6135 * lookup and hold child device
6136 */
6137 if ((child = ndi_devi_find(self, ndi_dc_getname(dcp),
6138 ndi_dc_getaddr(dcp))) == NULL) {
6139 rv = ENXIO;
6140 break;
6141 }
6142 retval = mdi_select_path(child, NULL,
6143 (MDI_SELECT_ONLINE_PATH | MDI_SELECT_STANDBY_PATH),
6144 NULL, &pip);
6145 if ((retval != MDI_SUCCESS) || (pip == NULL)) {
6146 VHCI_DEBUG(2, (CE_WARN, NULL, "!vhci_ioctl:"
6147 "Unable to get a path, dip 0x%p", (void *)child));
6148 rv = ENXIO;
6149 break;
6150 }
6151 svp = (scsi_vhci_priv_t *)mdi_pi_get_vhci_private(pip);
6152 if (vhci_recovery_reset(svp->svp_svl,
6153 &svp->svp_psd->sd_address, TRUE,
6154 VHCI_DEPTH_TARGET) == 0) {
6155 VHCI_DEBUG(1, (CE_NOTE, NULL,
6156 "!vhci_ioctl(pip:%p): "
6157 "reset failed\n", (void *)pip));
6158 rv = ENXIO;
6159 }
6160 mdi_rele_path(pip);
6161 break;
6162
6163 case DEVCTL_BUS_QUIESCE:
6164 case DEVCTL_BUS_UNQUIESCE:
6165 case DEVCTL_BUS_RESET:
6166 case DEVCTL_BUS_RESETALL:
6167 #ifdef DEBUG
6168 case DEVCTL_BUS_CONFIGURE:
6169 case DEVCTL_BUS_UNCONFIGURE:
6170 #endif
6171 rv = ENOTSUP;
6172 break;
6173
6174 default:
6175 rv = ENOTTY;
6176 } /* end of outer switch */
6177
6961 check_condition = 0;
6962 UA_condition = 0;
6963
6964 bp = scsi_alloc_consistent_buf(&svp->svp_psd->sd_address,
6965 (struct buf *)NULL, DEV_BSIZE, B_READ, NULL, NULL);
6966 if (!bp) {
6967 VHCI_DEBUG(1, (CE_NOTE, NULL,
6968 "vhci_failover !No resources (buf)\n"));
6969 mdi_rele_path(npip);
6970 goto done;
6971 }
6972 pkt = scsi_init_pkt(&svp->svp_psd->sd_address, NULL, bp,
6973 CDB_GROUP1, sizeof (struct scsi_arq_status), 0,
6974 PKT_CONSISTENT, NULL, NULL);
6975 if (pkt) {
6976 (void) scsi_setup_cdb((union scsi_cdb *)(uintptr_t)
6977 pkt->pkt_cdbp, SCMD_READ, 1, 1, 0);
6978 pkt->pkt_flags = FLAG_NOINTR;
6979 check_path_again:
6980 pkt->pkt_path_instance = mdi_pi_get_path_instance(npip);
6981 pkt->pkt_time = 3*30;
6982
6983 if (scsi_transport(pkt) == TRAN_ACCEPT) {
6984 switch (pkt->pkt_reason) {
6985 case CMD_CMPLT:
6986 switch (SCBP_C(pkt)) {
6987 case STATUS_GOOD:
6988 /* Already failed over */
6989 activation_done = 1;
6990 break;
6991 case STATUS_RESERVATION_CONFLICT:
6992 reserve_pending = 1;
6993 break;
6994 case STATUS_CHECK:
6995 check_condition = 1;
6996 break;
6997 }
6998 }
6999 }
7000 if (check_condition &&
7001 (pkt->pkt_state & STATE_ARQ_DONE)) {
8322 "vhci_uscsi_send_sense: enter: bp: %p pkt: %p scmd: %p",
8323 (void *)cmdbp, (void *)pkt, (void *)mp_uscmdp));
8324 /* set up the packet information and cdb */
8325 if ((rqbp = scsi_alloc_consistent_buf(mp_uscmdp->ap, NULL,
8326 SENSE_LENGTH, B_READ, NULL, NULL)) == NULL) {
8327 return (-1);
8328 }
8329
8330 if ((rqpkt = scsi_init_pkt(mp_uscmdp->ap, NULL, rqbp,
8331 CDB_GROUP0, 1, 0, PKT_CONSISTENT, NULL, NULL)) == NULL) {
8332 scsi_free_consistent_buf(rqbp);
8333 return (-1);
8334 }
8335
8336 (void) scsi_setup_cdb((union scsi_cdb *)(intptr_t)rqpkt->pkt_cdbp,
8337 SCMD_REQUEST_SENSE, 0, SENSE_LENGTH, 0);
8338
8339 mp_uscmdp->rqbp = rqbp;
8340 rqbp->b_private = mp_uscmdp;
8341 rqpkt->pkt_flags |= FLAG_SENSING;
8342 rqpkt->pkt_time = 60;
8343 rqpkt->pkt_comp = vhci_uscsi_iodone;
8344 rqpkt->pkt_private = mp_uscmdp;
8345
8346 /*
8347 * NOTE: This code path is related to MPAPI uscsi(7I), so path
8348 * selection is not based on path_instance.
8349 */
8350 if (scsi_pkt_allocated_correctly(rqpkt))
8351 rqpkt->pkt_path_instance = 0;
8352
8353 switch (scsi_transport(rqpkt)) {
8354 case TRAN_ACCEPT:
8355 VHCI_DEBUG(1, (CE_NOTE, NULL, "vhci_uscsi_send_sense: "
8356 "transport accepted."));
8357 break;
8358 case TRAN_BUSY:
8359 VHCI_DEBUG(1, (CE_NOTE, NULL, "vhci_uscsi_send_sense: "
8360 "transport busy, setting timeout."));
8361 vhci_restart_timeid = timeout(vhci_uscsi_restart_sense, rqpkt,
8362 (drv_usectohz(5 * 1000000)));
8537 uscmdp = mp_uscmdp->uscmdp;
8538 if (uscmdp->uscsi_flags & USCSI_RQENABLE) {
8539 stat_size = SENSE_LENGTH;
8540 } else {
8541 stat_size = 1;
8542 }
8543
8544 pkt = scsi_init_pkt(mp_uscmdp->ap, NULL, bp, uscmdp->uscsi_cdblen,
8545 stat_size, 0, 0, SLEEP_FUNC, NULL);
8546 if (pkt == NULL) {
8547 VHCI_DEBUG(4, (CE_NOTE, NULL,
8548 "vhci_uscsi_iostart: rval: EINVAL"));
8549 bp->b_resid = bp->b_bcount;
8550 uscmdp->uscsi_resid = bp->b_bcount;
8551 bioerror(bp, EINVAL);
8552 biodone(bp);
8553 return (EINVAL);
8554 }
8555
8556 pkt->pkt_time = uscmdp->uscsi_timeout;
8557 bcopy(uscmdp->uscsi_cdb, pkt->pkt_cdbp, (size_t)uscmdp->uscsi_cdblen);
8558 pkt->pkt_comp = vhci_uscsi_iodone;
8559 pkt->pkt_private = mp_uscmdp;
8560 if (uscmdp->uscsi_flags & USCSI_SILENT)
8561 pkt->pkt_flags |= FLAG_SILENT;
8562 if (uscmdp->uscsi_flags & USCSI_ISOLATE)
8563 pkt->pkt_flags |= FLAG_ISOLATE;
8564 if (uscmdp->uscsi_flags & USCSI_DIAGNOSE)
8565 pkt->pkt_flags |= FLAG_DIAGNOSE;
8566 if (uscmdp->uscsi_flags & USCSI_RENEGOT) {
8567 pkt->pkt_flags |= FLAG_RENEGOTIATE_WIDE_SYNC;
8568 }
8569 VHCI_DEBUG(4, (CE_WARN, NULL,
8570 "vhci_uscsi_iostart: ap: %p pkt: %p pcdbp: %p uscmdp: %p"
8571 " ucdbp: %p pcdblen: %d bp: %p count: %ld pip: %p"
8572 " stat_size: %d",
8573 (void *)mp_uscmdp->ap, (void *)pkt, (void *)pkt->pkt_cdbp,
8574 (void *)uscmdp, (void *)uscmdp->uscsi_cdb, pkt->pkt_cdblen,
8575 (void *)bp, bp->b_bcount, (void *)mp_uscmdp->pip, stat_size));
8576
|
1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2018 Nexenta Systems, Inc.
25 * Copyright (c) 2016 by Delphix. All rights reserved.
26 */
27
28 /*
29 * Multiplexed I/O SCSI vHCI implementation
30 */
31
32 #include <sys/conf.h>
33 #include <sys/file.h>
34 #include <sys/ddi.h>
35 #include <sys/sunddi.h>
36 #include <sys/scsi/scsi.h>
37 #include <sys/scsi/impl/scsi_reset_notify.h>
38 #include <sys/scsi/impl/services.h>
39 #include <sys/sunmdi.h>
40 #include <sys/mdi_impldefs.h>
41 #include <sys/scsi/adapters/scsi_vhci.h>
42 #include <sys/disp.h>
43 #include <sys/byteorder.h>
44
45 extern uintptr_t scsi_callback_id;
46 extern ddi_dma_attr_t scsi_alloc_attr;
47
48 #ifdef DEBUG
49 int vhci_debug = VHCI_DEBUG_DEFAULT_VAL;
50 #endif
51
52 /* retry for the vhci_do_prout command when a not ready is returned */
53 int vhci_prout_not_ready_retry = 180;
54
55 /*
56 * Timeout in seconds for SCSI commands used by vHCI.
57 */
58 int vhci_io_time = 30;
59
60 /*
61 * These values are defined to support the internal retry of
62 * SCSI packets for better sense code handling.
63 */
64 #define VHCI_CMD_CMPLT 0
65 #define VHCI_CMD_RETRY 1
66 #define VHCI_CMD_ERROR -1
67
68 #define PROPFLAGS (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM)
69 #define VHCI_SCSI_PERR 0x47
70 #define VHCI_PGR_ILLEGALOP -2
71 #define VHCI_NUM_UPDATE_TASKQ 8
72 /* changed to 132 to accomodate HDS */
73
74 /*
75 * Version Macros
76 */
77 #define VHCI_NAME_VERSION "SCSI VHCI Driver"
78 char vhci_version_name[] = VHCI_NAME_VERSION;
79
80 int vhci_first_time = 0;
119 * functions exported by scsi_vhci struct dev_ops
120 */
121 static int vhci_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
122 static int vhci_attach(dev_info_t *, ddi_attach_cmd_t);
123 static int vhci_detach(dev_info_t *, ddi_detach_cmd_t);
124
125 /*
126 * functions exported by scsi_vhci scsi_hba_tran_t transport table
127 */
128 static int vhci_scsi_tgt_init(dev_info_t *, dev_info_t *,
129 scsi_hba_tran_t *, struct scsi_device *);
130 static void vhci_scsi_tgt_free(dev_info_t *, dev_info_t *, scsi_hba_tran_t *,
131 struct scsi_device *);
132 static int vhci_pgr_register_start(scsi_vhci_lun_t *, struct scsi_pkt *);
133 static int vhci_scsi_start(struct scsi_address *, struct scsi_pkt *);
134 static int vhci_scsi_abort(struct scsi_address *, struct scsi_pkt *);
135 static int vhci_scsi_reset(struct scsi_address *, int);
136 static int vhci_scsi_reset_target(struct scsi_address *, int level,
137 uint8_t select_path);
138 static int vhci_scsi_reset_bus(struct scsi_address *);
139 static int vhci_scsi_reset_all_paths(struct scsi_address *);
140 static int vhci_scsi_getcap(struct scsi_address *, char *, int);
141 static int vhci_scsi_setcap(struct scsi_address *, char *, int, int);
142 static int vhci_commoncap(struct scsi_address *, char *, int, int, int);
143 static int vhci_pHCI_cap(struct scsi_address *ap, char *cap, int val, int whom,
144 mdi_pathinfo_t *pip);
145 static struct scsi_pkt *vhci_scsi_init_pkt(struct scsi_address *,
146 struct scsi_pkt *, struct buf *, int, int, int, int, int (*)(), caddr_t);
147 static void vhci_scsi_destroy_pkt(struct scsi_address *, struct scsi_pkt *);
148 static void vhci_scsi_dmafree(struct scsi_address *, struct scsi_pkt *);
149 static void vhci_scsi_sync_pkt(struct scsi_address *, struct scsi_pkt *);
150 static int vhci_scsi_reset_notify(struct scsi_address *, int, void (*)(caddr_t),
151 caddr_t);
152 static int vhci_scsi_get_bus_addr(struct scsi_device *, char *, int);
153 static int vhci_scsi_get_name(struct scsi_device *, char *, int);
154 static int vhci_scsi_bus_power(dev_info_t *, void *, pm_bus_power_op_t,
155 void *, void *);
156 static int vhci_scsi_bus_config(dev_info_t *, uint_t, ddi_bus_config_op_t,
157 void *, dev_info_t **);
158 static int vhci_scsi_bus_unconfig(dev_info_t *, uint_t, ddi_bus_config_op_t,
159 void *);
1374 * fail for some other reason. There is not an
1375 * easy way how to recover though. Log a warning
1376 * and return.
1377 */
1378 p_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
1379 vhci_log(CE_WARN, vhci->vhci_dip, "!Sending "
1380 "RELEASE(6) to %s failed, a potential "
1381 "reservation conflict ahead.",
1382 ddi_pathname(mdi_pi_get_phci(pip), p_path));
1383 kmem_free(p_path, MAXPATHLEN);
1384
1385 if (restore_lbp)
1386 (void) mdi_set_lb_policy(cdip, lbp);
1387
1388 /* no need to check pkt_reserve_cmd here */
1389 vlun->svl_flags &= ~VLUN_QUIESCED_FLG;
1390 return (TRAN_FATAL_ERROR);
1391 }
1392
1393 rel_pkt->pkt_cdbp[0] = SCMD_RELEASE;
1394 rel_pkt->pkt_time = vhci_io_time;
1395
1396 /*
1397 * Ignore the return value. If it will fail
1398 * then most likely it is no longer reserved
1399 * anyway.
1400 */
1401 (void) vhci_do_scsi_cmd(rel_pkt);
1402 VHCI_DEBUG(1, (CE_NOTE, NULL,
1403 "!vhci_scsi_start: path 0x%p, issued SCSI-2"
1404 " RELEASE\n", (void *)pip));
1405 scsi_destroy_pkt(rel_pkt);
1406 mdi_rele_path(pip);
1407 }
1408 }
1409
1410 VHCI_INCR_PATH_CMDCOUNT(svp);
1411
1412 /*
1413 * Ensure that no other IOs raced ahead, while a RESERVE cmd was
1414 * QUIESCING the same lun.
1523 /* Do not destroy phci packet information for PKT_DMA_PARTIAL */
1524 if ((vpkt->vpkt_flags & CFLAG_DMA_PARTIAL) == 0) {
1525 scsi_destroy_pkt(vpkt->vpkt_hba_pkt);
1526 vpkt->vpkt_hba_pkt = NULL;
1527 if (vpkt->vpkt_path) {
1528 MDI_PI_ERRSTAT(vpkt->vpkt_path, MDI_PI_TRANSERR);
1529 mdi_rele_path(vpkt->vpkt_path);
1530 vpkt->vpkt_path = NULL;
1531 }
1532 }
1533 return (TRAN_BUSY);
1534 }
1535
1536 /*
1537 * Function name : vhci_scsi_reset()
1538 *
1539 * Return Values : 0 - reset failed
1540 * 1 - reset succeeded
1541 */
1542
1543 static int
1544 vhci_scsi_reset(struct scsi_address *ap, int level)
1545 {
1546 if ((level == RESET_TARGET) || (level == RESET_LUN)) {
1547 return (vhci_scsi_reset_target(ap, level, TRUE));
1548 } else if (level == RESET_ALL) {
1549 return (vhci_scsi_reset_bus(ap));
1550 } else {
1551 return (0);
1552 }
1553 }
1554
1555 /*
1556 * vhci_recovery_reset:
1557 * Issues reset to the device
1558 * Input:
1559 * vlun - vhci lun pointer of the device
1560 * ap - address of the device
1561 * select_path:
1562 * If select_path is FALSE, then the address specified in ap is
1563 * the path on which reset will be issued.
1564 * If select_path is TRUE, then path is obtained by calling
1565 * mdi_select_path.
1566 *
1567 * recovery_depth:
1568 * Caller can specify the level of reset.
1569 * VHCI_DEPTH_LUN -
1570 * Issues LUN RESET if device supports lun reset.
1571 * VHCI_DEPTH_TARGET -
1572 * If Lun Reset fails or the device does not support
1598 recovery_depth--;
1599 }
1600
1601 if ((ret == 0) && recovery_depth) {
1602 (void) scsi_reset(ap, RESET_ALL);
1603 }
1604
1605 return (ret);
1606 }
1607
1608 /*
1609 * Note: The scsi_address passed to this routine could be the scsi_address
1610 * for the virtual device or the physical device. No assumptions should be
1611 * made in this routine about the contents of the ap structure.
1612 * Further, note that the child dip would be the dip of the ssd node regardless
1613 * of the scsi_address passed in.
1614 */
1615 static int
1616 vhci_scsi_reset_target(struct scsi_address *ap, int level, uint8_t select_path)
1617 {
1618 dev_info_t *vdip, *cdip = NULL;
1619 mdi_pathinfo_t *pip = NULL;
1620 mdi_pathinfo_t *npip = NULL;
1621 int rval = -1;
1622 scsi_vhci_priv_t *svp = NULL;
1623 struct scsi_address *pap = NULL;
1624 scsi_hba_tran_t *hba = NULL;
1625 int sps;
1626 struct scsi_vhci *vhci = NULL;
1627
1628 if (select_path != TRUE) {
1629 ASSERT(ap != NULL);
1630 if (level == RESET_LUN) {
1631 hba = ap->a_hba_tran;
1632 ASSERT(hba != NULL);
1633 return (hba->tran_reset(ap, RESET_LUN));
1634 }
1635 return (scsi_reset(ap, level));
1636 }
1637
1638 /*
1639 * SCSI address should be interpreted according to the pHBA flags.
1640 */
1641 if (ap->a_hba_tran->tran_hba_flags & SCSI_HBA_ADDR_COMPLEX)
1642 cdip = ADDR2DIP(ap);
1643 else if (ap->a_hba_tran->tran_hba_flags & SCSI_HBA_TRAN_CLONE)
1644 cdip = ap->a_hba_tran->tran_sd->sd_dev;
1645
1646 ASSERT(cdip != NULL);
1647 vdip = ddi_get_parent(cdip);
1648 ASSERT(vdip != NULL);
1649 vhci = ddi_get_soft_state(vhci_softstate, ddi_get_instance(vdip));
1650 ASSERT(vhci != NULL);
1651
1652 rval = mdi_select_path(cdip, NULL, MDI_SELECT_ONLINE_PATH, NULL, &pip);
1653 if ((rval != MDI_SUCCESS) || (pip == NULL)) {
1654 VHCI_DEBUG(2, (CE_WARN, NULL, "!vhci_scsi_reset_target: "
1655 "Unable to get a path, dip 0x%p", (void *)cdip));
1656 return (0);
1657 }
1658 again:
1659 svp = (scsi_vhci_priv_t *)mdi_pi_get_vhci_private(pip);
1660 if (svp == NULL) {
1661 VHCI_DEBUG(2, (CE_WARN, NULL, "!vhci_scsi_reset_target: "
1662 "priv is NULL, pip 0x%p", (void *)pip));
1663 mdi_rele_path(pip);
1664 return (0);
1665 }
1696 return (0);
1697 }
1698 mdi_rele_path(pip);
1699 pip = npip;
1700 goto again;
1701 }
1702 mdi_rele_path(pip);
1703 mutex_enter(&vhci->vhci_mutex);
1704 scsi_hba_reset_notify_callback(&vhci->vhci_mutex,
1705 &vhci->vhci_reset_notify_listf);
1706 mutex_exit(&vhci->vhci_mutex);
1707 VHCI_DEBUG(6, (CE_NOTE, NULL, "!vhci_scsi_reset_target: "
1708 "reset %d sent down pip:%p for cdip:%p\n", level,
1709 (void *)pip, (void *)cdip));
1710 return (1);
1711 }
1712 mdi_rele_path(pip);
1713 return (0);
1714 }
1715
1716 /* ARGSUSED */
1717 static int
1718 vhci_scsi_reset_bus(struct scsi_address *ap)
1719 {
1720 return (1);
1721 }
1722
1723 /*
1724 * This is a special version of LUN reset routine
1725 * which sends a reset down all available paths.
1726 */
1727 static int
1728 vhci_scsi_reset_all_paths(struct scsi_address *ap)
1729 {
1730 dev_info_t *vdip, *cdip = NULL;
1731 mdi_pathinfo_t *pip = NULL;
1732 mdi_pathinfo_t *npip = NULL;
1733 int rval = -1;
1734 scsi_vhci_priv_t *svp = NULL;
1735 struct scsi_address *pap = NULL;
1736 scsi_hba_tran_t *hba = NULL;
1737 int sps = MDI_SUCCESS;
1738 int reset_result = 0;
1739 struct scsi_vhci *vhci = NULL;
1740
1741 /*
1742 * SCSI address should be interpreted according to the pHBA flags.
1743 */
1744 if (ap->a_hba_tran->tran_hba_flags & SCSI_HBA_ADDR_COMPLEX)
1745 cdip = ADDR2DIP(ap);
1746 else if (ap->a_hba_tran->tran_hba_flags & SCSI_HBA_TRAN_CLONE)
1747 cdip = ap->a_hba_tran->tran_sd->sd_dev;
1748
1749 if (cdip == NULL || (vdip = ddi_get_parent(cdip)) == NULL ||
1750 (vhci = ddi_get_soft_state(vhci_softstate,
1751 ddi_get_instance(vdip))) == NULL) {
1752 VHCI_DEBUG(2, (CE_WARN, NULL, "!%s: "
1753 "Child info pointer NULL, cdip 0x%p",
1754 __func__, (void *)cdip));
1755 return (0);
1756 }
1757
1758 rval = mdi_select_path(cdip, NULL, MDI_SELECT_ONLINE_PATH, NULL, &pip);
1759 if ((rval != MDI_SUCCESS) || (pip == NULL)) {
1760 VHCI_DEBUG(2, (CE_WARN, NULL, "!%s: "
1761 "Unable to get a path, dip 0x%p",
1762 __func__, (void *)cdip));
1763 return (0);
1764 }
1765 again:
1766 svp = (scsi_vhci_priv_t *)mdi_pi_get_vhci_private(pip);
1767
1768 if (svp == NULL || svp->svp_psd == NULL) {
1769 VHCI_DEBUG(2, (CE_WARN, NULL, "!%s: "
1770 "private data is NULL, pip 0x%p",
1771 __func__, (void *)pip));
1772 mdi_rele_path(pip);
1773 return (0);
1774 }
1775
1776 pap = &svp->svp_psd->sd_address;
1777 hba = pap->a_hba_tran;
1778
1779 if (pap != NULL && hba != NULL && hba->tran_reset != NULL) {
1780 /*
1781 * The following sends reset down all available paths
1782 */
1783 if (sps == MDI_SUCCESS) {
1784 reset_result = hba->tran_reset(pap, RESET_LUN);
1785
1786 VHCI_DEBUG(2, (CE_WARN, vdip, "!%s%d: "
1787 "path %s, reset LUN %s",
1788 ddi_driver_name(cdip), ddi_get_instance(cdip),
1789 mdi_pi_spathname(pip),
1790 (reset_result ? "Success" : "Failed")));
1791
1792 /*
1793 * Select next path and issue the reset, repeat
1794 * until all paths are exhausted regardless of success
1795 * or failure of the previous reset.
1796 */
1797 sps = mdi_select_path(cdip, NULL,
1798 MDI_SELECT_ONLINE_PATH, pip, &npip);
1799 if ((sps != MDI_SUCCESS) || (npip == NULL)) {
1800 mdi_rele_path(pip);
1801 return (0);
1802 }
1803 mdi_rele_path(pip);
1804 pip = npip;
1805 goto again;
1806 }
1807 mdi_rele_path(pip);
1808 mutex_enter(&vhci->vhci_mutex);
1809 scsi_hba_reset_notify_callback(&vhci->vhci_mutex,
1810 &vhci->vhci_reset_notify_listf);
1811 mutex_exit(&vhci->vhci_mutex);
1812 VHCI_DEBUG(6, (CE_NOTE, NULL, "!vhci_scsi_reset_target: "
1813 "reset %d sent down pip:%p for cdip:%p\n", RESET_LUN,
1814 (void *)pip, (void *)cdip));
1815 return (1);
1816 }
1817 mdi_rele_path(pip);
1818 return (0);
1819 }
1820
1821 /*
1822 * called by vhci_getcap and vhci_setcap to get and set (respectively)
1823 * SCSI capabilities
1824 */
1825 /* ARGSUSED */
1826 static int
1827 vhci_commoncap(struct scsi_address *ap, char *cap,
1828 int val, int tgtonly, int doset)
1829 {
1830 struct scsi_vhci *vhci = ADDR2VHCI(ap);
1831 struct scsi_vhci_lun *vlun = ADDR2VLUN(ap);
1832 int cidx;
1833 int rval = 0;
1834
1835 if (cap == (char *)0) {
1836 VHCI_DEBUG(3, (CE_WARN, vhci->vhci_dip,
1837 "!vhci_commoncap: invalid arg"));
1838 return (rval);
1839 }
1840
3273 char *cpath;
3274
3275 ASSERT(vpkt != NULL);
3276 tpkt = vpkt->vpkt_tgt_pkt;
3277 ASSERT(tpkt != NULL);
3278 svp = (scsi_vhci_priv_t *)mdi_pi_get_vhci_private(vpkt->vpkt_path);
3279 ASSERT(svp != NULL);
3280 vlun = svp->svp_svl;
3281 ASSERT(vlun != NULL);
3282 lpath = vpkt->vpkt_path;
3283
3284 /*
3285 * sync up the target driver's pkt with the pkt that
3286 * we actually used
3287 */
3288 *(tpkt->pkt_scbp) = *(pkt->pkt_scbp);
3289 tpkt->pkt_resid = pkt->pkt_resid;
3290 tpkt->pkt_state = pkt->pkt_state;
3291 tpkt->pkt_statistics = pkt->pkt_statistics;
3292 tpkt->pkt_reason = pkt->pkt_reason;
3293 tpkt->pkt_start = pkt->pkt_start;
3294 tpkt->pkt_stop = pkt->pkt_stop;
3295
3296 /* Return path_instance information back to the target driver. */
3297 if (scsi_pkt_allocated_correctly(tpkt)) {
3298 if (scsi_pkt_allocated_correctly(pkt)) {
3299 /*
3300 * If both packets were correctly allocated,
3301 * return path returned by pHCI.
3302 */
3303 tpkt->pkt_path_instance = pkt->pkt_path_instance;
3304 } else {
3305 /* Otherwise return path of pHCI we used */
3306 tpkt->pkt_path_instance =
3307 mdi_pi_get_path_instance(lpath);
3308 }
3309 }
3310
3311 if (pkt->pkt_cdbp[0] == SCMD_PROUT &&
3312 ((pkt->pkt_cdbp[1] & 0x1f) == VHCI_PROUT_REGISTER) ||
3313 ((pkt->pkt_cdbp[1] & 0x1f) == VHCI_PROUT_R_AND_IGNORE)) {
3314 if ((SCBP_C(pkt) != STATUS_GOOD) ||
4046 }
4047
4048 /* Check for Reservation Conflict */
4049 bp = scsi_alloc_consistent_buf(
4050 &svp->svp_psd->sd_address, (struct buf *)NULL,
4051 DEV_BSIZE, B_READ, NULL, NULL);
4052 if (!bp) {
4053 VHCI_DEBUG(1, (CE_NOTE, NULL,
4054 "!vhci_update_pathstates: No resources "
4055 "(buf)\n"));
4056 mdi_rele_path(pip);
4057 goto done;
4058 }
4059 pkt = scsi_init_pkt(&svp->svp_psd->sd_address, NULL, bp,
4060 CDB_GROUP1, sizeof (struct scsi_arq_status), 0,
4061 PKT_CONSISTENT, NULL, NULL);
4062 if (pkt) {
4063 (void) scsi_setup_cdb((union scsi_cdb *)
4064 (uintptr_t)pkt->pkt_cdbp, SCMD_READ, 1, 1,
4065 0);
4066 pkt->pkt_time = 2 * vhci_io_time;
4067 pkt->pkt_flags = FLAG_NOINTR;
4068 pkt->pkt_path_instance =
4069 mdi_pi_get_path_instance(pip);
4070
4071 if ((scsi_transport(pkt) == TRAN_ACCEPT) &&
4072 (pkt->pkt_reason == CMD_CMPLT) &&
4073 (SCBP_C(pkt) ==
4074 STATUS_RESERVATION_CONFLICT)) {
4075 VHCI_DEBUG(1, (CE_NOTE, NULL,
4076 "!vhci_update_pathstates: reserv. "
4077 "conflict to be resolved on 0x%p\n",
4078 (void *)pip));
4079 svp_conflict = svp;
4080 }
4081 scsi_destroy_pkt(pkt);
4082 }
4083 scsi_free_consistent_buf(bp);
4084 } else if ((opinfo.opinfo_path_state == SCSI_PATH_INACTIVE) &&
4085 !(MDI_PI_IS_STANDBY(pip))) {
4086 VHCI_DEBUG(1, (CE_NOTE, NULL,
5311 if ((vlun->svl_flags & VLUN_RESERVE_ACTIVE_FLG) == 0) {
5312 /*
5313 * Issue SCSI-2 RELEASE only for the first time on
5314 * a new path just in case the host rebooted and
5315 * a reservation is still pending on this path.
5316 * IBM Shark storage does not clear RESERVE upon
5317 * host reboot.
5318 */
5319 pkt = scsi_init_pkt(ap, NULL, NULL, CDB_GROUP0,
5320 sizeof (struct scsi_arq_status), 0, 0,
5321 SLEEP_FUNC, NULL);
5322 if (pkt == NULL) {
5323 VHCI_DEBUG(1, (CE_NOTE, NULL,
5324 "!vhci_pathinfo_online: "
5325 "Release init_pkt failed :%p\n",
5326 (void *)pip));
5327 rval = MDI_FAILURE;
5328 goto failure;
5329 }
5330 pkt->pkt_cdbp[0] = SCMD_RELEASE;
5331 pkt->pkt_time = vhci_io_time;
5332
5333 VHCI_DEBUG(1, (CE_NOTE, NULL,
5334 "!vhci_path_online: path:%p "
5335 "Issued SCSI-2 RELEASE\n", (void *)pip));
5336
5337 /* Ignore the return value */
5338 (void) vhci_do_scsi_cmd(pkt);
5339 scsi_destroy_pkt(pkt);
5340 }
5341 }
5342
5343 rval = vhci_update_pathinfo(psd, pip, sfo, vlun, vhci);
5344 if (rval == MDI_FAILURE) {
5345 goto failure;
5346 }
5347
5348 /* Initialize MP-API data */
5349 vhci_update_mpapi_data(vhci, vlun, pip);
5350
5351 /*
6238
6239 case DEVCTL_DEVICE_RESET:
6240 /*
6241 * lookup and hold child device
6242 */
6243 if ((child = ndi_devi_find(self, ndi_dc_getname(dcp),
6244 ndi_dc_getaddr(dcp))) == NULL) {
6245 rv = ENXIO;
6246 break;
6247 }
6248 retval = mdi_select_path(child, NULL,
6249 (MDI_SELECT_ONLINE_PATH | MDI_SELECT_STANDBY_PATH),
6250 NULL, &pip);
6251 if ((retval != MDI_SUCCESS) || (pip == NULL)) {
6252 VHCI_DEBUG(2, (CE_WARN, NULL, "!vhci_ioctl:"
6253 "Unable to get a path, dip 0x%p", (void *)child));
6254 rv = ENXIO;
6255 break;
6256 }
6257 svp = (scsi_vhci_priv_t *)mdi_pi_get_vhci_private(pip);
6258
6259 VHCI_DEBUG(2, (CE_NOTE, NULL,
6260 "!reset %s@%s on all available paths",
6261 ndi_dc_getname(dcp), ndi_dc_getaddr(dcp)));
6262
6263 if (vhci_scsi_reset_all_paths(&svp->svp_psd->sd_address) != 0) {
6264 VHCI_DEBUG(2, (CE_WARN, NULL,
6265 "!vhci_ioctl(pip:%p): reset failed\n",
6266 (void *)pip));
6267 rv = ENXIO;
6268 }
6269 mdi_rele_path(pip);
6270 break;
6271
6272 case DEVCTL_BUS_QUIESCE:
6273 case DEVCTL_BUS_UNQUIESCE:
6274 case DEVCTL_BUS_RESET:
6275 case DEVCTL_BUS_RESETALL:
6276 #ifdef DEBUG
6277 case DEVCTL_BUS_CONFIGURE:
6278 case DEVCTL_BUS_UNCONFIGURE:
6279 #endif
6280 rv = ENOTSUP;
6281 break;
6282
6283 default:
6284 rv = ENOTTY;
6285 } /* end of outer switch */
6286
7070 check_condition = 0;
7071 UA_condition = 0;
7072
7073 bp = scsi_alloc_consistent_buf(&svp->svp_psd->sd_address,
7074 (struct buf *)NULL, DEV_BSIZE, B_READ, NULL, NULL);
7075 if (!bp) {
7076 VHCI_DEBUG(1, (CE_NOTE, NULL,
7077 "vhci_failover !No resources (buf)\n"));
7078 mdi_rele_path(npip);
7079 goto done;
7080 }
7081 pkt = scsi_init_pkt(&svp->svp_psd->sd_address, NULL, bp,
7082 CDB_GROUP1, sizeof (struct scsi_arq_status), 0,
7083 PKT_CONSISTENT, NULL, NULL);
7084 if (pkt) {
7085 (void) scsi_setup_cdb((union scsi_cdb *)(uintptr_t)
7086 pkt->pkt_cdbp, SCMD_READ, 1, 1, 0);
7087 pkt->pkt_flags = FLAG_NOINTR;
7088 check_path_again:
7089 pkt->pkt_path_instance = mdi_pi_get_path_instance(npip);
7090 pkt->pkt_time = 2 * vhci_io_time;
7091
7092 if (scsi_transport(pkt) == TRAN_ACCEPT) {
7093 switch (pkt->pkt_reason) {
7094 case CMD_CMPLT:
7095 switch (SCBP_C(pkt)) {
7096 case STATUS_GOOD:
7097 /* Already failed over */
7098 activation_done = 1;
7099 break;
7100 case STATUS_RESERVATION_CONFLICT:
7101 reserve_pending = 1;
7102 break;
7103 case STATUS_CHECK:
7104 check_condition = 1;
7105 break;
7106 }
7107 }
7108 }
7109 if (check_condition &&
7110 (pkt->pkt_state & STATE_ARQ_DONE)) {
8431 "vhci_uscsi_send_sense: enter: bp: %p pkt: %p scmd: %p",
8432 (void *)cmdbp, (void *)pkt, (void *)mp_uscmdp));
8433 /* set up the packet information and cdb */
8434 if ((rqbp = scsi_alloc_consistent_buf(mp_uscmdp->ap, NULL,
8435 SENSE_LENGTH, B_READ, NULL, NULL)) == NULL) {
8436 return (-1);
8437 }
8438
8439 if ((rqpkt = scsi_init_pkt(mp_uscmdp->ap, NULL, rqbp,
8440 CDB_GROUP0, 1, 0, PKT_CONSISTENT, NULL, NULL)) == NULL) {
8441 scsi_free_consistent_buf(rqbp);
8442 return (-1);
8443 }
8444
8445 (void) scsi_setup_cdb((union scsi_cdb *)(intptr_t)rqpkt->pkt_cdbp,
8446 SCMD_REQUEST_SENSE, 0, SENSE_LENGTH, 0);
8447
8448 mp_uscmdp->rqbp = rqbp;
8449 rqbp->b_private = mp_uscmdp;
8450 rqpkt->pkt_flags |= FLAG_SENSING;
8451 rqpkt->pkt_time = vhci_io_time;
8452 rqpkt->pkt_comp = vhci_uscsi_iodone;
8453 rqpkt->pkt_private = mp_uscmdp;
8454
8455 /*
8456 * NOTE: This code path is related to MPAPI uscsi(7I), so path
8457 * selection is not based on path_instance.
8458 */
8459 if (scsi_pkt_allocated_correctly(rqpkt))
8460 rqpkt->pkt_path_instance = 0;
8461
8462 switch (scsi_transport(rqpkt)) {
8463 case TRAN_ACCEPT:
8464 VHCI_DEBUG(1, (CE_NOTE, NULL, "vhci_uscsi_send_sense: "
8465 "transport accepted."));
8466 break;
8467 case TRAN_BUSY:
8468 VHCI_DEBUG(1, (CE_NOTE, NULL, "vhci_uscsi_send_sense: "
8469 "transport busy, setting timeout."));
8470 vhci_restart_timeid = timeout(vhci_uscsi_restart_sense, rqpkt,
8471 (drv_usectohz(5 * 1000000)));
8646 uscmdp = mp_uscmdp->uscmdp;
8647 if (uscmdp->uscsi_flags & USCSI_RQENABLE) {
8648 stat_size = SENSE_LENGTH;
8649 } else {
8650 stat_size = 1;
8651 }
8652
8653 pkt = scsi_init_pkt(mp_uscmdp->ap, NULL, bp, uscmdp->uscsi_cdblen,
8654 stat_size, 0, 0, SLEEP_FUNC, NULL);
8655 if (pkt == NULL) {
8656 VHCI_DEBUG(4, (CE_NOTE, NULL,
8657 "vhci_uscsi_iostart: rval: EINVAL"));
8658 bp->b_resid = bp->b_bcount;
8659 uscmdp->uscsi_resid = bp->b_bcount;
8660 bioerror(bp, EINVAL);
8661 biodone(bp);
8662 return (EINVAL);
8663 }
8664
8665 pkt->pkt_time = uscmdp->uscsi_timeout;
8666 if (pkt->pkt_time == 0)
8667 pkt->pkt_time = vhci_io_time;
8668
8669 bcopy(uscmdp->uscsi_cdb, pkt->pkt_cdbp, (size_t)uscmdp->uscsi_cdblen);
8670 pkt->pkt_comp = vhci_uscsi_iodone;
8671 pkt->pkt_private = mp_uscmdp;
8672 if (uscmdp->uscsi_flags & USCSI_SILENT)
8673 pkt->pkt_flags |= FLAG_SILENT;
8674 if (uscmdp->uscsi_flags & USCSI_ISOLATE)
8675 pkt->pkt_flags |= FLAG_ISOLATE;
8676 if (uscmdp->uscsi_flags & USCSI_DIAGNOSE)
8677 pkt->pkt_flags |= FLAG_DIAGNOSE;
8678 if (uscmdp->uscsi_flags & USCSI_RENEGOT) {
8679 pkt->pkt_flags |= FLAG_RENEGOTIATE_WIDE_SYNC;
8680 }
8681 VHCI_DEBUG(4, (CE_WARN, NULL,
8682 "vhci_uscsi_iostart: ap: %p pkt: %p pcdbp: %p uscmdp: %p"
8683 " ucdbp: %p pcdblen: %d bp: %p count: %ld pip: %p"
8684 " stat_size: %d",
8685 (void *)mp_uscmdp->ap, (void *)pkt, (void *)pkt->pkt_cdbp,
8686 (void *)uscmdp, (void *)uscmdp->uscsi_cdb, pkt->pkt_cdblen,
8687 (void *)bp, bp->b_bcount, (void *)mp_uscmdp->pip, stat_size));
8688
|