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 {
|