Print this page
9702 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>


  27  *    used to endorse or promote products derived from this software without
  28  *    specific prior written permission.
  29  *
  30  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  31  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  32  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  33  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  34  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  35  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  36  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  37  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  38  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  39  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  40  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  41  * DAMAGE.
  42  */
  43 
  44 /*
  45  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  46  * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
  47  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  48  * Copyright 2015, 2017 Citrus IT Limited. All rights reserved.
  49  * Copyright 2015 Garrett D'Amore <garrett@damore.org>
  50  */
  51 
  52 #include <sys/types.h>
  53 #include <sys/param.h>
  54 #include <sys/file.h>
  55 #include <sys/errno.h>
  56 #include <sys/open.h>
  57 #include <sys/cred.h>
  58 #include <sys/modctl.h>
  59 #include <sys/conf.h>
  60 #include <sys/devops.h>
  61 #include <sys/cmn_err.h>
  62 #include <sys/kmem.h>
  63 #include <sys/stat.h>
  64 #include <sys/mkdev.h>
  65 #include <sys/pci.h>
  66 #include <sys/scsi/scsi.h>
  67 #include <sys/ddi.h>
  68 #include <sys/sunddi.h>
  69 #include <sys/atomic.h>
  70 #include <sys/signal.h>
  71 #include <sys/byteorder.h>
  72 #include <sys/sdt.h>
  73 #include <sys/fs/dv_node.h>       /* devfs_clean */
  74 
  75 #include "mr_sas.h"
  76 
  77 /*
  78  * FMA header files
  79  */
  80 #include <sys/ddifm.h>
  81 #include <sys/fm/protocol.h>
  82 #include <sys/fm/util.h>
  83 #include <sys/fm/io/ddi.h>
  84 
  85 /* Macros to help Skinny and stock 2108/MFI live together. */
  86 #define WR_IB_PICK_QPORT(addr, instance) \
  87         if ((instance)->skinny) { \
  88                 WR_IB_LOW_QPORT((addr), (instance)); \
  89                 WR_IB_HIGH_QPORT(0, (instance)); \
  90         } else { \
  91                 WR_IB_QPORT((addr), (instance)); \
  92         }
  93 


