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