├── recipes-support └── lsiutil │ ├── files │ └── lsiutil-1.72.tar.gz │ └── lsiutil_1.72.bb ├── recipes-protocols └── scst │ ├── files │ ├── scst.conf │ └── 0001-add-mpt3.patch │ └── scst_svn.bb ├── recipes-kernel └── linux │ └── linux-stable.bbappend ├── recipes-core └── packagegroups │ └── packagegroup-stm-core.bb ├── README.md └── LICENSE /recipes-support/lsiutil/files/lsiutil-1.72.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exactassembly/meta-xa-stm/HEAD/recipes-support/lsiutil/files/lsiutil-1.72.tar.gz -------------------------------------------------------------------------------- /recipes-protocols/scst/files/scst.conf: -------------------------------------------------------------------------------- 1 | # Automatically generated by SCST Configurator v3.1.0-pre1. 2 | 3 | 4 | HANDLER vdisk_fileio { 5 | DEVICE DISK01 { 6 | filename /dev/md127 7 | read_only 0 8 | removeable 0 9 | rotational 0 10 | } 11 | } 12 | 13 | TARGET_DRIVER mpt3_scst { 14 | TARGET mpt3sas_0 { 15 | enabled 1 16 | 17 | LUN 0 DISK01 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /recipes-kernel/linux/linux-stable.bbappend: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Exact Assembly, LLC 3 | # Author: Ted Vaida 4 | # 5 | # This program is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU General Public License 7 | # as published by the Free Software Foundation; either version 2 8 | # of the License, or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | # 19 | # 20 | FILESEXTRAPATHS_prepend := "${THISDIR}/linux-stable:" 21 | 22 | SRC_URI_append = " \ 23 | file://linux-stable-4.1-mpt3sas_stm.patch \ 24 | " -------------------------------------------------------------------------------- /recipes-core/packagegroups/packagegroup-stm-core.bb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Exact Assembly, LLC 3 | # Author: Ted Vaida 4 | # 5 | # This program is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU General Public License 7 | # as published by the Free Software Foundation; either version 2 8 | # of the License, or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | # 19 | # 20 | SUMMARY = "Core packages required for SCSI Target Mode (SAS Target)" 21 | LICENSE = "GPLv2" 22 | 23 | PACKAGE_ARCH = "${MACHINE_ARCH}" 24 | 25 | PR = "r0" 26 | 27 | inherit packagegroup 28 | 29 | RDEPENDS_${PN} = "\ 30 | lsiutil \ 31 | scst \ 32 | kernel-module-mpt3sas \ 33 | kernel-module-mpt3sas-stm \ 34 | " 35 | -------------------------------------------------------------------------------- /recipes-support/lsiutil/lsiutil_1.72.bb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Exact Assembly, LLC 3 | # Author: Ted Vaida 4 | # 5 | # This program is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU General Public License 7 | # as published by the Free Software Foundation; either version 2 8 | # of the License, or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | # 19 | # 20 | SUMMARY="LSISAS device configuration utility" 21 | LICENSE="LSI Proprietary" 22 | LIC_FILES_CHKSUM = "file://lsiutil.c;md5=4222fde02c05461ed9e0edc5ca10c066" 23 | 24 | FILESEXTRAPATHS_prepend := "${THISDIR}/files:" 25 | 26 | SRC_URI = "file://lsiutil-${PV}.tar.gz" 27 | 28 | PR="1" 29 | 30 | S="${WORKDIR}/lsiutil" 31 | 32 | do_compile() { 33 | oe_runmake lsiutil 34 | } 35 | 36 | do_install() { 37 | install -d ${D}${sbindir} 38 | install ${S}/lsiutil ${D}${sbindir} 39 | } 40 | 41 | FILES_${PN} = " ${sbindir}/lsiutil " 42 | -------------------------------------------------------------------------------- /recipes-protocols/scst/scst_svn.bb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2015 Exact Assembly, LLC 3 | # Author: Ted Vaida 4 | # 5 | # This program is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU General Public License 7 | # as published by the Free Software Foundation; either version 2 8 | # of the License, or (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | # 19 | # 20 | SUMMARY="Linux SCSI Target Mode drivers and tools" 21 | LICENSE="GPLv2" 22 | LIC_FILES_CHKSUM = "file://scst/COPYING;md5=54facb70adf7e4bb1895398fd8759dd7" 23 | 24 | FILESEXTRAPATHS_prepend := "${THISDIR}/files:" 25 | 26 | RDEPENDS_${PN} = " \ 27 | perl \ 28 | perl-module-fcntl \ 29 | perl-module-io-dir \ 30 | perl-module-io-file \ 31 | perl-module-getopt-long \ 32 | perl-module-posix \ 33 | perl-module-overloading \ 34 | " 35 | 36 | DEPENDS=" \ 37 | virtual/kernel \ 38 | perl \ 39 | " 40 | 41 | do_configure[depends] += "virtual/kernel:do_shared_workdir" 42 | 43 | SRC_URI="svn://svn.code.sf.net/p/scst/svn;module=trunk" 44 | SRCREV="${AUTOREV}" 45 | 46 | SRC_URI_append = " \ 47 | file://0001-add-mpt3.patch;striplevel=0 \ 48 | file://scst.conf \ 49 | " 50 | 51 | PR="2" 52 | 53 | S="${WORKDIR}/trunk" 54 | 55 | inherit module-base kernel-module-split 56 | 57 | INSANE_SKIP_${PN} = "installed-vs-shipped" 58 | 59 | export STAGING_KERNEL_DIR 60 | 61 | FILES_${PN}-dev += " \ 62 | /include/scst/* \ 63 | " 64 | 65 | FILES_${PN} += " \ 66 | /lib/modules/* \ 67 | /man/* \ 68 | /usr/lib/perl5/* \ 69 | " 70 | 71 | do_unpack_mpt3() { 72 | rm -f ${S}/mpt3/mpi 73 | rm -f ${S}/mpt3/mpt3sas_stm.h 74 | ln -s ${STAGING_KERNEL_DIR}/drivers/scsi/mpt3sas/mpi ${S}/mpt3/mpi 75 | ln -s ${STAGING_KERNEL_DIR}/drivers/scsi/mpt3sas/mpt3sas_stm.h ${S}/mpt3/mpt3sas_stm.h 76 | } 77 | addtask unpack_mpt3 after do_unpack before do_configure 78 | 79 | addtask make_scripts after do_configure before do_compile 80 | 81 | EXTRA_OEMAKE = " \ 82 | 'EXTRA_CFLAGS=-I${S}/scst/include -DCONFIG_SCST_DEBUG -DCONFIG_SCST_TRACING' \ 83 | " 84 | 85 | do_configure() { 86 | } 87 | 88 | do_compile() { 89 | unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS 90 | oe_runmake KERNEL_PATH=${STAGING_KERNEL_DIR} \ 91 | KERNEL_SRC=${STAGING_KERNEL_DIR} \ 92 | KDIR=${STAGING_KERNEL_DIR} \ 93 | INSTALL_MOD_PATH=${D} \ 94 | DESTDIR=${D} \ 95 | PREFIX=/usr \ 96 | CC="${KERNEL_CC}" LD="${KERNEL_LD}" \ 97 | AR="${KERNEL_AR}" scst scstadm mpt3 98 | } 99 | 100 | do_install() { 101 | unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS 102 | oe_runmake INSTALL_MOD_PATH=${D} \ 103 | KERNEL_PATH=${STAGING_KERNEL_DIR} \ 104 | KERNEL_SRC=${STAGING_KERNEL_DIR} \ 105 | KDIR=${STAGING_KERNEL_DIR} \ 106 | DESTDIR=${D} \ 107 | PREFIX=/usr \ 108 | CC="${KERNEL_CC}" LD="${KERNEL_LD}" \ 109 | AR="${KERNEL_AR}" \ 110 | scst_install scstadm_install mpt3_install 111 | 112 | install -d ${D}/etc 113 | install -m 0644 ${WORKDIR}/scst.conf ${D}/etc 114 | install -d ${D}/usr/lib/perl5/5.22.0/SCST 115 | install -m 0644 ${S}/scstadmin/scstadmin.sysfs/scst-0.9.10/lib/SCST/SCST.pm ${D}/usr/lib/perl5/5.22.0/SCST/SCST.pm 116 | 117 | install -d ${D}${sysconfdir}/rc5.d 118 | ln -s ../init.d/scst ${D}${sysconfdir}/rc5.d/S99scst 119 | 120 | } 121 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SCSI Target Mode for LSISAS2 and LSISAS3 Host Bus Adapters 2 | ========================================================== 3 | 4 | This set of files provides support for adding SCSI Target Mode (STM) support to 5 | Yocto (https://www.yoctoproject.org/) based targets using the SCST 6 | (http://scst.sourceforge.net/) framework. 7 | 8 | If you want to use the SCST and Linux kernel patches outside of Yocto, look at 9 | the following two patch files: 10 | 11 | recipes-kernel/linux/linux-stable/linux-stable-4.1-mpt3sas_stm.patch 12 | 13 | recipes-protocols/scst/files/0001-add-mpt3.patch 14 | 15 | Requirements 16 | ------------ 17 | 18 | ### Supported HBAs 19 | SAS2.x (6Gbps) 20 | * 9200-8e 21 | * 9200-4i4e 22 | * Any device based on the LSISAS2008 chipset with LSI IT firmware 23 | 24 | SAS3.x (12Gbps) 25 | * 9300-8e 26 | * 9300-4i4e 27 | * Any device based on the LSISAS3008 chipset with LSI IT firmware 28 | 29 | ### Supported versions of Yocto 30 | This layer is known to work with Yocto version 1.7 and 1.8, and is maintained 31 | against the poky 'master' branch. 32 | 33 | ### Supported Linux kernels 34 | This layer is known to work with linux-stable 4.1.3, and may work with any 35 | relatively recent Linux branch depending on the status of the LSI mpt3sas 36 | driver code. 37 | 38 | ### Supported version of SCST 39 | This layer patch is known to work against SCST 3.0 40 | 41 | Configuration 42 | ------------- 43 | 44 | ### HBA Configuration 45 | In addition to having a compatible HBA, you must configure the HBA to enable 46 | Target SCSI operations. To do this, you must use the 'lsiutil' command line 47 | tool which is included with the packagegroup-stm-core package defined in this 48 | layer. See Appendix 1 below for specifics on using the lsiutil command. 49 | 50 | ### Yocto Configuration 51 | In order for Yocto to use this layer, you must add it to your layers.conf 52 | file. 53 | 54 | 55 | 56 | Appendix 1: Configuring HBAs with lsituil 57 | ========================================= 58 | The lsiutil utility allows you to edit NVDATA paramaters on the HBA to 59 | activate hardware and firmware Target I/O capabilities. In order to operate 60 | correctly, each PHY to be connected to a remote host must be part of a distinct 61 | port, and only a single port is supported in the current patch set. 62 | 63 | ### Example 64 | Here is an example of how one HBA has been configured with a single x4 port for 65 | normal Initator traffic, and a second x4 port for Target traffic: 66 | 67 | root@demox86-64:~# lsiutil 68 | 69 | LSI Logic MPT Configuration Utility, Version 1.72, Sep 09, 2014 70 | modprobe: module mptctl not found in modules.dep 71 | 72 | 1 MPT Port found 73 | 74 | Port Name Chip Vendor/Type/Rev MPT Rev Firmware Rev IOC 75 | 1. ioc0 LSI Logic SAS3008 C0 205 01000200 0 76 | 77 | Select a device: [1-1 or 0 to quit] 1 78 | 79 | 1. Identify firmware, BIOS, and/or FCode 80 | 2. Download firmware (update the FLASH) 81 | 4. Download/erase BIOS and/or FCode (update the FLASH) 82 | 8. Scan for devices 83 | 801. Scan for 1 LUN 84 | 810. Scan for 10 LUN's 85 | 10. Change IOC settings (interrupt coalescing) 86 | 13. Change SAS IO Unit settings 87 | 16. Display attached devices 88 | 20. Diagnostics 89 | 21. RAID actions 90 | 23. Reset target 91 | 42. Display operating system names for devices 92 | 43. Diagnostic Buffer actions 93 | 45. Concatenate SAS firmware and NVDATA files 94 | 59. Dump PCI config space 95 | 60. Show non-default settings 96 | 61. Restore default settings 97 | 66. Show SAS discovery errors 98 | 69. Show board manufacturing information 99 | 97. Reset SAS link, HARD RESET 100 | 98. Reset SAS link 101 | 99. Reset port 102 | e Enable expert mode in menus 103 | p Enable paged mode 104 | w Enable logging 105 | 106 | Main menu, select an option: [1-99 or e/p/w or 0 to quit] 13 107 | 108 | SATA Maximum Queue Depth: [0 to 255, default is 128] 109 | SAS Max Queue Depth, Narrow: [0 to 65535, default is 256] 110 | SAS Max Queue Depth, Wide: [0 to 65535, default is 256] 111 | Device Missing Report Delay: [0 to 2047, default is 0] 112 | Device Missing I/O Delay: [0 to 255, default is 0] 113 | 114 | PhyNum Link MinRate MaxRate Initiator Target Port 115 | 0 Enabled 3.0 12.0 Disabled Enabled 1 116 | 1 Enabled 3.0 12.0 Disabled Enabled 1 117 | 2 Enabled 3.0 12.0 Disabled Enabled 1 118 | 3 Enabled 3.0 12.0 Disabled Enabled 1 119 | 4 Enabled 3.0 12.0 Enabled Disabled Auto 120 | 5 Enabled 3.0 12.0 Enabled Disabled Auto 121 | 6 Enabled 3.0 12.0 Enabled Disabled Auto 122 | 7 Enabled 3.0 12.0 Enabled Disabled Auto 123 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. -------------------------------------------------------------------------------- /recipes-protocols/scst/files/0001-add-mpt3.patch: -------------------------------------------------------------------------------- 1 | Index: Makefile 2 | =================================================================== 3 | --- Makefile (revision 6459) 4 | +++ Makefile (working copy) 5 | @@ -45,6 +45,7 @@ 6 | QLA_OLD_INI_DIR=qla2x00t 7 | QLA_OLD_DIR=qla2x00t/qla2x00-target 8 | LSI_DIR=mpt 9 | +MPT3_DIR=mpt3 10 | USR_DIR=usr/fileio 11 | SRP_DIR=srpt 12 | SCST_LOCAL_DIR=scst_local 13 | @@ -107,6 +108,12 @@ 14 | @echo " lsi_install : lsi target: install" 15 | @echo " lsi_uninstall : lsi target: uninstall" 16 | @echo "" 17 | + @echo " mpt3 : make LSI MPT3 target" 18 | + @echo " mpt3_clean : mpt3 target: clean " 19 | + @echo " mpt3_extraclean : mpt3 target: clean + clean dependencies" 20 | + @echo " mpt3_install : mpt3 target: install" 21 | + @echo " mpt3_uninstall : mpt3 target: uninstall" 22 | + @echo "" 23 | @echo " srpt : make SRP target" 24 | @echo " srpt_clean : srp target: clean " 25 | @echo " srpt_extraclean : srp target: clean + clean dependencies" 26 | @@ -151,6 +158,7 @@ 27 | @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; else if [ -d $(QLA_OLD_DIR) ]; then cd $(QLA_OLD_DIR) && $(MAKE) $@; fi fi 28 | # @if [ -d $(QLA_OLD_DIR) ]; then cd $(QLA_OLD_DIR) && $(MAKE) $@; fi 29 | # @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi 30 | + @if [ -d $(MPT3_DIR) ]; then cd $(MPT3_DIR) && $(MAKE) $@; fi 31 | # @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi 32 | @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi 33 | @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi 34 | @@ -163,6 +171,7 @@ 35 | @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; else if [ -d $(QLA_OLD_DIR) ]; then cd $(QLA_OLD_DIR) && $(MAKE) $@; fi fi 36 | # @if [ -d $(QLA_OLD_DIR) ]; then cd $(QLA_OLD_DIR) && $(MAKE) $@; fi 37 | # @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi 38 | + @if [ -d $(MPT3_DIR) ]; then cd $(MPT3_DIR) && $(MAKE) $@; fi 39 | # @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi 40 | @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi 41 | @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi 42 | @@ -175,6 +184,7 @@ 43 | @if [ -d $(QLA_DIR) ]; then cd $(QLA_DIR) && $(MAKE) $@; else if [ -d $(QLA_OLD_DIR) ]; then cd $(QLA_OLD_DIR) && $(MAKE) $@; fi fi 44 | # @if [ -d $(QLA_OLD_DIR) ]; then cd $(QLA_OLD_DIR) && $(MAKE) $@; fi 45 | # @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi 46 | + @if [ -d $(MPT3_DIR) ]; then cd $(MPT3_DIR) && $(MAKE) $@; fi 47 | @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi 48 | @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi 49 | @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi 50 | @@ -189,6 +199,7 @@ 51 | @if [ -d $(QLA_OLD_INI_DIR) ]; then cd $(QLA_OLD_INI_DIR) && $(MAKE) $@; fi 52 | @if [ -d $(QLA_OLD_DIR) ]; then cd $(QLA_OLD_DIR) && $(MAKE) $@; fi 53 | # @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi 54 | + @if [ -d $(MPT3_DIR) ]; then cd $(MPT3_DIR) && $(MAKE) $@; fi 55 | @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi 56 | @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi 57 | @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi 58 | @@ -204,6 +215,7 @@ 59 | @if [ -d $(QLA_OLD_INI_DIR) ]; then cd $(QLA_OLD_INI_DIR) && $(MAKE) $@; fi 60 | @if [ -d $(QLA_OLD_DIR) ]; then cd $(QLA_OLD_DIR) && $(MAKE) $@; fi 61 | # @if [ -d $(LSI_DIR) ]; then cd $(LSI_DIR) && $(MAKE) $@; fi 62 | + @if [ -d $(MPT3_DIR) ]; then cd $(MPT3_DIR) && $(MAKE) $@; fi 63 | @if [ -d $(SRP_DIR) ]; then cd $(SRP_DIR) && $(MAKE) $@; fi 64 | @if [ -d $(ISCSI_DIR) ]; then cd $(ISCSI_DIR) && $(MAKE) $@; fi 65 | @if [ -d $(USR_DIR) ]; then cd $(USR_DIR) && $(MAKE) $@; fi 66 | @@ -332,6 +344,21 @@ 67 | lsi_extraclean: 68 | cd $(LSI_DIR) && $(MAKE) extraclean 69 | 70 | +mpt3: 71 | + cd $(MPT3_DIR) && $(MAKE) all 72 | + 73 | +mpt3_install: 74 | + cd $(MPT3_DIR) && $(MAKE) install 75 | + 76 | +mpt3_uninstall: 77 | + cd $(MPT3_DIR) && $(MAKE) uninstall 78 | + 79 | +mpt3_clean: 80 | + cd $(MPT3_DIR) && $(MAKE) clean 81 | + 82 | +mpt3_extraclean: 83 | + cd $(MPT3_DIR) && $(MAKE) extraclean 84 | + 85 | srpt: 86 | cd $(SRP_DIR) && $(MAKE) all 87 | 88 | @@ -532,6 +559,7 @@ 89 | qla qla_install qla_uninstall qla_clean qla_extraclean \ 90 | qla_old qla_old_install qla_old_uninstall qla_old_clean qla_old_extraclean \ 91 | lsi lsi_install lsi_uninstall lsi_clean lsi_extraclean \ 92 | + mpt3 mpt3_install mpt3_uninstall mpt3_clean mpt3_extraclean \ 93 | iscsi iscsi_install iscsi_uninstall iscsi_clean iscsi_extraclean \ 94 | emulex emulex_install emulex_uninstall emulex_clean emulex_extraclean \ 95 | scst scst_install scst_uninstall scst_clean scst_extraclean \ 96 | Index: mpt/Makefile 97 | =================================================================== 98 | --- mpt/Makefile (revision 6459) 99 | +++ mpt/Makefile (working copy) 100 | @@ -43,8 +43,8 @@ 101 | else 102 | ifeq ($(KERNELRELEASE),) 103 | KVER := $(strip $(shell \ 104 | - cat $(KDIR)/include/config/kernel.release 2>/dev/null || \ 105 | - make -s -C $(KDIR) kernelversion)) 106 | + cat $(KDIR)/include/config/kernel.release 2>/dev/null || \ 107 | + make -s -C $(KDIR) kernelversion)) 108 | else 109 | KVER := $(KERNELRELEASE) 110 | endif 111 | Index: mpt3/Makefile 112 | =================================================================== 113 | --- mpt3/Makefile (revision 0) 114 | +++ mpt3/Makefile (working copy) 115 | @@ -0,0 +1,120 @@ 116 | +# This program is free software; you can redistribute it and/or 117 | +# modify it under the terms of the GNU General Public License 118 | +# as published by the Free Software Foundation, version 2 119 | +# of the License. 120 | +# 121 | +# This program is distributed in the hope that it will be useful, 122 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of 123 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 124 | +# GNU General Public License for more details. 125 | +# 126 | +# 127 | +# Main targets: 128 | +# all (the default) : make all 129 | +# clean : clean files 130 | +# extraclean : clean + clean dependencies 131 | +# install : install 132 | +# uninstall : uninstall 133 | +# 134 | +# Notes : 135 | +# - install and uninstall must be made as root 136 | +# 137 | + 138 | +ifndef PREFIX 139 | + PREFIX=/usr/local 140 | +endif 141 | + 142 | + 143 | + 144 | +SCST_INC_DIR := $(SUBDIRS)/../scst/include 145 | +SCST_DIR := $(shell pwd)/../scst/src 146 | + 147 | +EXTRA_CFLAGS += -I$(SCST_INC_DIR) 148 | + 149 | +EXTRA_CFLAGS += -DCONFIG_SCST_EXTRACHECKS 150 | +#EXTRA_CFLAGS += -DCONFIG_SCST_TRACING 151 | +EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG 152 | +#EXTRA_CFLAGS += -DDEBUG_WORK_IN_THREAD 153 | + 154 | +ifeq ($(KVER),) 155 | + $(warning mpt3_scst KVER empty) 156 | + ifeq ($(KDIR),) 157 | + KVER := $(shell uname -r) 158 | + KDIR := /lib/modules/$(KVER)/build 159 | + else 160 | + ifeq ($(KERNELRELEASE),) 161 | + KVER := $(strip $(shell \ 162 | + cat $(KDIR)/include/config/kernel.release 2>/dev/null || \ 163 | + make -s -C $(KDIR) kernelversion)) 164 | + else 165 | + KVER := $(KERNELRELEASE) 166 | + endif 167 | + endif 168 | +else 169 | + $(warning mpt3_scst KVER is $(KVER)) 170 | + ifeq ($(KDIR),) 171 | + KDIR := /lib/modules/$(KVER)/build 172 | + $(warning mpt3_scst KDIR is now $(KDIR)) 173 | + endif 174 | +endif 175 | + 176 | +ifeq ($(INSTALL_MOD_PATH),) 177 | + $(warning mpt3_scst setting INSTALL_MOD_PATH to $(DESTDIR)) 178 | + export INSTALL_MOD_PATH := $(DESTDIR) 179 | +else 180 | + $(warning mpt3_scst INSTALL_MOD_PATH is $(DESTDIR)) 181 | +endif 182 | + 183 | +INSTALL_DIR := $(INSTALL_MOD_PATH)/lib/modules/$(KVER)/extra 184 | +LSI_INC_DIR := $(KDIR)/drivers/scsi/mpt3sas 185 | +EXTRA_CFLAGS += -I$(LSI_INC_DIR) 186 | + 187 | +ifneq ($(PATCHLEVEL),) 188 | +obj-m += mpt3_scst.o 189 | +else 190 | +######### BEGIN OUT-OF-TREE RULES ######### 191 | + 192 | +all: Modules.symvers Module.symvers 193 | + $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd) BUILD_INI=m 194 | + 195 | +tgt: Modules.symvers Module.symvers 196 | + $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd) BUILD_INI=n 197 | + 198 | +install: all 199 | + $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd) BUILD_INI=m \ 200 | + $$([ -n "$(DESTDIR)$(INSTALL_MOD_PATH)" ] && echo DEPMOD=true) \ 201 | + modules_install 202 | + 203 | +SCST_MOD_VERS := $(shell ls $(SCST_DIR)/Modules.symvers 2>/dev/null) 204 | +ifneq ($(SCST_MOD_VERS),) 205 | +Modules.symvers: $(SCST_DIR)/Modules.symvers 206 | + cp $(SCST_DIR)/Modules.symvers . 207 | +else 208 | +.PHONY: Modules.symvers 209 | +endif 210 | + 211 | +# It's renamed in 2.6.18 212 | +SCST_MOD_VERS := $(shell ls $(SCST_DIR)/Module.symvers 2>/dev/null) 213 | +ifneq ($(SCST_MOD_VERS),) 214 | +Module.symvers: $(SCST_DIR)/Module.symvers 215 | + cp $(SCST_DIR)/Module.symvers . 216 | +else 217 | +.PHONY: Module.symvers 218 | +endif 219 | + 220 | +uninstall: 221 | + rm -f $(INSTALL_DIR)/mpt3_scst.ko 222 | + -/sbin/depmod -b $(INSTALL_MOD_PATH)/ -a $(KVER) 223 | + 224 | +########## END OUT-OF-TREE RULES ########## 225 | +endif 226 | + 227 | +clean: 228 | + rm -f *.o *.ko .*.cmd *.mod.c .*.d .depend *~ Modules.symvers \ 229 | + Module.symvers Module.markers modules.order 230 | + rm -rf .tmp_versions 231 | + 232 | +extraclean: clean 233 | + rm -f *.orig *.rej 234 | + 235 | +.PHONY: all tgt install uninstall clean extraclean 236 | Index: mpt3/mpt3_scst.c 237 | =================================================================== 238 | --- mpt3/mpt3_scst.c (revision 0) 239 | +++ mpt3/mpt3_scst.c (working copy) 240 | @@ -0,0 +1,1318 @@ 241 | +/** 242 | + * 243 | + * @file mpt3scst_base.c 244 | + * @brief SCST driver for LSI FusionMPT2.5 (SAS 3.0) controllers 245 | + * @author Theodore Vaida 246 | + * 247 | + * @Copyright � 2015 Exact Assembly, LLC. All Rights Reserved. 248 | + * 249 | + * Redistribution and use in source and binary forms, with or without modification, 250 | + * are permitted provided that the following conditions are met: 251 | + * 252 | + * 1. Redistributions of source code must retain the above copyright notice, 253 | + * this list of conditions and the following disclaimer. 254 | + * 255 | + * 2. Redistributions in binary form must reproduce the above copyright notice, 256 | + * this list of conditions and the following disclaimer in the documentation and/or 257 | + * other materials provided with the distribution. 258 | + * 259 | + * 3. The name of the author may not be used to endorse or promote products derived from this 260 | + * software without specific prior written permission. 261 | + * 262 | + * THIS SOFTWARE IS PROVIDED BY [LICENSOR] "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 263 | + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 264 | + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 265 | + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 266 | + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 267 | + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 268 | + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 269 | + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 270 | + * 271 | + * 272 | + * @details This module deals with the mpt3sas specifics of SCSI Target mode 273 | + * 274 | + */ 275 | + 276 | +#include 277 | +#include 278 | +#include 279 | +#include 280 | +#include 281 | +#include 282 | + 283 | +#include "mpt3_scst.h" 284 | + 285 | + 286 | +#define MPT3SCST_DRIVER_AUTHOR "Exact Assembly, LLC " 287 | +#define MPT3SCST_DESCRIPTION "LSI MPT2.5/SAS3.0 SCSI Target Mode SCST driver" 288 | +#define MPT3SCST_MAJOR_VERSION 01 289 | +#define MPT3SCST_MINOR_VERSION 100 290 | +#define MPT3SCST_BUILD_VERSION 00 291 | +#define MPT3SCST_RELEASE_VERSION 00 292 | +#define MPT3SCST_DRIVER_VERSION "01.100.00.00" 293 | + 294 | +MODULE_AUTHOR(MPT3SCST_DRIVER_AUTHOR); 295 | +MODULE_DESCRIPTION(MPT3SCST_DESCRIPTION); 296 | +MODULE_LICENSE("GPL"); 297 | +MODULE_VERSION(MPT3SCST_DRIVER_VERSION); 298 | + 299 | +#define DPRINTK(fmt, args...) if (mpt3_scst_debug) printk(KERN_DEBUG "%s: " fmt, \ 300 | + __FUNCTION__ , ## args) 301 | + 302 | +#ifdef VERBOSE 303 | +#define VDPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, \ 304 | + __FUNCTION__ , ## args) 305 | +#else 306 | +#define VDPRINTK(fmt, args...) 307 | +#endif 308 | + 309 | +int mpt3_scst_debug = 0; 310 | +module_param(mpt3_scst_debug, int, S_IRUGO|S_IWUSR); 311 | +MODULE_PARM_DESC(mpt3_scst_debug, " enable debugging output "); 312 | + 313 | +static char *_mpt3scst_vendor = "none"; 314 | +module_param(_mpt3scst_vendor, charp, 0); 315 | +MODULE_PARM_DESC(_mpt3scst_vendor,"Vendor ID"); 316 | + 317 | +// from the LSI headers: 318 | +/* 319 | + * reset phases 320 | + */ 321 | +#define MPT3_IOC_PRE_RESET 1 /* prior to host reset */ 322 | +#define MPT3_IOC_AFTER_RESET 2 /* just after host reset */ 323 | +#define MPT3_IOC_DONE_RESET 3 /* links re-initialized */ 324 | + 325 | + 326 | +static mpt3scst_dd_t gmpt3scst_dd_t; 327 | + 328 | +static inline struct mpt3_init* 329 | +_devh_to_init(struct mpt3_ioc* ioc, u16 InitiatorDevHandle) { 330 | + struct mpt3_init* initptr; 331 | + unsigned long flags; 332 | + 333 | + // find the right session to handle this frame 334 | + spin_lock_irqsave(&ioc->lock,flags); 335 | + list_for_each_entry(initptr,&ioc->init_list,listh) 336 | + { 337 | + if (InitiatorDevHandle == initptr->InitiatorDevHandle) 338 | + { 339 | + spin_unlock_irqrestore(&ioc->lock,flags); 340 | + return initptr; 341 | + } 342 | + } 343 | + spin_unlock_irqrestore(&ioc->lock,flags); 344 | + return NULL; 345 | +} 346 | + 347 | +static inline struct mpt3_cmd* 348 | +_ioindex_to_cmd(struct mpt3_ioc *ioc, u16 IoIndex) { 349 | + struct mpt3_cmd *cmdptr; 350 | + unsigned long flags; 351 | + 352 | + spin_lock_irqsave(&ioc->lock,flags); 353 | + list_for_each_entry(cmdptr,&ioc->cmd_list,listh) { 354 | + if ( cmdptr->IoIndex == IoIndex ) 355 | + { 356 | + spin_unlock_irqrestore(&ioc->lock,flags); 357 | + return cmdptr; 358 | + } 359 | + } 360 | + spin_unlock_irqrestore(&ioc->lock,flags); 361 | + return NULL; 362 | +} 363 | + 364 | +/** 365 | + * called by either _scst_xmit_reponse (if no READ data) or 366 | + * by _stm_assist_complete if AUTO_GOOD was not set in the 367 | + * assist command 368 | + */ 369 | +static int 370 | +_send_status(struct mpt3_cmd* cmd) { 371 | + MPT3STM_CMD_BUFF *cmdbuf = NULL; 372 | + int mpi_rc; 373 | + u8 StatusFlags = 0; 374 | + 375 | + BUG_ON(!cmd); 376 | + BUG_ON(!cmd->init); 377 | + BUG_ON(!cmd->init->ioc); 378 | + 379 | + DPRINTK("C:%p I:%04x _send_status()\n",cmd,cmd->IoIndex); 380 | + 381 | + cmdbuf = mpt3stm_get_cmdbuff(cmd->init->ioc->iocidx,cmd->IoIndex); 382 | + BUG_ON(!cmdbuf); 383 | + 384 | + // initialize reply buffer (SAS frame for STATUS/RESPONSE) and SGL header 385 | + memset(&cmdbuf->rsp,0,sizeof(union _rsp_frame)); 386 | + 387 | + if (scst_cmd_get_sense_buffer_len(cmd->scst_cmd)) { 388 | + int sense_length = scst_cmd_get_sense_buffer_len(cmd->scst_cmd); 389 | + uint8_t *sense_buf = scst_cmd_get_sense_buffer(cmd->scst_cmd); 390 | + 391 | + DPRINTK("C:%p I:%04x returning %d sense\n",cmd,cmd->IoIndex,sense_length); 392 | + 393 | + if (sense_length > 394 | + (MPT3STM_RSP_BYTES - sizeof(Mpi2TargetSspRspIu_t))) { 395 | + DPRINTK("C:%p I:%04x WARNING!!! oversize sense buffer\n",cmd,cmd->IoIndex); 396 | + sense_length = (MPT3STM_RSP_BYTES - sizeof(Mpi2TargetSspRspIu_t)); 397 | + } 398 | + 399 | + cmdbuf->rsp.rspiu.DataPres = SAS_DATAPRES_SENSE; 400 | + cmdbuf->rsp.rspiu.SenseDataLength = cpu_to_be32( sense_length ); 401 | + cmdbuf->rsp.rspiu.ResponseDataLength = 0; 402 | + 403 | + // copy the sense data into the response IU 404 | + memcpy(cmdbuf->rsp.rspiu.ResponseSenseData, 405 | + sense_buf, 406 | + sense_length); 407 | + } 408 | + else { 409 | + // No sense 410 | + cmdbuf->rsp.rspiu.DataPres = SAS_DATAPRES_NODATA; 411 | + cmdbuf->rsp.rspiu.SenseDataLength = cpu_to_be32(0); 412 | + cmdbuf->rsp.rspiu.ResponseDataLength = cpu_to_be32(0); 413 | + if ( !cmdbuf->rsp.rspiu.Status ) { 414 | + DPRINTK("C:%p I:%04x using AUTO_GOOD\n",cmd,cmd->IoIndex); 415 | + // status code SUCCESS, no resp data or sense data 416 | + StatusFlags |= MPI2_TSS_FLAGS_AUTO_GOOD_STATUS; 417 | + } 418 | + else { 419 | + cmdbuf->rsp.rspiu.Status = scst_cmd_get_status(cmd->scst_cmd); 420 | + DPRINTK("C:%p I:%04x Status:%02x\n",cmd,cmd->IoIndex, 421 | + cmdbuf->rsp.rspiu.Status); 422 | + } 423 | + } 424 | + 425 | + DPRINTK("C:%p I:%04x issuing TARGET_STATUS\n",cmd,cmd->IoIndex); 426 | + 427 | + mpi_rc = mpt3stm_send_status(cmd->init->ioc->iocidx, 428 | + StatusFlags, 429 | + be16_to_cpu(cmdbuf->cmd.command.Tag), 430 | + be16_to_cpu(cmdbuf->cmd.command.InitiatorConnectionTag), 431 | + cmd->IoIndex); 432 | + switch (mpi_rc) { 433 | + case 0: 434 | + break; 435 | + case -EAGAIN: 436 | + pr_warn(MPT3SCST_FMT "MPT command buffers full for mpt3stm_send_status() I:%04x at %s:%d/%s()!\n", 437 | + cmd->IoIndex,__FILE__, __LINE__, __func__); 438 | + return SCST_TGT_RES_QUEUE_FULL; 439 | + break; 440 | + default: 441 | + pr_err(MPT3SCST_FMT "failed mpt3stm_assist(%d) for I:%04x at %s:%d/%s()!\n", 442 | + mpi_rc,cmd->IoIndex,__FILE__, __LINE__, __func__); 443 | + scst_set_delivery_status(cmd->scst_cmd, SCST_CMD_DELIVERY_FAILED); 444 | + return SCST_TGT_RES_FATAL_ERROR; 445 | + } 446 | + 447 | + // // Success! horray 448 | + return SCST_TGT_RES_SUCCESS; 449 | +} 450 | + 451 | +static int 452 | +_send_data(struct mpt3_cmd *cmd) 453 | +{ 454 | + u8 AssistFlags = MPI2_TARGET_ASSIST_FLAGS_DATA_DIRECTION; 455 | + // This buffer is for sending data (to a remote initiator) 456 | + int mpi_rc; 457 | + 458 | + DPRINTK("C:%p I:%04x DATA_READ\n", cmd,cmd->IoIndex); 459 | + 460 | + // The first TARGET_ASSIST command must always have a 0 here 461 | + cmd->SequenceNumber = 0; 462 | + 463 | + cmd->sg_dir = scst_cmd_get_data_direction(cmd->scst_cmd); 464 | + cmd->sg = scst_cmd_get_sg(cmd->scst_cmd); 465 | + cmd->sg_cnt = scst_cmd_get_sg_cnt(cmd->scst_cmd); 466 | + cmd->dma_size = scst_cmd_get_adjusted_resp_data_len(cmd->scst_cmd); 467 | + 468 | + DPRINTK("C:%p I:%04x issuing TARGET_ASSIST (send)\n",cmd,cmd->IoIndex); 469 | + // pass the baton to MPT 470 | + mpi_rc = mpt3stm_assist(cmd->init->ioc->iocidx, 471 | + AssistFlags, 472 | + cmd->QueueTag, 473 | + cmd->InitiatorConnectionTag, 474 | + cmd->IoIndex, 475 | + cmd->SequenceNumber, 476 | + 0, // SkipCount 477 | + cmd->dma_size, 478 | + cmd->sg, 479 | + cmd->sg_cnt, 480 | + DMA_TO_DEVICE); 481 | + switch (mpi_rc) { 482 | + case 0: 483 | + // Success! horray 484 | + break; 485 | + case -EAGAIN: 486 | + pr_warn(MPT3SCST_FMT "MPT command buffers full for mpt3stm_assist() I:%04x at %s:%d/%s()!\n", 487 | + cmd->IoIndex,__FILE__, __LINE__, __func__); 488 | + return SCST_TGT_RES_QUEUE_FULL; 489 | + break; 490 | + default: 491 | + pr_err(MPT3SCST_FMT "failed mpt3stm_assist(%d) at %s:%d/%s()!\n", 492 | + mpi_rc,__FILE__, __LINE__, __func__); 493 | + scst_set_delivery_status(cmd->scst_cmd, SCST_CMD_DELIVERY_FAILED); 494 | + return SCST_TGT_RES_FATAL_ERROR; 495 | + } 496 | + return SCST_TGT_RES_SUCCESS; 497 | +} 498 | + 499 | +/* 500 | + * This function is equivalent to the SCSI 501 | + * queuecommand. The target should transmit the response 502 | + * buffer and the status in the scst_cmd struct. 503 | + * The expectation is that this executing this command is NON-BLOCKING. 504 | + * If it is blocking, consider to set threads_num to some none 0 number. 505 | + * 506 | + * After the response is actually transmitted, the target 507 | + * should call the scst_tgt_cmd_done() function of the 508 | + * mid-level, which will allow it to free up the command. 509 | + * Returns one of the SCST_TGT_RES_* constants. 510 | + * 511 | + * Pay attention to "atomic" attribute of the cmd, which can be get 512 | + * by scst_cmd_atomic(): it is true if the function called in the 513 | + * atomic (non-sleeping) context. 514 | + * 515 | + * MUST HAVE 516 | + */ 517 | +static int 518 | +_scst_xmit_response(struct scst_cmd *scst_cmd) 519 | +{ 520 | + struct mpt3_cmd* cmd = scst_cmd_get_tgt_priv(scst_cmd); 521 | + 522 | + BUG_ON(!cmd); 523 | + DPRINTK("C:%p I:%04x xmit_response\n",cmd,cmd->IoIndex); 524 | + 525 | + // as specified in SCST documentation - check for abort and cleanup 526 | + if (scst_cmd_aborted_on_xmit(scst_cmd)) { 527 | + pr_err(MPT3SCST_FMT "C:%p I:%04x scst_cmd_aborted_on_xmit at %s:%d/%s()!\n", 528 | + cmd,cmd->IoIndex, 529 | + __FILE__, __LINE__, __func__); 530 | + 531 | + scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_ABORTED); 532 | + scst_tgt_cmd_done(scst_cmd, SCST_CONTEXT_SAME); 533 | + // Not sure if the below is correct? Should this be a "success" that 534 | + // we aborted it as required? 535 | + return SCST_TGT_RES_FATAL_ERROR; 536 | + } 537 | + 538 | + if ( SCST_DATA_READ == scst_cmd_get_data_direction(scst_cmd) ) { 539 | + DPRINTK("C:%p I:%04x jump to _send_data()\n",cmd,cmd->IoIndex); 540 | + return _send_data(cmd); 541 | + } 542 | + else if ( (SCST_DATA_NONE == scst_cmd_get_data_direction(scst_cmd)) || 543 | + (SCST_DATA_WRITE == scst_cmd_get_data_direction(scst_cmd)) ) { 544 | + if ( !scst_cmd_get_is_send_status(scst_cmd) ) { 545 | + DPRINTK("C:%p I:%04x !is_send_status\n",cmd,cmd->IoIndex); 546 | + return SCST_TGT_RES_SUCCESS; 547 | + } 548 | + DPRINTK("C:%p I:%04x jump to _send_status()\n",cmd,cmd->IoIndex); 549 | + // proceed to status 550 | + return _send_status(cmd); 551 | + } 552 | + 553 | + // Not READ, WRITE or NONE... 554 | + pr_err(MPT3SCST_FMT "C:%p I:%04x unsupported data direction (%d) at %s:%d/%s()!\n", 555 | + cmd,cmd->IoIndex, scst_cmd_get_data_direction(scst_cmd), 556 | + __FILE__, __LINE__, __func__); 557 | + return SCST_TGT_RES_FATAL_ERROR; 558 | +} 559 | + 560 | +/* 561 | + * This function informs the driver that data 562 | + * buffer corresponding to the said command have now been 563 | + * allocated and it is OK to receive data for this command. 564 | + * This function is necessary because a SCSI target does not 565 | + * have any control over the commands it receives. Most lower 566 | + * level protocols have a corresponding function which informs 567 | + * the initiator that buffers have been allocated e.g., XFER_ 568 | + * RDY in Fibre Channel. After the data is actually received 569 | + * the low-level driver needs to call scst_rx_data() in order to 570 | + * continue processing this command. 571 | + * Returns one of the SCST_TGT_RES_* constants. 572 | + * 573 | + * This command is expected to be NON-BLOCKING. 574 | + * If it is blocking, consider to set threads_num to some none 0 number. 575 | + * 576 | + * Pay attention to "atomic" attribute of the cmd, which can be get 577 | + * by scst_cmd_atomic(): it is true if the function called in the 578 | + * atomic (non-sleeping) context. 579 | + * 580 | + * OPTIONAL 581 | + */ 582 | +static int 583 | +_scst_rdy_to_xfer(struct scst_cmd *scst_cmd) 584 | +{ 585 | + struct mpt3_cmd *cmd = scst_cmd_get_tgt_priv(scst_cmd); 586 | + u8 AssistFlags = 0; 587 | + int mpi_rc; 588 | + int scst_status = SCST_TGT_RES_SUCCESS; 589 | + 590 | + DPRINTK("C:%p I:%04x DATA_WRITE\n", cmd,cmd->IoIndex); 591 | + cmd->SequenceNumber = 0; 592 | + 593 | + // This buffer is for receiving data (from a remote initiator) 594 | + //AssistFlags != MPI2_TARGET_ASSIST_FLAGS_DATA_DIRECTION; 595 | + 596 | + cmd->sg_dir = scst_cmd_get_data_direction(cmd->scst_cmd); 597 | + if ( SCST_DATA_WRITE != cmd->sg_dir) 598 | + { 599 | + DPRINTK("C:%p I:%04x !DATA_WRITE in rdy_to_xfer?\n", cmd,cmd->IoIndex); 600 | + return SCST_TGT_RES_SUCCESS; 601 | + } 602 | + scst_cmd_get_write_fields(cmd->scst_cmd, 603 | + &cmd->sg, 604 | + &cmd->sg_cnt); 605 | + cmd->dma_size = scst_cmd_get_bufflen(cmd->scst_cmd); 606 | + 607 | + DPRINTK("C:%p I:%04x issuing TARGET_ASSIST (receive)\n",cmd,cmd->IoIndex); 608 | + // pass the baton to MPT 609 | + mpi_rc = mpt3stm_assist(cmd->init->ioc->iocidx, 610 | + AssistFlags, 611 | + cmd->QueueTag, 612 | + cmd->InitiatorConnectionTag, 613 | + cmd->IoIndex, 614 | + cmd->SequenceNumber, 615 | + 0, // SkipCount 616 | + cmd->dma_size, 617 | + cmd->sg, 618 | + cmd->sg_cnt, 619 | + DMA_FROM_DEVICE); 620 | + switch (mpi_rc) { 621 | + case 0: 622 | + // Success! horray 623 | + break; 624 | + case -EAGAIN: 625 | + pr_warn(MPT3SCST_FMT "MPT command buffers full for mpt3stm_assist() I:%04x at %s:%d/%s()!\n", 626 | + cmd->IoIndex,__FILE__, __LINE__, __func__); 627 | + scst_status = SCST_TGT_RES_QUEUE_FULL; 628 | + break; 629 | + default: 630 | + pr_err(MPT3SCST_FMT "failed mpt3stm_assist(%d) at %s:%d/%s()!\n", 631 | + mpi_rc,__FILE__, __LINE__, __func__); 632 | + scst_status = SCST_TGT_RES_FATAL_ERROR; 633 | + } 634 | + DPRINTK("C:%p I:%04x (receive):%d posted\n",cmd,cmd->IoIndex,scst_status); 635 | + return scst_status; 636 | +} 637 | + 638 | +/* 639 | + * Called to notify the driver that the command is about to be freed. 640 | + * Necessary, because for aborted commands xmit_response() could not 641 | + * be called. Could be called on IRQ context. 642 | + * 643 | + * This callback is called when the last reference to cmd is dropped, 644 | + * which can be much later after scst_tgt_cmd_done() called by the 645 | + * target driver, so it is not recommended that the target driver 646 | + * clean hardware or connection related cmd resources in this callback. 647 | + * It is recommended to clean them before calling scst_tgt_cmd_done() 648 | + * instead. 649 | + * 650 | + * OPTIONAL 651 | + */ 652 | +//static void 653 | +//_scst_on_free_cmd(struct scst_cmd *scst_cmd) 654 | +//{ 655 | +// struct mpt3_cmd* cmd = scst_cmd_get_tgt_priv(scst_cmd); 656 | +// unsigned long flags; 657 | +// 658 | +// BUG_ON(!cmd); 659 | +// printk("C:%p I:%04x _scst_on_free_cmd\n",cmd->IoIndex); 660 | +// 661 | +//} 662 | + 663 | +/* 664 | + * This function informs the driver that the corresponding task 665 | + * management function has been completed, i.e. all the corresponding 666 | + * commands completed and freed. No return value expected. 667 | + * 668 | + * This function is expected to be NON-BLOCKING. 669 | + * 670 | + * Called without any locks held from a thread context. 671 | + * 672 | + * MUST HAVE if the target supports task management. 673 | + */ 674 | +static void 675 | +_scst_task_mgmt_fn_done(struct scst_mgmt_cmd *mgmt_cmd) 676 | +{ 677 | + DPRINTK("mpt3_scst: %s()\n",__func__); 678 | +} 679 | + 680 | +/* 681 | + * This function allows to enable or disable particular target. 682 | + * A disabled target doesn't receive and process any SCSI commands. 683 | + * 684 | + * SHOULD HAVE to avoid race when there are connected initiators, 685 | + * while target not yet completed the initial configuration. In this 686 | + * case the too early connected initiators would see not those devices, 687 | + * which they intended to see. 688 | + * 689 | + * If you are sure your target driver doesn't need enabling target, 690 | + * you should set enabled_attr_not_needed in 1. 691 | + */ 692 | +static int 693 | +_scst_enable_tgt(struct scst_tgt *scst_tgt, bool enable) 694 | +{ 695 | + struct mpt3_ioc *ioc = scst_tgt_get_tgt_priv(scst_tgt); 696 | + BUG_ON(!ioc); 697 | + return mpt3stm_enable(ioc->iocidx,enable); 698 | +} 699 | + 700 | +/* 701 | + * This function shows if particular target is enabled or not. 702 | + * 703 | + * SHOULD HAVE, see above why. 704 | + */ 705 | +static bool 706 | +_scst_is_tgt_enabled(struct scst_tgt *scst_tgt) 707 | +{ 708 | + struct mpt3_ioc *ioc = scst_tgt_get_tgt_priv(scst_tgt); 709 | + BUG_ON(!ioc); 710 | + return mpt3stm_is_enabled(ioc->iocidx); 711 | +} 712 | + 713 | +/* 714 | + * This function should free up the resources allocated to the device. 715 | + * The function should return 0 to indicate successful release 716 | + * or a negative value if there are some issues with the release. 717 | + * In the current version the return value is ignored. 718 | + * 719 | + * MUST HAVE 720 | + */ 721 | +static int 722 | +_scst_release(struct scst_tgt *scst_tgt) 723 | +{ 724 | + DPRINTK("mpt3_scst: %s()\n",__func__); 725 | + return 0; 726 | +} 727 | + 728 | +/* 729 | + * This function returns in tr_id the corresponding to sess initiator 730 | + * port TransportID in the form as it's used by PR commands, see 731 | + * "Transport Identifiers" in SPC. Space for the initiator port 732 | + * TransportID must be allocated via kmalloc(). Caller supposed to 733 | + * kfree() it, when it isn't needed anymore. 734 | + * 735 | + * If sess is NULL, this function must return TransportID PROTOCOL 736 | + * IDENTIFIER for the requested target. 737 | + * 738 | + * Returns 0 on success or negative error code otherwise. 739 | + * 740 | + * SHOULD HAVE, because it's required for Persistent Reservations. 741 | + */ 742 | +//int (*get_initiator_port_transport_id)(struct scst_tgt *tgt, 743 | +// struct scst_session *sess, uint8_t **transport_id); 744 | + 745 | + 746 | +static void 747 | +_process_task_frame(struct mpt3_cmd *cmd) 748 | +{ 749 | + unsigned long flags; 750 | + int scst_task_function = 0; 751 | + int rc; 752 | + 753 | + DPRINTK(MPT3SCST_FMT "task IU from dh:%04x @%016llx\n", 754 | + cmd->init->InitiatorDevHandle,cmd->init->SASAddress); 755 | + 756 | + 757 | + switch (cmd->TaskManagementFunction) { 758 | + case SAS_SSP_TSKMGMTFUNCTION_ABORT_TASK: 759 | + scst_task_function = SCST_ABORT_TASK; 760 | + break; 761 | + case SAS_SSP_TSKMGMTFUNCTION_ABORT_TASK_SET: 762 | + scst_task_function = SCST_ABORT_TASK_SET; 763 | + break; 764 | + case SAS_SSP_TSKMGMTFUNCTION_CLEAR_TASK_SET: 765 | + scst_task_function = SCST_CLEAR_TASK_SET; 766 | + break; 767 | + case SAS_SSP_TSKMGMTFUNCTION_CLEAR_ACA: 768 | + scst_task_function = SCST_CLEAR_ACA; 769 | + break; 770 | + case SAS_SSP_TSKMGMTFUNCTION_LOGICAL_UNIT_RESET: 771 | + scst_task_function = SCST_LUN_RESET; 772 | + break; 773 | + case SAS_SSP_TSKMGMTFUNCTION_I_T_NEXUS_RESET: 774 | + scst_task_function = SCST_TARGET_RESET; 775 | + break; 776 | + case SAS_SSP_TSKMGMTFUNCTION_QUERY_TASK: 777 | + case SAS_SSP_TSKMGMTFUNCTION_QUERY_TASK_SET: 778 | + case SAS_SSP_TSKMGMTFUNCTION_QUERY_ASYNCHRONOUS_EVENT: 779 | + default: 780 | + pr_err(MPT3SCST_FMT "invalid task:%02x at %s:%d/%s()!\n", 781 | + cmd->TaskManagementFunction,__FILE__, __LINE__, __func__); 782 | + break; 783 | + } 784 | + switch (scst_task_function) { 785 | + case SCST_ABORT_TASK: 786 | + rc = scst_rx_mgmt_fn_tag(cmd->init->scst_sess, 787 | + scst_task_function, 788 | + cmd->QueueTag, 789 | + SCST_NON_ATOMIC, // we are workq context 790 | + cmd); 791 | + break; 792 | + default: 793 | + rc = scst_rx_mgmt_fn_lun(cmd->init->scst_sess, 794 | + scst_task_function, 795 | + &cmd->LogicalUnitNumber[0], 796 | + 8, // size of LUN 797 | + SCST_NON_ATOMIC, // we are workq context 798 | + cmd); 799 | + break; 800 | + } 801 | + if (rc) 802 | + { 803 | + pr_err(MPT3SCST_FMT "failed scst_rx_mgmt_fn_tag/lun (%d) at %s:%d/%s()!\n", 804 | + rc,__FILE__, __LINE__, __func__); 805 | + spin_lock_irqsave(&cmd->init->ioc->lock,flags); 806 | + list_del(&cmd->listh); 807 | + spin_unlock_irqrestore(&cmd->init->ioc->lock,flags); 808 | + 809 | + kfree(cmd); 810 | + return; 811 | + } 812 | +} 813 | + 814 | +static void 815 | +_process_command_frame(struct mpt3_cmd *cmd) 816 | +{ 817 | + unsigned long flags; 818 | + DPRINTK("C:%p I:%04x command IU from dh:%04x @%016llx\n", 819 | + cmd,cmd->IoIndex,cmd->init->InitiatorDevHandle,cmd->init->SASAddress); 820 | + 821 | + cmd->scst_cmd = scst_rx_cmd(cmd->init->scst_sess, 822 | + &cmd->LogicalUnitNumber[0], 823 | + 8, // lun length 824 | + &cmd->CDB[0], 825 | + 16, 826 | + SCST_NON_ATOMIC); // workq context 827 | + if (!cmd->scst_cmd) 828 | + { 829 | + pr_err(MPT3SCST_FMT "failed scst_rx_cmd at %s:%d/%s()!\n", 830 | + __FILE__, __LINE__, __func__); 831 | + spin_lock_irqsave(&cmd->init->ioc->lock,flags); 832 | + list_del(&cmd->listh); 833 | + spin_unlock_irqrestore(&cmd->init->ioc->lock,flags); 834 | + kfree(cmd); 835 | + return; 836 | + } 837 | + // set SCST additional information from command frame 838 | + scst_cmd_set_tag(cmd->scst_cmd,cmd->QueueTag); 839 | + scst_cmd_set_tgt_priv(cmd->scst_cmd,cmd); 840 | + 841 | + // Allow SCST to continue processing this request 842 | + scst_cmd_init_done(cmd->scst_cmd,SCST_CONTEXT_DIRECT); 843 | +} 844 | + 845 | +static void 846 | +_process_cmd_on_workq(struct work_struct *work) { 847 | + struct mpt3_cmd* cmd = container_of(work,struct mpt3_cmd,work_entry); 848 | + switch (cmd->FrameType) { 849 | + case SAS_SSP_FRAMETYPE_CMD: 850 | + _process_command_frame(cmd); 851 | + break; 852 | + case SAS_SSP_FRAMETYPE_TASK: 853 | + _process_task_frame(cmd); 854 | + break; 855 | + } 856 | +} 857 | + 858 | +static void 859 | +_stm_command_received(u8 iocidx, u8 PhyNum, u16 IoIndex, u16 InitiatorDevHandle) 860 | +{ 861 | + struct mpt3_ioc *ioc = mpt3stm_ioc_get_priv(iocidx); 862 | + struct mpt3_init *init = NULL; 863 | + MPT3STM_CMD_BUFF* cmdbuf = mpt3stm_get_cmdbuff(iocidx, IoIndex); 864 | + struct mpt3_cmd *cmd = NULL; 865 | + unsigned long flags; 866 | + 867 | + BUG_ON(!ioc); 868 | + BUG_ON(!cmdbuf); 869 | + 870 | + init = _devh_to_init(ioc,InitiatorDevHandle); 871 | + if (!init) { 872 | + pr_warn(MPT3SCST_FMT "failed to find a session for dh:%04x at %s:%d/%s()!\n", 873 | + InitiatorDevHandle, 874 | + __FILE__, __LINE__, __func__); 875 | + return; 876 | + } 877 | + 878 | + cmd = kzalloc(sizeof(*cmd),GFP_ATOMIC); 879 | + if (!cmd) { 880 | + pr_err(MPT3SCST_FMT "failed kzalloc at %s:%d/%s()!\n", 881 | + __FILE__, __LINE__, __func__); 882 | + return; 883 | + } 884 | + cmd->init = init; 885 | + cmd->IoIndex = IoIndex; 886 | + 887 | + // pull common fields from cmdbuf (SAS IU) - frame is ANSI so BigEndian!!! 888 | + cmd->InitiatorConnectionTag = be16_to_cpu(cmdbuf->cmd.command.InitiatorConnectionTag); 889 | + cmd->FrameType = cmdbuf->cmd.command.FrameType; 890 | + cmd->SSPFlags = be16_to_cpu(cmdbuf->cmd.command.Flags); 891 | + cmd->TargetPortTransferTag = be16_to_cpu(cmdbuf->cmd.command.TargetPortTransferTag); 892 | + cmd->QueueTag = be16_to_cpu(cmdbuf->cmd.command.Tag); 893 | + cmd->DataOffset = be32_to_cpu(cmdbuf->cmd.command.DataOffset); 894 | + memcpy(cmd->LogicalUnitNumber,cmdbuf->cmd.command.LogicalUnitNumber,8); 895 | + 896 | + // determine if this is a Command IU or a Task IU and start processing 897 | + if ( SAS_SSP_FRAMETYPE_CMD == cmd->FrameType ) { 898 | + cmd->TaskAttribute = cmdbuf->cmd.command.TaskAttribute; 899 | + if (cmdbuf->cmd.command.AdditionalCDBLength) 900 | + pr_warn(MPT3SCST_FMT "command IU idx:%04x from %04x has AdditionalCDB bytes NOT SUPPORTED at %s:%d/%s()!\n", 901 | + IoIndex, InitiatorDevHandle, __FILE__, __LINE__, __func__); 902 | + memcpy(cmd->CDB,cmdbuf->cmd.command.CDB,16); 903 | + } 904 | + else if ( SAS_SSP_FRAMETYPE_TASK == cmdbuf->cmd.command.FrameType ) { 905 | + cmd->TaskManagementFunction = cmdbuf->cmd.task.TaskManagementFunction; 906 | + cmd->ManagedTaskTag = cmdbuf->cmd.task.ManagedTaskTag; 907 | + } 908 | + else { 909 | + pr_err(MPT3SCST_FMT "Invalid FrameType:%02x from dh:%04x at %s:%d/%s()!\n", 910 | + cmdbuf->cmd.command.FrameType, InitiatorDevHandle, 911 | + __FILE__, __LINE__, __func__); 912 | + return; 913 | + } 914 | + 915 | + if ( MPT3SCST_INIT_STATE_READY != atomic_read(&init->state)) 916 | + { 917 | + spin_lock_irqsave(&init->ioc->lock,flags); 918 | + list_add(&cmd->listh,&init->ioc->delayed_cmds); 919 | + spin_unlock_irqrestore(&init->ioc->lock,flags); 920 | + pr_warn(MPT3SCST_FMT "deferred processing for io:%04x dh:%04x at %s:%d/%s()!\n", 921 | + IoIndex,InitiatorDevHandle, 922 | + __FILE__, __LINE__, __func__); 923 | + return; 924 | + } 925 | + 926 | + INIT_WORK(&cmd->work_entry, _process_cmd_on_workq); 927 | + 928 | + spin_lock_irqsave(&init->ioc->lock,flags); 929 | + list_add(&cmd->listh,&init->ioc->cmd_list); 930 | + queue_work(init->workq, &cmd->work_entry); 931 | + spin_unlock_irqrestore(&init->ioc->lock,flags); 932 | +} 933 | + 934 | +static void 935 | +_process_status_complete_on_workq(struct work_struct *work) { 936 | + struct mpt3_cmd* cmd = container_of(work,struct mpt3_cmd,work_entry); 937 | + unsigned long flags; 938 | + int rc; 939 | + 940 | + if (!cmd->scst_cmd) { 941 | + pr_err(MPT3SCST_FMT "C:%p I:%04x has NULL scst_cmd at %s:%d/%s()!\n", 942 | + cmd,cmd->IoIndex, 943 | + __FILE__, __LINE__, __func__); 944 | + return; 945 | + } 946 | + if (!cmd->init) { 947 | + pr_err(MPT3SCST_FMT "C:%p I:%04x has NULL init at %s:%d/%s()!\n", 948 | + cmd,cmd->IoIndex, 949 | + __FILE__, __LINE__, __func__); 950 | + return; 951 | + } 952 | + if (!cmd->init->ioc) { 953 | + pr_err(MPT3SCST_FMT "C:%p I:%04x has NULL init->ioc at %s:%d/%s()!\n", 954 | + cmd,cmd->IoIndex, 955 | + __FILE__, __LINE__, __func__); 956 | + return; 957 | + } 958 | + 959 | + if (cmd->status_mpi_reply) { 960 | + u16 IOCStatus = (le16_to_cpu(cmd->status_mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK); 961 | + // Some sort of MPI/transport error occured, lets tell the SCST 962 | + // stack about it 963 | + switch (IOCStatus) { 964 | + case MPI2_IOCSTATUS_TARGET_ABORTED: 965 | + pr_warn(MPT3SCST_FMT "C:%p I:%04x was MPT aborted at %s:%d/%s()!\n", 966 | + cmd,cmd->IoIndex, 967 | + __FILE__, __LINE__, __func__); 968 | + scst_set_delivery_status(cmd->scst_cmd,SCST_CMD_DELIVERY_ABORTED); 969 | + break; 970 | + default: 971 | + pr_err(MPT3SCST_FMT "C:%p I:%04x was MPT failed (iocstatus=0x%04x) at %s:%d/%s()!\n", 972 | + cmd,cmd->IoIndex, IOCStatus, 973 | + __FILE__, __LINE__, __func__); 974 | + scst_set_delivery_status(cmd->scst_cmd,SCST_CMD_DELIVERY_FAILED); 975 | + break; 976 | + } 977 | + } 978 | + 979 | + if (cmd->scst_cmd->state != SCST_CMD_STATE_XMIT_WAIT) { 980 | + pr_err(MPT3SCST_FMT "C:%p I:%04x !SCST_CMD_STATE_XMIT_WAIT %s:%d/%s()!\n", 981 | + cmd,cmd->IoIndex, 982 | + __FILE__, __LINE__, __func__); 983 | + } else { 984 | + DPRINTK("C:%p I:%04x scst_tgt_cmd_done\n",cmd,cmd->IoIndex); 985 | + scst_tgt_cmd_done(cmd->scst_cmd, SCST_CONTEXT_DIRECT); 986 | + } 987 | + 988 | + if ( MPT3SCST_IOC_STATE_READY != atomic_read(&cmd->init->ioc->state)) { 989 | + pr_warn(MPT3SCST_FMT "C:%p I:%04x the ioc is not READY at %s:%d/%s()!\n", 990 | + cmd,cmd->IoIndex, 991 | + __FILE__, __LINE__, __func__); 992 | + } else { 993 | + // remove from ioc->cmd_list 994 | + spin_lock_irqsave(&cmd->init->ioc->lock,flags); 995 | + list_del(&cmd->listh); 996 | + spin_unlock_irqrestore(&cmd->init->ioc->lock,flags); 997 | + 998 | + // return the message frame to the IOC 999 | + mpt3stm_release_command(cmd->init->ioc->iocidx, cmd->IoIndex); 1000 | + kfree(cmd); 1001 | + } 1002 | +} 1003 | + 1004 | +static void 1005 | +_stm_status_complete(u8 iocidx, u16 IoIndex, 1006 | + Mpi2TargetErrorReply_t* mpi_reply) { 1007 | + struct mpt3_cmd *cmd = NULL; 1008 | + struct mpt3_ioc *ioc = mpt3stm_ioc_get_priv(iocidx); 1009 | + unsigned long flags; 1010 | + BUG_ON(!ioc); 1011 | + 1012 | + cmd = _ioindex_to_cmd(ioc,IoIndex); 1013 | + if (!cmd) { 1014 | + pr_err(MPT3SCST_FMT "C:%p I:%04x failed to find a command in list at %s:%d/%s()!\n", 1015 | + NULL,IoIndex, 1016 | + __FILE__, __LINE__, __func__); 1017 | + return; 1018 | + } 1019 | + 1020 | + BUG_ON(!cmd->init); 1021 | + if ( MPT3SCST_INIT_STATE_READY != atomic_read(&cmd->init->state)) { 1022 | + pr_warn(MPT3SCST_FMT "C:%p I:%04x the init/session is not READY at %s:%d/%s()!\n", 1023 | + cmd,IoIndex, 1024 | + __FILE__, __LINE__, __func__); 1025 | + return; 1026 | + } 1027 | + cmd->status_mpi_reply = mpi_reply; 1028 | + INIT_WORK(&cmd->work_entry, _process_status_complete_on_workq); 1029 | + // put this in the workq so that operations are 'normal' instead of inside 1030 | + // IRQ context 1031 | + spin_lock_irqsave(&cmd->init->ioc->lock,flags); 1032 | + queue_work(cmd->init->ioc->workq, &cmd->work_entry); 1033 | + spin_unlock_irqrestore(&cmd->init->ioc->lock,flags); 1034 | +} 1035 | + 1036 | +static void 1037 | +_process_assist_complete_on_workq(struct work_struct *work) { 1038 | + struct mpt3_cmd* cmd = container_of(work,struct mpt3_cmd,work_entry); 1039 | + 1040 | + if (SCST_DATA_WRITE == cmd->sg_dir) { 1041 | + int scst_rx_status = SCST_RX_STATUS_SUCCESS; 1042 | + if (cmd->assist_mpi_reply) { 1043 | + int missing_count = cmd->scst_cmd->bufflen 1044 | + - cmd->assist_mpi_reply->TransferCount; 1045 | + 1046 | + pr_err(MPT3SCST_FMT "C:%p I:%04x MPT missing:%d (iocstatus=0x%04x) at %s:%d/%s()!\n", 1047 | + cmd, cmd->IoIndex, 1048 | + missing_count,le16_to_cpu(cmd->assist_mpi_reply->IOCStatus), 1049 | + __FILE__, __LINE__, __func__); 1050 | + 1051 | + scst_cmd_set_write_not_received_data_len(cmd->scst_cmd, 1052 | + missing_count); 1053 | + 1054 | + scst_rx_status = SCST_RX_STATUS_ERROR; 1055 | + } 1056 | + else { 1057 | + DPRINTK("C:%p I:%04x ASSIST (receive) SequenceNum:%d\n", 1058 | + cmd,cmd->IoIndex,cmd->SequenceNumber); 1059 | + } 1060 | + 1061 | + DPRINTK("C:%p I:%04x ASSIST (receive) complete (%d)(%p)\n",cmd,cmd->IoIndex,scst_rx_status,cmd->assist_mpi_reply); 1062 | + // pass the baton to SCST for further processing 1063 | + scst_rx_data(cmd->scst_cmd, 1064 | + scst_rx_status, 1065 | + SCST_CONTEXT_DIRECT); 1066 | + } 1067 | + else if (SCST_DATA_READ == cmd->sg_dir) { 1068 | + DPRINTK("C:%p I:%04x ASSIST (send) complete (%p)\n",cmd,cmd->IoIndex,cmd->assist_mpi_reply); 1069 | + if (cmd->assist_mpi_reply) { 1070 | + // TODO: Some data may have been transmitted, do we care? 1071 | + 1072 | + u16 IOCStatus = (le16_to_cpu(cmd->assist_mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK); 1073 | + // Some sort of MPI/transport error occured, lets tell the SCST 1074 | + // stack about it 1075 | + switch (IOCStatus) { 1076 | + case MPI2_IOCSTATUS_TARGET_ABORTED: 1077 | + pr_err(MPT3SCST_FMT "C:%p I:%04x MPT ABORTED (iocstatus=0x%04x) at %s:%d/%s()!\n", 1078 | + cmd,cmd->IoIndex,IOCStatus, 1079 | + __FILE__, __LINE__, __func__); 1080 | + scst_set_delivery_status(cmd->scst_cmd, SCST_CMD_DELIVERY_ABORTED); 1081 | + break; 1082 | + default: 1083 | + pr_err(MPT3SCST_FMT "C:%p I:%04x MPT failed (iocstatus=0x%04x) at %s:%d/%s()!\n", 1084 | + cmd,cmd->IoIndex,IOCStatus, 1085 | + __FILE__, __LINE__, __func__); 1086 | + scst_set_delivery_status(cmd->scst_cmd, SCST_CMD_DELIVERY_FAILED); 1087 | + break; 1088 | + } 1089 | + } 1090 | + else { 1091 | + DPRINTK("C:%p I:%04x ASSIST (send) SequenceNum:%d\n", 1092 | + cmd,cmd->IoIndex,cmd->SequenceNumber); 1093 | + } 1094 | + // complete the SCSI protocol 1095 | + _send_status(cmd); 1096 | + } 1097 | + else if (SCST_DATA_NONE == cmd->sg_dir) { 1098 | + DPRINTK("C:%p I:%04x ASSIST (send) complete but dir NODATA?\n",cmd,cmd->IoIndex); 1099 | + } 1100 | + else { 1101 | + pr_warn(MPT3SCST_FMT "C:%p I:%04x not READ, WRITE or NONE? at %s:%d/%s()!\n", 1102 | + cmd,cmd->IoIndex, 1103 | + __FILE__, __LINE__, __func__); 1104 | + } 1105 | +} 1106 | + 1107 | +static void 1108 | +_stm_assist_complete(u8 iocidx, u16 IoIndex, u8 IOCSequenceNum, 1109 | + Mpi2TargetErrorReply_t* mpi_reply) 1110 | +{ 1111 | + struct mpt3_cmd *cmd = NULL; 1112 | + struct mpt3_ioc *ioc = mpt3stm_ioc_get_priv(iocidx); 1113 | + unsigned long flags; 1114 | + BUG_ON(!ioc); 1115 | + 1116 | + cmd = _ioindex_to_cmd(ioc,IoIndex); 1117 | + if (!cmd) { 1118 | + pr_err(MPT3SCST_FMT "failed to find a command in list for %04x at %s:%d/%s()!\n", 1119 | + IoIndex, 1120 | + __FILE__, __LINE__, __func__); 1121 | + return; 1122 | + } 1123 | + 1124 | + BUG_ON(!cmd->init); 1125 | + if ( MPT3SCST_INIT_STATE_READY != atomic_read(&cmd->init->state)) { 1126 | + pr_warn(MPT3SCST_FMT "C:%p I:%04x the init/session is not READY at %s:%d/%s()!\n", 1127 | + cmd,IoIndex, 1128 | + __FILE__, __LINE__, __func__); 1129 | + return; 1130 | + } 1131 | + 1132 | + cmd->assist_mpi_reply = mpi_reply; 1133 | + cmd->SequenceNumber = IOCSequenceNum; 1134 | + INIT_WORK(&cmd->work_entry, _process_assist_complete_on_workq); 1135 | + // put this in the workq so that operations are 'normal' instead of inside 1136 | + // IRQ context 1137 | + spin_lock_irqsave(&cmd->init->ioc->lock,flags); 1138 | + queue_work(cmd->init->ioc->workq, &cmd->work_entry); 1139 | + spin_unlock_irqrestore(&cmd->init->ioc->lock,flags); 1140 | +} 1141 | + 1142 | + 1143 | +void (*init_result_fn)(struct scst_session *sess, void *data, 1144 | + int result); 1145 | + 1146 | +static void 1147 | +_add_init_on_workq(struct work_struct *work) 1148 | +{ 1149 | + struct mpt3_init *init = container_of(work, struct mpt3_init, work_entry); 1150 | + struct mpt3_cmd *delayed_cmd, *next_cmd; 1151 | + unsigned long flags; 1152 | + 1153 | + sprintf(init->name, "%016llx", init->SASAddress); 1154 | + 1155 | + init->scst_sess = scst_register_session(init->ioc->scst_tgt, 1156 | + SCST_NON_ATOMIC, 1157 | + init->name, 1158 | + init, // tgt_priv 1159 | + init, // result_fn_data 1160 | + NULL); // _scst_alloc_session_done); 1161 | + if (!init->scst_sess) { 1162 | + spin_lock_irqsave(&init->ioc->lock,flags); 1163 | + list_del(&init->listh); 1164 | + spin_unlock_irqrestore(&init->ioc->lock,flags); 1165 | + kfree(init); 1166 | + pr_err(MPT3SCST_FMT "failed scst_register_session at %s:%d/%s()!\n", 1167 | + __FILE__, __LINE__, __func__); 1168 | + return; 1169 | + } 1170 | + 1171 | + scst_sess_set_tgt_priv(init->scst_sess, init); 1172 | + init->workq = alloc_ordered_workqueue( init->name, 0); // only one thing allowed to run at a time! 1173 | + pr_info(MPT3SCST_FMT "created session for initiator dh:%04x addr:%016llx\n", 1174 | + init->InitiatorDevHandle, init->SASAddress); 1175 | + // signal that we are now accepting commands 1176 | + atomic_set(&init->state,MPT3SCST_INIT_STATE_READY); 1177 | + 1178 | + spin_lock_irqsave(&init->ioc->lock,flags); 1179 | + list_for_each_entry_safe(delayed_cmd,next_cmd,&init->ioc->delayed_cmds,listh) { 1180 | + if ( delayed_cmd->init == init ) 1181 | + { 1182 | + // remove from deferred list 1183 | + list_del(&delayed_cmd->listh); 1184 | + 1185 | + // post to work queue 1186 | + INIT_WORK(&delayed_cmd->work_entry, _process_cmd_on_workq); 1187 | + list_add(&delayed_cmd->listh,&init->ioc->cmd_list); 1188 | + queue_work(init->workq, &delayed_cmd->work_entry); 1189 | + pr_info(MPT3SCST_FMT "delayed cmd:%04x posted\n", 1190 | + delayed_cmd->IoIndex); 1191 | + } 1192 | + } 1193 | + spin_unlock_irqrestore(&init->ioc->lock,flags); 1194 | + 1195 | +} 1196 | + 1197 | +/** 1198 | + * Called by the mpt3sas_stm driver in softirq state 1199 | + * quick check for an existing session for this devHandle 1200 | + * then complete the work on the workq 1201 | + */ 1202 | +static void 1203 | +_stm_initiator_add(u8 iocidx, 1204 | + MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE *pChange) 1205 | +{ 1206 | + struct mpt3_ioc *ioc = mpt3stm_ioc_get_priv(iocidx); 1207 | + struct mpt3_init *init = NULL; 1208 | + int devh; 1209 | + u64 *iptr; 1210 | + unsigned long flags; 1211 | + 1212 | + BUG_ON(!ioc); 1213 | + 1214 | + if ( MPT3SCST_IOC_STATE_READY != atomic_read(&ioc->state)) { 1215 | + pr_warn(MPT3SCST_FMT "the ioc:%d is not READY at %s:%d/%s()!\n", 1216 | + iocidx, 1217 | + __FILE__, __LINE__, __func__); 1218 | + return; 1219 | + } 1220 | + 1221 | + devh = le16_to_cpu(pChange->DevHandle); 1222 | + init = _devh_to_init(ioc,devh); 1223 | + if (init) { 1224 | + pr_warn(MPT3SCST_FMT "session (%016llx) already exists for dh:%04x\n", 1225 | + init->SASAddress,devh); 1226 | + return; 1227 | + } 1228 | + 1229 | + init = kzalloc(sizeof(struct mpt3_init),GFP_ATOMIC); 1230 | + if (!init) 1231 | + { 1232 | + pr_err(MPT3SCST_FMT "failed kzalloc at %s:%d/%s()!\n", 1233 | + __FILE__, __LINE__, __func__); 1234 | + return; 1235 | + } 1236 | + atomic_set(&init->state,MPT3SCST_INIT_STATE_NEW); 1237 | + init->ioc = ioc; 1238 | + init->InitiatorDevHandle = devh; 1239 | + iptr = (u64*)&pChange->SASAddress; 1240 | + init->SASAddress = le64_to_cpu( *iptr ); 1241 | + 1242 | + INIT_WORK(&init->work_entry, _add_init_on_workq); 1243 | + 1244 | + spin_lock_irqsave(&ioc->lock,flags); 1245 | + list_add(&init->listh,&ioc->init_list); 1246 | + queue_work(ioc->workq, &init->work_entry); 1247 | + spin_unlock_irqrestore(&ioc->lock,flags); 1248 | +} 1249 | + 1250 | +static void 1251 | +_remove_init_on_workq(struct work_struct *work) 1252 | +{ 1253 | + struct mpt3_init *init; 1254 | + u16 devh; 1255 | + u8 iocidx; 1256 | + unsigned long flags; 1257 | + 1258 | + init = container_of(work, struct mpt3_init, work_entry); 1259 | + devh = init->InitiatorDevHandle; 1260 | + iocidx = init->ioc->iocidx; 1261 | + 1262 | + pr_info(MPT3SCST_FMT "removing session for dh:%04x sas addr:%016llx\n", 1263 | + devh, init->SASAddress); 1264 | + // TODO: need to abort all TAs... 1265 | + 1266 | + // TODO: go through cmd list to force abort to SCST 1267 | + 1268 | + // clean out any cmds potentially waiting to process 1269 | + flush_workqueue(init->workq); 1270 | + 1271 | + // unregister the scst session, dont wait for commands to complete 1272 | + // as the host is already gone when we get called here 1273 | + scst_unregister_session(init->scst_sess, 1274 | + 0, // dont wait 1275 | + NULL); // no callback needed 1276 | + 1277 | + destroy_workqueue(init->workq); 1278 | + init->workq = NULL; 1279 | + 1280 | + // remove session from the IOC's list 1281 | + spin_lock_irqsave(&init->ioc->lock,flags); 1282 | + list_del(&init->listh); 1283 | + spin_unlock_irqrestore(&init->ioc->lock,flags); 1284 | + // remove the object from memory 1285 | + kfree(init); 1286 | + 1287 | + // tell the IOC to release the resources associated with this 1288 | + // initiator so that we will get a discovery event when the initiator 1289 | + // comes back 1290 | + mpt3stm_remove_device(iocidx,devh); 1291 | +} 1292 | + 1293 | +/** 1294 | + * Called by the mpt3sas_stm driver in softirq state 1295 | + * quick check for the session in the ioclist 1296 | + * then complete the work on the workq 1297 | + */ 1298 | +static void 1299 | +_stm_initiator_remove(u8 iocidx, 1300 | + MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE *pChange) 1301 | +{ 1302 | + struct mpt3_ioc *ioc = mpt3stm_ioc_get_priv(iocidx); 1303 | + struct mpt3_init *init = NULL; 1304 | + u64 sas_address; 1305 | + int devh; 1306 | + u64 *iptr; 1307 | + unsigned long flags; 1308 | + 1309 | + BUG_ON(!ioc); 1310 | + if ( MPT3SCST_IOC_STATE_READY != atomic_read(&ioc->state)) { 1311 | + pr_warn(MPT3SCST_FMT "the ioc:%d is not READY at %s:%d/%s()!\n", 1312 | + iocidx, 1313 | + __FILE__, __LINE__, __func__); 1314 | + return; 1315 | + } 1316 | + 1317 | + devh = le16_to_cpu(pChange->DevHandle); 1318 | + iptr = (u64*)&pChange->SASAddress; 1319 | + sas_address = le64_to_cpu( *iptr ); 1320 | + 1321 | + init = _devh_to_init(ioc,devh); 1322 | + 1323 | + if (!init) { 1324 | + pr_warn(MPT3SCST_FMT "no session found for dh:%04x addr:%016llx\n", 1325 | + devh, sas_address); 1326 | + } else { 1327 | + BUG_ON(sas_address != init->SASAddress); 1328 | + if (MPT3SCST_INIT_STATE_READY != atomic_read(&init->state)) 1329 | + { 1330 | + pr_warn(MPT3SCST_FMT "session found for dh:%04x but not READY?\n", 1331 | + devh); 1332 | + return; 1333 | + } 1334 | + // dont accept any more commands 1335 | + atomic_set(&init->state,MPT3SCST_INIT_STATE_EXITING); 1336 | + 1337 | + // process the removal on a workqueue instead of in ATOMIC/interrupt 1338 | + // context as called from the MPT3SAS->STM->us path 1339 | + INIT_WORK(&init->work_entry, _remove_init_on_workq ); 1340 | + 1341 | + spin_lock_irqsave(&ioc->lock,flags); 1342 | + queue_work(ioc->workq, &init->work_entry); 1343 | + spin_unlock_irqrestore(&ioc->lock,flags); 1344 | + } 1345 | +} 1346 | + 1347 | +/* 1348 | + * Called by the mpt3sas_stm layer when an MPI EVENT occurs 1349 | + */ 1350 | +static void 1351 | +_stm_event(u8 iocidx, MPI2_EVENT_NOTIFICATION_REPLY *pevent) 1352 | +{ 1353 | + switch (le16_to_cpu(pevent->Event)) { 1354 | + case MPI2_EVENT_STATE_CHANGE: 1355 | + // IOC hardware state change (doorbell) 1356 | + DPRINTK("MPI2_EVENT_STATE_CHANGE:%08x\n",mpt3stm_get_iocstate(iocidx,0)); 1357 | + break; 1358 | + case MPI2_EVENT_HARD_RESET_RECEIVED: 1359 | + // someone reset the logical bus 1360 | + DPRINTK("HARD RESET FROM REMOTE!\n"); 1361 | + break; 1362 | + case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 1363 | + DPRINTK("MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE!\n"); 1364 | + // remote devices 1365 | + break; 1366 | + case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: 1367 | + DPRINTK("MPI2_EVENT_SAS_BROADCAST_PRIMITIVE!\n"); 1368 | + break; 1369 | + case MPI2_EVENT_SAS_NOTIFY_PRIMITIVE: 1370 | + DPRINTK("MPI2_EVENT_SAS_NOTIFY_PRIMITIVE!\n"); 1371 | + break; 1372 | + case MPI2_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE: 1373 | + { 1374 | + MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE *pChange = 1375 | + (MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE*) &pevent->EventData[0]; 1376 | + switch (pChange->ReasonCode) { 1377 | + case MPI2_EVENT_SAS_INIT_RC_ADDED: 1378 | + _stm_initiator_add(iocidx, pChange); 1379 | + break; 1380 | + case MPI2_EVENT_SAS_INIT_RC_NOT_RESPONDING: 1381 | + _stm_initiator_remove(iocidx, pChange); 1382 | + break; 1383 | + default: 1384 | + pr_debug(MPT3SCST_FMT "Invalid event notification reason!\n"); 1385 | + break; 1386 | + } 1387 | + } 1388 | + break; 1389 | + case MPI2_EVENT_SAS_INIT_TABLE_OVERFLOW: 1390 | + default: 1391 | + break; 1392 | + // dont need to do anything 1393 | + // printk(MPT3SCST_FMT "ignored event: %04x\n",pevent->Event); 1394 | + } 1395 | + return; 1396 | +} 1397 | + 1398 | +void _stm_reset(u8 iocidx, int reset_phase) 1399 | +{ 1400 | + struct mpt3_ioc *ioc = mpt3stm_ioc_get_priv(iocidx); 1401 | + switch (reset_phase) { 1402 | + case MPT3_IOC_PRE_RESET: 1403 | + DPRINTK("I:%d MPT3_IOC_PRE_RESET\n",iocidx); 1404 | + if (ioc) { 1405 | + // TODO: unregister all sessions... and abort all commands 1406 | + atomic_set(&ioc->state,MPT3SCST_IOC_STATE_RESET); 1407 | + } 1408 | + break; 1409 | + case MPT3_IOC_AFTER_RESET: 1410 | + DPRINTK("I%d MPT3_IOC_AFTER_RESET\n", iocidx); 1411 | + break; 1412 | + case MPT3_IOC_DONE_RESET: 1413 | + DPRINTK("I%d MPT3_IOC_DONE_RESET\n", iocidx); 1414 | + atomic_set(&ioc->state,MPT3SCST_IOC_STATE_READY); 1415 | + break; 1416 | + } 1417 | + 1418 | +} 1419 | + 1420 | +MPT3STM_DISPATCH _dispatch_table = { 1421 | + .stm_reset = _stm_reset, 1422 | + .stm_event = _stm_event, 1423 | + .stm_command = _stm_command_received, 1424 | + .stm_assist_complete = _stm_assist_complete, 1425 | + .stm_status_complete = _stm_status_complete, 1426 | + .driver = MPT3SCST_DRIVER_NAME, 1427 | +}; 1428 | + 1429 | + 1430 | +static struct scst_tgt_template tgt_template = { 1431 | + .name = MPT3SCST_DRIVER_NAME, 1432 | + .sg_tablesize = 1, /* FIXME */ 1433 | + .use_clustering = 1, 1434 | + .xmit_response_atomic = 0, 1435 | + .rdy_to_xfer_atomic = 0, 1436 | +//#else 1437 | +// .xmit_response_atomic = 1, // async operation 1438 | +// .rdy_to_xfer_atomic = 1, 1439 | +//#endif 1440 | + .xmit_response = _scst_xmit_response, 1441 | + .rdy_to_xfer = _scst_rdy_to_xfer, 1442 | + // .on_hw_pending_cmd_timeout 1443 | + // .on_free_cmd = _scst_on_free_cmd, 1444 | + // .tgt_alloc_data_buff 1445 | + // .preprocessing_done 1446 | + // .pre_exec 1447 | + // .task_mgmt_affected_cmds_done 1448 | + .task_mgmt_fn_done = _scst_task_mgmt_fn_done, 1449 | + // .on_abort_cmd 1450 | + // .detect 1451 | + .release = _scst_release, 1452 | + // .get_initiator_port_transport_id TODO!! 1453 | + .enable_target = _scst_enable_tgt, 1454 | + .is_target_enabled = _scst_is_tgt_enabled, 1455 | +}; 1456 | + 1457 | +static void __exit _mpt3scst_exit(void) 1458 | +{ 1459 | + int i; 1460 | + struct mpt3_ioc *ioc; 1461 | + 1462 | + // remove all of the IOCs 1463 | + for (i = 0; i < gmpt3scst_dd_t.portmap.num_ports; i++) { 1464 | + ioc = mpt3stm_ioc_get_priv(gmpt3scst_dd_t.portmap.port[i].iocidx); 1465 | + if (ioc) { 1466 | + // TODO: unregister all sessions... 1467 | + atomic_set(&ioc->state,MPT3SCST_IOC_STATE_EXITING); 1468 | + if (ioc->workq) 1469 | + { 1470 | + flush_workqueue(ioc->workq); 1471 | + } 1472 | + scst_unregister_target(ioc->scst_tgt); 1473 | + mpt3stm_ioc_set_priv(gmpt3scst_dd_t.portmap.port[i].iocidx,NULL); 1474 | + if (ioc->workq) 1475 | + { 1476 | + destroy_workqueue(ioc->workq); 1477 | + } 1478 | + ioc->workq = NULL; 1479 | + 1480 | + } 1481 | + mpt3stm_deregister(gmpt3scst_dd_t.portmap.port[i].iocidx); 1482 | + } 1483 | + 1484 | + // remove ourselves from the SCST interface 1485 | + scst_unregister_target_template(&tgt_template); 1486 | + 1487 | + return; 1488 | +} 1489 | + 1490 | +static int __init _mpt3scst_init(void) 1491 | +{ 1492 | + int res = 0; 1493 | + int i; 1494 | + struct mpt3_ioc *ioc; 1495 | + char name[32]; 1496 | + 1497 | + pr_warn(MPT3SCST_FMT "Starting target driver!\n"); 1498 | + 1499 | + // tgt_template.vendor = _mpt3scst_vendor; 1500 | + memset(&gmpt3scst_dd_t,0,sizeof(gmpt3scst_dd_t)); 1501 | + 1502 | + // put in a reasonable number of SGLs 1503 | + tgt_template.sg_tablesize = mpt3stm_get_max_sges(0); 1504 | + res = scst_register_target_template(&tgt_template); 1505 | + if (res < 0) 1506 | + goto out; 1507 | + 1508 | + mpt3stm_get_portmap(&gmpt3scst_dd_t.portmap); 1509 | + 1510 | + for (i = 0; i < gmpt3scst_dd_t.portmap.num_ports; i++) { 1511 | + res = mpt3stm_register(gmpt3scst_dd_t.portmap.port[i].iocidx, 1512 | + &_dispatch_table ); 1513 | + if ( res ) { 1514 | + pr_err(MPT3SCST_FMT " failed mpt3stm_register() at %s:%d/%s()!\n", 1515 | + __FILE__, __LINE__, __func__); 1516 | + goto out_unreg_target; 1517 | + } 1518 | + ioc = kzalloc(sizeof(struct mpt3_ioc),GFP_KERNEL); 1519 | + ioc->iocidx = i; 1520 | + atomic_set(&ioc->state,MPT3SCST_IOC_STATE_NEW); 1521 | + 1522 | + ioc->max_sg_ents = mpt3stm_get_max_sges(i); 1523 | + 1524 | + INIT_LIST_HEAD(&ioc->init_list); 1525 | + INIT_LIST_HEAD(&ioc->cmd_list); 1526 | + INIT_LIST_HEAD(&ioc->delayed_cmds); 1527 | + spin_lock_init(&ioc->lock); 1528 | + 1529 | + snprintf(name, sizeof(name), "%s_%d", 1530 | + mpt3stm_get_adapter_name(ioc->iocidx), i); 1531 | + ioc->workq = alloc_workqueue( name, 1532 | + WQ_UNBOUND, 1533 | + 0 ); // use default max_active 1534 | + 1535 | + ioc->scst_tgt = scst_register_target(&tgt_template, name ); 1536 | + if (!ioc->scst_tgt) { 1537 | + pr_err(MPT3SCST_FMT " scst_register_target() failed"); 1538 | + 1539 | + res = -ENODEV; 1540 | + goto out; 1541 | + } 1542 | + 1543 | + scst_tgt_set_tgt_priv(ioc->scst_tgt, ioc); 1544 | + mpt3stm_ioc_set_priv(gmpt3scst_dd_t.portmap.port[i].iocidx,ioc); 1545 | + atomic_set(&ioc->state,MPT3SCST_IOC_STATE_READY); 1546 | + } 1547 | + 1548 | +out: 1549 | + 1550 | + return res; 1551 | + 1552 | +out_unreg_target: 1553 | + _mpt3scst_exit(); 1554 | + goto out; 1555 | +} 1556 | + 1557 | +module_init(_mpt3scst_init); 1558 | +module_exit(_mpt3scst_exit); 1559 | Index: mpt3/mpt3_scst.h 1560 | =================================================================== 1561 | --- mpt3/mpt3_scst.h (revision 0) 1562 | +++ mpt3/mpt3_scst.h (working copy) 1563 | @@ -0,0 +1,182 @@ 1564 | +/** 1565 | + * 1566 | + * @file mpt3scst.h 1567 | + * @brief SCST driver for LSI FusionMPT2.5 (SAS 3.0) controllers 1568 | + * @author Theodore Vaida 1569 | + * 1570 | + * @Copyright � 2015 Exact Assembly, LLC. All Rights Reserved. 1571 | + * 1572 | + * Redistribution and use in source and binary forms, with or without modification, 1573 | + * are permitted provided that the following conditions are met: 1574 | + * 1575 | + * 1. Redistributions of source code must retain the above copyright notice, 1576 | + * this list of conditions and the following disclaimer. 1577 | + * 1578 | + * 2. Redistributions in binary form must reproduce the above copyright notice, 1579 | + * this list of conditions and the following disclaimer in the documentation and/or 1580 | + * other materials provided with the distribution. 1581 | + * 1582 | + * 3. The name of the author may not be used to endorse or promote products derived from this 1583 | + * software without specific prior written permission. 1584 | + * 1585 | + * THIS SOFTWARE IS PROVIDED BY [LICENSOR] "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 1586 | + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1587 | + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1588 | + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 1589 | + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1590 | + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 1591 | + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1592 | + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1593 | + * 1594 | + * 1595 | + * @details This module deals with the mpt3sas specifics of SCSI Target mode 1596 | + * 1597 | + */ 1598 | + 1599 | +#ifndef __MPT3SCST_H 1600 | +#define __MPT3SCST_H 1601 | + 1602 | +#include 1603 | + 1604 | +#include 1605 | +#include 1606 | +#include 1607 | +#include 1608 | +#include 1609 | +#include 1610 | +#include 1611 | +#include 1612 | +#include 1613 | +#include 1614 | +#include 1615 | + 1616 | +#include 1617 | +#include 1618 | +#include 1619 | + 1620 | +#include "mpi/mpi2_type.h" 1621 | +#include "mpi/mpi2.h" 1622 | +#include "mpi/mpi2_ioc.h" 1623 | +#include "mpi/mpi2_cnfg.h" 1624 | +#include "mpi/mpi2_init.h" 1625 | +#include "mpi/mpi2_raid.h" 1626 | +#include "mpi/mpi2_tool.h" 1627 | +#include "mpi/mpi2_sas.h" 1628 | +#include "mpi/mpi2_targ.h" 1629 | + 1630 | +#include "mpt3sas_stm.h" 1631 | + 1632 | +#include "../include/scst.h" 1633 | +#include "../include/scst_debug.h" 1634 | + 1635 | +/*****************************************************************************/ 1636 | + 1637 | +#define MPT3SCST_DRIVER_NAME "mpt3_scst" 1638 | +#define MPT3SCST_FMT "mpt3_scst:" 1639 | + 1640 | +struct mpt3_initiator; 1641 | +struct mpt3_ioc; 1642 | + 1643 | +/* Session's flags */ 1644 | +#define MPT3SCST_SESS_INITING 0 /* The session is being unregistered */ 1645 | +#define MPT3SCST_SESS_SHUTDOWN 1 /* The session is being unregistered */ 1646 | + 1647 | +#define MPT3SCST_CMD_NEW (0) 1648 | +#define MPT3SCST_CMD_DATA_PHASE (1) 1649 | +#define MPT3SCST_CMD_STATUS_PHASE (2) 1650 | +#define MPT3SCST_CMD_DONE (8) 1651 | + 1652 | +#define SAS_SSP_TSKMGMTFUNCTION_ABORT_TASK (0x01) 1653 | +#define SAS_SSP_TSKMGMTFUNCTION_ABORT_TASK_SET (0x02) 1654 | +#define SAS_SSP_TSKMGMTFUNCTION_CLEAR_TASK_SET (0x04) 1655 | +#define SAS_SSP_TSKMGMTFUNCTION_LOGICAL_UNIT_RESET (0x08) 1656 | +#define SAS_SSP_TSKMGMTFUNCTION_I_T_NEXUS_RESET (0x10) 1657 | +#define SAS_SSP_TSKMGMTFUNCTION_CLEAR_ACA (0x40) 1658 | +#define SAS_SSP_TSKMGMTFUNCTION_QUERY_TASK (0x80) 1659 | +#define SAS_SSP_TSKMGMTFUNCTION_QUERY_TASK_SET (0x81) 1660 | +#define SAS_SSP_TSKMGMTFUNCTION_QUERY_ASYNCHRONOUS_EVENT (0x82) 1661 | + 1662 | +struct mpt3_cmd 1663 | +{ 1664 | + struct work_struct work_entry; // work_entry used by init->workq for cmds 1665 | + 1666 | + struct mpt3_init *init; 1667 | + struct list_head listh; // ioc->cmd_list 1668 | + struct scst_cmd *scst_cmd; 1669 | + 1670 | + dma_addr_t dma_handle; 1671 | + 1672 | + scst_data_direction sg_dir; 1673 | + struct scatterlist *sg; 1674 | + int sg_cnt; 1675 | + int mapped_sg_cnt; 1676 | + int dma_size; 1677 | + 1678 | + // MPT specific bits 1679 | + u16 IoIndex; 1680 | + u8 SequenceNumber; 1681 | + Mpi2TargetErrorReply_t* assist_mpi_reply; 1682 | + Mpi2TargetErrorReply_t* status_mpi_reply; 1683 | + 1684 | + // ANSI SCSI T10 specified bits 1685 | + u16 InitiatorConnectionTag; 1686 | + u8 FrameType; 1687 | + u16 SSPFlags; 1688 | + u16 TargetPortTransferTag; 1689 | + u16 QueueTag; 1690 | + u32 DataOffset; 1691 | + U8 LogicalUnitNumber[8]; /* 0x18 */ 1692 | + u8 TaskManagementFunction; 1693 | + u8 TaskAttribute; 1694 | + u16 ManagedTaskTag; 1695 | + U8 CDB[16]; /* 0x24 */ 1696 | +}; 1697 | + 1698 | +#define MPT3SCST_INIT_STATE_NEW (0) 1699 | +#define MPT3SCST_INIT_STATE_READY (1) 1700 | +#define MPT3SCST_INIT_STATE_EXITING (-2) 1701 | + 1702 | +struct mpt3_init 1703 | +{ 1704 | + struct scst_session *scst_sess; 1705 | + struct mpt3_ioc *ioc; 1706 | + atomic_t state; 1707 | + 1708 | + struct list_head listh; // handle for ioc->init_list 1709 | + struct work_struct work_entry; // work_entry used by ioc->workq add/remove 1710 | + 1711 | + u16 InitiatorDevHandle; 1712 | + u64 SASAddress; 1713 | + char name[32]; 1714 | + unsigned long sess_flags; 1715 | + 1716 | + struct workqueue_struct *workq; // work queue for cmd_list 1717 | +}; 1718 | + 1719 | +#define MPT3SCST_IOC_STATE_NEW (0) 1720 | +#define MPT3SCST_IOC_STATE_READY (1) 1721 | +#define MPT3SCST_IOC_STATE_RESET (-1) 1722 | +#define MPT3SCST_IOC_STATE_EXITING (-2) 1723 | + 1724 | +struct mpt3_ioc 1725 | +{ 1726 | + u8 iocidx; 1727 | + atomic_t state; 1728 | + 1729 | + u8 max_sg_ents; 1730 | + struct scst_tgt *scst_tgt; 1731 | + 1732 | + spinlock_t lock; 1733 | + struct list_head init_list; 1734 | + struct list_head cmd_list; 1735 | + struct list_head delayed_cmds; // where to put commands before init is READY 1736 | + struct workqueue_struct *workq; // work queue for init_list 1737 | +}; 1738 | + 1739 | +typedef struct mpt3scst_dd 1740 | +{ 1741 | + struct mpt3stm_ports portmap; 1742 | +} mpt3scst_dd_t; 1743 | + 1744 | + 1745 | +#endif 1746 | Index: scst/src/Makefile 1747 | =================================================================== 1748 | --- scst/src/Makefile (revision 6459) 1749 | +++ scst/src/Makefile (working copy) 1750 | @@ -37,7 +37,6 @@ 1751 | 1752 | ifneq ($(PATCHLEVEL),) 1753 | SCST_INC_DIR := $(SUBDIRS)/../include 1754 | - 1755 | obj-m := scst.o 1756 | 1757 | scst-y += scst_main.o 1758 | @@ -55,18 +54,23 @@ 1759 | 1760 | else 1761 | ######### BEGIN OUT-OF-TREE RULES ######### 1762 | - 1763 | ifeq ($(KVER),) 1764 | ifeq ($(KDIR),) 1765 | KVER := $(shell uname -r) 1766 | KDIR := /lib/modules/$(KVER)/build 1767 | else 1768 | - KVER := $(strip $(shell \ 1769 | - cat $(KDIR)/include/config/kernel.release 2>/dev/null || \ 1770 | - make -s -C $(KDIR) kernelversion)) 1771 | + ifeq ($(KERNELRELEASE),) 1772 | + KVER := $(strip $(shell \ 1773 | + cat $(KDIR)/include/config/kernel.release 2>/dev/null || \ 1774 | + make -s -C $(KDIR) kernelversion)) 1775 | + else 1776 | + KVER := $(KERNELRELEASE) 1777 | + endif 1778 | endif 1779 | else 1780 | - KDIR := /lib/modules/$(KVER)/build 1781 | + ifeq ($(KDIR),) 1782 | + KDIR := /lib/modules/$(KVER)/build 1783 | + endif 1784 | endif 1785 | 1786 | ifeq ($(INSTALL_MOD_PATH),) 1787 | @@ -97,8 +101,11 @@ 1788 | 1789 | # The file Modules.symvers has been renamed in the 2.6.18 kernel to 1790 | # Module.symvers. Find out which name to use by looking in $(KDIR). 1791 | -MODULE_SYMVERS:=$(shell if [ -e $(KDIR)/Module.symvers ]; then \ 1792 | - echo Module.symvers; else echo Modules.symvers; fi) 1793 | +#MODULE_SYMVERS:=$(shell if [ -e $(KDIR)/Module.symvers ]; then \ 1794 | +# echo Module.symvers; else echo Modules.symvers; fi) 1795 | +# TV- Yocto builds in a different directory than KDIR, so we just go ahead and 1796 | +# set the value 1797 | +MODULE_SYMVERS:=Module.symvers 1798 | 1799 | install: all 1800 | @if [ -z "$(DESTDIR)" ] && \ 1801 | @@ -106,10 +113,9 @@ 1802 | echo Error: the scst and/or scst-devel RPMs must be uninstalled first; \ 1803 | false; fi 1804 | -rm -f $(INSTALL_DIR)/scsi_tgt.ko 1805 | - install -d $(INSTALL_DIR) 1806 | - install -d $(INSTALL_DIR)/dev_handlers 1807 | - install -m 644 dev_handlers/*.ko $(INSTALL_DIR)/dev_handlers 1808 | - install -m 644 scst.ko $(INSTALL_DIR) 1809 | + $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd) BUILD_INI=m \ 1810 | + $$([ -n "$(DESTDIR)$(INSTALL_MOD_PATH)" ] && echo DEPMOD=true) \ 1811 | + modules_install 1812 | install -d $(INSTALL_DIR_H) 1813 | install -m 644 ../include/scst.h $(INSTALL_DIR_H) 1814 | install -m 644 ../include/scst_sgv.h $(INSTALL_DIR_H) 1815 | --------------------------------------------------------------------------------