Print this page
NEX-18203 fcp should call mdi_pi_offline() without NDI_DEVI_REMOVE
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
NEX-17944 HBA drivers don't need the redundant devfs_clean step
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-3153 fcp unable to offline paths to drives behind ATTO Fibrebridge 6500
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
        
*** 16,28 ****
   * fields enclosed by brackets "[]" replaced with your own identifying
   * information: Portions Copyright [yyyy] [name of copyright owner]
   *
   * CDDL HEADER END
   */
  /*
   * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
!  *
   * Fibre Channel SCSI ULP Mapping driver
   */
  
  #include <sys/scsi/scsi.h>
  #include <sys/types.h>
--- 16,35 ----
   * fields enclosed by brackets "[]" replaced with your own identifying
   * information: Portions Copyright [yyyy] [name of copyright owner]
   *
   * CDDL HEADER END
   */
+ 
  /*
   * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
!  */
! 
! /*
!  * Copyright 2018 Nexenta Systems, Inc.
!  */
! 
! /*
   * Fibre Channel SCSI ULP Mapping driver
   */
  
  #include <sys/scsi/scsi.h>
  #include <sys/types.h>
*** 38,48 ****
  #include <sys/time.h>
  #include <sys/utsname.h>
  #include <sys/scsi/impl/scsi_reset_notify.h>
  #include <sys/ndi_impldefs.h>
  #include <sys/byteorder.h>
- #include <sys/fs/dv_node.h>
  #include <sys/ctype.h>
  #include <sys/sunmdi.h>
  
  #include <sys/fibre-channel/fc.h>
  #include <sys/fibre-channel/impl/fc_ulpif.h>
