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) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 /*
28 * Copyright (c) 2000 to 2010, LSI Corporation.
29 * All rights reserved.
30 *
31 * Redistribution and use in source and binary forms of all code within
32 * this file that is exclusively owned by LSI, with or without
33 * modification, is permitted provided that, in addition to the CDDL 1.0
34 * License requirements, the following conditions are met:
35 *
36 * Neither the name of the author nor the names of its contributors may be
37 * used to endorse or promote products derived from this software without
38 * specific prior written permission.
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
43 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
44 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
52 */
53
54 /*
55 * mptsas - This is a driver based on LSI Logic's MPT2.0 interface.
56 *
57 */
58
59 #if defined(lint) || defined(DEBUG)
60 #define MPTSAS_DEBUG
61 #endif
62
63 /*
64 * standard header files.
65 */
66 #include <sys/note.h>
67 #include <sys/scsi/scsi.h>
68 #include <sys/pci.h>
69 #include <sys/file.h>
70 #include <sys/cpuvar.h>
71 #include <sys/policy.h>
72 #include <sys/sysevent.h>
73 #include <sys/sysevent/eventdefs.h>
74 #include <sys/sysevent/dr.h>
75 #include <sys/sata/sata_defs.h>
76 #include <sys/scsi/generic/sas.h>
77 #include <sys/scsi/impl/scsi_sas.h>
78
79 #pragma pack(1)
80 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
81 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
82 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
83 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
84 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
85 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
86 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
87 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h>
88 #pragma pack()
89
90 /*
91 * private header files.
11934 case REG_MEM_WRITE:
11935 ddi_put32(mpt->m_datap,
11936 (uint32_t *)(void *)mpt->m_reg +
11937 driverdata.RegOffset,
11938 driverdata.RegData);
11939 break;
11940
11941 default:
11942 status = EINVAL;
11943 break;
11944 }
11945 } else {
11946 status = EFAULT;
11947 }
11948
11949 mutex_exit(&mpt->m_mutex);
11950 return (status);
11951 }
11952
11953 static int
11954 mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp,
11955 int *rval)
11956 {
11957 int status = 0;
11958 mptsas_t *mpt;
11959 mptsas_update_flash_t flashdata;
11960 mptsas_pass_thru_t passthru_data;
11961 mptsas_adapter_data_t adapter_data;
11962 mptsas_pci_info_t pci_info;
11963 int copylen;
11964
11965 int iport_flag = 0;
11966 dev_info_t *dip = NULL;
11967 mptsas_phymask_t phymask = 0;
11968 struct devctl_iocdata *dcp = NULL;
11969 uint32_t slotstatus = 0;
11970 char *addr = NULL;
11971 mptsas_target_t *ptgt = NULL;
11972
11973 *rval = MPTIOCTL_STATUS_GOOD;
12054 slotstatus, addr));
12055 #endif
12056 if (cmd == DEVCTL_DEVICE_OFFLINE) {
12057 slotstatus |=
12058 MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
12059 } else {
12060 slotstatus &=
12061 ~MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
12062 }
12063 if (mptsas_set_led_status(mpt, ptgt, slotstatus) !=
12064 DDI_SUCCESS) {
12065 NDBG14(("mptsas_ioctl: set LED for tgt %s "
12066 "failed %x", addr, slotstatus));
12067 }
12068 mutex_exit(&mpt->m_mutex);
12069 ndi_dc_freehdl(dcp);
12070 }
12071 goto out;
12072 }
12073 switch (cmd) {
12074 case MPTIOCTL_UPDATE_FLASH:
12075 if (ddi_copyin((void *)data, &flashdata,
12076 sizeof (struct mptsas_update_flash), mode)) {
12077 status = EFAULT;
12078 break;
12079 }
12080
12081 mutex_enter(&mpt->m_mutex);
12082 if (mptsas_update_flash(mpt,
12083 (caddr_t)(long)flashdata.PtrBuffer,
12084 flashdata.ImageSize, flashdata.ImageType, mode)) {
12085 status = EFAULT;
12086 }
12087
12088 /*
12089 * Reset the chip to start using the new
12090 * firmware. Reset if failed also.
12091 */
12092 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
12093 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
|
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) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
26 */
27
28 /*
29 * Copyright (c) 2000 to 2010, LSI Corporation.
30 * All rights reserved.
31 *
32 * Redistribution and use in source and binary forms of all code within
33 * this file that is exclusively owned by LSI, with or without
34 * modification, is permitted provided that, in addition to the CDDL 1.0
35 * License requirements, the following conditions are met:
36 *
37 * Neither the name of the author nor the names of its contributors may be
38 * used to endorse or promote products derived from this software without
39 * specific prior written permission.
40 *
41 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
42 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
43 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
44 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
45 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
53 */
54
55 /*
56 * mptsas - This is a driver based on LSI Logic's MPT2.0 interface.
57 *
58 */
59
60 #if defined(lint) || defined(DEBUG)
61 #define MPTSAS_DEBUG
62 #endif
63
64 /*
65 * standard header files.
66 */
67 #include <sys/note.h>
68 #include <sys/scsi/scsi.h>
69 #include <sys/pci.h>
70 #include <sys/file.h>
71 #include <sys/cpuvar.h>
72 #include <sys/policy.h>
73 #include <sys/model.h>
74 #include <sys/sysevent.h>
75 #include <sys/sysevent/eventdefs.h>
76 #include <sys/sysevent/dr.h>
77 #include <sys/sata/sata_defs.h>
78 #include <sys/scsi/generic/sas.h>
79 #include <sys/scsi/impl/scsi_sas.h>
80
81 #pragma pack(1)
82 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
83 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
84 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
85 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
86 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
87 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
88 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
89 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h>
90 #pragma pack()
91
92 /*
93 * private header files.
11936 case REG_MEM_WRITE:
11937 ddi_put32(mpt->m_datap,
11938 (uint32_t *)(void *)mpt->m_reg +
11939 driverdata.RegOffset,
11940 driverdata.RegData);
11941 break;
11942
11943 default:
11944 status = EINVAL;
11945 break;
11946 }
11947 } else {
11948 status = EFAULT;
11949 }
11950
11951 mutex_exit(&mpt->m_mutex);
11952 return (status);
11953 }
11954
11955 static int
11956 get_disk_info(mptsas_t *mpt, intptr_t data, int mode)
11957 {
11958 int i = 0;
11959 int count = 0;
11960 int ret = 0;
11961 mptsas_target_t *ptgt;
11962 mptsas_disk_info_t *di;
11963 STRUCT_DECL(mptsas_get_disk_info, gdi);
11964
11965 STRUCT_INIT(gdi, get_udatamodel());
11966
11967 if (ddi_copyin((void *)data, STRUCT_BUF(gdi), STRUCT_SIZE(gdi),
11968 mode) != 0) {
11969 return (EFAULT);
11970 }
11971
11972 /* Find out how many targets there are. */
11973 mutex_enter(&mpt->m_mutex);
11974 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11975 MPTSAS_HASH_FIRST);
11976 while (ptgt != NULL) {
11977 count++;
11978 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11979 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11980 }
11981 mutex_exit(&mpt->m_mutex);
11982
11983 /*
11984 * If we haven't been asked to copy out information on each target,
11985 * then just return the count.
11986 */
11987 STRUCT_FSET(gdi, DiskCount, count);
11988 if (STRUCT_FGETP(gdi, PtrDiskInfoArray) == NULL)
11989 goto copy_out;
11990
11991 /*
11992 * If we haven't been given a large enough buffer to copy out into,
11993 * let the caller know.
11994 */
11995 if (STRUCT_FGET(gdi, DiskInfoArraySize) <
11996 count * sizeof (mptsas_disk_info_t)) {
11997 ret = ENOSPC;
11998 goto copy_out;
11999 }
12000
12001 di = kmem_zalloc(count * sizeof (mptsas_disk_info_t), KM_SLEEP);
12002
12003 mutex_enter(&mpt->m_mutex);
12004 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
12005 MPTSAS_HASH_FIRST);
12006 while (ptgt != NULL) {
12007 if (i >= count) {
12008 /*
12009 * The number of targets changed while we weren't
12010 * looking, so give up.
12011 */
12012 mutex_exit(&mpt->m_mutex);
12013 kmem_free(di, count * sizeof (mptsas_disk_info_t));
12014 return (EAGAIN);
12015 }
12016 di[i].Instance = mpt->m_instance;
12017 di[i].Enclosure = ptgt->m_enclosure;
12018 di[i].Slot = ptgt->m_slot_num;
12019 di[i].SasAddress = ptgt->m_sas_wwn;
12020
12021 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
12022 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
12023 i++;
12024 }
12025 mutex_exit(&mpt->m_mutex);
12026 STRUCT_FSET(gdi, DiskCount, i);
12027
12028 /* Copy out the disk information to the caller. */
12029 if (ddi_copyout((void *)di, STRUCT_FGETP(gdi, PtrDiskInfoArray),
12030 i * sizeof (mptsas_disk_info_t), mode) != 0) {
12031 ret = EFAULT;
12032 }
12033
12034 kmem_free(di, count * sizeof (mptsas_disk_info_t));
12035
12036 copy_out:
12037 if (ddi_copyout(STRUCT_BUF(gdi), (void *)data, STRUCT_SIZE(gdi),
12038 mode) != 0) {
12039 ret = EFAULT;
12040 }
12041
12042 return (ret);
12043 }
12044
12045 static int
12046 mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp,
12047 int *rval)
12048 {
12049 int status = 0;
12050 mptsas_t *mpt;
12051 mptsas_update_flash_t flashdata;
12052 mptsas_pass_thru_t passthru_data;
12053 mptsas_adapter_data_t adapter_data;
12054 mptsas_pci_info_t pci_info;
12055 int copylen;
12056
12057 int iport_flag = 0;
12058 dev_info_t *dip = NULL;
12059 mptsas_phymask_t phymask = 0;
12060 struct devctl_iocdata *dcp = NULL;
12061 uint32_t slotstatus = 0;
12062 char *addr = NULL;
12063 mptsas_target_t *ptgt = NULL;
12064
12065 *rval = MPTIOCTL_STATUS_GOOD;
12146 slotstatus, addr));
12147 #endif
12148 if (cmd == DEVCTL_DEVICE_OFFLINE) {
12149 slotstatus |=
12150 MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
12151 } else {
12152 slotstatus &=
12153 ~MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
12154 }
12155 if (mptsas_set_led_status(mpt, ptgt, slotstatus) !=
12156 DDI_SUCCESS) {
12157 NDBG14(("mptsas_ioctl: set LED for tgt %s "
12158 "failed %x", addr, slotstatus));
12159 }
12160 mutex_exit(&mpt->m_mutex);
12161 ndi_dc_freehdl(dcp);
12162 }
12163 goto out;
12164 }
12165 switch (cmd) {
12166 case MPTIOCTL_GET_DISK_INFO:
12167 status = get_disk_info(mpt, data, mode);
12168 break;
12169 case MPTIOCTL_UPDATE_FLASH:
12170 if (ddi_copyin((void *)data, &flashdata,
12171 sizeof (struct mptsas_update_flash), mode)) {
12172 status = EFAULT;
12173 break;
12174 }
12175
12176 mutex_enter(&mpt->m_mutex);
12177 if (mptsas_update_flash(mpt,
12178 (caddr_t)(long)flashdata.PtrBuffer,
12179 flashdata.ImageSize, flashdata.ImageType, mode)) {
12180 status = EFAULT;
12181 }
12182
12183 /*
12184 * Reset the chip to start using the new
12185 * firmware. Reset if failed also.
12186 */
12187 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
12188 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
|