7725         mrevt->event = event;
7726         mrevt->wwn = wwn;
7727 
7728         if ((ddi_taskq_dispatch(instance->taskq,
7729             (void (*)(void *))mrsas_issue_evt_taskq, mrevt, DDI_NOSLEEP)) !=
7730             DDI_SUCCESS) {
7731                 con_log(CL_ANN1, (CE_NOTE,
7732                     "mr_sas: Event task failed for t%dl%d event = %d",
7733                     tgt, lun, event));
7734                 kmem_free(mrevt, sizeof (struct mrsas_eventinfo));
7735                 return (DDI_FAILURE);
7736         }
7737         DTRACE_PROBE3(service_evt, int, tgt, int, lun, int, event);
7738         return (DDI_SUCCESS);
7739 }
7740 
7741 static void
7742 mrsas_issue_evt_taskq(struct mrsas_eventinfo *mrevt)
7743 {
7744         struct mrsas_instance *instance = mrevt->instance;
7745         dev_info_t *dip, *pdip;
7746         int circ1 = 0;
7747         char *devname;
7748 
7749         con_log(CL_ANN1, (CE_NOTE, "mrsas_issue_evt_taskq: called for"
7750             " tgt %d lun %d event %d",
7751             mrevt->tgt, mrevt->lun, mrevt->event));
7752 
7753         if (mrevt->tgt < MRDRV_MAX_LD && mrevt->lun == 0) {
7754                 mutex_enter(&instance->config_dev_mtx);
7755                 dip = instance->mr_ld_list[mrevt->tgt].dip;
7756                 mutex_exit(&instance->config_dev_mtx);
7757         } else {
7758                 mutex_enter(&instance->config_dev_mtx);
7759                 dip = instance->mr_tbolt_pd_list[mrevt->tgt].dip;
7760                 mutex_exit(&instance->config_dev_mtx);
7761         }
7762 
7763 
7764         ndi_devi_enter(instance->dip, &circ1);
7765         switch (mrevt->event) {
7766         case MRSAS_EVT_CONFIG_TGT:
7767                 if (dip == NULL) {
7768 
7769                         if (mrevt->lun == 0) {
7770                                 (void) mrsas_config_ld(instance, mrevt->tgt,
7771                                     0, NULL);
7772                         } else if (instance->tbolt || instance->skinny) {
7773                                 (void) mrsas_tbolt_config_pd(instance,
7774                                     mrevt->tgt,
7775                                     1, NULL);
7776                         }
7777                         con_log(CL_ANN1, (CE_NOTE,
7778                             "mr_sas: EVT_CONFIG_TGT called:"
7779                             " for tgt %d lun %d event %d",
7780                             mrevt->tgt, mrevt->lun, mrevt->event));
7781 
7782                 } else {
7783                         con_log(CL_ANN1, (CE_NOTE,
7784                             "mr_sas: EVT_CONFIG_TGT dip != NULL:"
7785                             " for tgt %d lun %d event %d",
7786                             mrevt->tgt, mrevt->lun, mrevt->event));
7787                 }
7788                 break;
7789         case MRSAS_EVT_UNCONFIG_TGT:
7790                 if (dip) {
7791                         if (i_ddi_devi_attached(dip)) {
7792 
7793                                 pdip = ddi_get_parent(dip);
7794 
7795                                 devname = kmem_zalloc(MAXNAMELEN + 1, KM_SLEEP);
7796                                 (void) ddi_deviname(dip, devname);
7797 
7798                                 (void) devfs_clean(pdip, devname + 1,
7799                                     DV_CLEAN_FORCE);
7800                                 kmem_free(devname, MAXNAMELEN + 1);
7801                         }
7802                         (void) ndi_devi_offline(dip, NDI_DEVI_REMOVE);
7803                         con_log(CL_ANN1, (CE_NOTE,
7804                             "mr_sas: EVT_UNCONFIG_TGT called:"
7805                             " for tgt %d lun %d event %d",
7806                             mrevt->tgt, mrevt->lun, mrevt->event));
7807                 } else {
7808                         con_log(CL_ANN1, (CE_NOTE,
7809                             "mr_sas: EVT_UNCONFIG_TGT dip == NULL:"
7810                             " for tgt %d lun %d event %d",
7811                             mrevt->tgt, mrevt->lun, mrevt->event));
7812                 }
7813                 break;
7814         }
7815         kmem_free(mrevt, sizeof (struct mrsas_eventinfo));
7816         ndi_devi_exit(instance->dip, circ1);
7817 }
7818 
7819 
7820 int
7821 mrsas_mode_sense_build(struct scsi_pkt *pkt)
7822 {




  27  *    used to endorse or promote products derived from this software without
  28  *    specific prior written permission.
  29  *
  30  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  31  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  32  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  33  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  34  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  35  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  36  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  37  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  38  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  39  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  40  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  41  * DAMAGE.
  42  */
  43 
  44 /*
  45  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  46  * Copyright (c) 2011 Bayard G. Bell. All rights reserved.
  47  * Copyright 2018 Nexenta Systems, Inc.
  48  * Copyright 2015, 2017 Citrus IT Limited. All rights reserved.
  49  * Copyright 2015 Garrett D'Amore <garrett@damore.org>
  50  */
  51 
  52 #include <sys/types.h>
  53 #include <sys/param.h>
  54 #include <sys/file.h>
  55 #include <sys/errno.h>
  56 #include <sys/open.h>
  57 #include <sys/cred.h>
  58 #include <sys/modctl.h>
  59 #include <sys/conf.h>
  60 #include <sys/devops.h>
  61 #include <sys/cmn_err.h>
  62 #include <sys/kmem.h>
  63 #include <sys/stat.h>
  64 #include <sys/mkdev.h>
  65 #include <sys/pci.h>
  66 #include <sys/scsi/scsi.h>
  67 #include <sys/ddi.h>
  68 #include <sys/sunddi.h>
  69 #include <sys/atomic.h>
  70 #include <sys/signal.h>
  71 #include <sys/byteorder.h>
  72 #include <sys/sdt.h>

  73 
  74 #include "mr_sas.h"
  75 
  76 /*
  77  * FMA header files
  78  */
  79 #include <sys/ddifm.h>
  80 #include <sys/fm/protocol.h>
  81 #include <sys/fm/util.h>
  82 #include <sys/fm/io/ddi.h>
  83 
  84 /* Macros to help Skinny and stock 2108/MFI live together. */
  85 #define WR_IB_PICK_QPORT(addr, instance) \
  86         if ((instance)->skinny) { \
  87                 WR_IB_LOW_QPORT((addr), (instance)); \
  88                 WR_IB_HIGH_QPORT(0, (instance)); \
  89         } else { \
  90                 WR_IB_QPORT((addr), (instance)); \
  91         }
  92 


7724         mrevt->event = event;
7725         mrevt->wwn = wwn;
7726 
7727         if ((ddi_taskq_dispatch(instance->taskq,
7728             (void (*)(void *))mrsas_issue_evt_taskq, mrevt, DDI_NOSLEEP)) !=
7729             DDI_SUCCESS) {
7730                 con_log(CL_ANN1, (CE_NOTE,
7731                     "mr_sas: Event task failed for t%dl%d event = %d",
7732                     tgt, lun, event));
7733                 kmem_free(mrevt, sizeof (struct mrsas_eventinfo));
7734                 return (DDI_FAILURE);
7735         }
7736         DTRACE_PROBE3(service_evt, int, tgt, int, lun, int, event);
7737         return (DDI_SUCCESS);
7738 }
7739 
7740 static void
7741 mrsas_issue_evt_taskq(struct mrsas_eventinfo *mrevt)
7742 {
7743         struct mrsas_instance *instance = mrevt->instance;
7744         dev_info_t *dip;
7745         int circ1 = 0;

7746 
7747         con_log(CL_ANN1, (CE_NOTE, "mrsas_issue_evt_taskq: called for"
7748             " tgt %d lun %d event %d",
7749             mrevt->tgt, mrevt->lun, mrevt->event));
7750 
7751         if (mrevt->tgt < MRDRV_MAX_LD && mrevt->lun == 0) {
7752                 mutex_enter(&instance->config_dev_mtx);
7753                 dip = instance->mr_ld_list[mrevt->tgt].dip;
7754                 mutex_exit(&instance->config_dev_mtx);
7755         } else {
7756                 mutex_enter(&instance->config_dev_mtx);
7757                 dip = instance->mr_tbolt_pd_list[mrevt->tgt].dip;
7758                 mutex_exit(&instance->config_dev_mtx);
7759         }
7760 
7761 
7762         ndi_devi_enter(instance->dip, &circ1);
7763         switch (mrevt->event) {
7764         case MRSAS_EVT_CONFIG_TGT:
7765                 if (dip == NULL) {

7766                         if (mrevt->lun == 0) {
7767                                 (void) mrsas_config_ld(instance, mrevt->tgt,
7768                                     0, NULL);
7769                         } else if (instance->tbolt || instance->skinny) {
7770                                 (void) mrsas_tbolt_config_pd(instance,
7771                                     mrevt->tgt,
7772                                     1, NULL);
7773                         }
7774                         con_log(CL_ANN1, (CE_NOTE,
7775                             "mr_sas: EVT_CONFIG_TGT called:"
7776                             " for tgt %d lun %d event %d",
7777                             mrevt->tgt, mrevt->lun, mrevt->event));

7778                 } else {
7779                         con_log(CL_ANN1, (CE_NOTE,
7780                             "mr_sas: EVT_CONFIG_TGT dip != NULL:"
7781                             " for tgt %d lun %d event %d",
7782                             mrevt->tgt, mrevt->lun, mrevt->event));
7783                 }
7784                 break;
7785         case MRSAS_EVT_UNCONFIG_TGT:
7786                 if (dip) {
7787                         (void) ndi_devi_offline(dip,
7788                             NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE);










7789                         con_log(CL_ANN1, (CE_NOTE,
7790                             "mr_sas: EVT_UNCONFIG_TGT called:"
7791                             " for tgt %d lun %d event %d",
7792                             mrevt->tgt, mrevt->lun, mrevt->event));
7793                 } else {
7794                         con_log(CL_ANN1, (CE_NOTE,
7795                             "mr_sas: EVT_UNCONFIG_TGT dip == NULL:"
7796                             " for tgt %d lun %d event %d",
7797                             mrevt->tgt, mrevt->lun, mrevt->event));
7798                 }
7799                 break;
7800         }
7801         kmem_free(mrevt, sizeof (struct mrsas_eventinfo));
7802         ndi_devi_exit(instance->dip, circ1);
7803 }
7804 
7805 
7806 int
7807 mrsas_mode_sense_build(struct scsi_pkt *pkt)
7808 {