--- 45,54 ----
*** 3864,3873 ****
--- 3870,3881 ----
                  tcount = plun->lun_tgt->tgt_change_cnt;
                  mutex_exit(&pptr->port_mutex);
  
                  if (cmd == DEVCTL_DEVICE_REMOVE) {
                          flag = NDI_DEVI_REMOVE;
+                         if (is_mpxio)
+                                 flag |= NDI_USER_REQ;
                  }
  
                  if (is_mpxio) {
                          mdi_devi_exit(pptr->port_dip, circ);
                  } else {
*** 8149,8160 ****
          int                     rval = NDI_FAILURE;
          int                     circ;
          child_info_t            *ccip;
          struct fcp_port         *pptr = plun->lun_tgt->tgt_port;
          int                     is_mpxio = pptr->port_mpxio;
-         dev_info_t              *cdip, *pdip;
-         char                    *devname;
  
          if ((old_mpxio != 0) && (plun->lun_mpxio != old_mpxio)) {
                  /*
                   * When this event gets serviced, lun_cip and lun_mpxio
                   * has changed, so it should be invalidated now.
--- 8157,8166 ----
*** 8190,8238 ****
                          rval = NDI_SUCCESS;
                  }
                  return (rval);
          }
  
-         /*
-          * Explicit devfs_clean() due to ndi_devi_offline() not
-          * executing devfs_clean() if parent lock is held.
-          */
-         ASSERT(!servicing_interrupt());
-         if (online == FCP_OFFLINE) {
-                 if (plun->lun_mpxio == 0) {
-                         if (plun->lun_cip == cip) {
-                                 cdip = DIP(plun->lun_cip);
-                         } else {
-                                 cdip = DIP(cip);
-                         }
-                 } else if ((plun->lun_cip == cip) && plun->lun_cip) {
-                         cdip = mdi_pi_get_client(PIP(plun->lun_cip));
-                 } else if ((plun->lun_cip != cip) && cip) {
-                         /*
-                          * This means a DTYPE/GUID change, we shall get the
-                          * dip of the old cip instead of the current lun_cip.
-                          */
-                         cdip = mdi_pi_get_client(PIP(cip));
-                 }
-                 if (cdip) {
-                         if (i_ddi_devi_attached(cdip)) {
-                                 pdip = ddi_get_parent(cdip);
-                                 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
-                                 ndi_devi_enter(pdip, &circ);
-                                 (void) ddi_deviname(cdip, devname);
-                                 /*
-                                  * Release parent lock before calling
-                                  * devfs_clean().
-                                  */
-                                 ndi_devi_exit(pdip, circ);
-                                 (void) devfs_clean(pdip, devname + 1,
-                                     DV_CLEAN_FORCE);
-                                 kmem_free(devname, MAXNAMELEN + 1);
-                         }
-                 }
-         }
- 
          if (fc_ulp_busy_port(pptr->port_fp_handle) != 0) {
                  return (NDI_FAILURE);
          }
  
          if (is_mpxio) {
--- 8196,8205 ----
*** 13068,13086 ****
  
          fcp_wwn_to_ascii(plun->lun_tgt->tgt_port_wwn.raw_wwn, buf);
  
          (void) snprintf(uaddr, MAXNAMELEN, "w%s,%x", buf, plun->lun_num);
  
!         if (plun->lun_old_guid) {
!                 if (mdi_pi_find(pdip, plun->lun_old_guid, uaddr) == pip) {
                          rval = FC_SUCCESS;
                  }
!         } else {
!                 if (mdi_pi_find(pdip, plun->lun_guid, uaddr) == pip) {
!                         rval = FC_SUCCESS;
!                 }
!         }
          return (rval);
  }
  
  static mdi_pathinfo_t *
  fcp_find_existing_pip(struct fcp_lun *plun, dev_info_t *pdip)
--- 13035,13048 ----
  
          fcp_wwn_to_ascii(plun->lun_tgt->tgt_port_wwn.raw_wwn, buf);
  
          (void) snprintf(uaddr, MAXNAMELEN, "w%s,%x", buf, plun->lun_num);
  
!         if (mdi_pi_find(pdip, NULL, uaddr) == pip) {
                  rval = FC_SUCCESS;
          }
! 
          return (rval);
  }
  
  static mdi_pathinfo_t *
  fcp_find_existing_pip(struct fcp_lun *plun, dev_info_t *pdip)
*** 13310,13320 ****
  
          if (lun_mpxio == 0) {
                  cdip = DIP(cip);
                  mutex_exit(&plun->lun_mutex);
                  mutex_exit(&pptr->port_mutex);
!                 rval = ndi_devi_offline(DIP(cip), flags);
                  if (rval != NDI_SUCCESS) {
                          FCP_TRACE(fcp_logq, pptr->port_instbuf,
                              fcp_trace, FCP_BUF_LEVEL_3, 0,
                              "fcp_offline_child: ndi_devi_offline failed "
                              "rval=%x cip=%p", rval, cip);
--- 13272,13282 ----
  
          if (lun_mpxio == 0) {
                  cdip = DIP(cip);
                  mutex_exit(&plun->lun_mutex);
                  mutex_exit(&pptr->port_mutex);
!                 rval = ndi_devi_offline(DIP(cip), NDI_DEVFS_CLEAN | flags);
                  if (rval != NDI_SUCCESS) {
                          FCP_TRACE(fcp_logq, pptr->port_instbuf,
                              fcp_trace, FCP_BUF_LEVEL_3, 0,
                              "fcp_offline_child: ndi_devi_offline failed "
                              "rval=%x cip=%p", rval, cip);
*** 13329,13339 ****
                   * during mdi_pi_offline
                   */
                  mdi_hold_path(PIP(cip));
                  mdi_devi_exit_phci(pptr->port_dip, *circ);
  
!                 rval = mdi_pi_offline(PIP(cip), flags);
  
                  mdi_devi_enter_phci(pptr->port_dip, circ);
                  mdi_rele_path(PIP(cip));
  
                  rval = (rval == MDI_SUCCESS) ? NDI_SUCCESS : NDI_FAILURE;
--- 13291,13301 ----
                   * during mdi_pi_offline
                   */
                  mdi_hold_path(PIP(cip));
                  mdi_devi_exit_phci(pptr->port_dip, *circ);
  
!                 rval = mdi_pi_offline(PIP(cip), flags & ~NDI_DEVI_REMOVE);
  
                  mdi_devi_enter_phci(pptr->port_dip, circ);
                  mdi_rele_path(PIP(cip));
  
                  rval = (rval == MDI_SUCCESS) ? NDI_SUCCESS : NDI_FAILURE;
*** 13429,13456 ****
  
                          mutex_exit(&plun->lun_mutex);
                          mutex_exit(&plun->lun_tgt->tgt_mutex);
                          mutex_exit(&plun->lun_tgt->tgt_port->port_mutex);
  
!                         mdi_devi_enter(
!                             plun->lun_tgt->tgt_port->port_dip, &circ);
  
                          /*
                           * Exit phci to avoid deadlock with power management
                           * code during mdi_pi_offline
                           */
                          mdi_hold_path(PIP(cip));
!                         mdi_devi_exit_phci(
!                             plun->lun_tgt->tgt_port->port_dip, circ);
!                         (void) mdi_pi_offline(PIP(cip),
!                             NDI_DEVI_REMOVE);
!                         mdi_devi_enter_phci(
!                             plun->lun_tgt->tgt_port->port_dip, &circ);
                          mdi_rele_path(PIP(cip));
  
!                         mdi_devi_exit(
!                             plun->lun_tgt->tgt_port->port_dip, circ);
  
                          FCP_TRACE(fcp_logq,
                              plun->lun_tgt->tgt_port->port_instbuf,
                              fcp_trace, FCP_BUF_LEVEL_3, 0,
                              "lun=%p pip freed %p", plun, cip);
--- 13391,13416 ----
  
                          mutex_exit(&plun->lun_mutex);
                          mutex_exit(&plun->lun_tgt->tgt_mutex);
                          mutex_exit(&plun->lun_tgt->tgt_port->port_mutex);
  
!                         mdi_devi_enter(plun->lun_tgt->tgt_port->port_dip,
!                             &circ);
  
                          /*
                           * Exit phci to avoid deadlock with power management
                           * code during mdi_pi_offline
                           */
                          mdi_hold_path(PIP(cip));
!                         mdi_devi_exit_phci(plun->lun_tgt->tgt_port->port_dip,
!                             circ);
!                         (void) mdi_pi_offline(PIP(cip), 0);
!                         mdi_devi_enter_phci(plun->lun_tgt->tgt_port->port_dip,
!                             &circ);
                          mdi_rele_path(PIP(cip));
  
!                         mdi_devi_exit(plun->lun_tgt->tgt_port->port_dip, circ);
  
                          FCP_TRACE(fcp_logq,
                              plun->lun_tgt->tgt_port->port_instbuf,
                              fcp_trace, FCP_BUF_LEVEL_3, 0,
                              "lun=%p pip freed %p", plun, cip);