aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-07-03 01:56:22 -0400
committerDan Williams <dan.j.williams@intel.com>2011-07-03 01:56:22 -0400
commit6f231dda68080759f1aed3769896e94c73099f0f (patch)
tree45b6ce02fa40e0e9c35526ac6c45950138387516
parent59c5f46fbe01a00eedf54a23789634438bb80603 (diff)
isci: Intel(R) C600 Series Chipset Storage Control Unit Driver
Support for the up to 2x4-port 6Gb/s SAS controllers embedded in the chipset. This is a snapshot of the first publicly available version of the driver, commit 4c1db2d0 in the 'historical' branch. git://git.kernel.org/pub/scm/linux/kernel/git/djbw/isci.git historical Signed-off-by: Maciej Trela <maciej.trela@intel.com> Signed-off-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: Edmund Nadolski <edmund.nadolski@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/scsi/Kconfig34
-rw-r--r--drivers/scsi/Makefile1
-rw-r--r--drivers/scsi/isci/Makefile30
-rw-r--r--drivers/scsi/isci/core/intel_ata.h554
-rw-r--r--drivers/scsi/isci/core/intel_sas.h948
-rw-r--r--drivers/scsi/isci/core/intel_sat.h95
-rw-r--r--drivers/scsi/isci/core/intel_sata.h280
-rw-r--r--drivers/scsi/isci/core/intel_scsi.h474
-rw-r--r--drivers/scsi/isci/core/sati_device.h156
-rw-r--r--drivers/scsi/isci/core/sati_translator_sequence.h304
-rw-r--r--drivers/scsi/isci/core/sati_types.h145
-rw-r--r--drivers/scsi/isci/core/sci_base_controller.h306
-rw-r--r--drivers/scsi/isci/core/sci_base_memory_descriptor_list.c159
-rw-r--r--drivers/scsi/isci/core/sci_base_memory_descriptor_list.h155
-rw-r--r--drivers/scsi/isci/core/sci_base_phy.h205
-rw-r--r--drivers/scsi/isci/core/sci_base_port.h203
-rw-r--r--drivers/scsi/isci/core/sci_base_remote_device.h277
-rw-r--r--drivers/scsi/isci/core/sci_base_request.h195
-rw-r--r--drivers/scsi/isci/core/sci_base_state.h90
-rw-r--r--drivers/scsi/isci/core/sci_base_state_machine.c182
-rw-r--r--drivers/scsi/isci/core/sci_base_state_machine.h139
-rw-r--r--drivers/scsi/isci/core/sci_controller.h100
-rw-r--r--drivers/scsi/isci/core/sci_controller_constants.h215
-rw-r--r--drivers/scsi/isci/core/sci_memory_descriptor_list.h169
-rw-r--r--drivers/scsi/isci/core/sci_object.h99
-rw-r--r--drivers/scsi/isci/core/sci_pool.h199
-rw-r--r--drivers/scsi/isci/core/sci_status.h409
-rw-r--r--drivers/scsi/isci/core/sci_types.h88
-rw-r--r--drivers/scsi/isci/core/sci_util.c70
-rw-r--r--drivers/scsi/isci/core/sci_util.h138
-rw-r--r--drivers/scsi/isci/core/scic_config_parameters.h347
-rw-r--r--drivers/scsi/isci/core/scic_controller.h586
-rw-r--r--drivers/scsi/isci/core/scic_io_request.h512
-rw-r--r--drivers/scsi/isci/core/scic_phy.h303
-rw-r--r--drivers/scsi/isci/core/scic_port.h213
-rw-r--r--drivers/scsi/isci/core/scic_remote_device.h295
-rw-r--r--drivers/scsi/isci/core/scic_sds_controller.c4147
-rw-r--r--drivers/scsi/isci/core/scic_sds_controller.h706
-rw-r--r--drivers/scsi/isci/core/scic_sds_controller_registers.h463
-rw-r--r--drivers/scsi/isci/core/scic_sds_pci.h95
-rw-r--r--drivers/scsi/isci/core/scic_sds_phy.c2807
-rw-r--r--drivers/scsi/isci/core/scic_sds_phy.h491
-rw-r--r--drivers/scsi/isci/core/scic_sds_phy_registers.h187
-rw-r--r--drivers/scsi/isci/core/scic_sds_port.c2757
-rw-r--r--drivers/scsi/isci/core/scic_sds_port.h514
-rw-r--r--drivers/scsi/isci/core/scic_sds_port_configuration_agent.c851
-rw-r--r--drivers/scsi/isci/core/scic_sds_port_configuration_agent.h108
-rw-r--r--drivers/scsi/isci/core/scic_sds_port_registers.h223
-rw-r--r--drivers/scsi/isci/core/scic_sds_remote_device.c2252
-rw-r--r--drivers/scsi/isci/core/scic_sds_remote_device.h602
-rw-r--r--drivers/scsi/isci/core/scic_sds_remote_node_context.c1244
-rw-r--r--drivers/scsi/isci/core/scic_sds_remote_node_context.h342
-rw-r--r--drivers/scsi/isci/core/scic_sds_remote_node_table.c600
-rw-r--r--drivers/scsi/isci/core/scic_sds_remote_node_table.h196
-rw-r--r--drivers/scsi/isci/core/scic_sds_request.c2179
-rw-r--r--drivers/scsi/isci/core/scic_sds_request.h484
-rw-r--r--drivers/scsi/isci/core/scic_sds_smp_remote_device.c410
-rw-r--r--drivers/scsi/isci/core/scic_sds_smp_request.c669
-rw-r--r--drivers/scsi/isci/core/scic_sds_smp_request.h70
-rw-r--r--drivers/scsi/isci/core/scic_sds_ssp_request.c340
-rw-r--r--drivers/scsi/isci/core/scic_sds_stp_packet_request.c838
-rw-r--r--drivers/scsi/isci/core/scic_sds_stp_packet_request.h154
-rw-r--r--drivers/scsi/isci/core/scic_sds_stp_pio_request.h116
-rw-r--r--drivers/scsi/isci/core/scic_sds_stp_remote_device.c975
-rw-r--r--drivers/scsi/isci/core/scic_sds_stp_request.c2004
-rw-r--r--drivers/scsi/isci/core/scic_sds_stp_request.h221
-rw-r--r--drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.c379
-rw-r--r--drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.h286
-rw-r--r--drivers/scsi/isci/core/scic_task_request.h148
-rw-r--r--drivers/scsi/isci/core/scic_user_callback.h740
-rw-r--r--drivers/scsi/isci/core/scu_completion_codes.h280
-rw-r--r--drivers/scsi/isci/core/scu_constants.h151
-rw-r--r--drivers/scsi/isci/core/scu_event_codes.h336
-rw-r--r--drivers/scsi/isci/core/scu_registers.h1824
-rw-r--r--drivers/scsi/isci/core/scu_remote_node_context.h230
-rw-r--r--drivers/scsi/isci/core/scu_task_context.h943
-rw-r--r--drivers/scsi/isci/core/scu_unsolicited_frame.h117
-rw-r--r--drivers/scsi/isci/core/scu_viit_data.h179
-rw-r--r--drivers/scsi/isci/deprecated.c491
-rw-r--r--drivers/scsi/isci/events.c619
-rw-r--r--drivers/scsi/isci/firmware/Makefile19
-rw-r--r--drivers/scsi/isci/firmware/README36
-rw-r--r--drivers/scsi/isci/firmware/create_fw.c177
-rw-r--r--drivers/scsi/isci/host.c781
-rw-r--r--drivers/scsi/isci/host.h283
-rw-r--r--drivers/scsi/isci/init.c613
-rw-r--r--drivers/scsi/isci/isci.h138
-rw-r--r--drivers/scsi/isci/phy.c179
-rw-r--r--drivers/scsi/isci/phy.h104
-rw-r--r--drivers/scsi/isci/port.c484
-rw-r--r--drivers/scsi/isci/port.h153
-rw-r--r--drivers/scsi/isci/remote_device.c698
-rw-r--r--drivers/scsi/isci/remote_device.h154
-rw-r--r--drivers/scsi/isci/request.c1472
-rw-r--r--drivers/scsi/isci/request.h429
-rw-r--r--drivers/scsi/isci/sata.c356
-rw-r--r--drivers/scsi/isci/sata.h83
-rw-r--r--drivers/scsi/isci/sci_environment.h112
-rw-r--r--drivers/scsi/isci/task.c1691
-rw-r--r--drivers/scsi/isci/task.h368
-rw-r--r--drivers/scsi/isci/timers.c319
-rw-r--r--drivers/scsi/isci/timers.h126
-rw-r--r--firmware/Makefile1
-rw-r--r--firmware/isci/isci_firmware.bin.ihex11
104 files changed, 51230 insertions, 0 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 4a1f029c4fe9..3aa664fa892e 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -830,6 +830,40 @@ config SCSI_GDTH
830 To compile this driver as a module, choose M here: the 830 To compile this driver as a module, choose M here: the
831 module will be called gdth. 831 module will be called gdth.
832 832
833config SCSI_ISCI
834 tristate "Intel(R) C600 Series Chipset SAS Controller"
835 depends on PCI && SCSI
836 # little endian host assumptions
837 depends on X86
838 # (temporary): dma api misuse
839 depends on !DMAR
840 # (temporary): known alpha quality driver
841 depends on EXPERIMENTAL
842 select SCSI_SAS_LIBSAS
843 ---help---
844 This driver supports the 6Gb/s SAS capabilities of the storage
845 control unit found in the Intel(R) C600 series chipset.
846
847 The experimental tag will be removed after the driver exits alpha
848
849choice
850 prompt "Default Silicon Revision"
851 depends on SCSI_ISCI
852 default PBG_HBA_A2
853 # temporary A-step silicon is pre-production
854
855config PBG_HBA_BETA
856 bool "B0"
857
858config PBG_HBA_A2
859 bool "A2"
860
861config PBG_HBA_A0
862 bool "A0"
863
864endchoice
865
866
833config SCSI_GENERIC_NCR5380 867config SCSI_GENERIC_NCR5380
834 tristate "Generic NCR5380/53c400 SCSI PIO support" 868 tristate "Generic NCR5380/53c400 SCSI PIO support"
835 depends on ISA && SCSI 869 depends on ISA && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 7ad0b8a79ae8..3c08f5352b2d 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -73,6 +73,7 @@ obj-$(CONFIG_SCSI_AACRAID) += aacraid/
73obj-$(CONFIG_SCSI_AIC7XXX_OLD) += aic7xxx_old.o 73obj-$(CONFIG_SCSI_AIC7XXX_OLD) += aic7xxx_old.o
74obj-$(CONFIG_SCSI_AIC94XX) += aic94xx/ 74obj-$(CONFIG_SCSI_AIC94XX) += aic94xx/
75obj-$(CONFIG_SCSI_PM8001) += pm8001/ 75obj-$(CONFIG_SCSI_PM8001) += pm8001/
76obj-$(CONFIG_SCSI_ISCI) += isci/
76obj-$(CONFIG_SCSI_IPS) += ips.o 77obj-$(CONFIG_SCSI_IPS) += ips.o
77obj-$(CONFIG_SCSI_FD_MCS) += fd_mcs.o 78obj-$(CONFIG_SCSI_FD_MCS) += fd_mcs.o
78obj-$(CONFIG_SCSI_FUTURE_DOMAIN)+= fdomain.o 79obj-$(CONFIG_SCSI_FUTURE_DOMAIN)+= fdomain.o
diff --git a/drivers/scsi/isci/Makefile b/drivers/scsi/isci/Makefile
new file mode 100644
index 000000000000..34f7af3525f4
--- /dev/null
+++ b/drivers/scsi/isci/Makefile
@@ -0,0 +1,30 @@
1#TODO kill SCIC_SDS_4_ENABLED it is always true for this
2#generation of silicon
3EXTRA_CFLAGS += -DSCIC_SDS_4_ENABLED
4
5#temporary until atapi support ready
6EXTRA_CFLAGS += -DDISABLE_ATAPI
7
8EXTRA_CFLAGS += -Idrivers/scsi/isci/core/ -Idrivers/scsi/isci/
9obj-$(CONFIG_SCSI_ISCI) += isci.o
10isci-objs := init.o phy.o request.o sata.o \
11 remote_device.o port.o timers.o deprecated.o \
12 host.o task.o events.o \
13 core/scic_sds_controller.o \
14 core/scic_sds_remote_device.o \
15 core/scic_sds_request.o \
16 core/scic_sds_stp_request.o \
17 core/scic_sds_stp_packet_request.o \
18 core/scic_sds_stp_remote_device.o \
19 core/scic_sds_port.o \
20 core/scic_sds_port_configuration_agent.o \
21 core/scic_sds_phy.o \
22 core/scic_sds_ssp_request.o \
23 core/scic_sds_remote_node_context.o \
24 core/scic_sds_smp_request.o \
25 core/scic_sds_smp_remote_device.o \
26 core/scic_sds_remote_node_table.o \
27 core/scic_sds_unsolicited_frame_control.o \
28 core/sci_base_memory_descriptor_list.o \
29 core/sci_base_state_machine.o \
30 core/sci_util.o
diff --git a/drivers/scsi/isci/core/intel_ata.h b/drivers/scsi/isci/core/intel_ata.h
new file mode 100644
index 000000000000..48b297e50bd0
--- /dev/null
+++ b/drivers/scsi/isci/core/intel_ata.h
@@ -0,0 +1,554 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file defines all of the ATA related constants, enumerations, and types.
58 * Please note that this file does not necessarily contain an exhaustive
59 * list of all constants, commands, sub-commands, etc.
60 *
61 *
62 */
63
64#ifndef _ATA_H_
65#define _ATA_H_
66
67#include <linux/types.h>
68
69/**
70 *
71 *
72 * ATA_COMMAND_CODES These constants depict the various ATA command codes
73 * defined in the ATA/ATAPI specification.
74 */
75#define ATA_IDENTIFY_DEVICE 0xEC
76#define ATA_CHECK_POWER_MODE 0xE5
77#define ATA_STANDBY 0xE2
78#define ATA_STANDBY_IMMED 0xE0
79#define ATA_IDLE_IMMED 0xE1
80#define ATA_IDLE 0xE3
81#define ATA_FLUSH_CACHE 0xE7
82#define ATA_FLUSH_CACHE_EXT 0xEA
83#define ATA_READ_DMA_EXT 0x25
84#define ATA_READ_DMA 0xC8
85#define ATA_READ_SECTORS_EXT 0x24
86#define ATA_READ_SECTORS 0x20
87#define ATA_WRITE_DMA_EXT 0x35
88#define ATA_WRITE_DMA 0xCA
89#define ATA_WRITE_SECTORS_EXT 0x34
90#define ATA_WRITE_SECTORS 0x30
91#define ATA_WRITE_UNCORRECTABLE 0x45
92#define ATA_READ_VERIFY_SECTORS 0x40
93#define ATA_READ_VERIFY_SECTORS_EXT 0x42
94#define ATA_READ_BUFFER 0xE4
95#define ATA_WRITE_BUFFER 0xE8
96#define ATA_EXECUTE_DEVICE_DIAG 0x90
97#define ATA_SET_FEATURES 0xEF
98#define ATA_SMART 0xB0
99#define ATA_PACKET_IDENTIFY 0xA1
100#define ATA_PACKET 0xA0
101#define ATA_READ_FPDMA 0x60
102#define ATA_WRITE_FPDMA 0x61
103#define ATA_READ_LOG_EXT 0x2F
104#define ATA_NOP 0x00
105#define ATA_DEVICE_RESET 0x08
106#define ATA_MEDIA_EJECT 0xED
107
108/**
109 *
110 *
111 * ATA_SMART_SUB_COMMAND_CODES These constants define the ATA SMART command
112 * sub-codes that can be executed.
113 */
114#define ATA_SMART_SUB_CMD_ENABLE 0xD8
115#define ATA_SMART_SUB_CMD_DISABLE 0xD9
116#define ATA_SMART_SUB_CMD_RETURN_STATUS 0xDA
117#define ATA_SMART_SUB_CMD_READ_LOG 0xD5
118
119/**
120 *
121 *
122 * ATA_SET_FEATURES_SUB_COMMAND_CODES These constants define the ATA SET
123 * FEATURES command sub-codes that can be executed.
124 */
125#define ATA_SET_FEATURES_SUB_CMD_ENABLE_CACHE 0x02
126#define ATA_SET_FEATURES_SUB_CMD_DISABLE_CACHE 0x82
127#define ATA_SET_FEATURES_SUB_CMD_DISABLE_READ_AHEAD 0x55
128#define ATA_SET_FEATURES_SUB_CMD_ENABLE_READ_AHEAD 0xAA
129#define ATA_SET_FEATURES_SUB_CMD_SET_TRANSFER_MODE 0x3
130
131/**
132 *
133 *
134 * ATA_READ_LOG_EXT_PAGE_CODES This is a list of log page codes available for
135 * use.
136 */
137#define ATA_LOG_PAGE_NCQ_ERROR 0x10
138#define ATA_LOG_PAGE_SMART_SELF_TEST 0x06
139#define ATA_LOG_PAGE_EXTENDED_SMART_SELF_TEST 0x07
140
141/**
142 *
143 *
144 * ATA_LOG_PAGE_NCQ_ERROR_CONSTANTS These constants define standard values for
145 * use when requesting the NCQ error log page.
146 */
147#define ATA_LOG_PAGE_NCQ_ERROR_SECTOR 0
148#define ATA_LOG_PAGE_NCQ_ERROR_SECTOR_COUNT 1
149
150/**
151 *
152 *
153 * ATA_STATUS_REGISTER_BITS The following are status register bit definitions
154 * per ATA/ATAPI-7.
155 */
156#define ATA_STATUS_REG_BSY_BIT 0x80
157#define ATA_STATUS_REG_DEVICE_FAULT_BIT 0x20
158#define ATA_STATUS_REG_ERROR_BIT 0x01
159
160/**
161 *
162 *
163 * ATA_ERROR_REGISTER_BITS The following are error register bit definitions per
164 * ATA/ATAPI-7.
165 */
166#define ATA_ERROR_REG_NO_MEDIA_BIT 0x02
167#define ATA_ERROR_REG_ABORT_BIT 0x04
168#define ATA_ERROR_REG_MEDIA_CHANGE_REQUEST_BIT 0x08
169#define ATA_ERROR_REG_ID_NOT_FOUND_BIT 0x10
170#define ATA_ERROR_REG_MEDIA_CHANGE_BIT 0x20
171#define ATA_ERROR_REG_UNCORRECTABLE_BIT 0x40
172#define ATA_ERROR_REG_WRITE_PROTECTED_BIT 0x40
173#define ATA_ERROR_REG_ICRC_BIT 0x80
174
175/**
176 *
177 *
178 * ATA_CONTROL_REGISTER_BITS The following are control register bit definitions
179 * per ATA/ATAPI-7
180 */
181#define ATA_CONTROL_REG_INTERRUPT_ENABLE_BIT 0x02
182#define ATA_CONTROL_REG_SOFT_RESET_BIT 0x04
183#define ATA_CONTROL_REG_HIGH_ORDER_BYTE_BIT 0x80
184
185/**
186 *
187 *
188 * ATA_DEVICE_HEAD_REGISTER_BITS The following are device/head register bit
189 * definitions per ATA/ATAPI-7.
190 */
191#define ATA_DEV_HEAD_REG_LBA_MODE_ENABLE 0x40
192#define ATA_DEV_HEAD_REG_FUA_ENABLE 0x80
193
194/**
195 *
196 *
197 * ATA_IDENTIFY_DEVICE_FIELD_LENGTHS The following constants define the number
198 * of bytes contained in various fields found in the IDENTIFY DEVICE data
199 * structure.
200 */
201#define ATA_IDENTIFY_SERIAL_NUMBER_LEN 20
202#define ATA_IDENTIFY_MODEL_NUMBER_LEN 40
203#define ATA_IDENTIFY_FW_REVISION_LEN 8
204#define ATA_IDENTIFY_48_LBA_LEN 8
205#define ATA_IDENTIFY_MEDIA_SERIAL_NUMBER_LEN 30
206#define ATA_IDENTIFY_WWN_LEN 8
207
208/**
209 *
210 *
211 * ATA_IDENTIFY_DEVICE_FIELD_MASKS The following constants define bit masks
212 * utilized to determine if a feature is supported/enabled or if a bit is
213 * simply set inside of the IDENTIFY DEVICE data structre.
214 */
215#define ATA_IDENTIFY_REMOVABLE_MEDIA_ENABLE 0x0080
216#define ATA_IDENTIFY_CAPABILITIES1_NORMAL_DMA_ENABLE 0x0100
217#define ATA_IDENTIFY_CAPABILITIES1_STANDBY_ENABLE 0x2000
218#define ATA_IDENTIFY_COMMAND_SET_SUPPORTED0_SMART_ENABLE 0x0001
219#define ATA_IDENTIFY_COMMAND_SET_SUPPORTED1_48BIT_ENABLE 0x0400
220#define ATA_IDENTIFY_COMMAND_SET_WWN_SUPPORT_ENABLE 0x0100
221#define ATA_IDENTIFY_COMMAND_SET_ENABLED0_SMART_ENABLE 0x0001
222#define ATA_IDENTIFY_SATA_CAPABILITIES_NCQ_ENABLE 0x0100
223#define ATA_IDENTIFY_NCQ_QUEUE_DEPTH_ENABLE 0x001F
224#define ATA_IDENTIFY_SECTOR_LARGER_THEN_512_ENABLE 0x0100
225#define ATA_IDENTIFY_LOGICAL_SECTOR_PER_PHYSICAL_SECTOR_MASK 0x000F
226#define ATA_IDENTIFY_LOGICAL_SECTOR_PER_PHYSICAL_SECTOR_ENABLE 0x2000
227#define ATA_IDENTIFY_WRITE_UNCORRECTABLE_SUPPORT 0x0004
228#define ATA_IDENTIFY_COMMAND_SET_SMART_SELF_TEST_SUPPORTED 0x0002
229
230/**
231 *
232 *
233 * ATAPI_IDENTIFY_DEVICE_FIELD_MASKS These constants define the various bit
234 * definitions for the fields in the PACKET IDENTIFY DEVICE data structure.
235 */
236#define ATAPI_IDENTIFY_16BYTE_CMD_PCKT_ENABLE 0x01
237
238/**
239 *
240 *
241 * ATA_PACKET_FEATURE_BITS These constants define the various bit definitions
242 * for the ATA PACKET feature register.
243 */
244#define ATA_PACKET_FEATURE_DMA 0x01
245#define ATA_PACKET_FEATURE_OVL 0x02
246#define ATA_PACKET_FEATURE_DMADIR 0x04
247
248/**
249 *
250 *
251 * ATA_Device_Power_Mode_Values These constants define the power mode values
252 * returned by ATA_Check_Power_Mode
253 */
254#define ATA_STANDBY_POWER_MODE 0x00
255#define ATA_IDLE_POWER_MODE 0x80
256#define ATA_ACTIVE_POWER_MODE 0xFF
257
258/**
259 *
260 *
261 * ATA_WRITE_UNCORRECTIABLE feature field values These constants define the
262 * Write Uncorrectable feature values used with the SATI translation.
263 */
264#define ATA_WRITE_UNCORRECTABLE_PSUEDO 0x55
265#define ATA_WRITE_UNCORRECTABLE_FLAGGED 0xAA
266
267
268
269/**
270 * struct ATA_IDENTIFY_DEVICE - This structure depicts the ATA IDENTIFY DEVICE
271 * data format.
272 *
273 *
274 */
275struct ata_identify_device_data {
276 u16 general_config_bits; /* word 00 */
277 u16 obsolete0; /* word 01 (num cylinders) */
278 u16 vendor_specific_config_bits; /* word 02 */
279 u16 obsolete1; /* word 03 (num heads) */
280 u16 retired1[2]; /* words 04-05 */
281 u16 obsolete2; /* word 06 (sectors / track) */
282 u16 reserved_for_compact_flash1[2]; /* words 07-08 */
283 u16 retired0; /* word 09 */
284 u8 serial_number[ATA_IDENTIFY_SERIAL_NUMBER_LEN]; /* word 10-19 */
285 u16 retired2[2]; /* words 20-21 */
286 u16 obsolete4; /* word 22 */
287 u8 firmware_revision[ATA_IDENTIFY_FW_REVISION_LEN]; /* words 23-26 */
288 u8 model_number[ATA_IDENTIFY_MODEL_NUMBER_LEN]; /* words 27-46 */
289 u16 max_sectors_per_multiple; /* word 47 */
290 u16 reserved0; /* word 48 */
291 u16 capabilities1; /* word 49 */
292 u16 capabilities2; /* word 50 */
293 u16 obsolete5[2]; /* words 51-52 */
294 u16 validity_bits; /* word 53 */
295 u16 obsolete6[5]; /*
296 * words 54-58 Used to be:
297 * current cylinders,
298 * current heads,
299 * current sectors/Track,
300 * current capacity */
301 u16 current_max_sectors_per_multiple; /* word 59 */
302 u8 total_num_sectors[4]; /* words 60-61 */
303 u16 obsolete7; /* word 62 */
304 u16 multi_word_dma_mode; /* word 63 */
305 u16 pio_modes_supported; /* word 64 */
306 u16 min_multiword_dma_transfer_cycle; /* word 65 */
307 u16 rec_min_multiword_dma_transfer_cycle; /* word 66 */
308 u16 min_pio_transfer_no_flow_ctrl; /* word 67 */
309 u16 min_pio_transfer_with_flow_ctrl; /* word 68 */
310 u16 reserved1[2]; /* words 69-70 */
311 u16 reserved2[4]; /* words 71-74 */
312 u16 queue_depth; /* word 75 */
313 u16 serial_ata_capabilities; /* word 76 */
314 u16 serial_ata_reserved; /* word 77 */
315 u16 serial_ata_features_supported; /* word 78 */
316 u16 serial_ata_features_enabled; /* word 79 */
317 u16 major_version_number; /* word 80 */
318 u16 minor_version_number; /* word 81 */
319 u16 command_set_supported0; /* word 82 */
320 u16 command_set_supported1; /* word 83 */
321 u16 command_set_supported_extention; /* word 84 */
322 u16 command_set_enabled0; /* word 85 */
323 u16 command_set_enabled1; /* word 86 */
324 u16 command_set_default; /* word 87 */
325 u16 ultra_dma_mode; /* word 88 */
326 u16 security_erase_completion_time; /* word 89 */
327 u16 enhanced_security_erase_time; /* word 90 */
328 u16 current_power_mgmt_value; /* word 91 */
329 u16 master_password_revision; /* word 92 */
330 u16 hardware_reset_result; /* word 93 */
331 u16 current_acoustic_management_value; /* word 94 */
332 u16 stream_min_request_size; /* word 95 */
333 u16 stream_transfer_time; /* word 96 */
334 u16 stream_access_latency; /* word 97 */
335 u16 stream_performance_granularity[2]; /* words 98-99 */
336 u8 max_48bit_lba[ATA_IDENTIFY_48_LBA_LEN]; /* words 100-103 */
337 u16 streaming_transfer_time; /* word 104 */
338 u16 reserved3; /* word 105 */
339 u16 physical_logical_sector_info; /* word 106 */
340 u16 acoustic_test_interseek_delay; /* word 107 */
341 u8 world_wide_name[ATA_IDENTIFY_WWN_LEN]; /* words 108-111 */
342 u8 reserved_for_wwn_extention[ATA_IDENTIFY_WWN_LEN]; /* words 112-115 */
343 u16 reserved4; /* word 116 */
344 u8 words_per_logical_sector[4]; /* words 117-118 */
345 u16 command_set_supported2; /* word 119 */
346 u16 reserved5[7]; /* words 120-126 */
347 u16 removable_media_status; /* word 127 */
348 u16 security_status; /* word 128 */
349 u16 vendor_specific1[31]; /* words 129-159 */
350 u16 cfa_power_mode1; /* word 160 */
351 u16 reserved_for_compact_flash2[7]; /* words 161-167 */
352 u16 device_nominal_form_factor; /* word 168 */
353 u16 reserved_for_compact_flash3[7]; /* words 169-175 */
354 u16 current_media_serial_number[ATA_IDENTIFY_MEDIA_SERIAL_NUMBER_LEN]; /* words 176-205 */
355 u16 reserved6[3]; /* words 206-208 */
356 u16 logical_sector_alignment; /* words 209 */
357 u16 reserved7[7]; /* words 210-216 */
358 u16 nominal_media_rotation_rate; /* word 217 */
359 u16 reserved8[37]; /* words 218-254 */
360 u16 integrity_word; /* word 255 */
361
362};
363
364#define ATA_IDENTIFY_DEVICE_GET_OFFSET(field_name) \
365 ((unsigned long)&(((struct ata_identify_device_data *)0)->field_name))
366#define ATA_IDENTIFY_DEVICE_WCE_ENABLE 0x20
367#define ATA_IDENTIFY_DEVICE_RA_ENABLE 0x40
368
369/**
370 * struct ATAPI_IDENTIFY_PACKET_DATA - The following structure depicts the
371 * ATA-ATAPI 7 version of the IDENTIFY PACKET DEVICE data structure.
372 *
373 *
374 */
375struct atapi_identify_packet_device {
376 u16 generalConfigBits; /* word 00 */
377 u16 reserved0; /* word 01 (num cylinders) */
378 u16 uniqueConfigBits; /* word 02 */
379 u16 reserved1[7]; /* words 03 - 09 */
380 u8 serialNumber[ATA_IDENTIFY_SERIAL_NUMBER_LEN]; /* word 10-19 */
381 u16 reserved2[3]; /* words 20-22 */
382 u8 firmwareRevision[ATA_IDENTIFY_FW_REVISION_LEN]; /* words 23-26 */
383 u8 modelNumber[ATA_IDENTIFY_MODEL_NUMBER_LEN]; /* words 27-46 */
384 u16 reserved4[2]; /* words 47-48 */
385 u16 capabilities1; /* word 49 */
386 u16 capabilities2; /* word 50 */
387 u16 obsolete0[2]; /* words 51-52 */
388 u16 validityBits; /* word 53 */
389 u16 reserved[8]; /* words 54-61 */
390
391 u16 DMADIRBitRequired; /* word 62, page2 */
392 u16 multiWordDmaMode; /* word 63 */
393 u16 pioModesSupported; /* word 64 */
394 u16 minMultiwordDmaTransferCycle; /* word 65 */
395 u16 recMinMultiwordDmaTransferCycle; /* word 66 */
396 u16 minPioTransferNoFlowCtrl; /* word 67 */
397 u16 minPioTransferWithFlowCtrl; /* word 68 */
398 u16 reserved6[2]; /* words 69-70 */
399 u16 nsFromPACKETReceiptToBusRelease; /* word 71 */
400 u16 nsFromSERVICEReceiptToBSYreset; /* wore 72 */
401 u16 reserved7[2]; /* words 73-74 */
402 u16 queueDepth; /* word 75 */
403 u16 serialAtaCapabilities; /* word 76 */
404 u16 serialAtaReserved; /* word 77 */
405 u16 serialAtaFeaturesSupported; /* word 78 */
406 u16 serialAtaFeaturesEnabled; /* word 79 */
407
408 u16 majorVersionNumber; /* word 80, page3 */
409 u16 minorVersionNumber; /* word 81 */
410 u16 commandSetSupported0; /* word 82 */
411 u16 commandSetSupported1; /* word 83 */
412
413 u16 commandSetSupportedExtention; /* word 84, page4 */
414 u16 commandSetEnabled0; /* word 85 */
415 u16 commandSetEnabled1; /* word 86 */
416 u16 commandSetDefault; /* word 87 */
417
418 u16 ultraDmaMode; /* word 88, page5 */
419 u16 reserved8[4]; /* words 89 - 92 */
420
421 u16 hardwareResetResult; /* word 93, page6 */
422 u16 currentAcousticManagementValue; /* word 94 */
423 u16 reserved9[30]; /* words 95-124 */
424 u16 ATAPIByteCount0Behavior; /* word 125 */
425 u16 obsolete1; /* word 126 */
426 u16 removableMediaStatus; /* word 127, */
427
428 u16 securityStatus; /* word 128, page7 */
429 u16 vendorSpecific1[31]; /* words 129-159 */
430 u16 reservedForCompactFlash[16]; /* words 160-175 */
431 u16 reserved10[79]; /* words 176-254 */
432 u16 integrityWord; /* word 255 */
433};
434
435/**
436 * struct ata_extended_smart_self_test_log - The following structure depicts
437 * the ATA-8 version of the Extended SMART self test log page descriptor
438 * entry.
439 *
440 *
441 */
442union ata_descriptor_entry {
443 struct DESCRIPTOR_ENTRY {
444 u8 lba_field;
445 u8 status_byte;
446 u8 time_stamp_low;
447 u8 time_stamp_high;
448 u8 checkpoint_byte;
449 u8 failing_lba_low;
450 u8 failing_lba_mid;
451 u8 failing_lba_high;
452 u8 failing_lba_low_ext;
453 u8 failing_lba_mid_ext;
454 u8 failing_lba_high_ext;
455
456 u8 vendor_specific1;
457 u8 vendor_specific2;
458 u8 vendor_specific3;
459 u8 vendor_specific4;
460 u8 vendor_specific5;
461 u8 vendor_specific6;
462 u8 vendor_specific7;
463 u8 vendor_specific8;
464 u8 vendor_specific9;
465 u8 vendor_specific10;
466 u8 vendor_specific11;
467 u8 vendor_specific12;
468 u8 vendor_specific13;
469 u8 vendor_specific14;
470 u8 vendor_specific15;
471 } DESCRIPTOR_ENTRY;
472
473 u8 descriptor_entry[26];
474
475};
476
477/**
478 * struct ata_extended_smart_self_test_log - The following structure depicts
479 * the ATA-8 version of the SMART self test log page descriptor entry.
480 *
481 *
482 */
483union ata_smart_descriptor_entry {
484 struct SMART_DESCRIPTOR_ENTRY {
485 u8 lba_field;
486 u8 status_byte;
487 u8 time_stamp_low;
488 u8 time_stamp_high;
489 u8 checkpoint_byte;
490 u8 failing_lba_low;
491 u8 failing_lba_mid;
492 u8 failing_lba_high;
493 u8 failing_lba_low_ext;
494
495 u8 vendor_specific1;
496 u8 vendor_specific2;
497 u8 vendor_specific3;
498 u8 vendor_specific4;
499 u8 vendor_specific5;
500 u8 vendor_specific6;
501 u8 vendor_specific7;
502 u8 vendor_specific8;
503 u8 vendor_specific9;
504 u8 vendor_specific10;
505 u8 vendor_specific11;
506 u8 vendor_specific12;
507 u8 vendor_specific13;
508 u8 vendor_specific14;
509 u8 vendor_specific15;
510 } SMART_DESCRIPTOR_ENTRY;
511
512 u8 smart_descriptor_entry[24];
513
514};
515
516/**
517 * struct ata_extended_smart_self_test_log - The following structure depicts
518 * the ATA-8 version of the Extended SMART self test log page.
519 *
520 *
521 */
522struct ata_extended_smart_self_test_log {
523 u8 self_test_log_data_structure_revision_number; /* byte 0 */
524 u8 reserved0; /* byte 1 */
525 u8 self_test_descriptor_index[2]; /* byte 2-3 */
526
527 union ata_descriptor_entry descriptor_entrys[19]; /* bytes 4-497 */
528
529 u8 vendor_specific[2]; /* byte 498-499 */
530 u8 reserved1[11]; /* byte 500-510 */
531 u8 data_structure_checksum; /* byte 511 */
532
533};
534
535/**
536 * struct ata_extended_smart_self_test_log - The following structure depicts
537 * the ATA-8 version of the SMART self test log page.
538 *
539 *
540 */
541struct ata_smart_self_test_log {
542 u8 self_test_log_data_structure_revision_number[2]; /* bytes 0-1 */
543
544 union ata_smart_descriptor_entry descriptor_entrys[21]; /* bytes 2-505 */
545
546 u8 vendor_specific[2]; /* byte 506-507 */
547 u8 self_test_index; /* byte 508 */
548 u8 reserved1[2]; /* byte 509-510 */
549 u8 data_structure_checksum; /* byte 511 */
550
551};
552
553#endif /* _ATA_H_ */
554
diff --git a/drivers/scsi/isci/core/intel_sas.h b/drivers/scsi/isci/core/intel_sas.h
new file mode 100644
index 000000000000..eb9686ea35f1
--- /dev/null
+++ b/drivers/scsi/isci/core/intel_sas.h
@@ -0,0 +1,948 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _INTEL_SAS_H_
57#define _INTEL_SAS_H_
58
59/**
60 * This file contains all of the definitions relating to structures, constants,
61 * etc. defined by the SAS specification.
62 *
63 *
64 */
65
66#include "intel_sata.h"
67#include "intel_scsi.h"
68
69/**
70 * struct sci_sas_address - This structure depicts how a SAS address is
71 * represented by SCI.
72 *
73 *
74 */
75struct sci_sas_address {
76 /**
77 * This member contains the higher 32-bits of the SAS address.
78 */
79 u32 high;
80
81 /**
82 * This member contains the lower 32-bits of the SAS address.
83 */
84 u32 low;
85
86};
87
88/**
89 * struct sci_sas_identify_address_frame_protocols - This structure depicts the
90 * contents of bytes 2 and 3 in the SAS IDENTIFY ADDRESS FRAME (IAF).
91 *
92 * For specific information on each of these individual fields please reference
93 * the SAS specification Link layer section on address frames.
94 */
95struct sci_sas_identify_address_frame_protocols {
96 union {
97 struct {
98 u16 restricted1:1;
99 u16 smp_initiator:1;
100 u16 stp_initiator:1;
101 u16 ssp_initiator:1;
102 u16 reserved3:4;
103 u16 restricted2:1;
104 u16 smp_target:1;
105 u16 stp_target:1;
106 u16 ssp_target:1;
107 u16 reserved4:4;
108 } bits;
109
110 u16 all;
111 } u;
112
113};
114
115/**
116 * struct sci_sas_identify_address_frame - This structure depicts the contents
117 * of the SAS IDENTIFY ADDRESS FRAME (IAF).
118 *
119 * For specific information on each of these individual fields please reference
120 * the SAS specification Link layer section on address frames.
121 */
122struct sci_sas_identify_address_frame {
123 u16 address_frame_type:4;
124 u16 device_type:3;
125 u16 reserved1:1;
126 u16 reason:4;
127 u16 reserved2:4;
128
129 struct sci_sas_identify_address_frame_protocols protocols;
130
131 struct sci_sas_address device_name;
132 struct sci_sas_address sas_address;
133
134 u32 phy_identifier:8;
135 u32 break_reply_capable:1;
136 u32 requested_in_zpsds:1;
137 u32 in_zpsds_persistent:1;
138 u32 reserved5:21;
139
140 u32 reserved6[4];
141
142};
143
144/**
145 * struct sas_capabilities - This structure depicts the various SAS
146 * capabilities supported by the directly attached target device. For
147 * specific information on each of these individual fields please reference
148 * the SAS specification Phy layer section on speed negotiation windows.
149 *
150 *
151 */
152struct sas_capabilities {
153 union {
154#if defined (SCIC_SDS_4_ENABLED)
155 struct {
156 /**
157 * The SAS specification indicates the start bit shall always be set to
158 * 1. This implementation will have the start bit set to 0 if the
159 * PHY CAPABILITIES were either not received or speed negotiation failed.
160 */
161 u32 start:1;
162 u32 tx_ssc_type:1;
163 u32 reserved1:2;
164 u32 requested_logical_link_rate:4;
165
166 u32 gen1_without_ssc_supported:1;
167 u32 gen1_with_ssc_supported:1;
168 u32 gen2_without_ssc_supported:1;
169 u32 gen2_with_ssc_supported:1;
170 u32 gen3_without_ssc_supported:1;
171 u32 gen3_with_ssc_supported:1;
172 u32 reserved2:17;
173 u32 parity:1;
174 } bits;
175#endif /* (SCIC_SDS_4_ENABLED) */
176
177 u32 all;
178 } u;
179
180};
181
182/**
183 * enum _SCI_SAS_LINK_RATE - This enumeration depicts the SAS specification
184 * defined link speeds.
185 *
186 *
187 */
188enum sci_sas_link_rate {
189 SCI_SAS_NO_LINK_RATE = 0,
190 SCI_SATA_SPINUP_HOLD = 0x3,
191 SCI_SAS_150_GB = 0x8,
192 SCI_SAS_300_GB = 0x9,
193 SCI_SAS_600_GB = 0xA
194};
195
196/**
197 * enum _SCI_SAS_TASK_ATTRIBUTE - This enumeration depicts the SAM/SAS
198 * specification defined task attribute values for a command information
199 * unit.
200 *
201 *
202 */
203enum sci_sas_task_attribute {
204 SCI_SAS_SIMPLE_ATTRIBUTE = 0,
205 SCI_SAS_HEAD_OF_QUEUE_ATTRIBUTE = 1,
206 SCI_SAS_ORDERED_ATTRIBUTE = 2,
207 SCI_SAS_ACA_ATTRIBUTE = 4,
208};
209
210/**
211 * enum _SCI_SAS_TASK_MGMT_FUNCTION - This enumeration depicts the SAM/SAS
212 * specification defined task management functions.
213 *
214 * This HARD_RESET function listed here is not actually defined as a task
215 * management function in the industry standard.
216 */
217enum sci_sas_task_mgmt_function {
218 SCI_SAS_ABORT_TASK = SCSI_TASK_REQUEST_ABORT_TASK,
219 SCI_SAS_ABORT_TASK_SET = SCSI_TASK_REQUEST_ABORT_TASK_SET,
220 SCI_SAS_CLEAR_TASK_SET = SCSI_TASK_REQUEST_CLEAR_TASK_SET,
221 SCI_SAS_LOGICAL_UNIT_RESET = SCSI_TASK_REQUEST_LOGICAL_UNIT_RESET,
222 SCI_SAS_I_T_NEXUS_RESET = SCSI_TASK_REQUEST_I_T_NEXUS_RESET,
223 SCI_SAS_CLEAR_ACA = SCSI_TASK_REQUEST_CLEAR_ACA,
224 SCI_SAS_QUERY_TASK = SCSI_TASK_REQUEST_QUERY_TASK,
225 SCI_SAS_QUERY_TASK_SET = SCSI_TASK_REQUEST_QUERY_TASK_SET,
226 SCI_SAS_QUERY_ASYNCHRONOUS_EVENT = SCSI_TASK_REQUEST_QUERY_UNIT_ATTENTION,
227 SCI_SAS_HARD_RESET = 0xFF
228};
229
230
231/**
232 * enum _SCI_SAS_FRAME_TYPE - This enumeration depicts the SAS specification
233 * defined SSP frame types.
234 *
235 *
236 */
237enum sci_sas_frame_type {
238 SCI_SAS_DATA_FRAME = 0x01,
239 SCI_SAS_XFER_RDY_FRAME = 0x05,
240 SCI_SAS_COMMAND_FRAME = 0x06,
241 SCI_SAS_RESPONSE_FRAME = 0x07,
242 SCI_SAS_TASK_FRAME = 0x16
243};
244
245/**
246 * struct sci_ssp_command_iu - This structure depicts the contents of the SSP
247 * COMMAND INFORMATION UNIT. For specific information on each of these
248 * individual fields please reference the SAS specification SSP transport
249 * layer section.
250 *
251 *
252 */
253struct sci_ssp_command_iu {
254 u32 lun_upper;
255 u32 lun_lower;
256
257 u32 additional_cdb_length:6;
258 u32 reserved0:2;
259 u32 reserved1:8;
260 u32 enable_first_burst:1;
261 u32 task_priority:4;
262 u32 task_attribute:3;
263 u32 reserved2:8;
264
265 u32 cdb[4];
266
267};
268
269/**
270 * struct sci_ssp_task_iu - This structure depicts the contents of the SSP TASK
271 * INFORMATION UNIT. For specific information on each of these individual
272 * fields please reference the SAS specification SSP transport layer section.
273 *
274 *
275 */
276struct sci_ssp_task_iu {
277 u32 lun_upper;
278 u32 lun_lower;
279
280 u32 reserved0:8;
281 u32 task_function:8;
282 u32 reserved1:8;
283 u32 reserved2:8;
284
285 u32 reserved3:16;
286 u32 task_tag:16;
287
288 u32 reserved4[3];
289
290};
291
292#define SSP_RESPONSE_IU_MAX_DATA 64
293
294#define SCI_SSP_RESPONSE_IU_DATA_PRESENT_MASK (0x03)
295
296
297#define sci_ssp_get_sense_data_length(sense_data_length_buffer) \
298 SCIC_BUILD_DWORD(sense_data_length_buffer)
299
300#define sci_ssp_get_response_data_length(response_data_length_buffer) \
301 SCIC_BUILD_DWORD(response_data_length_buffer)
302
303/**
304 * struct sci_ssp_response_iu - This structure depicts the contents of the SSP
305 * RESPONSE INFORMATION UNIT. For specific information on each of these
306 * individual fields please reference the SAS specification SSP transport
307 * layer section.
308 *
309 *
310 */
311struct sci_ssp_response_iu {
312 u8 reserved0[8];
313
314 u8 retry_delay_timer[2];
315 u8 data_present;
316 u8 status;
317
318 u8 reserved1[4];
319 u8 sense_data_length[4];
320 u8 response_data_length[4];
321
322 u32 data[SSP_RESPONSE_IU_MAX_DATA];
323
324};
325
326/**
327 * enum _SCI_SAS_DATA_PRESENT_TYPE - This enumeration depicts the SAS
328 * specification defined SSP data present types in struct sci_ssp_response_iu.
329 *
330 *
331 */
332enum sci_ssp_response_iu_data_present_type {
333 SCI_SSP_RESPONSE_IU_NO_DATA = 0x00,
334 SCI_SSP_RESPONSE_IU_RESPONSE_DATA = 0x01,
335 SCI_SSP_RESPONSE_IU_SENSE_DATA = 0x02
336};
337
338/**
339 * struct sci_ssp_frame_header - This structure depicts the contents of an SSP
340 * frame header. For specific information on the individual fields please
341 * reference the SAS specification transport layer SSP frame format.
342 *
343 *
344 */
345struct sci_ssp_frame_header {
346 /* Word 0 */
347 u32 hashed_destination_address:24;
348 u32 frame_type:8;
349
350 /* Word 1 */
351 u32 hashed_source_address:24;
352 u32 reserved1_0:8;
353
354 /* Word 2 */
355 u32 reserved2_2:6;
356 u32 fill_bytes:2;
357 u32 reserved2_1:3;
358 u32 tlr_control:2;
359 u32 retry_data_frames:1;
360 u32 retransmit:1;
361 u32 changing_data_pointer:1;
362 u32 reserved2_0:16;
363
364 /* Word 3 */
365 u32 uiResv4;
366
367 /* Word 4 */
368 u16 target_port_transfer_tag;
369 u16 tag;
370
371 /* Word 5 */
372 u32 data_offset;
373
374};
375
376/**
377 * struct smp_request_header - This structure defines the contents of an SMP
378 * Request header.
379 *
380 * For specific information on each of these individual fields please reference
381 * the SAS specification.
382 */
383struct smp_request_header {
384 u8 smp_frame_type; /* byte 0 */
385 u8 function; /* byte 1 */
386 u8 allocated_response_length; /* byte 2 */
387 u8 request_length; /* byte 3 */
388};
389
390/**
391 * struct smp_response_header - This structure depicts the contents of the SAS
392 * SMP DISCOVER RESPONSE frame. For specific information on each of these
393 * individual fields please reference the SAS specification Link layer
394 * section on address frames.
395 *
396 *
397 */
398struct smp_response_header {
399 u8 smp_frame_type; /* byte 0 */
400 u8 function; /* byte 1 */
401 u8 function_result; /* byte 2 */
402 u8 response_length; /* byte 3 */
403};
404
405/**
406 * struct smp_request_general - This structure defines the contents of an SMP
407 * Request that is comprised of the struct smp_request_header and a CRC.
408 *
409 * For specific information on each of these individual fields please reference
410 * the SAS specification.
411 */
412struct smp_request_general {
413 u32 crc; /* bytes 4-7 */
414
415};
416
417/**
418 * struct smp_request_phy_identifier - This structure defines the contents of
419 * an SMP Request that is comprised of the struct smp_request_header and a phy
420 * identifier. Examples: SMP_REQUEST_DISCOVER, SMP_REQUEST_REPORT_PHY_SATA.
421 *
422 * For specific information on each of these individual fields please reference
423 * the SAS specification.
424 */
425struct smp_request_phy_identifier {
426 u32 reserved_byte4_7; /* bytes 4-7 */
427
428 u32 ignore_zone_group:1; /* byte 8 */
429 u32 reserved_byte8:7;
430
431 u32 phy_identifier:8; /* byte 9 */
432 u32 reserved_byte10:8; /* byte 10 */
433 u32 reserved_byte11:8; /* byte 11 */
434
435};
436
437/**
438 * struct smp_request_configure_route_information - This structure defines the
439 * contents of an SMP Configure Route Information request.
440 *
441 * For specific information on each of these individual fields please reference
442 * the SAS specification.
443 */
444struct smp_request_configure_route_information {
445 u32 expected_expander_change_count:16; /* bytes 4-5 */
446 u32 expander_route_index_high:8;
447 u32 expander_route_index:8; /* bytes 6-7 */
448
449 u32 reserved_byte8:8; /* bytes 8 */
450 u32 phy_identifier:8; /* bytes 9 */
451 u32 reserved_byte_10_11:16; /* bytes 10-11 */
452
453 u32 reserved_byte_12_bit_0_6:7;
454 u32 disable_route_entry:1; /* byte 12 */
455 u32 reserved_byte_13_15:24; /* bytes 13-15 */
456
457 u32 routed_sas_address[2]; /* bytes 16-23 */
458 u8 reserved_byte_24_39[16]; /* bytes 24-39 */
459
460};
461
462/**
463 * struct smp_request_phy_control - This structure defines the contents of an
464 * SMP Phy Controler request.
465 *
466 * For specific information on each of these individual fields please reference
467 * the SAS specification.
468 */
469struct smp_request_phy_control {
470 u16 expected_expander_change_count; /* byte 4-5 */
471
472 u16 reserved_byte_6_7; /* byte 6-7 */
473 u8 reserved_byte_8; /* byte 8 */
474
475 u8 phy_identifier; /* byte 9 */
476 u8 phy_operation; /* byte 10 */
477
478 u8 update_partial_pathway_timeout_value:1;
479 u8 reserved_byte_11_bit_1_7:7; /* byte 11 */
480
481 u8 reserved_byte_12_23[12]; /* byte 12-23 */
482
483 u8 attached_device_name[8]; /* byte 24-31 */
484
485 u8 reserved_byte_32_bit_3_0:4; /* byte 32 */
486 u8 programmed_minimum_physical_link_rate:4;
487
488 u8 reserved_byte_33_bit_3_0:4; /* byte 33 */
489 u8 programmed_maximum_physical_link_rate:4;
490
491 u16 reserved_byte_34_35; /* byte 34-35 */
492
493 u8 partial_pathway_timeout_value:4;
494 u8 reserved_byte_36_bit_4_7:4; /* byte 36 */
495
496 u16 reserved_byte_37_38; /* byte 37-38 */
497 u8 reserved_byte_39; /* byte 39 */
498
499};
500
501/**
502 * struct smp_request_vendor_specific - This structure depicts the vendor
503 * specific space for SMP request.
504 *
505 *
506 */
507 #define SMP_REQUEST_VENDOR_SPECIFIC_MAX_LENGTH 1016
508struct smp_request_vendor_specific {
509 u8 request_bytes[SMP_REQUEST_VENDOR_SPECIFIC_MAX_LENGTH];
510};
511
512/**
513 * struct smp_request - This structure simply unionizes the existing request
514 * structures into a common request type.
515 *
516 *
517 */
518struct smp_request {
519 struct smp_request_header header;
520
521 union { /* bytes 4-N */
522 struct smp_request_general report_general;
523 struct smp_request_phy_identifier discover;
524 struct smp_request_general report_manufacturer_information;
525 struct smp_request_phy_identifier report_phy_sata;
526 struct smp_request_phy_control phy_control;
527 struct smp_request_phy_identifier report_phy_error_log;
528 struct smp_request_phy_identifier report_route_information;
529 struct smp_request_configure_route_information configure_route_information;
530 struct smp_request_vendor_specific vendor_specific_request;
531 } request;
532
533};
534
535
536/**
537 * struct smp_response_report_general - This structure depicts the SMP Report
538 * General for expander devices. It adheres to the SAS-2.1 specification.
539 *
540 * For specific information on each of these individual fields please reference
541 * the SAS specification Application layer section on SMP.
542 */
543struct smp_response_report_general {
544 u16 expander_change_count; /* byte 4-5 */
545 u16 expander_route_indexes; /* byte 6-7 */
546
547 u32 reserved_byte8:7; /* byte 8 bit 0-6 */
548 u32 long_response:1; /* byte 8 bit 7 */
549
550 u32 number_of_phys:8; /* byte 9 */
551
552 u32 configurable_route_table:1; /* byte 10 */
553 u32 configuring:1;
554 u32 configures_others:1;
555 u32 open_reject_retry_supported:1;
556 u32 stp_continue_awt:1;
557 u32 self_configuring:1;
558 u32 zone_configuring:1;
559 u32 table_to_table_supported:1;
560
561 u32 reserved_byte11:8; /* byte 11 */
562
563 u32 enclosure_logical_identifier_high; /* byte 12-15 */
564 u32 enclosure_logical_identifier_low; /* byte 16-19 */
565
566 u32 reserved_byte20_23;
567 u32 reserved_byte24_27;
568
569};
570
571struct smp_response_report_general_long {
572 struct smp_response_report_general sas1_1;
573
574 struct {
575 u16 reserved1;
576 u16 stp_bus_inactivity_time_limit;
577 u16 stp_max_connect_time_limit;
578 u16 stp_smp_i_t_nexus_loss_time;
579
580 u32 zoning_enabled:1;
581 u32 zoning_supported:1;
582 u32 physicaL_presence_asserted:1;
583 u32 zone_locked:1;
584 u32 reserved2:1;
585 u32 num_zone_groups:3;
586 u32 saving_zoning_enabled_supported:3;
587 u32 saving_zone_perms_table_supported:1;
588 u32 saving_zone_phy_info_supported:1;
589 u32 saving_zone_manager_password_supported:1;
590 u32 saving:1;
591 u32 reserved3:1;
592 u32 max_number_routed_sas_addresses:16;
593
594 struct sci_sas_address active_zone_manager_sas_address;
595
596 u16 zone_lock_inactivity_time_limit;
597 u16 reserved4;
598
599 u8 reserved5;
600 u8 first_enclosure_connector_element_index;
601 u8 number_of_enclosure_connector_element_indices;
602 u8 reserved6;
603
604 u32 reserved7:7;
605 u32 reduced_functionality:1;
606 u32 time_to_reduce_functionality:8;
607 u32 initial_time_to_reduce_functionality:8;
608 u8 max_reduced_functionality_time;
609
610 u16 last_self_config_status_descriptor_index;
611 u16 max_number_of_stored_self_config_status_descriptors;
612
613 u16 last_phy_event_list_descriptor_index;
614 u16 max_number_of_stored_phy_event_list_descriptors;
615 } sas2;
616
617};
618
619/**
620 * struct smp_response_report_manufacturer_information - This structure depicts
621 * the SMP report manufacturer information for expander devices. It adheres
622 * to the SAS-2.1 specification.
623 *
624 * For specific information on each of these individual fields please reference
625 * the SAS specification Application layer section on SMP.
626 */
627struct smp_response_report_manufacturer_information {
628 u32 expander_change_count:16; /* bytes 4-5 */
629 u32 reserved1:16;
630
631 u32 sas1_1_format:1;
632 u32 reserved2:31;
633
634 u8 vendor_id[8];
635 u8 product_id[16];
636 u8 product_revision_level[4];
637 u8 component_vendor_id[8];
638 u8 component_id[2];
639 u8 component_revision_level;
640 u8 reserved3;
641 u8 vendor_specific[8];
642
643};
644
645#define SMP_RESPONSE_DISCOVER_FORMAT_1_1_SIZE 52
646#define SMP_RESPONSE_DISCOVER_FORMAT_2_SIZE 116
647
648/**
649 * struct smp_discover_response_protocols - This structure depicts the discover
650 * response where the supported protocols by the remote phy are specified.
651 *
652 * For specific information on each of these individual fields please reference
653 * the SAS specification Link layer section on address frames.
654 */
655struct smp_discover_response_protocols {
656 union {
657 struct {
658 u16 attached_sata_host:1;
659 u16 attached_smp_initiator:1;
660 u16 attached_stp_initiator:1;
661 u16 attached_ssp_initiator:1;
662 u16 reserved3:4;
663 u16 attached_sata_device:1;
664 u16 attached_smp_target:1;
665 u16 attached_stp_target:1;
666 u16 attached_ssp_target:1;
667 u16 reserved4:3;
668 u16 attached_sata_port_selector:1;
669 } bits;
670
671 u16 all;
672 } u;
673
674};
675
676/**
677 * struct SMP_RESPONSE_DISCOVER_FORMAT - This structure defines the SMP phy
678 * discover response format. It handles both SAS1.1 and SAS 2 definitions.
679 * The unions indicate locations where the SAS specification versions differ
680 * from one another.
681 *
682 *
683 */
684struct smp_response_discover {
685
686 union {
687 struct {
688 u8 reserved[2];
689 } sas1_1;
690
691 struct {
692 u16 expander_change_count;
693 } sas2;
694
695 } u1;
696
697 u8 reserved1[3];
698 u8 phy_identifier;
699 u8 reserved2[2];
700
701 union {
702 struct {
703 u16 reserved1:4;
704 u16 attached_device_type:3;
705 u16 reserved2:1;
706 u16 negotiated_physical_link_rate:4;
707 u16 reserved3:4;
708 } sas1_1;
709
710 struct {
711 u16 attached_reason:4;
712 u16 attached_device_type:3;
713 u16 reserved2:1;
714 u16 negotiated_logical_link_rate:4;
715 u16 reserved3:4;
716 } sas2;
717
718 } u2;
719
720 struct smp_discover_response_protocols protocols;
721 struct sci_sas_address sas_address;
722 struct sci_sas_address attached_sas_address;
723
724 u8 attached_phy_identifier;
725
726 union {
727 struct {
728 u8 reserved;
729 } sas1_1;
730
731 struct {
732 u8 attached_break_reply_capable:1;
733 u8 attached_requested_inside_zpsds:1;
734 u8 attached_inside_zpsds_persistent:1;
735 u8 reserved1:5;
736 } sas2;
737
738 } u3;
739
740 u8 reserved_for_identify[6];
741
742 u32 hardware_min_physical_link_rate:4;
743 u32 programmed_min_physical_link_rate:4;
744 u32 hardware_max_physical_link_rate:4;
745 u32 programmed_max_physical_link_rate:4;
746 u32 phy_change_count:8;
747 u32 partial_pathway_timeout_value:4;
748 u32 reserved5:3;
749 u32 virtual_phy:1;
750
751 u32 routing_attribute:4;
752 u32 reserved6:4;
753 u32 connector_type:7;
754 u32 reserved7:1;
755 u32 connector_element_index:8;
756 u32 connector_physical_link:8;
757
758 u16 reserved8;
759 u16 vendor_specific;
760
761 union {
762 struct {
763 /**
764 * In the SAS 1.1 specification this structure ends after 52 bytes.
765 * As a result, the contents of this field should never have a
766 * real value. It is undefined.
767 */
768 u8 undefined[SMP_RESPONSE_DISCOVER_FORMAT_2_SIZE
769 - SMP_RESPONSE_DISCOVER_FORMAT_1_1_SIZE];
770 } sas1_1;
771
772 struct {
773 struct sci_sas_address attached_device_name;
774
775 u32 zoning_enabled:1;
776 u32 inside_zpsds:1;
777 u32 zone_group_persistent:1;
778 u32 reserved1:1;
779 u32 requested_inside_zpsds:1;
780 u32 inside_zpsds_persistent:1;
781 u32 requested_inside_zpsds_changed_by_expander:1;
782 u32 reserved2:1;
783 u32 reserved_for_zoning_fields:16;
784 u32 zone_group:8;
785
786 u8 self_configuration_status;
787 u8 self_configuration_levels_completed;
788 u16 reserved_for_self_config_fields;
789
790 struct sci_sas_address self_configuration_sas_address;
791
792 u32 programmed_phy_capabilities;
793 u32 current_phy_capabilities;
794 u32 attached_phy_capabilities;
795
796 u32 reserved3;
797
798 u32 reserved4:16;
799 u32 negotiated_physical_link_rate:4;
800 u32 reason:4;
801 u32 hardware_muxing_supported:1;
802 u32 negotiated_ssc:1;
803 u32 reserved5:6;
804
805 u32 default_zoning_enabled:1;
806 u32 reserved6:1;
807 u32 default_zone_group_persistent:1;
808 u32 reserved7:1;
809 u32 default_requested_inside_zpsds:1;
810 u32 default_inside_zpsds_persistent:1;
811 u32 reserved8:2;
812 u32 reserved9:16;
813 u32 default_zone_group:8;
814
815 u32 saved_zoning_enabled:1;
816 u32 reserved10:1;
817 u32 saved_zone_group_persistent:1;
818 u32 reserved11:1;
819 u32 saved_requested_inside_zpsds:1;
820 u32 saved_inside_zpsds_persistent:1;
821 u32 reserved12:18;
822 u32 saved_zone_group:8;
823
824 u32 reserved14:2;
825 u32 shadow_zone_group_persistent:1;
826 u32 reserved15:1;
827 u32 shadow_requested_inside_zpsds:1;
828 u32 shadow_inside_zpsds_persistent:1;
829 u32 reserved16:18;
830 u32 shadow_zone_group:8;
831
832 u8 device_slot_number;
833 u8 device_slot_group_number;
834 u8 device_slot_group_output_connector[6];
835 } sas2;
836
837 } u4;
838
839};
840
841/**
842 * struct smp_response_report_phy_sata - This structure depicts the contents of
843 * the SAS SMP REPORT PHY SATA frame. For specific information on each of
844 * these individual fields please reference the SAS specification Link layer
845 * section on address frames.
846 *
847 *
848 */
849struct smp_response_report_phy_sata {
850 u32 ignored_byte_4_7; /* bytes 4-7 */
851
852 u32 affiliations_valid:1;
853 u32 affiliations_supported:1;
854 u32 reserved_byte11:6; /* byte 11 */
855 u32 ignored_byte10:8; /* byte 10 */
856 u32 phy_identifier:8; /* byte 9 */
857 u32 reserved_byte_8:8; /* byte 8 */
858
859 u32 reserved_12_15;
860 u32 stp_sas_address[2];
861 u8 device_to_host_fis[20];
862 u32 reserved_44_47;
863 u32 affiliated_stp_initiator_sas_address[2];
864
865};
866
867struct smp_response_vendor_specific {
868 u8 response_bytes[SMP_REQUEST_VENDOR_SPECIFIC_MAX_LENGTH];
869};
870
871union smp_response_body {
872 struct smp_response_report_general report_general;
873 struct smp_response_report_manufacturer_information report_manufacturer_information;
874 struct smp_response_discover discover;
875 struct smp_response_report_phy_sata report_phy_sata;
876 struct smp_response_vendor_specific vendor_specific_response;
877};
878
879/**
880 * struct smp_response - This structure simply unionizes the existing response
881 * structures into a common response type.
882 *
883 *
884 */
885struct smp_response {
886 struct smp_response_header header;
887
888 union smp_response_body response;
889
890};
891
892/* SMP Request Functions */
893#define SMP_FUNCTION_REPORT_GENERAL 0x00
894#define SMP_FUNCTION_REPORT_MANUFACTURER_INFORMATION 0x01
895#define SMP_FUNCTION_DISCOVER 0x10
896#define SMP_FUNCTION_REPORT_PHY_ERROR_LOG 0x11
897#define SMP_FUNCTION_REPORT_PHY_SATA 0x12
898#define SMP_FUNCTION_REPORT_ROUTE_INFORMATION 0X13
899#define SMP_FUNCTION_CONFIGURE_ROUTE_INFORMATION 0X90
900#define SMP_FUNCTION_PHY_CONTROL 0x91
901#define SMP_FUNCTION_PHY_TEST 0x92
902
903#define SMP_FRAME_TYPE_REQUEST 0x40
904#define SMP_FRAME_TYPE_RESPONSE 0x41
905
906#define PHY_OPERATION_NOP 0x00
907#define PHY_OPERATION_LINK_RESET 0x01
908#define PHY_OPERATION_HARD_RESET 0x02
909#define PHY_OPERATION_DISABLE 0x03
910#define PHY_OPERATION_CLEAR_ERROR_LOG 0x05
911#define PHY_OPERATION_CLEAR_AFFILIATION 0x06
912
913#define NPLR_PHY_ENABLED_UNK_LINK_RATE 0x00
914#define NPLR_PHY_DISABLED 0x01
915#define NPLR_PHY_ENABLED_SPD_NEG_FAILED 0x02
916#define NPLR_PHY_ENABLED_SATA_HOLD 0x03
917#define NPLR_PHY_ENABLED_1_5G 0x08
918#define NPLR_PHY_ENABLED_3_0G 0x09
919
920/* SMP Function Result values. */
921#define SMP_RESULT_FUNCTION_ACCEPTED 0x00
922#define SMP_RESULT_UNKNOWN_FUNCTION 0x01
923#define SMP_RESULT_FUNCTION_FAILED 0x02
924#define SMP_RESULT_INVALID_REQUEST_FRAME_LEN 0x03
925#define SMP_RESULT_INAVALID_EXPANDER_CHANGE_COUNT 0x04
926#define SMP_RESULT_BUSY 0x05
927#define SMP_RESULT_INCOMPLETE_DESCRIPTOR_LIST 0x06
928#define SMP_RESULT_PHY_DOES_NOT_EXIST 0x10
929#define SMP_RESULT_INDEX_DOES_NOT_EXIST 0x11
930#define SMP_RESULT_PHY_DOES_NOT_SUPPORT_SATA 0x12
931#define SMP_RESULT_UNKNOWN_PHY_OPERATION 0x13
932#define SMP_RESULT_UNKNOWN_PHY_TEST_FUNCTION 0x14
933#define SMP_RESULT_PHY_TEST_IN_PROGRESS 0x15
934#define SMP_RESULT_PHY_VACANT 0x16
935
936/* Attached Device Types */
937#define SMP_NO_DEVICE_ATTACHED 0
938#define SMP_END_DEVICE_ONLY 1
939#define SMP_EDGE_EXPANDER_DEVICE 2
940#define SMP_FANOUT_EXPANDER_DEVICE 3
941
942/* Expander phy routine attribute */
943#define DIRECT_ROUTING_ATTRIBUTE 0
944#define SUBTRACTIVE_ROUTING_ATTRIBUTE 1
945#define TABLE_ROUTING_ATTRIBUTE 2
946
947#endif /* _INTEL_SAS_H_ */
948
diff --git a/drivers/scsi/isci/core/intel_sat.h b/drivers/scsi/isci/core/intel_sat.h
new file mode 100644
index 000000000000..c4d78ed35cf1
--- /dev/null
+++ b/drivers/scsi/isci/core/intel_sat.h
@@ -0,0 +1,95 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SAT_H_
57#define _SAT_H_
58
59/**
60 * This file contains constants and constructs defined in the SCSI to ATA
61 * Translation (SAT) T10 standard. For more information please refer to
62 * www.t10.org.
63 *
64 *
65 */
66
67/**
68 *
69 *
70 * SAT_PROTOCOLS These constants indicate the various protocol values that can
71 * be supported in a SAT translator.
72 */
73#define SAT_PROTOCOL_ATA_HARD_RESET 0
74#define SAT_PROTOCOL_SOFT_RESET 1
75#define SAT_PROTOCOL_NON_DATA 3
76#define SAT_PROTOCOL_PIO_DATA_IN 4
77#define SAT_PROTOCOL_PIO_DATA_OUT 5
78#define SAT_PROTOCOL_DMA 6
79#define SAT_PROTOCOL_DMA_QUEUED 7
80#define SAT_PROTOCOL_DEVICE_DIAGNOSTIC 8
81#define SAT_PROTOCOL_DEVICE_RESET 9
82#define SAT_PROTOCOL_UDMA_DATA_IN 10
83#define SAT_PROTOCOL_UDMA_DATA_OUT 11
84#define SAT_PROTOCOL_FPDMA 12
85#define SAT_PROTOCOL_RETURN_RESPONSE_INFO 15
86
87#define SAT_PROTOCOL_PACKET 0x10
88#define SAT_PROTOCOL_PACKET_NON_DATA (SAT_PROTOCOL_PACKET | 0x0)
89#define SAT_PROTOCOL_PACKET_DMA_DATA_IN (SAT_PROTOCOL_PACKET | 0x1)
90#define SAT_PROTOCOL_PACKET_DMA_DATA_OUT (SAT_PROTOCOL_PACKET | 0x2)
91#define SAT_PROTOCOL_PACKET_PIO_DATA_IN (SAT_PROTOCOL_PACKET | 0x3)
92#define SAT_PROTOCOL_PACKET_PIO_DATA_OUT (SAT_PROTOCOL_PACKET | 0x4)
93
94#endif /* _SAT_H_ */
95
diff --git a/drivers/scsi/isci/core/intel_sata.h b/drivers/scsi/isci/core/intel_sata.h
new file mode 100644
index 000000000000..47390d54064d
--- /dev/null
+++ b/drivers/scsi/isci/core/intel_sata.h
@@ -0,0 +1,280 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SATA_H_
57#define _SATA_H_
58
59#include <linux/types.h>
60
61/**
62 * This file defines all of the SATA releated constants, enumerations, and
63 * types. Please note that this file does not necessarily contain an
64 * exhaustive list of all contants and commands.
65 *
66 *
67 */
68
69/**
70 *
71 *
72 * SATA FIS Types These constants depict the various SATA FIS types devined in
73 * the serial ATA specification.
74 */
75#define SATA_FIS_TYPE_REGH2D 0x27
76#define SATA_FIS_TYPE_REGD2H 0x34
77#define SATA_FIS_TYPE_SETDEVBITS 0xA1
78#define SATA_FIS_TYPE_DMA_ACTIVATE 0x39
79#define SATA_FIS_TYPE_DMA_SETUP 0x41
80#define SATA_FIS_TYPE_BIST_ACTIVATE 0x58
81#define SATA_FIS_TYPE_PIO_SETUP 0x5F
82#define SATA_FIS_TYPE_DATA 0x46
83
84#define SATA_REGISTER_FIS_SIZE 0x20
85
86/**
87 * struct sata_fis_header - This is the common definition for a SATA FIS Header
88 * word. A different header word is defined for any FIS type that does not
89 * use the standard header.
90 *
91 *
92 */
93struct sata_fis_header {
94 u32 fis_type:8; /* word 0 */
95 u32 pm_port:4;
96 u32 reserved:1;
97 u32 direction_flag:1; /* direction */
98 u32 interrupt_flag:1;
99 u32 command_flag:1; /* command, auto_activate, or notification */
100 u32 status:8;
101 u32 error:8;
102};
103
104
105/**
106 * struct sata_fis_reg_h2d - This is the definition for a SATA Host to Device
107 * Register FIS.
108 *
109 *
110 */
111struct sata_fis_reg_h2d {
112 u32 fis_type:8; /* word 0 */
113 u32 pm_port:4;
114 u32 reserved0:3;
115 u32 command_flag:1;
116 u32 command:8;
117 u32 features:8;
118 u32 lba_low:8; /* word 1 */
119 u32 lba_mid:8;
120 u32 lba_high:8;
121 u32 device:8;
122 u32 lba_low_exp:8; /* word 2 */
123 u32 lba_mid_exp:8;
124 u32 lba_high_exp:8;
125 u32 features_exp:8;
126 u32 sector_count:8; /* word 3 */
127 u32 sector_count_exp:8;
128 u32 reserved1:8;
129 u32 control:8;
130 u32 reserved2; /* word 4 */
131};
132
133/**
134 * struct sata_fis_reg_d2h - SATA Device To Host FIS
135 *
136 *
137 */
138struct sata_fis_reg_d2h {
139 u32 fis_type:8; /* word 0 */
140 u32 pm_port:4;
141 u32 reserved0:2;
142 u32 irq:1;
143 u32 reserved1:1;
144 u32 status:8;
145 u32 error:8;
146 u8 lba_low; /* word 1 */
147 u8 lba_mid;
148 u8 lba_high;
149 u8 device;
150 u8 lba_low_exp; /* word 2 */
151 u8 lba_mid_exp;
152 u8 lba_high_exp;
153 u8 reserved;
154 u8 sector_count; /* word 3 */
155 u8 sector_count_exp;
156 u16 reserved2;
157 u32 reserved3;
158};
159
160/**
161 *
162 *
163 * Status field bit definitions
164 */
165#define SATA_FIS_STATUS_DEVBITS_MASK (0x77)
166
167/**
168 * struct sata_fis_set_dev_bits - SATA Set Device Bits FIS
169 *
170 *
171 */
172struct sata_fis_set_dev_bits {
173 u32 fis_type:8; /* word 0 */
174 u32 pm_port:4;
175 u32 reserved0:2;
176 u32 irq:1;
177 u32 notification:1;
178 u32 status_low:4;
179 u32 status_high:4;
180 u32 error:8;
181 u32 s_active; /* word 1 */
182};
183
184/**
185 * struct sata_fis_dma_activate - SATA DMA Activate FIS
186 *
187 *
188 */
189struct sata_fis_dma_activate {
190 u32 fis_type:8; /* word 0 */
191 u32 pm_port:4;
192 u32 reserved0:24;
193};
194
195/**
196 *
197 *
198 * The lower 5 bits in the DMA Buffer ID Low field of the DMA Setup are used to
199 * communicate the command tag.
200 */
201#define SATA_DMA_SETUP_TAG_ENABLE 0x1F
202
203#define SATA_DMA_SETUP_AUTO_ACT_ENABLE 0x80
204
205/**
206 * struct sata_fis_dma_setup - SATA DMA Setup FIS
207 *
208 *
209 */
210struct sata_fis_dma_setup {
211 u32 fis_type:8; /* word 0 */
212 u32 pm_port:4;
213 u32 reserved_00:1;
214 u32 direction:1;
215 u32 irq:1;
216 u32 auto_activate:1;
217 u32 reserved_01:16;
218 u32 dma_buffer_id_low; /* word 1 */
219 u32 dma_buffer_id_high; /* word 2 */
220 u32 reserved0; /* word 3 */
221 u32 dma_buffer_offset; /* word 4 */
222 u32 dma_transfer_count; /* word 5 */
223 u32 reserved1; /* word 6 */
224};
225
226/**
227 * struct sata_fis_bist_activate - SATA BIST Activate FIS
228 *
229 *
230 */
231struct sata_fis_bist_activate {
232 u32 fis_type:8; /* word 0 */
233 u32 reserved0:8;
234 u32 pattern_definition:8;
235 u32 reserved1:8;
236 u32 data1; /* word 1 */
237 u32 data2; /* word 1 */
238};
239
240/*
241 * SATA PIO Setup FIS
242 */
243struct sata_fis_pio_setup {
244 u32 fis_type:8; /* word 0 */
245 u32 pm_port:4;
246 u32 reserved_00:1;
247 u32 direction:1;
248 u32 irq:1;
249 u32 reserved_01:1;
250 u32 status:8;
251 u32 error:8;
252 u32 lba_low:8; /* word 1 */
253 u32 lba_mid:8;
254 u32 lba_high:8;
255 u32 device:8;
256 u32 lba_low_exp:8; /* word 2 */
257 u32 lba_mid_exp:8;
258 u32 lba_high_exp:8;
259 u32 reserved:8;
260 u32 sector_count:8; /* word 3 */
261 u32 sector_count_exp:8;
262 u32 reserved1:8;
263 u32 ending_status:8;
264 u32 transfter_count:16; /* word 4 */
265 u32 reserved3:16;
266};
267
268/**
269 * struct sata_fis_data - SATA Data FIS
270 *
271 *
272 */
273struct sata_fis_data {
274 u32 fis_type:8; /* word 0 */
275 u32 pm_port:4;
276 u32 reserved0:24;
277 u8 data[4]; /* word 1 */
278};
279
280#endif /* _SATA_H_ */
diff --git a/drivers/scsi/isci/core/intel_scsi.h b/drivers/scsi/isci/core/intel_scsi.h
new file mode 100644
index 000000000000..1e45d3c98127
--- /dev/null
+++ b/drivers/scsi/isci/core/intel_scsi.h
@@ -0,0 +1,474 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file defines all of the SCSI related constants, enumerations, and
58 * types. Please note that this file does not necessarily contain an
59 * exhaustive list of all constants, commands, sub-commands, etc.
60 *
61 *
62 */
63
64#ifndef _SCSI_H__
65#define _SCSI_H__
66
67
68/*
69 * ******************************************************************************
70 * * C O N S T A N T S A N D M A C R O S
71 * ****************************************************************************** */
72
73/**
74 * enum _SCSI_TASK_MGMT_REQUEST_CODES - This enumberation contains the
75 * constants to be used for SCSI task management request codes. SAM does
76 * not specify any particular values for these codes so constants used here
77 * are the same as those specified in SAS.
78 *
79 *
80 */
81enum scsi_task_mgmt_request_codes {
82 SCSI_TASK_REQUEST_ABORT_TASK = 0x01,
83 SCSI_TASK_REQUEST_ABORT_TASK_SET = 0x02,
84 SCSI_TASK_REQUEST_CLEAR_TASK_SET = 0x04,
85 SCSI_TASK_REQUEST_LOGICAL_UNIT_RESET = 0x08,
86 SCSI_TASK_REQUEST_I_T_NEXUS_RESET = 0x10,
87 SCSI_TASK_REQUEST_CLEAR_ACA = 0x40,
88 SCSI_TASK_REQUEST_QUERY_TASK = 0x80,
89 SCSI_TASK_REQUEST_QUERY_TASK_SET = 0x81,
90 SCSI_TASK_REQUEST_QUERY_UNIT_ATTENTION = 0x82,
91
92};
93
94/**
95 * enum _SCSI_TASK_MGMT_RESPONSE_CODES - This enumeration contains all of the
96 * SCSI task management response codes.
97 *
98 *
99 */
100enum scsi_task_mgmt_response_codes {
101 SCSI_TASK_MGMT_FUNC_COMPLETE = 0,
102 SCSI_INVALID_FRAME = 2,
103 SCSI_TASK_MGMT_FUNC_NOT_SUPPORTED = 4,
104 SCSI_TASK_MGMT_FUNC_FAILED = 5,
105 SCSI_TASK_MGMT_FUNC_SUCCEEDED = 8,
106 SCSI_INVALID_LUN = 9
107};
108
109/**
110 * enum _SCSI_SENSE_RESPONSE_CODE - this enumeration depicts the types of sense
111 * data responses as per SPC-3.
112 *
113 *
114 */
115enum scsi_sense_response_code {
116 SCSI_FIXED_CURRENT_RESPONSE_CODE = 0x70,
117 SCSI_FIXED_DEFERRED_RESPONSE_CODE = 0x71,
118 SCSI_DESCRIPTOR_CURRENT_RESPONSE_CODE = 0x72,
119 SCSI_DESCRIPTOR_DEFERRED_RESPONSE_CODE = 0x73
120
121};
122
123/*
124 * This constant represents the valid bit located in byte 0 of a FIXED
125 * format sense data. */
126#define SCSI_FIXED_SENSE_DATA_VALID_BIT 0x80
127
128#define SCSI_FIXED_SENSE_DATA_BASE_LENGTH 18
129
130/* This value is used in the DATAPRES field of the SCSI Response IU. */
131#define SCSI_RESPONSE_DATA_PRES_SENSE_DATA 0x02
132
133/**
134 *
135 *
136 * SCSI_SENSE_KEYS These constants delineate all of the SCSI protocol sense key
137 * constants
138 */
139#define SCSI_SENSE_NO_SENSE 0x00
140#define SCSI_SENSE_RECOVERED_ERROR 0x01
141#define SCSI_SENSE_NOT_READY 0x02
142#define SCSI_SENSE_MEDIUM_ERROR 0x03
143#define SCSI_SENSE_HARDWARE_ERROR 0x04
144#define SCSI_SENSE_ILLEGAL_REQUEST 0x05
145#define SCSI_SENSE_UNIT_ATTENTION 0x06
146#define SCSI_SENSE_DATA_PROTECT 0x07
147#define SCSI_SENSE_BLANK_CHECK 0x08
148#define SCSI_SENSE_VENDOR_SPECIFIC 0x09
149#define SCSI_SENSE_COPY_ABORTED 0x0A
150#define SCSI_SENSE_ABORTED_COMMAND 0x0B
151#define SCSI_SENSE_VOLUME_OVERFLOW 0x0D
152#define SCSI_SENSE_MISCOMPARE 0x0E
153
154/**
155 *
156 *
157 * SCSI_ADDITIONAL_SENSE_CODES These constants delineate all of the SCSI
158 * protocol additional sense code constants.
159 */
160#define SCSI_ASC_NO_ADDITIONAL_SENSE 0x00
161#define SCSI_ASC_INITIALIZING_COMMAND_REQUIRED 0x04
162#define SCSI_ASC_LUN_SELF_TEST_IN_PROGRESS 0x04
163#define SCSI_ASC_LUN_FORMAT_IN_PROGRESS 0x04
164#define SCSI_ASC_LUN_NOT_RESPOND_TO_SELECTION 0x05
165#define SCSI_ASC_UNRECOVERED_READ_ERROR 0x11
166#define SCSI_ASC_INVALID_COMMAND_OPERATION_CODE 0x20
167#define SCSI_ASC_LBA_OUT_OF_RANGE 0x21
168#define SCSI_ASC_INVALID_FIELD_IN_CDB 0x24
169#define SCSI_ASC_INVALID_FIELD_IN_PARM_LIST 0x26
170#define SCSI_ASC_WRITE_PROTECTED 0x27
171#define SCSI_ASC_NOT_READY_TO_READY_CHANGE 0x28
172#define SCSI_ASC_SAVING_PARMS_NOT_SUPPORTED 0x39
173#define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3A
174#define SCSI_ASC_INTERNAL_TARGET_FAILURE 0x44
175#define SCSI_ASC_IU_CRC_ERROR_DETECTED 0x47
176#define SCSI_ASC_MEDIUM_REMOVAL_REQUEST 0x5A
177#define SCSI_ASC_COMMAND_SEQUENCE_ERROR 0x2C
178#define SCSI_ASC_MEDIA_LOAD_OR_EJECT_FAILED 0x53
179#define SCSI_ASC_HARDWARE_IMPENDING_FAILURE 0x5D
180#define SCSI_ASC_POWER_STATE_CHANGE 0x5E
181#define SCSI_DIAGNOSTIC_FAILURE_ON_COMPONENT 0x40
182#define SCSI_ASC_ATA_DEVICE_FEATURE_NOT_ENABLED 0x67
183
184/**
185 *
186 *
187 * SCSI_ADDITIONAL_SENSE_CODE_QUALIFIERS This enumeration contains all of the
188 * used SCSI protocol additional sense code qualifier constants.
189 */
190#define SCSI_ASCQ_NO_ADDITIONAL_SENSE 0x00
191#define SCSI_ASCQ_INVALID_FIELD_IN_CDB 0x00
192#define SCSI_ASCQ_INVALID_FIELD_IN_PARM_LIST 0x00
193#define SCSI_ASCQ_LUN_NOT_RESPOND_TO_SELECTION 0x00
194#define SCSI_ASCQ_INTERNAL_TARGET_FAILURE 0x00
195#define SCSI_ASCQ_LBA_OUT_OF_RANGE 0x00
196#define SCSI_ASCQ_MEDIUM_NOT_PRESENT 0x00
197#define SCSI_ASCQ_NOT_READY_TO_READY_CHANGE 0x00
198#define SCSI_ASCQ_WRITE_PROTECTED 0x00
199#define SCSI_ASCQ_UNRECOVERED_READ_ERROR 0x00
200#define SCSI_ASCQ_SAVING_PARMS_NOT_SUPPORTED 0x00
201#define SCSI_ASCQ_INVALID_COMMAND_OPERATION_CODE 0x00
202#define SCSI_ASCQ_MEDIUM_REMOVAL_REQUEST 0x01
203#define SCSI_ASCQ_INITIALIZING_COMMAND_REQUIRED 0x02
204#define SCSI_ASCQ_IU_CRC_ERROR_DETECTED 0x03
205#define SCSI_ASCQ_LUN_FORMAT_IN_PROGRESS 0x04
206#define SCSI_ASCQ_LUN_SELF_TEST_IN_PROGRESS 0x09
207#define SCSI_ASCQ_GENERAL_HARD_DRIVE_FAILURE 0x10
208#define SCSI_ASCQ_IDLE_CONDITION_ACTIVATE_BY_COMMAND 0x03
209#define SCSI_ASCQ_STANDBY_CONDITION_ACTIVATE_BY_COMMAND 0x04
210#define SCSI_ASCQ_POWER_STATE_CHANGE_TO_IDLE 0x42
211#define SCSI_ASCQ_POWER_STATE_CHANGE_TO_STANDBY 0x43
212#define SCSI_ASCQ_ATA_DEVICE_FEATURE_NOT_ENABLED 0x0B
213#define SCSI_ASCQ_UNRECOVERED_READ_ERROR_AUTO_REALLOCATE_FAIL 0x04
214
215
216
217/**
218 *
219 *
220 * SCSI_STATUS_CODES These constants define all of the used SCSI status values.
221 */
222#define SCSI_STATUS_GOOD 0x00
223#define SCSI_STATUS_CHECK_CONDITION 0x02
224#define SCSI_STATUS_CONDITION_MET 0x04
225#define SCSI_STATUS_BUSY 0x08
226#define SCSI_STATUS_TASKFULL 0x28
227#define SCSI_STATUS_ACA 0x30
228#define SCSI_STATUS_ABORT 0x40
229
230/**
231 *
232 *
233 * SCSI_OPERATION_CODES These constants delineate all of the SCSI
234 * command/operation codes.
235 */
236#define SCSI_INQUIRY 0x12
237#define SCSI_READ_CAPACITY_10 0x25
238#define SCSI_SERVICE_ACTION_IN_16 0x9E
239#define SCSI_TEST_UNIT_READY 0x00
240#define SCSI_START_STOP_UNIT 0x1B
241#define SCSI_SYNCHRONIZE_CACHE_10 0x35
242#define SCSI_SYNCHRONIZE_CACHE_16 0x91
243#define SCSI_REQUEST_SENSE 0x03
244#define SCSI_REPORT_LUNS 0xA0
245#define SCSI_REASSIGN_BLOCKS 0x07
246#define SCSI_READ_6 0x08
247#define SCSI_READ_10 0x28
248#define SCSI_READ_12 0xA8
249#define SCSI_READ_16 0x88
250#define SCSI_WRITE_6 0x0A
251#define SCSI_WRITE_10 0x2A
252#define SCSI_WRITE_12 0xAA
253#define SCSI_WRITE_16 0x8A
254#define SCSI_VERIFY_10 0x2F
255#define SCSI_VERIFY_12 0xAF
256#define SCSI_VERIFY_16 0x8F
257#define SCSI_SEEK_6 0x01
258#define SCSI_SEEK_10 0x02
259#define SCSI_WRITE_VERIFY 0x2E
260#define SCSI_FORMAT_UNIT 0x04
261#define SCSI_READ_BUFFER 0x3C
262#define SCSI_WRITE_BUFFER 0x3B
263#define SCSI_SEND_DIAGNOSTIC 0x1D
264#define SCSI_RECEIVE_DIAGNOSTIC 0x1C
265#define SCSI_MODE_SENSE_6 0x1A
266#define SCSI_MODE_SENSE_10 0x5A
267#define SCSI_MODE_SELECT_6 0x15
268#define SCSI_MODE_SELECT_10 0x55
269#define SCSI_MAINTENANCE_IN 0xA3
270#define SCSI_LOG_SENSE 0x4D
271#define SCSI_LOG_SELECT 0x4C
272#define SCSI_RESERVE_6 0x16
273#define SCSI_RESERVE_10 0x56
274#define SCSI_RELEASE_6 0x17
275#define SCSI_RELEASE_10 0x57
276#define SCSI_ATA_PASSTHRU_12 0xA1
277#define SCSI_ATA_PASSTHRU_16 0x85
278#define SCSI_WRITE_LONG_10 0x3F
279#define SCSI_WRITE_LONG_16 0x9F
280#define SCSI_PERSISTENT_RESERVE_IN 0x5E
281#define SCSI_PERSISTENT_RESERVE_OUT 0x5F
282
283/**
284 *
285 *
286 * SCSI_SERVICE_ACTION_IN_CODES Service action in operations.
287 */
288#define SCSI_SERVICE_ACTION_IN_CODES_READ_CAPACITY_16 0x10
289
290#define SCSI_SERVICE_ACTION_MASK 0x1f
291
292/**
293 *
294 *
295 * SCSI_MAINTENANCE_IN_SERVICE_ACTION_CODES MAINTENANCE IN service action codes.
296 */
297#define SCSI_REPORT_TASK_MGMT 0x0D
298#define SCSI_REPORT_OP_CODES 0x0C
299
300/**
301 *
302 *
303 * SCSI_MODE_PAGE_CONTROLS These constants delineate all of the used SCSI Mode
304 * Page control values.
305 */
306#define SCSI_MODE_SENSE_PC_CURRENT 0x0
307#define SCSI_MODE_SENSE_PC_CHANGEABLE 0x1
308#define SCSI_MODE_SENSE_PC_DEFAULT 0x2
309#define SCSI_MODE_SENSE_PC_SAVED 0x3
310
311#define SCSI_MODE_SENSE_PC_SHIFT 0x06
312#define SCSI_MODE_SENSE_PAGE_CODE_ENABLE 0x3F
313#define SCSI_MODE_SENSE_DBD_ENABLE 0x08
314#define SCSI_MODE_SENSE_LLBAA_ENABLE 0x10
315
316/**
317 *
318 *
319 * SCSI_MODE_PAGE_CODES These constants delineate all of the used SCSI Mode
320 * Page codes.
321 */
322#define SCSI_MODE_PAGE_READ_WRITE_ERROR 0x01
323#define SCSI_MODE_PAGE_DISCONNECT_RECONNECT 0x02
324#define SCSI_MODE_PAGE_CACHING 0x08
325#define SCSI_MODE_PAGE_CONTROL 0x0A
326#define SCSI_MODE_PAGE_PROTOCOL_SPECIFIC_PORT 0x19
327#define SCSI_MODE_PAGE_POWER_CONDITION 0x1A
328#define SCSI_MODE_PAGE_INFORMATIONAL_EXCP_CONTROL 0x1C
329#define SCSI_MODE_PAGE_ALL_PAGES 0x3F
330
331#define SCSI_MODE_SENSE_ALL_SUB_PAGES_CODE 0xFF
332#define SCSI_MODE_SENSE_NO_SUB_PAGES_CODE 0x0
333#define SCSI_MODE_SENSE_PROTOCOL_PORT_NUM_SUBPAGES 0x1
334#define SCSI_MODE_PAGE_CACHE_PAGE_WCE_BIT 0x04
335#define SCSI_MODE_PAGE_CACHE_PAGE_DRA_BIT 0x20
336#define SCSI_MODE_PAGE_DEXCPT_ENABLE 0x08
337#define SCSI_MODE_SENSE_HEADER_FUA_ENABLE 0x10
338#define SCSI_MODE_PAGE_POWER_CONDITION_STANDBY 0x1
339#define SCSI_MODE_PAGE_POWER_CONDITION_IDLE 0x2
340
341#define SCSI_MODE_SENSE_6_HEADER_LENGTH 4
342#define SCSI_MODE_SENSE_10_HEADER_LENGTH 8
343#define SCSI_MODE_SENSE_STD_BLOCK_DESCRIPTOR_LENGTH 8
344#define SCSI_MODE_SENSE_LLBA_BLOCK_DESCRIPTOR_LENGTH 16
345
346#define SCSI_MODE_PAGE_INFORMATIONAL_EXCP_DXCPT_ENABLE 0x08
347#define SCSI_MODE_PAGE_19_SAS_ID 0x6
348#define SCSI_MODE_PAGE_19_SUB1_PAGE_NUM 0x1
349#define SCSI_MODE_PAGE_19_SUB1_PC 0x59
350
351#define SCSI_MODE_HEADER_MEDIUM_TYPE_SBC 0x00
352
353/* Mode Select constrains related masks value */
354#define SCSI_MODE_SELECT_PF_BIT 0x1
355#define SCSI_MODE_SELECT_PF_MASK 0x10
356#define SCSI_MODE_SELECT_MODE_PAGE_MRIE_BYTE 0x6
357#define SCSI_MODE_SELECT_MODE_PAGE_MRIE_MASK 0x0F
358#define SCSI_MODE_SELECT_MODE_PAGE_SPF_MASK 0x40
359#define SCSI_MODE_SELECT_MODE_PAGE_01_AWRE_MASK 0x80
360#define SCSI_MODE_SELECT_MODE_PAGE_01_ARRE_MASK 0x40
361#define SCSI_MODE_SELECT_MODE_PAGE_01_RC_ERBITS_MASK 0x1F
362#define SCSI_MODE_SELECT_MODE_PAGE_08_FSW_LBCSS_NVDIS 0xC1
363#define SCSI_MODE_SELECT_MODE_PAGE_1C_PERF_TEST 0x84
364#define SCSI_MODE_SELECT_MODE_PAGE_0A_TST_TMF_RLEC 0xF1
365#define SCSI_MODE_SELECT_MODE_PAGE_0A_MODIFIER 0xF0
366#define SCSI_MODE_SELECT_MODE_PAGE_0A_UA_SWP 0x38
367#define SCSI_MODE_SELECT_MODE_PAGE_0A_TAS_AUTO 0x47
368
369
370#define SCSI_CONTROL_BYTE_NACA_BIT_ENABLE 0x04
371#define SCSI_MOVE_FUA_BIT_ENABLE 0x08
372#define SCSI_READ_CAPACITY_PMI_BIT_ENABLE 0x01
373#define SCSI_READ_CAPACITY_10_DATA_LENGTH 8
374#define SCSI_READ_CAPACITY_16_DATA_LENGTH 32
375
376/* Inquiry constants */
377#define SCSI_INQUIRY_EVPD_ENABLE 0x01
378#define SCSI_INQUIRY_PAGE_CODE_OFFSET 0x02
379#define SCSI_INQUIRY_SUPPORTED_PAGES_PAGE 0x00
380#define SCSI_INQUIRY_UNIT_SERIAL_NUM_PAGE 0x80
381#define SCSI_INQUIRY_DEVICE_ID_PAGE 0x83
382#define SCSI_INQUIRY_ATA_INFORMATION_PAGE 0x89
383#define SCSI_INQUIRY_BLOCK_DEVICE_PAGE 0xB1
384#define SCSI_INQUIRY_BLOCK_DEVICE_LENGTH 0x3C
385#define SCSI_INQUIRY_STANDARD_ALLOCATION_LENGTH 0x24 /* 36 */
386
387#define SCSI_REQUEST_SENSE_ALLOCATION_LENGTH 0xFC /* 252 */
388
389/** Defines the log page codes that are use in gathing Smart data
390 */
391#define SCSI_LOG_PAGE_SUPPORTED_PAGES 0x00
392#define SCSI_LOG_PAGE_INFORMATION_EXCEPTION 0x2F
393#define SCSI_LOG_PAGE_SELF_TEST 0x10
394
395/**
396 *
397 *
398 * SCSI_INQUIRY_VPD The following are constants used with vital product data
399 * inquiry pages. Values are already shifted into the proper nibble location.
400 */
401#define SCSI_PIV_ENABLE 0x80
402#define SCSI_LUN_ASSOCIATION 0x00
403#define SCSI_TARGET_PORT_ASSOCIATION 0x10
404
405#define SCSI_VEN_UNIQUE_IDENTIFIER_TYPE 0x00
406#define SCSI_NAA_IDENTIFIER_TYPE 0x03
407
408#define SCSI_T10_IDENTIFIER_TYPE 0x01
409#define SCSI_BINARY_CODE_SET 0x01
410#define SCSI_ASCII_CODE_SET 0x02
411#define SCSI_FC_PROTOCOL_IDENTIFIER 0x00
412#define SCSI_SAS_PROTOCOL_IDENTIFIER 0x60
413
414#define SCSI_VERIFY_BYTCHK_ENABLED 0x02
415
416#define SCSI_SYNCHRONIZE_CACHE_IMMED_ENABLED 0x02
417/**
418 *
419 *
420 * SCSI_START_STOP_UNIT_POWER_CONDITION_CODES The following are SCSI Start Stop
421 * Unit command Power Condition codes.
422 */
423#define SCSI_START_STOP_UNIT_POWER_CONDITION_START_VALID 0x0
424#define SCSI_START_STOP_UNIT_POWER_CONDITION_ACTIVE 0x1
425#define SCSI_START_STOP_UNIT_POWER_CONDITION_IDLE 0x2
426#define SCSI_START_STOP_UNIT_POWER_CONDITION_STANDBY 0x3
427#define SCSI_START_STOP_UNIT_POWER_CONDITION_LU_CONTROL 0x7
428#define SCSI_START_STOP_UNIT_POWER_CONDITION_FORCE_S_CONTROL 0xB
429
430#define SCSI_START_STOP_UNIT_IMMED_MASK 0x1
431#define SCSI_START_STOP_UNIT_IMMED_SHIFT 0
432
433#define SCSI_START_STOP_UNIT_START_BIT_MASK 0x1
434#define SCSI_START_STOP_UNIT_START_BIT_SHIFT 0
435
436#define SCSI_START_STOP_UNIT_LOEJ_BIT_MASK 0x2
437#define SCSI_START_STOP_UNIT_LOEJ_BIT_SHIFT 1
438
439#define SCSI_START_STOP_UNIT_NO_FLUSH_MASK 0x4
440#define SCSI_START_STOP_UNIT_NO_FLUSH_SHIFT 2
441
442#define SCSI_START_STOP_UNIT_POWER_CONDITION_MODIFIER_MASK 0xF
443#define SCSI_START_STOP_UNIT_POWER_CONDITION_MODIFIER_SHIFT 0
444
445#define SCSI_START_STOP_UNIT_POWER_CONDITION_MASK 0xF0
446#define SCSI_START_STOP_UNIT_POWER_CONDITION_SHIFT 4
447
448#define SCSI_LOG_SENSE_PC_FIELD_MASK 0xC0
449#define SCSI_LOG_SENSE_PC_FIELD_SHIFT 6
450
451#define SCSI_LOG_SENSE_PAGE_CODE_FIELD_MASK 0x3F
452#define SCSI_LOG_SENSE_PAGE_CODE_FIELD_SHIFT 0
453
454/**
455 *
456 *
457 * MRIE - Method of reporting informational exceptions codes
458 */
459#define NO_REPORTING_INFO_EXCEPTION_CONDITION 0x0
460#define ASYNCHRONOUS_EVENT_REPORTING 0x1
461#define ESTABLISH_UNIT_ATTENTION_CONDITION 0x2
462#define CONDITIONALLY_GENERATE_RECOVERED_ERROR 0x3
463#define UNCONDITIONALLY_GENERATE_RECOVERED_ERROR 0x4
464#define GENERATE_NO_SENSE 0x5
465#define REPORT_INFO_EXCEPTION_CONDITION_ON_REQUEST 0x6
466
467#define SCSI_INFORMATION_EXCEPTION_DEXCPT_BIT 0x08
468
469/* Reassign Blocks masks */
470#define SCSI_REASSIGN_BLOCKS_LONGLBA_BIT 0x02
471#define SCSI_REASSIGN_BLOCKS_LONGLIST_BIT 0x01
472
473#endif /* _SCSI_H_ */
474
diff --git a/drivers/scsi/isci/core/sati_device.h b/drivers/scsi/isci/core/sati_device.h
new file mode 100644
index 000000000000..4d1cfde12cae
--- /dev/null
+++ b/drivers/scsi/isci/core/sati_device.h
@@ -0,0 +1,156 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SATI_DEVICE_H_
57#define _SATI_DEVICE_H_
58
59/**
60 * This file contains all of the defintions for the SATI remote device object.
61 * Some translations require information to be remembered on a per device
62 * basis. This information is stored in the object defined in this file.
63 *
64 *
65 */
66
67#include "sati_types.h"
68#include "intel_ata.h"
69
70/**
71 * enum _SATI_DEVICE_STATE - This enumeration depicts the various states
72 * possible for the a translation remote device object.
73 *
74 *
75 */
76enum sati_device_state {
77 SATI_DEVICE_STATE_OPERATIONAL,
78 SATI_DEVICE_STATE_STOPPED,
79 SATI_DEVICE_STATE_STANDBY,
80 SATI_DEVICE_STATE_IDLE,
81 SATI_DEVICE_STATE_DEVICE_FAULT_OCCURRED,
82 SATI_DEVICE_STATE_FORMAT_UNIT_IN_PROGRESS,
83 SATI_DEVICE_STATE_SELF_TEST_IN_PROGRESS,
84 SATI_DEVICE_STATE_SEQUENCE_INCOMPLETE,
85 SATI_DEVICE_STATE_UNIT_ATTENTION_CONDITION
86
87};
88
89/**
90 *
91 *
92 * SATI_DEVICE_CAPABILITIES These constants define the various capabilities
93 * that a remote device may support for which there is an impact on translation.
94 */
95#define SATI_DEVICE_CAP_UDMA_ENABLE 0x00000001
96#define SATI_DEVICE_CAP_NCQ_REQUESTED_ENABLE 0x00000002
97#define SATI_DEVICE_CAP_NCQ_SUPPORTED_ENABLE 0x00000004
98#define SATI_DEVICE_CAP_48BIT_ENABLE 0x00000008
99#define SATI_DEVICE_CAP_DMA_FUA_ENABLE 0x00000010
100#define SATI_DEVICE_CAP_SMART_SUPPORT 0x00000020
101#define SATI_DEVICE_CAP_REMOVABLE_MEDIA 0x00000040
102#define SATI_DEVICE_CAP_SMART_ENABLE 0x00000080
103#define SATI_DEVICE_CAP_WRITE_UNCORRECTABLE_ENABLE 0x00000100
104#define SATI_DEVICE_CAP_MULTIPLE_SECTORS_PER_PHYSCIAL_SECTOR 0x00000200
105#define SATI_DEVICE_CAP_SMART_SELF_TEST_SUPPORT 0x00000400
106
107
108/**
109 * struct sati_device - The SATI_DEVICE structure define the state of the
110 * remote device with respect to translation.
111 *
112 *
113 */
114struct sati_device {
115 /**
116 * This field simply dictates the state of the SATI device.
117 */
118 enum sati_device_state state;
119
120 /**
121 * This field indicates features supported by the remote device that
122 * impact translation execution.
123 */
124 u16 capabilities;
125
126 /**
127 * This field indicates the depth of the native command queue supported
128 * by the device.
129 */
130 u8 ncq_depth;
131
132 /**
133 * This field stores the additional sense code for a unit attention
134 * condition.
135 */
136 u8 unit_attention_asc;
137
138 /**
139 * This field indicates the additional sense code qualifier for a unit
140 * attention condition.
141 */
142 u8 unit_attention_ascq;
143
144};
145
146void sati_device_construct(
147 struct sati_device *device,
148 bool is_ncq_enabled,
149 u8 max_ncq_depth);
150
151void sati_device_update_capabilities(
152 struct sati_device *device,
153 struct ata_identify_device_data *identify);
154
155#endif /* _SATI_TRANSLATOR_SEQUENCE_H_ */
156
diff --git a/drivers/scsi/isci/core/sati_translator_sequence.h b/drivers/scsi/isci/core/sati_translator_sequence.h
new file mode 100644
index 000000000000..592570d50ebd
--- /dev/null
+++ b/drivers/scsi/isci/core/sati_translator_sequence.h
@@ -0,0 +1,304 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SATI_TRANSLATOR_SEQUENCE_H_
57#define _SATI_TRANSLATOR_SEQUENCE_H_
58
59/**
60 * This file contains all of the defintions for the SATI translator sequence.
61 * A translator sequence is simply a defintion for the various sequences of
62 * commands that occur in this translator.
63 *
64 *
65 */
66
67#include "sati_device.h"
68
69/**
70 * enum _SATI_TRANSLATOR_SEQUENCE_TYPE - This enumeration defines the possible
71 * sequence types for the translator.
72 *
73 *
74 */
75enum sati_translator_sequence_type {
76 /* SCSI Primary Command (SPC) sequences. */
77 SATI_SEQUENCE_REPORT_LUNS,
78 SATI_SEQUENCE_TEST_UNIT_READY,
79 SATI_SEQUENCE_INQUIRY_STANDARD,
80 SATI_SEQUENCE_INQUIRY_SUPPORTED_PAGES,
81 SATI_SEQUENCE_INQUIRY_SERIAL_NUMBER,
82 SATI_SEQUENCE_INQUIRY_DEVICE_ID,
83 SATI_SEQUENCE_INQUIRY_BLOCK_DEVICE,
84 SATI_SEQUENCE_MODE_SENSE_6_CACHING,
85 SATI_SEQUENCE_MODE_SENSE_6_INFORMATIONAL_EXCP_CONTROL,
86 SATI_SEQUENCE_MODE_SENSE_6_READ_WRITE_ERROR,
87 SATI_SEQUENCE_MODE_SENSE_6_DISCONNECT_RECONNECT,
88 SATI_SEQUENCE_MODE_SENSE_6_CONTROL,
89 SATI_SEQUENCE_MODE_SENSE_6_ALL_PAGES,
90 SATI_SEQUENCE_MODE_SENSE_10_CACHING,
91 SATI_SEQUENCE_MODE_SENSE_10_INFORMATIONAL_EXCP_CONTROL,
92 SATI_SEQUENCE_MODE_SENSE_10_READ_WRITE_ERROR,
93 SATI_SEQUENCE_MODE_SENSE_10_DISCONNECT_RECONNECT,
94 SATI_SEQUENCE_MODE_SENSE_10_CONTROL,
95 SATI_SEQUENCE_MODE_SENSE_10_ALL_PAGES,
96 SATI_SEQUENCE_MODE_SELECT_MODE_PAGE_CACHING,
97 SATI_SEQUENCE_MODE_SELECT_MODE_POWER_CONDITION,
98 SATI_SEQUENCE_MODE_SELECT_MODE_INFORMATION_EXCEPT_CONTROL,
99
100 /* Log Sense Sequences */
101 SATI_SEQUENCE_LOG_SENSE_SELF_TEST_LOG_PAGE,
102 SATI_SEQUENCE_LOG_SENSE_EXTENDED_SELF_TEST_LOG_PAGE,
103 SATI_SEQUENCE_LOG_SENSE_SUPPORTED_LOG_PAGE,
104 SATI_SEQUENCE_LOG_SENSE_INFO_EXCEPTION_LOG_PAGE,
105
106 /* SCSI Block Command (SBC) sequences. */
107
108 SATI_SEQUENCE_READ_6,
109 SATI_SEQUENCE_READ_10,
110 SATI_SEQUENCE_READ_12,
111 SATI_SEQUENCE_READ_16,
112
113 SATI_SEQUENCE_READ_CAPACITY_10,
114 SATI_SEQUENCE_READ_CAPACITY_16,
115
116 SATI_SEQUENCE_SYNCHRONIZE_CACHE,
117
118 SATI_SEQUENCE_VERIFY_10,
119 SATI_SEQUENCE_VERIFY_12,
120 SATI_SEQUENCE_VERIFY_16,
121
122 SATI_SEQUENCE_WRITE_6,
123 SATI_SEQUENCE_WRITE_10,
124 SATI_SEQUENCE_WRITE_12,
125 SATI_SEQUENCE_WRITE_16,
126
127 SATI_SEQUENCE_START_STOP_UNIT,
128
129 SATI_SEQUENCE_REASSIGN_BLOCKS,
130
131 /* SCSI Task Requests sequences */
132
133 SATI_SEQUENCE_LUN_RESET,
134
135 SATI_SEQUENCE_REQUEST_SENSE_SMART_RETURN_STATUS,
136 SATI_SEQUENCE_REQUEST_SENSE_CHECK_POWER_MODE,
137
138 SATI_SEQUENCE_WRITE_LONG
139
140};
141
142#define SATI_SEQUENCE_TYPE_READ_MIN SATI_SEQUENCE_READ_6
143#define SATI_SEQUENCE_TYPE_READ_MAX SATI_SEQUENCE_READ_16
144
145/**
146 *
147 *
148 * SATI_SEQUENCE_STATES These constants depict the various state values
149 * associated with a translation sequence.
150 */
151#define SATI_SEQUENCE_STATE_INITIAL 0
152#define SATI_SEQUENCE_STATE_TRANSLATE_DATA 1
153#define SATI_SEQUENCE_STATE_AWAIT_RESPONSE 2
154#define SATI_SEQUENCE_STATE_FINAL 3
155#define SATI_SEQUENCE_STATE_INCOMPLETE 4
156
157/**
158 *
159 *
160 * SATI_DATA_DIRECTIONS These constants depict the various types of data
161 * directions for a translation sequence. Data can flow in/out (read/write) or
162 * no data at all.
163 */
164#define SATI_DATA_DIRECTION_NONE 0
165#define SATI_DATA_DIRECTION_IN 1
166#define SATI_DATA_DIRECTION_OUT 2
167
168/**
169 * struct SATI_MODE_SELECT_PROCESSING_STATE - This structure contains all of
170 * the current processing states for processing mode select 6 and 10
171 * commands' parameter fields.
172 *
173 *
174 */
175typedef struct SATI_MODE_SELECT_PROCESSING_STATE {
176 u8 *mode_pages;
177 u32 mode_page_offset;
178 u32 mode_pages_size;
179 u32 size_of_data_processed;
180 u32 total_ata_command_sent;
181 u32 ata_command_sent_for_cmp; /* cmp: current mode page */
182 bool current_mode_page_processed;
183
184} SATI_MODE_SELECT_PROCESSING_STATE_T;
185
186
187enum SATI_REASSIGN_BLOCKS_ATA_COMMAND_STATUS {
188 SATI_REASSIGN_BLOCKS_READY_TO_SEND,
189 SATI_REASSIGN_BLOCKS_COMMAND_FAIL,
190 SATI_REASSIGN_BLOCKS_COMMAND_SUCCESS,
191};
192
193/**
194 * struct sati_reassign_blocks_processing_state - This structure contains all
195 * of the current processing states for processing reassign block command's
196 * parameter fields.
197 *
198 *
199 */
200struct sati_reassign_blocks_processing_state {
201 u32 lba_offset;
202 u32 block_lists_size;
203 u8 lba_size;
204 u32 size_of_data_processed;
205 u32 ata_command_sent_for_current_lba;
206 bool current_lba_processed;
207 enum SATI_REASSIGN_BLOCKS_ATA_COMMAND_STATUS ata_command_status;
208
209};
210
211#define SATI_ATAPI_REQUEST_SENSE_CDB_LENGTH 12
212
213/**
214 * struct sati_atapi_data - The SATI_ATAPI_DATA structure is for sati atapi IO
215 * specific data.
216 *
217 *
218 */
219struct sati_atapi_data {
220 u8 request_sense_cdb[SATI_ATAPI_REQUEST_SENSE_CDB_LENGTH];
221};
222
223/**
224 * struct sati_translator_sequence - This structure contains all of the
225 * translation information associated with a particular request.
226 *
227 *
228 */
229struct sati_translator_sequence {
230 /**
231 * This field contains the sequence type determined by the SATI.
232 */
233 u8 type;
234
235 /**
236 * This field indicates the current state for the sequence.
237 */
238 u8 state;
239
240 /**
241 * This field indicates the data direction (none, read, or write) for
242 * the translated request.
243 */
244 u8 data_direction;
245
246 /**
247 * This field contains the SATA/ATA protocol to be utilized during
248 * the IO transfer.
249 */
250 u8 protocol;
251
252 /**
253 * This field is utilized for sequences requiring data translation.
254 * It specifies the amount of data requested by the caller from the
255 * operation. It's necessary, because at times the user requests less
256 * data than is available. Thus, we need to avoid overrunning the
257 * buffer.
258 */
259 u32 allocation_length;
260
261 /**
262 * This field specifies the amount of data that will actually be
263 * transfered across the wire for this ATA request.
264 */
265 u32 ata_transfer_length;
266
267 /**
268 * This field specifies the amount of data bytes that have been
269 * set in a translation sequence. It will be incremented every time
270 * a data byte has been set by a sati translation.
271 */
272 u16 number_data_bytes_set;
273
274 /**
275 * This field indicates whether or not the sense response has been set
276 * by the translation sequence.
277 */
278 bool is_sense_response_set;
279
280 /**
281 * This field specifies the remote device context for which this
282 * translator sequence is destined.
283 */
284 struct sati_device *device;
285
286 /**
287 * This field is utilized to provide the translator with memory space
288 * required for translations that utilize multiple requests.
289 */
290 union {
291 u32 translated_command;
292 u32 move_sector_count;
293 u32 scratch;
294 struct sati_reassign_blocks_processing_state reassign_blocks_process_state;
295 SATI_MODE_SELECT_PROCESSING_STATE_T process_state;
296 struct sati_atapi_data sati_atapi_data;
297 } command_specific_data;
298
299};
300
301
302
303#endif /* _SATI_TRANSLATOR_SEQUENCE_H_ */
304
diff --git a/drivers/scsi/isci/core/sati_types.h b/drivers/scsi/isci/core/sati_types.h
new file mode 100644
index 000000000000..b6159e06c280
--- /dev/null
+++ b/drivers/scsi/isci/core/sati_types.h
@@ -0,0 +1,145 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SATI_TYPES_H_
57#define _SATI_TYPES_H_
58
59/**
60 * This file contains various type definitions to be utilized with SCSI to ATA
61 * Translation Implementation.
62 *
63 *
64 */
65
66/**
67 * enum _SATI_STATUS - This enumeration defines the possible return values from
68 * the SATI translation methods.
69 *
70 *
71 */
72enum sati_status {
73 /**
74 * This indicates that the translation was supported and occurred
75 * without error.
76 */
77 SATI_SUCCESS,
78
79 /**
80 * This indicates that the translation was supported, occurred without
81 * error, and no additional translation is necessary. This is done in
82 * conditions where the SCSI command doesn't require any interaction with
83 * the remote device.
84 */
85 SATI_COMPLETE,
86
87 /**
88 * This indicated everything SATI_COMPLETE does in addition to the response data
89 * not using all the memory allocated by the OS.
90 */
91 SATI_COMPLETE_IO_DONE_EARLY,
92
93 /**
94 * This indicates that translator sequence has finished some specific
95 * command in the sequence, but additional commands are necessary.
96 */
97 SATI_SEQUENCE_INCOMPLETE,
98
99 /**
100 * This indicates a general failure has occurred for which no further
101 * specification information is available.
102 */
103 SATI_FAILURE,
104
105 /**
106 * This indicates that the result of the IO request indicates a
107 * failure. The caller should reference the corresponding response
108 * data for further details.
109 */
110 SATI_FAILURE_CHECK_RESPONSE_DATA,
111
112 /**
113 * This status indicates that the supplied sequence type doesn't map
114 * to an existing definition.
115 */
116 SATI_FAILURE_INVALID_SEQUENCE_TYPE,
117
118 /**
119 * This status indicates that the supplied sequence state doesn't match
120 * the operation being requested by the user.
121 */
122 SATI_FAILURE_INVALID_STATE
123
124};
125
126#if (!defined(DISABLE_SATI_MODE_SENSE) \
127 || !defined(DISABLE_SATI_MODE_SELECT) \
128 || !defined(DISABLE_SATI_REQUEST_SENSE)) \
129
130#if !defined(ENABLE_SATI_MODE_PAGES)
131/**
132 *
133 *
134 * This macro enables the common mode page data structures and code. Currently,
135 * MODE SENSE, MODE SELECT, and REQUEST SENSE all make reference to this common
136 * code. As a result, enable the common mode page code if any of these 3 are
137 * being translated.
138 */
139#define ENABLE_SATI_MODE_PAGES
140#endif /* !defined(ENABLE_SATI_MODE_PAGES) */
141
142#endif /* MODE_SENSE/SELECT/REQUEST_SENSE */
143
144#endif /* _SATI_TYPES_H_ */
145
diff --git a/drivers/scsi/isci/core/sci_base_controller.h b/drivers/scsi/isci/core/sci_base_controller.h
new file mode 100644
index 000000000000..36c53406ea5a
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_base_controller.h
@@ -0,0 +1,306 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_BASE_CONTROLLER_H_
57#define _SCI_BASE_CONTROLLER_H_
58
59#include "intel_sas.h"
60#include "sci_controller_constants.h"
61#include "sci_base_state.h"
62#include "sci_base_memory_descriptor_list.h"
63#include "sci_base_state_machine.h"
64#include "sci_object.h"
65
66struct sci_base_memory_descriptor_list;
67
68/**
69 * enum sci_base_controller_states - This enumeration depicts all the states
70 * for the common controller state machine.
71 *
72 *
73 */
74enum sci_base_controller_states {
75 /**
76 * Simply the initial state for the base controller state machine.
77 */
78 SCI_BASE_CONTROLLER_STATE_INITIAL = 0,
79
80 /**
81 * This state indicates that the controller is reset. The memory for
82 * the controller is in it's initial state, but the controller requires
83 * initialization.
84 * This state is entered from the INITIAL state.
85 * This state is entered from the RESETTING state.
86 */
87 SCI_BASE_CONTROLLER_STATE_RESET,
88
89 /**
90 * This state is typically an action state that indicates the controller
91 * is in the process of initialization. In this state no new IO operations
92 * are permitted.
93 * This state is entered from the RESET state.
94 */
95 SCI_BASE_CONTROLLER_STATE_INITIALIZING,
96
97 /**
98 * This state indicates that the controller has been successfully
99 * initialized. In this state no new IO operations are permitted.
100 * This state is entered from the INITIALIZING state.
101 */
102 SCI_BASE_CONTROLLER_STATE_INITIALIZED,
103
104 /**
105 * This state indicates the the controller is in the process of becoming
106 * ready (i.e. starting). In this state no new IO operations are permitted.
107 * This state is entered from the INITIALIZED state.
108 */
109 SCI_BASE_CONTROLLER_STATE_STARTING,
110
111 /**
112 * This state indicates the controller is now ready. Thus, the user
113 * is able to perform IO operations on the controller.
114 * This state is entered from the STARTING state.
115 */
116 SCI_BASE_CONTROLLER_STATE_READY,
117
118 /**
119 * This state is typically an action state that indicates the controller
120 * is in the process of resetting. Thus, the user is unable to perform
121 * IO operations on the controller. A reset is considered destructive in
122 * most cases.
123 * This state is entered from the READY state.
124 * This state is entered from the FAILED state.
125 * This state is entered from the STOPPED state.
126 */
127 SCI_BASE_CONTROLLER_STATE_RESETTING,
128
129 /**
130 * This state indicates that the controller is in the process of stopping.
131 * In this state no new IO operations are permitted, but existing IO
132 * operations are allowed to complete.
133 * This state is entered from the READY state.
134 */
135 SCI_BASE_CONTROLLER_STATE_STOPPING,
136
137 /**
138 * This state indicates that the controller has successfully been stopped.
139 * In this state no new IO operations are permitted.
140 * This state is entered from the STOPPING state.
141 */
142 SCI_BASE_CONTROLLER_STATE_STOPPED,
143
144 /**
145 * This state indicates that the controller could not successfully be
146 * initialized. In this state no new IO operations are permitted.
147 * This state is entered from the INITIALIZING state.
148 * This state is entered from the STARTING state.
149 * This state is entered from the STOPPING state.
150 * This state is entered from the RESETTING state.
151 */
152 SCI_BASE_CONTROLLER_STATE_FAILED,
153
154 SCI_BASE_CONTROLLER_MAX_STATES
155
156};
157
158/**
159 * struct sci_base_controller - The base controller object abstracts the fields
160 * common to all SCI controller objects.
161 *
162 *
163 */
164struct sci_base_controller {
165 /**
166 * The field specifies that the parent object for the base controller
167 * is the base object itself.
168 */
169 struct sci_base_object parent;
170
171 /**
172 * This field points to the memory descriptor list associated with this
173 * controller. The MDL indicates the memory requirements necessary for
174 * this controller object.
175 */
176 struct sci_base_memory_descriptor_list mdl;
177
178 /**
179 * This field contains the information for the base controller state
180 * machine.
181 */
182 struct sci_base_state_machine state_machine;
183};
184
185/* Forward declarations */
186struct sci_base_remote_device;
187struct sci_base_request;
188
189typedef enum sci_status
190(*sci_base_controller_handler_t)(struct sci_base_controller *);
191
192typedef enum sci_status
193(*sci_base_controller_timed_handler_t)(struct sci_base_controller *, u32);
194
195typedef enum sci_status
196(*sci_base_controller_request_handler_t)(struct sci_base_controller *,
197 struct sci_base_remote_device *,
198 struct sci_base_request *);
199
200typedef enum sci_status
201(*sci_base_controller_start_request_handler_t)(struct sci_base_controller *,
202 struct sci_base_remote_device *,
203 struct sci_base_request *, u16);
204
205/**
206 * struct sci_base_controller_state_handler - This structure contains all of
207 * the state handler methods common to base controller state machines.
208 * Handler methods provide the ability to change the behavior for user
209 * requests or transitions depending on the state the machine is in.
210 *
211 *
212 */
213struct sci_base_controller_state_handler {
214 /**
215 * The start_handler specifies the method invoked when a user attempts to
216 * start a controller.
217 */
218 sci_base_controller_timed_handler_t start;
219
220 /**
221 * The stop_handler specifies the method invoked when a user attempts to
222 * stop a controller.
223 */
224 sci_base_controller_timed_handler_t stop;
225
226 /**
227 * The reset_handler specifies the method invoked when a user attempts to
228 * reset a controller.
229 */
230 sci_base_controller_handler_t reset;
231
232 /**
233 * The initialize_handler specifies the method invoked when a user
234 * attempts to initialize a controller.
235 */
236 sci_base_controller_handler_t initialize;
237
238 /**
239 * The start_io_handler specifies the method invoked when a user
240 * attempts to start an IO request for a controller.
241 */
242 sci_base_controller_start_request_handler_t start_io;
243
244 /**
245 * The complete_io_handler specifies the method invoked when a user
246 * attempts to complete an IO request for a controller.
247 */
248 sci_base_controller_request_handler_t complete_io;
249
250 /**
251 * The continue_io_handler specifies the method invoked when a user
252 * attempts to continue an IO request for a controller.
253 */
254 sci_base_controller_request_handler_t continue_io;
255
256 /**
257 * The start_task_handler specifies the method invoked when a user
258 * attempts to start a task management request for a controller.
259 */
260 sci_base_controller_start_request_handler_t start_task;
261
262 /**
263 * The complete_task_handler specifies the method invoked when a user
264 * attempts to complete a task management request for a controller.
265 */
266 sci_base_controller_request_handler_t complete_task;
267
268};
269
270/**
271 * sci_base_controller_construct() - Construct the base controller
272 * @this_controller: This parameter specifies the base controller to be
273 * constructed.
274 * @state_table: This parameter specifies the table of state definitions to be
275 * utilized for the controller state machine.
276 * @mde_array: This parameter specifies the array of memory descriptor entries
277 * to be managed by this list.
278 * @mde_array_length: This parameter specifies the size of the array of entries.
279 * @next_mdl: This parameter specifies a subsequent MDL object to be managed by
280 * this MDL object.
281 * @oem_parameters: This parameter specifies the original equipment
282 * manufacturer parameters to be utilized by this controller object.
283 *
284 */
285static inline void sci_base_controller_construct(
286 struct sci_base_controller *scic_base,
287 const struct sci_base_state *state_table,
288 struct sci_physical_memory_descriptor *mdes,
289 u32 mde_count,
290 struct sci_base_memory_descriptor_list *next_mdl)
291{
292 scic_base->parent.private = NULL;
293
294 sci_base_state_machine_construct(
295 &scic_base->state_machine,
296 &scic_base->parent,
297 state_table,
298 SCI_BASE_CONTROLLER_STATE_INITIAL
299 );
300
301 sci_base_mdl_construct(&scic_base->mdl, mdes, mde_count, next_mdl);
302
303 sci_base_state_machine_start(&scic_base->state_machine);
304}
305
306#endif /* _SCI_BASE_CONTROLLER_H_ */
diff --git a/drivers/scsi/isci/core/sci_base_memory_descriptor_list.c b/drivers/scsi/isci/core/sci_base_memory_descriptor_list.c
new file mode 100644
index 000000000000..86ae6a855399
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_base_memory_descriptor_list.c
@@ -0,0 +1,159 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file contains the base implementation for the memory descriptor list.
58 * This is currently comprised of MDL iterator methods.
59 *
60 *
61 */
62
63#include "sci_environment.h"
64#include "sci_base_memory_descriptor_list.h"
65
66/*
67 * ******************************************************************************
68 * * P U B L I C M E T H O D S
69 * ****************************************************************************** */
70
71void sci_mdl_first_entry(
72 struct sci_base_memory_descriptor_list *base_mdl)
73{
74 base_mdl->next_index = 0;
75
76 /*
77 * If this MDL is managing another MDL, then recursively rewind that MDL
78 * object as well. */
79 if (base_mdl->next_mdl != SCI_INVALID_HANDLE)
80 sci_mdl_first_entry(base_mdl->next_mdl);
81}
82
83
84void sci_mdl_next_entry(
85 struct sci_base_memory_descriptor_list *base_mdl)
86{
87 /*
88 * If there is at least one more entry left in the array, then change
89 * the next pointer to it. */
90 if (base_mdl->next_index < base_mdl->length)
91 base_mdl->next_index++;
92 else if (base_mdl->next_index == base_mdl->length) {
93 /*
94 * This MDL has exhausted it's set of entries. If this MDL is managing
95 * another MDL, then start iterating through that MDL. */
96 if (base_mdl->next_mdl != SCI_INVALID_HANDLE)
97 sci_mdl_next_entry(base_mdl->next_mdl);
98 }
99}
100
101
102struct sci_physical_memory_descriptor *sci_mdl_get_current_entry(
103 struct sci_base_memory_descriptor_list *base_mdl)
104{
105 if (base_mdl->next_index < base_mdl->length)
106 return &base_mdl->mde_array[base_mdl->next_index];
107 else if (base_mdl->next_index == base_mdl->length) {
108 /*
109 * This MDL has exhausted it's set of entries. If this MDL is managing
110 * another MDL, then return it's current entry. */
111 if (base_mdl->next_mdl != SCI_INVALID_HANDLE)
112 return sci_mdl_get_current_entry(base_mdl->next_mdl);
113 }
114
115 return NULL;
116}
117
118/*
119 * ******************************************************************************
120 * * P R O T E C T E D M E T H O D S
121 * ****************************************************************************** */
122
123void sci_base_mdl_construct(
124 struct sci_base_memory_descriptor_list *mdl,
125 struct sci_physical_memory_descriptor *mde_array,
126 u32 mde_array_length,
127 struct sci_base_memory_descriptor_list *next_mdl)
128{
129 mdl->length = mde_array_length;
130 mdl->mde_array = mde_array;
131 mdl->next_index = 0;
132 mdl->next_mdl = next_mdl;
133}
134
135/* --------------------------------------------------------------------------- */
136
137bool sci_base_mde_is_valid(
138 struct sci_physical_memory_descriptor *mde,
139 u32 alignment,
140 u32 size,
141 u16 attributes)
142{
143 /* Only need the lower 32 bits to ensure alignment is met. */
144 u32 physical_address = lower_32_bits(mde->physical_address);
145
146 if (
147 ((((unsigned long)mde->virtual_address) & (alignment - 1)) != 0)
148 || ((physical_address & (alignment - 1)) != 0)
149 || (mde->constant_memory_alignment != alignment)
150 || (mde->constant_memory_size != size)
151 || (mde->virtual_address == NULL)
152 || (mde->constant_memory_attributes != attributes)
153 ) {
154 return false;
155 }
156
157 return true;
158}
159
diff --git a/drivers/scsi/isci/core/sci_base_memory_descriptor_list.h b/drivers/scsi/isci/core/sci_base_memory_descriptor_list.h
new file mode 100644
index 000000000000..257d6e368b4a
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_base_memory_descriptor_list.h
@@ -0,0 +1,155 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_BASE_MEMORY_DESCRIPTOR_LIST_H_
57#define _SCI_BASE_MEMORY_DESCRIPTOR_LIST_H_
58
59/**
60 * This file contains the protected interface structures, constants and
61 * interface methods for the struct sci_base_memory_descriptor_list object.
62 *
63 *
64 */
65
66
67#include "sci_types.h"
68#include "sci_memory_descriptor_list.h"
69
70
71/**
72 * struct sci_base_memory_descriptor_list - This structure contains all of the
73 * fields necessary to implement a simple stack for managing the list of
74 * available controller indices.
75 *
76 *
77 */
78struct sci_base_memory_descriptor_list {
79 /**
80 * This field indicates the length of the memory descriptor entry array.
81 */
82 u32 length;
83
84 /**
85 * This field is utilized to provide iterator pattern functionality.
86 * It indicates the index of the next memory descriptor in the iteration.
87 */
88 u32 next_index;
89
90 /**
91 * This field will point to the list of memory descriptors.
92 */
93 struct sci_physical_memory_descriptor *mde_array;
94
95 /**
96 * This field simply allows a user to chain memory descriptor lists
97 * together if desired. This field will be initialized to
98 * SCI_INVALID_HANDLE.
99 */
100 struct sci_base_memory_descriptor_list *next_mdl;
101
102};
103
104/**
105 * sci_base_mdl_construct() - This method is invoked to construct an memory
106 * descriptor list. It initializes the fields of the MDL.
107 * @mdl: This parameter specifies the memory descriptor list to be constructed.
108 * @mde_array: This parameter specifies the array of memory descriptor entries
109 * to be managed by this list.
110 * @mde_array_length: This parameter specifies the size of the array of entries.
111 * @next_mdl: This parameter specifies a subsequent MDL object to be managed by
112 * this MDL object.
113 *
114 * none.
115 */
116void sci_base_mdl_construct(
117 struct sci_base_memory_descriptor_list *mdl,
118 struct sci_physical_memory_descriptor *mde_array,
119 u32 mde_array_length,
120 struct sci_base_memory_descriptor_list *next_mdl);
121
122/**
123 * sci_base_mde_construct() -
124 *
125 * This macro constructs an memory descriptor entry with the given alignment
126 * and size
127 */
128#define sci_base_mde_construct(mde, alignment, size, attributes) \
129 { \
130 (mde)->constant_memory_alignment = (alignment); \
131 (mde)->constant_memory_size = (size); \
132 (mde)->constant_memory_attributes = (attributes); \
133 }
134
135/**
136 * sci_base_mde_is_valid() - This method validates that the memory descriptor
137 * is correctly filled out by the SCI User
138 * @mde: This parameter is the mde entry to validate
139 * @alignment: This parameter specifies the expected alignment of the memory
140 * for the mde.
141 * @size: This parameter specifies the memory size expected for the mde its
142 * value should not have been changed by the SCI User.
143 * @attributes: This parameter specifies the attributes for the memory
144 * descriptor provided.
145 *
146 * bool This method returns an indication as to whether the supplied MDE is
147 * valid or not. true The MDE is valid. false The MDE is not valid.
148 */
149bool sci_base_mde_is_valid(
150 struct sci_physical_memory_descriptor *mde,
151 u32 alignment,
152 u32 size,
153 u16 attributes);
154
155#endif /* _SCI_BASE_MEMORY_DESCRIPTOR_LIST_H_ */
diff --git a/drivers/scsi/isci/core/sci_base_phy.h b/drivers/scsi/isci/core/sci_base_phy.h
new file mode 100644
index 000000000000..6c0d9bbbc95f
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_base_phy.h
@@ -0,0 +1,205 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_BASE_PHY_H_
57#define _SCI_BASE_PHY_H_
58
59/**
60 * This file contains all of the structures, constants, and methods common to
61 * all phy object definitions.
62 *
63 *
64 */
65
66#include "sci_base_state_machine.h"
67
68/**
69 * enum sci_base_phy_states - This enumeration depicts the standard states
70 * common to all phy state machine implementations.
71 *
72 *
73 */
74enum sci_base_phy_states {
75 /**
76 * Simply the initial state for the base domain state machine.
77 */
78 SCI_BASE_PHY_STATE_INITIAL,
79
80 /**
81 * This state indicates that the phy has successfully been stopped.
82 * In this state no new IO operations are permitted on this phy.
83 * This state is entered from the INITIAL state.
84 * This state is entered from the STARTING state.
85 * This state is entered from the READY state.
86 * This state is entered from the RESETTING state.
87 */
88 SCI_BASE_PHY_STATE_STOPPED,
89
90 /**
91 * This state indicates that the phy is in the process of becomming
92 * ready. In this state no new IO operations are permitted on this phy.
93 * This state is entered from the STOPPED state.
94 * This state is entered from the READY state.
95 * This state is entered from the RESETTING state.
96 */
97 SCI_BASE_PHY_STATE_STARTING,
98
99 /**
100 * This state indicates the the phy is now ready. Thus, the user
101 * is able to perform IO operations utilizing this phy as long as it
102 * is currently part of a valid port.
103 * This state is entered from the STARTING state.
104 */
105 SCI_BASE_PHY_STATE_READY,
106
107 /**
108 * This state indicates that the phy is in the process of being reset.
109 * In this state no new IO operations are permitted on this phy.
110 * This state is entered from the READY state.
111 */
112 SCI_BASE_PHY_STATE_RESETTING,
113
114 /**
115 * Simply the final state for the base phy state machine.
116 */
117 SCI_BASE_PHY_STATE_FINAL,
118
119 SCI_BASE_PHY_MAX_STATES
120
121};
122
123/**
124 * struct sci_base_phy - This structure defines all of the fields common to PHY
125 * objects.
126 *
127 *
128 */
129struct sci_base_phy {
130 /**
131 * This field depicts the parent object (struct sci_base_object) for the phy.
132 */
133 struct sci_base_object parent;
134
135 /**
136 * This field contains the information for the base phy state machine.
137 */
138 struct sci_base_state_machine state_machine;
139};
140
141typedef enum sci_status (*SCI_BASE_PHY_HANDLER_T)(
142 struct sci_base_phy *
143 );
144
145/**
146 * struct sci_base_phy_state_handler - This structure contains all of the state
147 * handler methods common to base phy state machines. Handler methods
148 * provide the ability to change the behavior for user requests or
149 * transitions depending on the state the machine is in.
150 *
151 *
152 */
153struct sci_base_phy_state_handler {
154 /**
155 * The start_handler specifies the method invoked when there is an
156 * attempt to start a phy.
157 */
158 SCI_BASE_PHY_HANDLER_T start_handler;
159
160 /**
161 * The stop_handler specifies the method invoked when there is an
162 * attempt to stop a phy.
163 */
164 SCI_BASE_PHY_HANDLER_T stop_handler;
165
166 /**
167 * The reset_handler specifies the method invoked when there is an
168 * attempt to reset a phy.
169 */
170 SCI_BASE_PHY_HANDLER_T reset_handler;
171
172 /**
173 * The destruct_handler specifies the method invoked when attempting to
174 * destruct a phy.
175 */
176 SCI_BASE_PHY_HANDLER_T destruct_handler;
177
178};
179
180/**
181 * sci_base_phy_construct() - Construct the base phy
182 * @this_phy: This parameter specifies the base phy to be constructed.
183 * @state_table: This parameter specifies the table of state definitions to be
184 * utilized for the phy state machine.
185 *
186 */
187static inline void sci_base_phy_construct(
188 struct sci_base_phy *base_phy,
189 const struct sci_base_state *state_table)
190{
191 base_phy->parent.private = NULL;
192 sci_base_state_machine_construct(
193 &base_phy->state_machine,
194 &base_phy->parent,
195 state_table,
196 SCI_BASE_PHY_STATE_INITIAL
197 );
198
199 sci_base_state_machine_start(
200 &base_phy->state_machine
201 );
202}
203
204
205#endif /* _SCI_BASE_PHY_H_ */
diff --git a/drivers/scsi/isci/core/sci_base_port.h b/drivers/scsi/isci/core/sci_base_port.h
new file mode 100644
index 000000000000..4e2031d195f0
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_base_port.h
@@ -0,0 +1,203 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_BASE_PORT_H_
57#define _SCI_BASE_PORT_H_
58
59#include "sci_base_state_machine.h"
60#include "sci_object.h"
61
62/**
63 * enum sci_base_port_states - This enumeration depicts all the states for the
64 * common port state machine.
65 *
66 *
67 */
68enum sci_base_port_states {
69 /**
70 * This state indicates that the port has successfully been stopped.
71 * In this state no new IO operations are permitted.
72 * This state is entered from the STOPPING state.
73 */
74 SCI_BASE_PORT_STATE_STOPPED,
75
76 /**
77 * This state indicates that the port is in the process of stopping.
78 * In this state no new IO operations are permitted, but existing IO
79 * operations are allowed to complete.
80 * This state is entered from the READY state.
81 */
82 SCI_BASE_PORT_STATE_STOPPING,
83
84 /**
85 * This state indicates the port is now ready. Thus, the user is
86 * able to perform IO operations on this port.
87 * This state is entered from the STARTING state.
88 */
89 SCI_BASE_PORT_STATE_READY,
90
91 /**
92 * This state indicates the port is in the process of performing a hard
93 * reset. Thus, the user is unable to perform IO operations on this
94 * port.
95 * This state is entered from the READY state.
96 */
97 SCI_BASE_PORT_STATE_RESETTING,
98
99 /**
100 * This state indicates the port has failed a reset request. This state
101 * is entered when a port reset request times out.
102 * This state is entered from the RESETTING state.
103 */
104 SCI_BASE_PORT_STATE_FAILED,
105
106 SCI_BASE_PORT_MAX_STATES
107
108};
109
110/**
111 * struct sci_base_port - The base port object abstracts the fields common to
112 * all SCI port objects.
113 *
114 *
115 */
116struct sci_base_port {
117 /**
118 * The field specifies that the parent object for the base controller
119 * is the base object itself.
120 */
121 struct sci_base_object parent;
122
123 /**
124 * This field contains the information for the base port state machine.
125 */
126 struct sci_base_state_machine state_machine;
127};
128
129struct sci_base_phy;
130
131typedef enum sci_status (*SCI_BASE_PORT_HANDLER_T)(
132 struct sci_base_port *
133 );
134
135typedef enum sci_status (*SCI_BASE_PORT_PHY_HANDLER_T)(
136 struct sci_base_port *,
137 struct sci_base_phy *
138 );
139
140typedef enum sci_status (*SCI_BASE_PORT_RESET_HANDLER_T)(
141 struct sci_base_port *,
142 u32 timeout
143 );
144
145/**
146 * struct sci_base_port_state_handler - This structure contains all of the
147 * state handler methods common to base port state machines. Handler
148 * methods provide the ability to change the behavior for user requests or
149 * transitions depending on the state the machine is in.
150 *
151 *
152 */
153struct sci_base_port_state_handler {
154 /**
155 * The start_handler specifies the method invoked when a user attempts to
156 * start a port.
157 */
158 SCI_BASE_PORT_HANDLER_T start_handler;
159
160 /**
161 * The stop_handler specifies the method invoked when a user attempts to
162 * stop a port.
163 */
164 SCI_BASE_PORT_HANDLER_T stop_handler;
165
166 /**
167 * The destruct_handler specifies the method invoked when attempting to
168 * destruct a port.
169 */
170 SCI_BASE_PORT_HANDLER_T destruct_handler;
171
172 /**
173 * The reset_handler specifies the method invoked when a user attempts to
174 * hard reset a port.
175 */
176 SCI_BASE_PORT_RESET_HANDLER_T reset_handler;
177
178 /**
179 * The add_phy_handler specifies the method invoked when a user attempts to
180 * add another phy into the port.
181 */
182 SCI_BASE_PORT_PHY_HANDLER_T add_phy_handler;
183
184 /**
185 * The remove_phy_handler specifies the method invoked when a user
186 * attempts to remove a phy from the port.
187 */
188 SCI_BASE_PORT_PHY_HANDLER_T remove_phy_handler;
189
190};
191
192/**
193 * sci_base_port_construct() - Construct the base port object
194 * @this_port: This parameter specifies the base port to be constructed.
195 * @state_table: This parameter specifies the table of state definitions to be
196 * utilized for the domain state machine.
197 *
198 */
199void sci_base_port_construct(
200 struct sci_base_port *this_port,
201 const struct sci_base_state *state_table);
202
203#endif /* _SCI_BASE_PORT_H_ */
diff --git a/drivers/scsi/isci/core/sci_base_remote_device.h b/drivers/scsi/isci/core/sci_base_remote_device.h
new file mode 100644
index 000000000000..fe6614b8ef5b
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_base_remote_device.h
@@ -0,0 +1,277 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_BASE_REMOTE_DEVICE_H_
57#define _SCI_BASE_REMOTE_DEVICE_H_
58
59/**
60 * This file contains all of the structures, constants, and methods common to
61 * all remote device object definitions.
62 *
63 *
64 */
65
66#include "sci_base_state_machine.h"
67
68struct sci_base_request;
69
70/**
71 * enum sci_base_remote_device_states - This enumeration depicts all the states
72 * for the common remote device state machine.
73 *
74 *
75 */
76enum sci_base_remote_device_states {
77 /**
78 * Simply the initial state for the base remote device state machine.
79 */
80 SCI_BASE_REMOTE_DEVICE_STATE_INITIAL,
81
82 /**
83 * This state indicates that the remote device has successfully been
84 * stopped. In this state no new IO operations are permitted.
85 * This state is entered from the INITIAL state.
86 * This state is entered from the STOPPING state.
87 */
88 SCI_BASE_REMOTE_DEVICE_STATE_STOPPED,
89
90 /**
91 * This state indicates the the remote device is in the process of
92 * becoming ready (i.e. starting). In this state no new IO operations
93 * are permitted.
94 * This state is entered from the STOPPED state.
95 */
96 SCI_BASE_REMOTE_DEVICE_STATE_STARTING,
97
98 /**
99 * This state indicates the remote device is now ready. Thus, the user
100 * is able to perform IO operations on the remote device.
101 * This state is entered from the STARTING state.
102 */
103 SCI_BASE_REMOTE_DEVICE_STATE_READY,
104
105 /**
106 * This state indicates that the remote device is in the process of
107 * stopping. In this state no new IO operations are permitted, but
108 * existing IO operations are allowed to complete.
109 * This state is entered from the READY state.
110 * This state is entered from the FAILED state.
111 */
112 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING,
113
114 /**
115 * This state indicates that the remote device has failed.
116 * In this state no new IO operations are permitted.
117 * This state is entered from the INITIALIZING state.
118 * This state is entered from the READY state.
119 */
120 SCI_BASE_REMOTE_DEVICE_STATE_FAILED,
121
122 /**
123 * This state indicates the device is being reset.
124 * In this state no new IO operations are permitted.
125 * This state is entered from the READY state.
126 */
127 SCI_BASE_REMOTE_DEVICE_STATE_RESETTING,
128
129 /**
130 * Simply the final state for the base remote device state machine.
131 */
132 SCI_BASE_REMOTE_DEVICE_STATE_FINAL,
133
134 SCI_BASE_REMOTE_DEVICE_MAX_STATES
135
136};
137
138/**
139 * struct sci_base_remote_device - The base remote device object abstracts the
140 * fields common to all SCI remote device objects.
141 *
142 *
143 */
144struct sci_base_remote_device {
145 /**
146 * The field specifies that the parent object for the base remote
147 * device is the base object itself.
148 */
149 struct sci_base_object parent;
150
151 /**
152 * This field contains the information for the base remote device state
153 * machine.
154 */
155 struct sci_base_state_machine state_machine;
156};
157
158
159typedef enum sci_status (*SCI_BASE_REMOTE_DEVICE_HANDLER_T)(
160 struct sci_base_remote_device *
161 );
162
163typedef enum sci_status (*SCI_BASE_REMOTE_DEVICE_REQUEST_HANDLER_T)(
164 struct sci_base_remote_device *,
165 struct sci_base_request *
166 );
167
168typedef enum sci_status (*SCI_BASE_REMOTE_DEVICE_HIGH_PRIORITY_REQUEST_COMPLETE_HANDLER_T)(
169 struct sci_base_remote_device *,
170 struct sci_base_request *,
171 void *,
172 enum sci_io_status
173 );
174
175/**
176 * struct sci_base_remote_device_state_handler - This structure contains all of
177 * the state handler methods common to base remote device state machines.
178 * Handler methods provide the ability to change the behavior for user
179 * requests or transitions depending on the state the machine is in.
180 *
181 *
182 */
183struct sci_base_remote_device_state_handler {
184 /**
185 * The start_handler specifies the method invoked when a user attempts to
186 * start a remote device.
187 */
188 SCI_BASE_REMOTE_DEVICE_HANDLER_T start_handler;
189
190 /**
191 * The stop_handler specifies the method invoked when a user attempts to
192 * stop a remote device.
193 */
194 SCI_BASE_REMOTE_DEVICE_HANDLER_T stop_handler;
195
196 /**
197 * The fail_handler specifies the method invoked when a remote device
198 * failure has occurred. A failure may be due to an inability to
199 * initialize/configure the device.
200 */
201 SCI_BASE_REMOTE_DEVICE_HANDLER_T fail_handler;
202
203 /**
204 * The destruct_handler specifies the method invoked when attempting to
205 * destruct a remote device.
206 */
207 SCI_BASE_REMOTE_DEVICE_HANDLER_T destruct_handler;
208
209 /**
210 * The reset handler specifies the method invloked when requesting to reset a
211 * remote device.
212 */
213 SCI_BASE_REMOTE_DEVICE_HANDLER_T reset_handler;
214
215 /**
216 * The reset complete handler specifies the method invloked when reporting
217 * that a reset has completed to the remote device.
218 */
219 SCI_BASE_REMOTE_DEVICE_HANDLER_T reset_complete_handler;
220
221 /**
222 * The start_io_handler specifies the method invoked when a user
223 * attempts to start an IO request for a remote device.
224 */
225 SCI_BASE_REMOTE_DEVICE_REQUEST_HANDLER_T start_io_handler;
226
227 /**
228 * The complete_io_handler specifies the method invoked when a user
229 * attempts to complete an IO request for a remote device.
230 */
231 SCI_BASE_REMOTE_DEVICE_REQUEST_HANDLER_T complete_io_handler;
232
233 /**
234 * The continue_io_handler specifies the method invoked when a user
235 * attempts to continue an IO request for a remote device.
236 */
237 SCI_BASE_REMOTE_DEVICE_REQUEST_HANDLER_T continue_io_handler;
238
239 /**
240 * The start_task_handler specifies the method invoked when a user
241 * attempts to start a task management request for a remote device.
242 */
243 SCI_BASE_REMOTE_DEVICE_REQUEST_HANDLER_T start_task_handler;
244
245 /**
246 * The complete_task_handler specifies the method invoked when a user
247 * attempts to complete a task management request for a remote device.
248 */
249 SCI_BASE_REMOTE_DEVICE_REQUEST_HANDLER_T complete_task_handler;
250
251};
252
253/**
254 * sci_base_remote_device_construct() - Construct the base remote device
255 * @this_remote_device: This parameter specifies the base remote device to be
256 * constructed.
257 * @state_table: This parameter specifies the table of state definitions to be
258 * utilized for the remote device state machine.
259 *
260 */
261static inline void sci_base_remote_device_construct(
262 struct sci_base_remote_device *base_dev,
263 const struct sci_base_state *state_table)
264{
265 base_dev->parent.private = NULL;
266 sci_base_state_machine_construct(
267 &base_dev->state_machine,
268 &base_dev->parent,
269 state_table,
270 SCI_BASE_REMOTE_DEVICE_STATE_INITIAL
271 );
272
273 sci_base_state_machine_start(
274 &base_dev->state_machine
275 );
276}
277#endif /* _SCI_BASE_REMOTE_DEVICE_H_ */
diff --git a/drivers/scsi/isci/core/sci_base_request.h b/drivers/scsi/isci/core/sci_base_request.h
new file mode 100644
index 000000000000..d1b2195b228a
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_base_request.h
@@ -0,0 +1,195 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_BASE_REQUST_H_
57#define _SCI_BASE_REQUST_H_
58
59/**
60 * This file contains all of the constants, types, and method declarations for
61 * the SCI base IO and task request objects.
62 *
63 *
64 */
65
66#include "sci_base_state_machine.h"
67
68/**
69 * enum sci_base_request_states - This enumeration depicts all the states for
70 * the common request state machine.
71 *
72 *
73 */
74enum sci_base_request_states {
75 /**
76 * Simply the initial state for the base request state machine.
77 */
78 SCI_BASE_REQUEST_STATE_INITIAL,
79
80 /**
81 * This state indicates that the request has been constructed. This state
82 * is entered from the INITIAL state.
83 */
84 SCI_BASE_REQUEST_STATE_CONSTRUCTED,
85
86 /**
87 * This state indicates that the request has been started. This state is
88 * entered from the CONSTRUCTED state.
89 */
90 SCI_BASE_REQUEST_STATE_STARTED,
91
92 /**
93 * This state indicates that the request has completed.
94 * This state is entered from the STARTED state. This state is entered from
95 * the ABORTING state.
96 */
97 SCI_BASE_REQUEST_STATE_COMPLETED,
98
99 /**
100 * This state indicates that the request is in the process of being
101 * terminated/aborted.
102 * This state is entered from the CONSTRUCTED state.
103 * This state is entered from the STARTED state.
104 */
105 SCI_BASE_REQUEST_STATE_ABORTING,
106
107 /**
108 * Simply the final state for the base request state machine.
109 */
110 SCI_BASE_REQUEST_STATE_FINAL,
111};
112
113/**
114 * struct sci_base_request - The base request object abstracts the fields
115 * common to all SCI IO and task request objects.
116 *
117 *
118 */
119struct sci_base_request {
120 /**
121 * The field specifies that the parent object for the base request is the
122 * base object itself.
123 */
124 struct sci_base_object parent;
125
126 /**
127 * This field contains the information for the base request state machine.
128 */
129 struct sci_base_state_machine state_machine;
130};
131
132typedef enum sci_status (*SCI_BASE_REQUEST_HANDLER_T)(
133 struct sci_base_request *this_request
134 );
135
136/**
137 * struct sci_base_request_state_handler - This structure contains all of the
138 * state handler methods common to base IO and task request state machines.
139 * Handler methods provide the ability to change the behavior for user
140 * requests or transitions depending on the state the machine is in.
141 *
142 *
143 */
144struct sci_base_request_state_handler {
145 /**
146 * The start_handler specifies the method invoked when a user attempts to
147 * start a request.
148 */
149 SCI_BASE_REQUEST_HANDLER_T start_handler;
150
151 /**
152 * The abort_handler specifies the method invoked when a user attempts to
153 * abort a request.
154 */
155 SCI_BASE_REQUEST_HANDLER_T abort_handler;
156
157 /**
158 * The complete_handler specifies the method invoked when a user attempts to
159 * complete a request.
160 */
161 SCI_BASE_REQUEST_HANDLER_T complete_handler;
162
163 /**
164 * The destruct_handler specifies the method invoked when a user attempts to
165 * destruct a request.
166 */
167 SCI_BASE_REQUEST_HANDLER_T destruct_handler;
168
169};
170
171/**
172 * sci_base_request_construct() - Construct the base request.
173 * @this_request: This parameter specifies the base request to be constructed.
174 * @state_table: This parameter specifies the table of state definitions to be
175 * utilized for the request state machine.
176 *
177 */
178static inline void sci_base_request_construct(
179 struct sci_base_request *base_req,
180 const struct sci_base_state *my_state_table)
181{
182 base_req->parent.private = NULL;
183 sci_base_state_machine_construct(
184 &base_req->state_machine,
185 &base_req->parent,
186 my_state_table,
187 SCI_BASE_REQUEST_STATE_INITIAL
188 );
189
190 sci_base_state_machine_start(
191 &base_req->state_machine
192 );
193}
194
195#endif /* _SCI_BASE_REQUST_H_ */
diff --git a/drivers/scsi/isci/core/sci_base_state.h b/drivers/scsi/isci/core/sci_base_state.h
new file mode 100644
index 000000000000..d6b9c1a951b1
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_base_state.h
@@ -0,0 +1,90 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_BASE_STATE_H_
57#define _SCI_BASE_STATE_H_
58
59#include "sci_object.h"
60
61typedef void (*SCI_BASE_STATE_HANDLER_T)(
62 void
63 );
64
65typedef void (*SCI_STATE_TRANSITION_T)(
66 struct sci_base_object *base_object
67 );
68
69/**
70 * struct sci_base_state - The base state object abstracts the fields common to
71 * all state objects defined in SCI.
72 *
73 *
74 */
75struct sci_base_state {
76 /**
77 * This field is a function pointer that defines the method to be
78 * invoked when the state is entered.
79 */
80 SCI_STATE_TRANSITION_T enter_state;
81
82 /**
83 * This field is a function pointer that defines the method to be
84 * invoked when the state is exited.
85 */
86 SCI_STATE_TRANSITION_T exit_state;
87
88};
89
90#endif /* _SCI_BASE_STATE_H_ */
diff --git a/drivers/scsi/isci/core/sci_base_state_machine.c b/drivers/scsi/isci/core/sci_base_state_machine.c
new file mode 100644
index 000000000000..5b1e8da55fe6
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_base_state_machine.c
@@ -0,0 +1,182 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file contains all of the functionality common to all state machine
58 * object implementations.
59 *
60 *
61 */
62
63#include "sci_base_state_machine.h"
64
65static void sci_state_machine_exit_state(struct sci_base_state_machine *sm)
66{
67 u32 state = sm->current_state_id;
68 SCI_STATE_TRANSITION_T exit = sm->state_table[state].exit_state;
69
70 if (exit)
71 exit(sm->state_machine_owner);
72}
73
74static void sci_state_machine_enter_state(struct sci_base_state_machine *sm)
75{
76 u32 state = sm->current_state_id;
77 SCI_STATE_TRANSITION_T enter = sm->state_table[state].enter_state;
78
79 if (enter)
80 enter(sm->state_machine_owner);
81}
82
83/*
84 * ******************************************************************************
85 * * P R O T E C T E D M E T H O D S
86 * ****************************************************************************** */
87
88/**
89 * This method will set the initial state and state table for the state
90 * machine. The caller should follow this request with the initialize
91 * request to cause the state machine to start.
92 * @sm: This parameter provides the state machine object to be
93 * constructed.
94 * @state_machine_owner: This parameter indicates the object that is owns the
95 * state machine being constructed.
96 * @state_table: This parameter specifies the table of state objects that is
97 * managed by this state machine.
98 * @initial_state: This parameter specifies the value of the initial state for
99 * this state machine.
100 *
101 */
102void sci_base_state_machine_construct(struct sci_base_state_machine *sm,
103 struct sci_base_object *owner,
104 const struct sci_base_state *state_table,
105 u32 initial_state)
106{
107 sm->state_machine_owner = owner;
108 sm->initial_state_id = initial_state;
109 sm->previous_state_id = initial_state;
110 sm->current_state_id = initial_state;
111 sm->state_table = state_table;
112}
113
114/**
115 * This method will cause the state machine to enter the initial state.
116 * @sm: This parameter specifies the state machine that is to
117 * be started.
118 *
119 * sci_base_state_machine_construct() for how to set the initial state none
120 */
121void sci_base_state_machine_start(struct sci_base_state_machine *sm)
122{
123 sm->current_state_id = sm->initial_state_id;
124#if defined(SCI_BASE_ENABLE_SUBJECT_NOTIFICATION)
125 sci_base_subject_notify(&sm->parent);
126#endif
127 sci_state_machine_enter_state(sm);
128}
129
130/**
131 * This method will cause the state machine to exit it's current state only.
132 * @sm: This parameter specifies the state machine that is to
133 * be stopped.
134 *
135 */
136void sci_base_state_machine_stop(
137 struct sci_base_state_machine *sm)
138{
139 sci_state_machine_exit_state(sm);
140#if defined(SCI_BASE_ENABLE_SUBJECT_NOTIFICATION)
141 sci_base_subject_notify(&sm->parent);
142#endif
143}
144
145/**
146 * This method performs an update to the current state of the state machine.
147 * @sm: This parameter specifies the state machine for which
148 * the caller wishes to perform a state change.
149 * @next_state: This parameter specifies the new state for the state machine.
150 *
151 */
152void sci_base_state_machine_change_state(
153 struct sci_base_state_machine *sm,
154 u32 next_state)
155{
156 sci_state_machine_exit_state(sm);
157
158 sm->previous_state_id = sm->current_state_id;
159 sm->current_state_id = next_state;
160
161#if defined(SCI_BASE_ENABLE_SUBJECT_NOTIFICATION)
162 /* Notify of the state change prior to entering the state. */
163 sci_base_subject_notify(&sm->parent);
164#endif
165
166 sci_state_machine_enter_state(sm);
167}
168
169/**
170 * This method simply returns the current state of the state machine to the
171 * caller.
172 * @sm: This parameter specifies the state machine for which to
173 * retrieve the current state.
174 *
175 * This method returns a u32 value indicating the current state for the
176 * supplied state machine.
177 */
178u32 sci_base_state_machine_get_state(struct sci_base_state_machine *sm)
179{
180 return sm->current_state_id;
181}
182
diff --git a/drivers/scsi/isci/core/sci_base_state_machine.h b/drivers/scsi/isci/core/sci_base_state_machine.h
new file mode 100644
index 000000000000..cee38bd3d127
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_base_state_machine.h
@@ -0,0 +1,139 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_BASE_STATE_MACHINE_H_
57#define _SCI_BASE_STATE_MACHINE_H_
58
59/**
60 * This file contains all structures, constants, or method declarations common
61 * to all state machines defined in SCI.
62 *
63 *
64 */
65
66
67#include "sci_base_state.h"
68
69
70/**
71 * SET_STATE_HANDLER() -
72 *
73 * This macro simply provides simplified retrieval of an objects state handler.
74 */
75#define SET_STATE_HANDLER(object, table, state) \
76 (object)->state_handlers = &(table)[(state)]
77
78/**
79 * struct sci_base_state_machine - This structure defines the fields common to
80 * all state machines.
81 *
82 *
83 */
84struct sci_base_state_machine {
85 /**
86 * This field points to the start of the state machine's state table.
87 */
88 const struct sci_base_state *state_table;
89
90 /**
91 * This field points to the object to which this state machine is
92 * associated. It serves as a cookie to be provided to the state
93 * enter/exit methods.
94 */
95 struct sci_base_object *state_machine_owner;
96
97 /**
98 * This field simply indicates the state value for the state machine's
99 * initial state.
100 */
101 u32 initial_state_id;
102
103 /**
104 * This field indicates the current state of the state machine.
105 */
106 u32 current_state_id;
107
108 /**
109 * This field indicates the previous state of the state machine.
110 */
111 u32 previous_state_id;
112
113};
114
115/*
116 * ******************************************************************************
117 * * P R O T E C T E D M E T H O D S
118 * ****************************************************************************** */
119
120void sci_base_state_machine_construct(
121 struct sci_base_state_machine *this_state_machine,
122 struct sci_base_object *state_machine_owner,
123 const struct sci_base_state *state_table,
124 u32 initial_state);
125
126void sci_base_state_machine_start(
127 struct sci_base_state_machine *this_state_machine);
128
129void sci_base_state_machine_stop(
130 struct sci_base_state_machine *this_state_machine);
131
132void sci_base_state_machine_change_state(
133 struct sci_base_state_machine *this_state_machine,
134 u32 next_state);
135
136u32 sci_base_state_machine_get_state(
137 struct sci_base_state_machine *this_state_machine);
138
139#endif /* _SCI_BASE_STATE_MACHINE_H_ */
diff --git a/drivers/scsi/isci/core/sci_controller.h b/drivers/scsi/isci/core/sci_controller.h
new file mode 100644
index 000000000000..26c3548cbf7a
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_controller.h
@@ -0,0 +1,100 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_CONTROLLER_H_
57#define _SCI_CONTROLLER_H_
58
59/**
60 * This file contains all of the interface methods that can be called by an SCI
61 * user on all SCI controller objects.
62 *
63 *
64 */
65
66
67#include "sci_types.h"
68
69struct sci_base_memory_descriptor_list;
70struct scic_sds_controller;
71
72#define SCI_CONTROLLER_INVALID_IO_TAG 0xFFFF
73
74/**
75 * sci_controller_get_memory_descriptor_list_handle() - This method simply
76 * returns a handle for the memory descriptor list associated with the
77 * supplied controller. The descriptor list provides DMA safe/capable
78 * memory requirements for this controller.
79 * @controller: This parameter specifies the controller for which to retrieve
80 * the DMA safe memory descriptor list.
81 *
82 * The user must adhere to the alignment requirements specified in memory
83 * descriptor. In situations where the operating environment does not offer
84 * memory allocation utilities supporting alignment, then it is the
85 * responsibility of the user to manually align the memory buffer for SCI.
86 * Thus, the user may have to allocate a larger buffer to meet the alignment.
87 * Additionally, the user will need to remember the actual memory allocation
88 * addresses in order to ensure the memory can be properly freed when necessary
89 * to do so. This method will return a valid handle, but the MDL may not be
90 * accurate until after the user has invoked the associated
91 * sci_controller_initialize() routine. A pointer to a physical memory
92 * descriptor array.
93 */
94struct sci_base_memory_descriptor_list *
95 sci_controller_get_memory_descriptor_list_handle(
96 struct scic_sds_controller *controller);
97
98
99#endif /* _SCI_CONTROLLER_H_ */
100
diff --git a/drivers/scsi/isci/core/sci_controller_constants.h b/drivers/scsi/isci/core/sci_controller_constants.h
new file mode 100644
index 000000000000..06c34c7bdd5f
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_controller_constants.h
@@ -0,0 +1,215 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_CONTROLLER_CONSTANTS_H_
57#define _SCI_CONTROLLER_CONSTANTS_H_
58
59/**
60 * This file contains constant values that change based on the type of core or
61 * framework being managed. These constants are exported in order to
62 * provide the user with information as to the bounds (i.e. how many) of
63 * specific objects.
64 *
65 *
66 */
67
68
69#ifdef SCIC_SDS_4_ENABLED
70
71#ifndef SCI_MAX_PHYS
72/**
73 *
74 *
75 * This constant defines the maximum number of phy objects that can be
76 * supported for the SCU Driver Standard (SDS) library. This is tied directly
77 * to silicon capabilities.
78 */
79#define SCI_MAX_PHYS (4)
80#endif
81
82#ifndef SCI_MAX_PORTS
83/**
84 *
85 *
86 * This constant defines the maximum number of port objects that can be
87 * supported for the SCU Driver Standard (SDS) library. This is tied directly
88 * to silicon capabilities.
89 */
90#define SCI_MAX_PORTS SCI_MAX_PHYS
91#endif
92
93#ifndef SCI_MIN_SMP_PHYS
94/**
95 *
96 *
97 * This constant defines the minimum number of SMP phy objects that can be
98 * supported for a single expander level. This was determined by using 36
99 * physical phys and room for 2 virtual phys.
100 */
101#define SCI_MIN_SMP_PHYS (38)
102#endif
103
104#ifndef SCI_MAX_SMP_PHYS
105/**
106 *
107 *
108 * This constant defines the maximum number of SMP phy objects that can be
109 * supported for the SCU Driver Standard (SDS) library. This number can be
110 * increased if required.
111 */
112#define SCI_MAX_SMP_PHYS (384)
113#endif
114
115#ifndef SCI_MAX_REMOTE_DEVICES
116/**
117 *
118 *
119 * This constant defines the maximum number of remote device objects that can
120 * be supported for the SCU Driver Standard (SDS) library. This is tied
121 * directly to silicon capabilities.
122 */
123#define SCI_MAX_REMOTE_DEVICES (256)
124#endif
125
126#ifndef SCI_MIN_REMOTE_DEVICES
127/**
128 *
129 *
130 * This constant defines the minimum number of remote device objects that can
131 * be supported for the SCU Driver Standard (SDS) library. This # can be
132 * configured for minimum memory environments to any value less than
133 * SCI_MAX_REMOTE_DEVICES
134 */
135#define SCI_MIN_REMOTE_DEVICES (16)
136#endif
137
138#ifndef SCI_MAX_IO_REQUESTS
139/**
140 *
141 *
142 * This constant defines the maximum number of IO request objects that can be
143 * supported for the SCU Driver Standard (SDS) library. This is tied directly
144 * to silicon capabilities.
145 */
146#define SCI_MAX_IO_REQUESTS (256)
147#endif
148
149#ifndef SCI_MIN_IO_REQUESTS
150/**
151 *
152 *
153 * This constant defines the minimum number of IO request objects that can be
154 * supported for the SCU Driver Standard (SDS) library. This # can be
155 * configured for minimum memory environments to any value less than
156 * SCI_MAX_IO_REQUESTS.
157 */
158#define SCI_MIN_IO_REQUESTS (1)
159#endif
160
161#ifndef SCI_MAX_MSIX_MESSAGES
162/**
163 *
164 *
165 * This constant defines the maximum number of MSI-X interrupt vectors/messages
166 * supported for an SCU hardware controller instance.
167 */
168#define SCI_MAX_MSIX_MESSAGES (2)
169#endif
170
171#ifndef SCI_MAX_SCATTER_GATHER_ELEMENTS
172/**
173 *
174 *
175 * This constant defines the maximum number of Scatter-Gather Elements to be
176 * used by any SCI component.
177 */
178#define SCI_MAX_SCATTER_GATHER_ELEMENTS 130
179#endif
180
181#ifndef SCI_MIN_SCATTER_GATHER_ELEMENTS
182/**
183 *
184 *
185 * This constant defines the minimum number of Scatter-Gather Elements to be
186 * used by any SCI component.
187 */
188#define SCI_MIN_SCATTER_GATHER_ELEMENTS 1
189#endif
190
191#else /* SCIC_SDS_4_ENABLED */
192
193#error "SCI Core configuration left unspecified (e.g. SCIC_SDS_4_ENABLED)"
194
195#endif /* SCIC_SDS_4_ENABLED */
196
197/**
198 *
199 *
200 * This constant defines the maximum number of controllers that can occur in a
201 * single silicon package.
202 */
203#define SCI_MAX_CONTROLLERS 2
204
205/**
206 *
207 *
208 * The maximum number of supported domain objects is currently tied to the
209 * maximum number of support port objects.
210 */
211#define SCI_MAX_DOMAINS SCI_MAX_PORTS
212
213
214#endif /* _SCI_CONTROLLER_CONSTANTS_H_ */
215
diff --git a/drivers/scsi/isci/core/sci_memory_descriptor_list.h b/drivers/scsi/isci/core/sci_memory_descriptor_list.h
new file mode 100644
index 000000000000..44de1c18d2c8
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_memory_descriptor_list.h
@@ -0,0 +1,169 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_MEMORY_DESCRIPTOR_LIST_H_
57#define _SCI_MEMORY_DESCRIPTOR_LIST_H_
58
59/**
60 * This file contains all of the basic data types utilized by an SCI user or
61 * implementor.
62 *
63 *
64 */
65
66
67#include "sci_types.h"
68
69struct sci_base_memory_descriptor_list;
70
71/**
72 *
73 *
74 * SCI_MDE_ATTRIBUTES These constants depict memory attributes for the Memory
75 * Descriptor Entries (MDEs) contained in the MDL.
76 */
77#define SCI_MDE_ATTRIBUTE_CACHEABLE 0x0001
78#define SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS 0x0002
79
80/**
81 * struct sci_physical_memory_descriptor - This structure defines a description
82 * of a memory location for the SCI implementation.
83 *
84 *
85 */
86struct sci_physical_memory_descriptor {
87 /**
88 * This field contains the virtual address associated with this descriptor
89 * element. This field shall be zero when the descriptor is retrieved from
90 * the SCI implementation. The user shall set this field prior
91 * sci_controller_start()
92 */
93 void *virtual_address;
94
95 /**
96 * This field contains the physical address associated with this desciptor
97 * element. This field shall be zero when the descriptor is retrieved from
98 * the SCI implementation. The user shall set this field prior
99 * sci_controller_start()
100 */
101 dma_addr_t physical_address;
102
103 /**
104 * This field contains the size requirement for this memory descriptor.
105 * A value of zero for this field indicates the end of the descriptor
106 * list. The value should be treated as read only for an SCI user.
107 */
108 u32 constant_memory_size;
109
110 /**
111 * This field contains the alignment requirement for this memory
112 * descriptor. A value of zero for this field indicates the end of the
113 * descriptor list. All other values indicate the number of bytes to
114 * achieve the necessary alignment. The value should be treated as
115 * read only for an SCI user.
116 */
117 u32 constant_memory_alignment;
118
119 /**
120 * This field contains an indication regarding the desired memory
121 * attributes for this memory descriptor entry.
122 * Notes:
123 * - If the cacheable attribute is set, the user can allocate
124 * memory that is backed by cache for better performance. It
125 * is not required that the memory be backed by cache.
126 * - If the physically contiguous attribute is set, then the
127 * entire memory must be physically contiguous across all
128 * page boundaries.
129 */
130 u16 constant_memory_attributes;
131
132};
133
134/**
135 * sci_mdl_first_entry() - This method simply rewinds the MDL iterator back to
136 * the first memory descriptor entry in the list.
137 * @mdl: This parameter specifies the memory descriptor list that is to be
138 * rewound.
139 *
140 */
141void sci_mdl_first_entry(
142 struct sci_base_memory_descriptor_list *mdl);
143
144/**
145 * sci_mdl_next_entry() - This method simply updates the "current" pointer to
146 * the next sequential memory descriptor.
147 * @mdl: This parameter specifies the memory descriptor list for which to
148 * return the next memory descriptor entry in the list.
149 *
150 * none.
151 */
152void sci_mdl_next_entry(
153 struct sci_base_memory_descriptor_list *mdl);
154
155/**
156 * sci_mdl_get_current_entry() - This method simply returns the current memory
157 * descriptor entry.
158 * @mdl: This parameter specifies the memory descriptor list for which to
159 * return the current memory descriptor entry.
160 *
161 * This method returns a pointer to the current physical memory descriptor in
162 * the MDL. NULL This value is returned if there are no descriptors in the list.
163 */
164struct sci_physical_memory_descriptor *sci_mdl_get_current_entry(
165 struct sci_base_memory_descriptor_list *mdl);
166
167
168#endif /* _SCI_MEMORY_DESCRIPTOR_LIST_H_ */
169
diff --git a/drivers/scsi/isci/core/sci_object.h b/drivers/scsi/isci/core/sci_object.h
new file mode 100644
index 000000000000..930694264f1a
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_object.h
@@ -0,0 +1,99 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_OBJECT_H_
57#define _SCI_OBJECT_H_
58
59/**
60 * This file contains all of the method and constants associated with the SCI
61 * base object. The SCI base object is the class from which all other
62 * objects derive in the Storage Controller Interface.
63 *
64 *
65 */
66
67
68#include "sci_types.h"
69#include "sci_status.h"
70
71/**
72 * struct sci_base_object - all core objects must include this as their
73 * first member to permit the casting below
74 *
75 * TODO: unwind this assumption, convert these routines and callers to pass a struct
76 * sci_base_object pointer without casting, or convert 'private' to the
77 * expected type per-object
78 *
79 */
80struct sci_base_object {
81 void *private;
82};
83
84static inline void *sci_object_get_association(void *obj)
85{
86 struct sci_base_object *base = obj;
87
88 return base->private;
89}
90
91static inline void sci_object_set_association(void *obj, void *private)
92{
93 struct sci_base_object *base = obj;
94
95 base->private = private;
96}
97
98#endif /* _SCI_OBJECT_H_ */
99
diff --git a/drivers/scsi/isci/core/sci_pool.h b/drivers/scsi/isci/core/sci_pool.h
new file mode 100644
index 000000000000..c0d2ea32529b
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_pool.h
@@ -0,0 +1,199 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file contains the interface to the pool class. This class allows two
58 * different two different priority tasks to insert and remove items from
59 * the free pool. The user of the pool is expected to evaluate the pool
60 * condition empty before a get operation and pool condition full before a
61 * put operation. Methods Provided: - sci_pool_create() -
62 * sci_pool_initialize() - sci_pool_empty() - sci_pool_full() -
63 * sci_pool_get() - sci_pool_put()
64 *
65 *
66 */
67
68#ifndef _SCI_POOL_H_
69#define _SCI_POOL_H_
70
71/**
72 * SCI_POOL_INCREMENT() -
73 *
74 * Private operation for the pool
75 */
76#define SCI_POOL_INCREMENT(this_pool, index) \
77 (((index) + 1) == (this_pool).size ? 0 : (index) + 1)
78
79/**
80 * SCI_POOL_CREATE() -
81 *
82 * This creates a pool structure of pool_name. The members in the pool are of
83 * type with number of elements equal to size.
84 */
85#define SCI_POOL_CREATE(pool_name, type, pool_size) \
86 struct \
87 { \
88 u32 size; \
89 u32 get; \
90 u32 put; \
91 type array[(pool_size) + 1]; \
92 } pool_name
93
94
95/**
96 * sci_pool_empty() -
97 *
98 * This macro evaluates the pool and returns true if the pool is empty. If the
99 * pool is empty the user should not perform any get operation on the pool.
100 */
101#define sci_pool_empty(this_pool) \
102 ((this_pool).get == (this_pool).put)
103
104/**
105 * sci_pool_full() -
106 *
107 * This macro evaluates the pool and returns true if the pool is full. If the
108 * pool is full the user should not perform any put operation.
109 */
110#define sci_pool_full(this_pool) \
111 (SCI_POOL_INCREMENT(this_pool, (this_pool).put) == (this_pool).get)
112
113/**
114 * sci_pool_size() -
115 *
116 * This macro returns the size of the pool created. The internal size of the
117 * pool is actually 1 larger then necessary in order to ensure get and put
118 * pointers can be written simultaneously by different users. As a result,
119 * this macro subtracts 1 from the internal size
120 */
121#define sci_pool_size(this_pool) \
122 ((this_pool).size - 1)
123
124/**
125 * sci_pool_count() -
126 *
127 * This macro indicates the number of elements currently contained in the pool.
128 */
129#define sci_pool_count(this_pool) \
130 (\
131 sci_pool_empty((this_pool)) \
132 ? 0 \
133 : (\
134 sci_pool_full((this_pool)) \
135 ? sci_pool_size((this_pool)) \
136 : (\
137 (this_pool).get > (this_pool).put \
138 ? ((this_pool).size - (this_pool).get + (this_pool).put) \
139 : ((this_pool).put - (this_pool).get) \
140 ) \
141 ) \
142 )
143
144/**
145 * sci_pool_initialize() -
146 *
147 * This macro initializes the pool to an empty condition.
148 */
149#define sci_pool_initialize(this_pool) \
150 { \
151 (this_pool).size = (sizeof((this_pool).array) / sizeof((this_pool).array[0])); \
152 (this_pool).get = 0; \
153 (this_pool).put = 0; \
154 }
155
156/**
157 * sci_pool_get() -
158 *
159 * This macro will get the next free element from the pool. This should only be
160 * called if the pool is not empty.
161 */
162#define sci_pool_get(this_pool, my_value) \
163 { \
164 (my_value) = (this_pool).array[(this_pool).get]; \
165 (this_pool).get = SCI_POOL_INCREMENT((this_pool), (this_pool).get); \
166 }
167
168/**
169 * sci_pool_put() -
170 *
171 * This macro will put the value into the pool. This should only be called if
172 * the pool is not full.
173 */
174#define sci_pool_put(this_pool, the_value) \
175 { \
176 (this_pool).array[(this_pool).put] = (the_value); \
177 (this_pool).put = SCI_POOL_INCREMENT((this_pool), (this_pool).put); \
178 }
179
180/**
181 * sci_pool_erase() -
182 *
183 * This macro will search the pool and remove any elements in the pool matching
184 * the supplied value. This method can only be utilized on pools
185 */
186#define sci_pool_erase(this_pool, type, the_value) \
187 { \
188 type tmp_value; \
189 u32 index; \
190 u32 element_count = sci_pool_count((this_pool)); \
191 \
192 for (index = 0; index < element_count; index++) { \
193 sci_pool_get((this_pool), tmp_value); \
194 if (tmp_value != (the_value)) \
195 sci_pool_put((this_pool), tmp_value); \
196 } \
197 }
198
199#endif /* _SCI_POOL_H_ */
diff --git a/drivers/scsi/isci/core/sci_status.h b/drivers/scsi/isci/core/sci_status.h
new file mode 100644
index 000000000000..72b61081c28d
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_status.h
@@ -0,0 +1,409 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_STATUS_H_
57#define _SCI_STATUS_H_
58
59/**
60 * This file contains all of the return status codes utilized across the
61 * various sub-components in SCI.
62 *
63 *
64 */
65
66
67/**
68 * enum _SCI_STATUS - This is the general return status enumeration for non-IO,
69 * non-task management related SCI interface methods.
70 *
71 *
72 */
73enum sci_status {
74 /**
75 * This member indicates successful completion.
76 */
77 SCI_SUCCESS = 0,
78
79 /**
80 * This value indicates that the calling method completed successfully,
81 * but that the IO may have completed before having it's start method
82 * invoked. This occurs during SAT translation for requests that do
83 * not require an IO to the target or for any other requests that may
84 * be completed without having to submit IO.
85 */
86 SCI_SUCCESS_IO_COMPLETE_BEFORE_START,
87
88 /**
89 * This Value indicates that the SCU hardware returned an early response
90 * because the io request specified more data than is returned by the
91 * target device (mode pages, inquiry data, etc.). The completion routine
92 * will handle this case to get the actual number of bytes transferred.
93 */
94 SCI_SUCCESS_IO_DONE_EARLY,
95
96 /**
97 * This member indicates that the object for which a state change is
98 * being requested is already in said state.
99 */
100 SCI_WARNING_ALREADY_IN_STATE,
101
102 /**
103 * This member indicates interrupt coalescence timer may cause SAS
104 * specification compliance issues (i.e. SMP target mode response
105 * frames must be returned within 1.9 milliseconds).
106 */
107 SCI_WARNING_TIMER_CONFLICT,
108
109 /**
110 * This field indicates a sequence of action is not completed yet. Mostly,
111 * this status is used when multiple ATA commands are needed in a SATI translation.
112 */
113 SCI_WARNING_SEQUENCE_INCOMPLETE,
114
115 /**
116 * This member indicates that there was a general failure.
117 */
118 SCI_FAILURE,
119
120 /**
121 * This member indicates that the SCI implementation is unable to complete
122 * an operation due to a critical flaw the prevents any further operation
123 * (i.e. an invalid pointer).
124 */
125 SCI_FATAL_ERROR,
126
127 /**
128 * This member indicates the calling function failed, because the state
129 * of the controller is in a state that prevents successful completion.
130 */
131 SCI_FAILURE_INVALID_STATE,
132
133 /**
134 * This member indicates the calling function failed, because there is
135 * insufficient resources/memory to complete the request.
136 */
137 SCI_FAILURE_INSUFFICIENT_RESOURCES,
138
139 /**
140 * This member indicates the calling function failed, because the
141 * controller object required for the operation can't be located.
142 */
143 SCI_FAILURE_CONTROLLER_NOT_FOUND,
144
145 /**
146 * This member indicates the calling function failed, because the
147 * discovered controller type is not supported by the library.
148 */
149 SCI_FAILURE_UNSUPPORTED_CONTROLLER_TYPE,
150
151 /**
152 * This member indicates the calling function failed, because the
153 * requested initialization data version isn't supported.
154 */
155 SCI_FAILURE_UNSUPPORTED_INIT_DATA_VERSION,
156
157 /**
158 * This member indicates the calling function failed, because the
159 * requested configuration of SAS Phys into SAS Ports is not supported.
160 */
161 SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION,
162
163 /**
164 * This member indicates the calling function failed, because the
165 * requested protocol is not supported by the remote device, port,
166 * or controller.
167 */
168 SCI_FAILURE_UNSUPPORTED_PROTOCOL,
169
170 /**
171 * This member indicates the calling function failed, because the
172 * requested information type is not supported by the SCI implementation.
173 */
174 SCI_FAILURE_UNSUPPORTED_INFORMATION_TYPE,
175
176 /**
177 * This member indicates the calling function failed, because the
178 * device already exists.
179 */
180 SCI_FAILURE_DEVICE_EXISTS,
181
182 /**
183 * This member indicates the calling function failed, because adding
184 * a phy to the object is not possible.
185 */
186 SCI_FAILURE_ADDING_PHY_UNSUPPORTED,
187
188 /**
189 * This member indicates the calling function failed, because the
190 * requested information type is not supported by the SCI implementation.
191 */
192 SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD,
193
194 /**
195 * This member indicates the calling function failed, because the SCI
196 * implementation does not support the supplied time limit.
197 */
198 SCI_FAILURE_UNSUPPORTED_TIME_LIMIT,
199
200 /**
201 * This member indicates the calling method failed, because the SCI
202 * implementation does not contain the specified Phy.
203 */
204 SCI_FAILURE_INVALID_PHY,
205
206 /**
207 * This member indicates the calling method failed, because the SCI
208 * implementation does not contain the specified Port.
209 */
210 SCI_FAILURE_INVALID_PORT,
211
212 /**
213 * This member indicates the calling method was partly successful
214 * The port was reset but not all phys in port are operational
215 */
216 SCI_FAILURE_RESET_PORT_PARTIAL_SUCCESS,
217
218 /**
219 * This member indicates that calling method failed
220 * The port reset did not complete because none of the phys are operational
221 */
222 SCI_FAILURE_RESET_PORT_FAILURE,
223
224 /**
225 * This member indicates the calling method failed, because the SCI
226 * implementation does not contain the specified remote device.
227 */
228 SCI_FAILURE_INVALID_REMOTE_DEVICE,
229
230 /**
231 * This member indicates the calling method failed, because the remote
232 * device is in a bad state and requires a reset.
233 */
234 SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED,
235
236 /**
237 * This member indicates the calling method failed, because the SCI
238 * implementation does not contain or support the specified IO tag.
239 */
240 SCI_FAILURE_INVALID_IO_TAG,
241
242 /**
243 * This member indicates that the operation failed and the user should
244 * check the response data associated with the IO.
245 */
246 SCI_FAILURE_IO_RESPONSE_VALID,
247
248 /**
249 * This member indicates that the operation failed, the failure is
250 * controller implementation specific, and the response data associated
251 * with the request is not valid. You can query for the controller
252 * specific error information via scic_controller_get_request_status()
253 */
254 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR,
255
256 /**
257 * This member indicated that the operation failed because the
258 * user requested this IO to be terminated.
259 */
260 SCI_FAILURE_IO_TERMINATED,
261
262 /**
263 * This member indicates that the operation failed and the associated
264 * request requires a SCSI abort task to be sent to the target.
265 */
266 SCI_FAILURE_IO_REQUIRES_SCSI_ABORT,
267
268 /**
269 * This member indicates that the operation failed because the supplied
270 * device could not be located.
271 */
272 SCI_FAILURE_DEVICE_NOT_FOUND,
273
274 /**
275 * This member indicates that the operation failed because the
276 * objects association is required and is not correctly set.
277 */
278 SCI_FAILURE_INVALID_ASSOCIATION,
279
280 /**
281 * This member indicates that the operation failed, because a timeout
282 * occurred.
283 */
284 SCI_FAILURE_TIMEOUT,
285
286 /**
287 * This member indicates that the operation failed, because the user
288 * specified a value that is either invalid or not supported.
289 */
290 SCI_FAILURE_INVALID_PARAMETER_VALUE,
291
292 /**
293 * This value indicates that the operation failed, because the number
294 * of messages (MSI-X) is not supported.
295 */
296 SCI_FAILURE_UNSUPPORTED_MESSAGE_COUNT,
297
298 /**
299 * This value indicates that the method failed due to a lack of
300 * available NCQ tags.
301 */
302 SCI_FAILURE_NO_NCQ_TAG_AVAILABLE,
303
304 /**
305 * This value indicates that a protocol violation has occurred on the
306 * link.
307 */
308 SCI_FAILURE_PROTOCOL_VIOLATION,
309
310 /**
311 * This value indicates a failure condition that retry may help to clear.
312 */
313 SCI_FAILURE_RETRY_REQUIRED,
314
315 /**
316 * This field indicates the retry limit was reached when a retry is attempted
317 */
318 SCI_FAILURE_RETRY_LIMIT_REACHED,
319
320 /**
321 * This member indicates the calling method was partly successful.
322 * Mostly, this status is used when a LUN_RESET issued to an expander attached
323 * STP device in READY NCQ substate needs to have RNC suspended/resumed
324 * before posting TC.
325 */
326 SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS,
327
328 /**
329 * This field indicates an illegal phy connection based on the routing attribute
330 * of both expander phy attached to each other.
331 */
332 SCI_FAILURE_ILLEGAL_ROUTING_ATTRIBUTE_CONFIGURATION,
333
334 /**
335 * This field indicates a CONFIG ROUTE INFO command has a response with function result
336 * INDEX DOES NOT EXIST, usually means exceeding max route index.
337 */
338 SCI_FAILURE_EXCEED_MAX_ROUTE_INDEX,
339
340 /**
341 * This value indicates that an unsupported PCI device ID has been
342 * specified. This indicates that attempts to invoke
343 * scic_library_allocate_controller() will fail.
344 */
345 SCI_FAILURE_UNSUPPORTED_PCI_DEVICE_ID
346
347};
348
349/**
350 * enum _SCI_IO_STATUS - This enumeration depicts all of the possible IO
351 * completion status values. Each value in this enumeration maps directly
352 * to a value in the enum sci_status enumeration. Please refer to that
353 * enumeration for detailed comments concerning what the status represents.
354 *
355 * Add the API to retrieve the SCU status from the core. Check to see that the
356 * following status are properly handled: - SCI_IO_FAILURE_UNSUPPORTED_PROTOCOL
357 * - SCI_IO_FAILURE_INVALID_IO_TAG
358 */
359enum sci_io_status {
360 SCI_IO_SUCCESS = SCI_SUCCESS,
361 SCI_IO_FAILURE = SCI_FAILURE,
362 SCI_IO_SUCCESS_COMPLETE_BEFORE_START = SCI_SUCCESS_IO_COMPLETE_BEFORE_START,
363 SCI_IO_SUCCESS_IO_DONE_EARLY = SCI_SUCCESS_IO_DONE_EARLY,
364 SCI_IO_FAILURE_INVALID_STATE = SCI_FAILURE_INVALID_STATE,
365 SCI_IO_FAILURE_INSUFFICIENT_RESOURCES = SCI_FAILURE_INSUFFICIENT_RESOURCES,
366 SCI_IO_FAILURE_UNSUPPORTED_PROTOCOL = SCI_FAILURE_UNSUPPORTED_PROTOCOL,
367 SCI_IO_FAILURE_RESPONSE_VALID = SCI_FAILURE_IO_RESPONSE_VALID,
368 SCI_IO_FAILURE_CONTROLLER_SPECIFIC_ERR = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR,
369 SCI_IO_FAILURE_TERMINATED = SCI_FAILURE_IO_TERMINATED,
370 SCI_IO_FAILURE_REQUIRES_SCSI_ABORT = SCI_FAILURE_IO_REQUIRES_SCSI_ABORT,
371 SCI_IO_FAILURE_INVALID_PARAMETER_VALUE = SCI_FAILURE_INVALID_PARAMETER_VALUE,
372 SCI_IO_FAILURE_NO_NCQ_TAG_AVAILABLE = SCI_FAILURE_NO_NCQ_TAG_AVAILABLE,
373 SCI_IO_FAILURE_PROTOCOL_VIOLATION = SCI_FAILURE_PROTOCOL_VIOLATION,
374
375 SCI_IO_FAILURE_REMOTE_DEVICE_RESET_REQUIRED = SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED,
376
377 SCI_IO_FAILURE_RETRY_REQUIRED = SCI_FAILURE_RETRY_REQUIRED,
378 SCI_IO_FAILURE_RETRY_LIMIT_REACHED = SCI_FAILURE_RETRY_LIMIT_REACHED,
379 SCI_IO_FAILURE_INVALID_REMOTE_DEVICE = SCI_FAILURE_INVALID_REMOTE_DEVICE
380};
381
382/**
383 * enum _SCI_TASK_STATUS - This enumeration depicts all of the possible task
384 * completion status values. Each value in this enumeration maps directly
385 * to a value in the enum sci_status enumeration. Please refer to that
386 * enumeration for detailed comments concerning what the status represents.
387 *
388 * Check to see that the following status are properly handled:
389 */
390enum sci_task_status {
391 SCI_TASK_SUCCESS = SCI_SUCCESS,
392 SCI_TASK_FAILURE = SCI_FAILURE,
393 SCI_TASK_FAILURE_INVALID_STATE = SCI_FAILURE_INVALID_STATE,
394 SCI_TASK_FAILURE_INSUFFICIENT_RESOURCES = SCI_FAILURE_INSUFFICIENT_RESOURCES,
395 SCI_TASK_FAILURE_UNSUPPORTED_PROTOCOL = SCI_FAILURE_UNSUPPORTED_PROTOCOL,
396 SCI_TASK_FAILURE_INVALID_TAG = SCI_FAILURE_INVALID_IO_TAG,
397 SCI_TASK_FAILURE_RESPONSE_VALID = SCI_FAILURE_IO_RESPONSE_VALID,
398 SCI_TASK_FAILURE_CONTROLLER_SPECIFIC_ERR = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR,
399 SCI_TASK_FAILURE_TERMINATED = SCI_FAILURE_IO_TERMINATED,
400 SCI_TASK_FAILURE_INVALID_PARAMETER_VALUE = SCI_FAILURE_INVALID_PARAMETER_VALUE,
401
402 SCI_TASK_FAILURE_REMOTE_DEVICE_RESET_REQUIRED = SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED,
403 SCI_TASK_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS = SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS
404
405};
406
407
408#endif /* _SCI_STATUS_H_ */
409
diff --git a/drivers/scsi/isci/core/sci_types.h b/drivers/scsi/isci/core/sci_types.h
new file mode 100644
index 000000000000..431735d1a589
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_types.h
@@ -0,0 +1,88 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_TYPES_H_
57#define _SCI_TYPES_H_
58
59#include <linux/string.h>
60
61#define sci_cb_make_physical_address(physical_addr, addr_upper, addr_lower) \
62 ((physical_addr) = (addr_lower) | ((u64)addr_upper) << 32)
63
64#define SCI_INVALID_HANDLE 0x0
65
66/**
67 * The SCI_LIBRARY_HANDLE_T will be utilized by SCI users as an opaque handle
68 * for the SCI Library object.
69 *
70 * SCI_LIBRARY_HANDLE_T
71 */
72typedef void *SCI_LIBRARY_HANDLE_T;
73
74
75typedef enum {
76 SCI_IO_REQUEST_DATA_IN = 0, /* Read operation */
77 SCI_IO_REQUEST_DATA_OUT, /* Write operation */
78 SCI_IO_REQUEST_NO_DATA
79} SCI_IO_REQUEST_DATA_DIRECTION;
80
81
82enum sci_controller_mode {
83 SCI_MODE_SPEED, /* Optimized for performance */
84 SCI_MODE_SIZE /* Optimized for memory use */
85};
86
87#endif /* _SCI_TYPES_H_ */
88
diff --git a/drivers/scsi/isci/core/sci_util.c b/drivers/scsi/isci/core/sci_util.c
new file mode 100644
index 000000000000..5cdd96f29a9e
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_util.c
@@ -0,0 +1,70 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include "sci_util.h"
57
58void scic_word_copy_with_swap(
59 u32 *destination,
60 u32 *source,
61 u32 word_count)
62{
63 while (word_count--) {
64 *destination = SCIC_SWAP_DWORD(*source);
65
66 source++;
67 destination++;
68 }
69}
70
diff --git a/drivers/scsi/isci/core/sci_util.h b/drivers/scsi/isci/core/sci_util.h
new file mode 100644
index 000000000000..67e2badf8ea8
--- /dev/null
+++ b/drivers/scsi/isci/core/sci_util.h
@@ -0,0 +1,138 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_UTIL_H_
57#define _SCI_UTIL_H_
58
59#include "sci_types.h"
60
61/**
62 * SCIC_SWAP_DWORD() -
63 *
64 * Normal byte swap macro
65 */
66#define SCIC_SWAP_DWORD(x) \
67 (\
68 (((x) >> 24) & 0x000000FF) \
69 | (((x) >> 8) & 0x0000FF00) \
70 | (((x) << 8) & 0x00FF0000) \
71 | (((x) << 24) & 0xFF000000) \
72 )
73
74#define SCIC_BUILD_DWORD(char_buffer) \
75 (\
76 ((char_buffer)[0] << 24) \
77 | ((char_buffer)[1] << 16) \
78 | ((char_buffer)[2] << 8) \
79 | ((char_buffer)[3]) \
80 )
81
82#define SCI_FIELD_OFFSET(type, field) ((unsigned long)&(((type *)0)->field))
83
84/**
85 * sci_physical_address_add() -
86 *
87 * This macro simply performs addition on an dma_addr_t type. The
88 * lower u32 value is "clipped" or "wrapped" back through 0. When this occurs
89 * the upper 32-bits are incremented by 1.
90 */
91#define sci_physical_address_add(physical_address, value) \
92 { \
93 u32 lower = lower_32_bits((physical_address)); \
94 u32 upper = upper_32_bits((physical_address)); \
95 \
96 if (lower + (value) < lower) \
97 upper += 1; \
98 \
99 lower += (value); \
100 sci_cb_make_physical_address(physical_address, upper, lower); \
101 }
102
103/**
104 * sci_physical_address_subtract() -
105 *
106 * This macro simply performs subtraction on an dma_addr_t type. The
107 * lower u32 value is "clipped" or "wrapped" back through 0. When this occurs
108 * the upper 32-bits are decremented by 1.
109 */
110#define sci_physical_address_subtract(physical_address, value) \
111 { \
112 u32 lower = lower_32_bits((physical_address)); \
113 u32 upper = upper_32_bits((physical_address)); \
114 \
115 if (lower - (value) > lower) \
116 upper -= 1; \
117 \
118 lower -= (value); \
119 sci_cb_make_physical_address(physical_address, upper, lower); \
120 }
121
122/**
123 * scic_word_copy_with_swap() - Copy the data from source to destination and
124 * swap the bytes during the copy.
125 * @destination: This parameter specifies the destination address to which the
126 * data is to be copied.
127 * @source: This parameter specifies the source address from which data is to
128 * be copied.
129 * @word_count: This parameter specifies the number of 32-bit words to copy and
130 * byte swap.
131 *
132 */
133void scic_word_copy_with_swap(
134 u32 *destination,
135 u32 *source,
136 u32 word_count);
137
138#endif /* _SCI_UTIL_H_ */
diff --git a/drivers/scsi/isci/core/scic_config_parameters.h b/drivers/scsi/isci/core/scic_config_parameters.h
new file mode 100644
index 000000000000..4c16a50a0658
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_config_parameters.h
@@ -0,0 +1,347 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_SDS_USER_PARAMETERS_H_
57#define _SCIC_SDS_USER_PARAMETERS_H_
58
59/**
60 * This file contains all of the structure definitions and interface methods
61 * that can be called by a SCIC user on the SCU Driver Standard
62 * (struct scic_sds_user_parameters) user parameter block.
63 *
64 *
65 */
66
67
68#include "sci_types.h"
69#include "sci_status.h"
70#include "intel_sas.h"
71#include "sci_controller_constants.h"
72
73struct scic_sds_controller;
74
75/**
76 *
77 *
78 * SCIC_SDS_PARM_PHY_SPEED These constants define the speeds utilized for a
79 * phy/port.
80 */
81#define SCIC_SDS_PARM_NO_SPEED 0
82
83/**
84 *
85 *
86 * This value of 1 indicates generation 1 (i.e. 1.5 Gb/s).
87 */
88#define SCIC_SDS_PARM_GEN1_SPEED 1
89
90/**
91 *
92 *
93 * This value of 2 indicates generation 2 (i.e. 3.0 Gb/s).
94 */
95#define SCIC_SDS_PARM_GEN2_SPEED 2
96
97/**
98 *
99 *
100 * This value of 3 indicates generation 3 (i.e. 6.0 Gb/s).
101 */
102#define SCIC_SDS_PARM_GEN3_SPEED 3
103
104/**
105 *
106 *
107 * For range checks, the max speed generation
108 */
109#define SCIC_SDS_PARM_MAX_SPEED SCIC_SDS_PARM_GEN3_SPEED
110
111/**
112 * struct scic_sds_user_parameters - This structure delineates the various user
113 * parameters that can be changed by the core user.
114 *
115 *
116 */
117struct scic_sds_user_parameters {
118 struct {
119 /**
120 * This field specifies the NOTIFY (ENABLE SPIN UP) primitive
121 * insertion frequency for this phy index.
122 */
123 u32 notify_enable_spin_up_insertion_frequency;
124
125 /**
126 * This method specifies the number of transmitted DWORDs within which
127 * to transmit a single ALIGN primitive. This value applies regardless
128 * of what type of device is attached or connection state. A value of
129 * 0 indicates that no ALIGN primitives will be inserted.
130 */
131 u16 align_insertion_frequency;
132
133 /**
134 * This method specifies the number of transmitted DWORDs within which
135 * to transmit 2 ALIGN primitives. This applies for SAS connections
136 * only. A minimum value of 3 is required for this field.
137 */
138 u16 in_connection_align_insertion_frequency;
139
140 /**
141 * This field indicates the maximum speed generation to be utilized
142 * by phys in the supplied port.
143 * - A value of 1 indicates generation 1 (i.e. 1.5 Gb/s).
144 * - A value of 2 indicates generation 2 (i.e. 3.0 Gb/s).
145 * - A value of 3 indicates generation 3 (i.e. 6.0 Gb/s).
146 */
147 u8 max_speed_generation;
148
149 } phys[SCI_MAX_PHYS];
150
151 /**
152 * This field specifies the maximum number of direct attached devices
153 * that can have power supplied to them simultaneously.
154 */
155 u8 max_number_concurrent_device_spin_up;
156
157 /**
158 * This field specifies the number of seconds to allow a phy to consume
159 * power before yielding to another phy.
160 *
161 */
162 u8 phy_spin_up_delay_interval;
163
164 /**
165 * These timer values specifies how long a link will remain open with no
166 * activity in increments of a microsecond, it can be in increments of
167 * 100 microseconds if the upper most bit is set.
168 *
169 */
170 u16 stp_inactivity_timeout;
171 u16 ssp_inactivity_timeout;
172
173 /**
174 * These timer values specifies how long a link will remain open in increments
175 * of 100 microseconds.
176 *
177 */
178 u16 stp_max_occupancy_timeout;
179 u16 ssp_max_occupancy_timeout;
180
181 /**
182 * This timer value specifies how long a link will remain open with no
183 * outbound traffic in increments of a microsecond.
184 *
185 */
186 u8 no_outbound_task_timeout;
187
188};
189
190/**
191 * This structure/union specifies the various different user parameter sets
192 * available. Each type is specific to a hardware controller version.
193 *
194 * union scic_user_parameters
195 */
196union scic_user_parameters {
197 /**
198 * This field specifies the user parameters specific to the
199 * Storage Controller Unit (SCU) Driver Standard (SDS) version
200 * 1.
201 */
202 struct scic_sds_user_parameters sds1;
203
204};
205
206
207/**
208 *
209 *
210 * SCIC_SDS_OEM_PHY_MASK These constants define the valid values for phy_mask
211 */
212
213/**
214 *
215 *
216 * This is the min value assignable to a port's phy mask
217 */
218#define SCIC_SDS_PARM_PHY_MASK_MIN 0x0
219
220/**
221 *
222 *
223 * This is the max value assignable to a port's phy mask
224 */
225#define SCIC_SDS_PARM_PHY_MASK_MAX 0xF
226
227/**
228 * struct scic_sds_oem_parameters - This structure delineates the various OEM
229 * parameters that must be set the core user.
230 *
231 *
232 */
233struct scic_sds_oem_parameters {
234 struct {
235 /**
236 * This field indicates whether Spread Spectrum Clocking (SSC)
237 * should be enabled or disabled.
238 */
239 bool do_enable_ssc;
240
241 } controller;
242
243 struct {
244 /**
245 * This field specifies the phys to be contained inside a port.
246 * The bit position in the mask specifies the index of the phy
247 * to be contained in the port. Multiple bits (i.e. phys)
248 * can be contained in a single port.
249 */
250 u8 phy_mask;
251
252 } ports[SCI_MAX_PORTS];
253
254 struct {
255 /**
256 * This field specifies the SAS address to be transmitted on
257 * for this phy index.
258 */
259 struct sci_sas_address sas_address;
260
261 } phys[SCI_MAX_PHYS];
262
263};
264
265/**
266 * This structure/union specifies the various different OEM parameter sets
267 * available. Each type is specific to a hardware controller version.
268 *
269 * union scic_oem_parameters
270 */
271union scic_oem_parameters {
272 /**
273 * This field specifies the OEM parameters specific to the
274 * Storage Controller Unit (SCU) Driver Standard (SDS) version
275 * 1.
276 */
277 struct scic_sds_oem_parameters sds1;
278
279};
280
281/**
282 * scic_user_parameters_set() - This method allows the user to attempt to
283 * change the user parameters utilized by the controller.
284 * @controller: This parameter specifies the controller on which to set the
285 * user parameters.
286 * @user_parameters: This parameter specifies the USER_PARAMETERS object
287 * containing the potential new values.
288 *
289 * Indicate if the update of the user parameters was successful. SCI_SUCCESS
290 * This value is returned if the operation succeeded. SCI_FAILURE_INVALID_STATE
291 * This value is returned if the attempt to change the user parameter failed,
292 * because changing one of the parameters is not currently allowed.
293 * SCI_FAILURE_INVALID_PARAMETER_VALUE This value is returned if the user
294 * supplied an invalid interrupt coalescence time, spin up delay interval, etc.
295 */
296enum sci_status scic_user_parameters_set(
297 struct scic_sds_controller *controller,
298 union scic_user_parameters *user_parameters);
299
300/**
301 * scic_user_parameters_get() - This method allows the user to retrieve the
302 * user parameters utilized by the controller.
303 * @controller: This parameter specifies the controller on which to set the
304 * user parameters.
305 * @user_parameters: This parameter specifies the USER_PARAMETERS object into
306 * which the framework shall save it's parameters.
307 *
308 */
309void scic_user_parameters_get(
310 struct scic_sds_controller *controller,
311 union scic_user_parameters *user_parameters);
312
313/**
314 * scic_oem_parameters_set() - This method allows the user to attempt to change
315 * the OEM parameters utilized by the controller.
316 * @controller: This parameter specifies the controller on which to set the
317 * user parameters.
318 * @oem_parameters: This parameter specifies the OEM parameters object
319 * containing the potential new values.
320 *
321 * Indicate if the update of the user parameters was successful. SCI_SUCCESS
322 * This value is returned if the operation succeeded. SCI_FAILURE_INVALID_STATE
323 * This value is returned if the attempt to change the user parameter failed,
324 * because changing one of the parameters is not currently allowed.
325 * SCI_FAILURE_INVALID_PARAMETER_VALUE This value is returned if the user
326 * supplied an unsupported value for one of the OEM parameters.
327 */
328enum sci_status scic_oem_parameters_set(
329 struct scic_sds_controller *controller,
330 union scic_oem_parameters *oem_parameters);
331
332/**
333 * scic_oem_parameters_get() - This method allows the user to retreive the OEM
334 * parameters utilized by the controller.
335 * @controller: This parameter specifies the controller on which to set the
336 * user parameters.
337 * @oem_parameters: This parameter specifies the OEM parameters object in which
338 * to write the core's OEM parameters.
339 *
340 */
341void scic_oem_parameters_get(
342 struct scic_sds_controller *controller,
343 union scic_oem_parameters *oem_parameters);
344
345
346#endif /* _SCIC_SDS_USER_PARAMETERS_H_ */
347
diff --git a/drivers/scsi/isci/core/scic_controller.h b/drivers/scsi/isci/core/scic_controller.h
new file mode 100644
index 000000000000..756b14fcd9a4
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_controller.h
@@ -0,0 +1,586 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_CONTROLLER_H_
57#define _SCIC_CONTROLLER_H_
58
59/**
60 * This file contains all of the interface methods that can be called by an
61 * SCIC user on a controller object.
62 *
63 *
64 */
65
66
67#include "sci_types.h"
68#include "sci_status.h"
69#include "sci_controller.h"
70#include "scic_config_parameters.h"
71
72struct scic_sds_request;
73struct scic_sds_phy;
74struct scic_sds_port;
75struct scic_sds_remote_device;
76
77/**
78 * enum _SCIC_INTERRUPT_TYPE - This enumeration depicts the various types of
79 * interrupts that are potentially supported by a SCI Core implementation.
80 *
81 *
82 */
83enum scic_interrupt_type {
84 SCIC_LEGACY_LINE_INTERRUPT_TYPE,
85 SCIC_MSIX_INTERRUPT_TYPE,
86
87 /**
88 * This enumeration value indicates the use of polling.
89 */
90 SCIC_NO_INTERRUPTS
91
92};
93
94/**
95 * This method is called by the SCI user in order to have the SCI
96 * implementation handle the interrupt. This method performs minimal
97 * processing to allow for streamlined interrupt time usage.
98 *
99 * SCIC_CONTROLLER_INTERRUPT_HANDLER true: returned if there is an interrupt to
100 * process and it was processed. false: returned if no interrupt was processed.
101 */
102typedef bool (*SCIC_CONTROLLER_INTERRUPT_HANDLER)(
103 struct scic_sds_controller *controller
104 );
105
106/**
107 * This method is called by the SCI user to process completions generated as a
108 * result of a previously handled interrupt. This method will result in the
109 * completion of IO requests and handling of other controller generated
110 * events. This method should be called some time after the interrupt
111 * handler.
112 *
113 * Most, if not all, of the user callback APIs are invoked from within this
114 * API. As a result, the user should be cognizent of the operating level at
115 * which they invoke this API.
116 */
117typedef void (*SCIC_CONTROLLER_COMPLETION_HANDLER)(
118 struct scic_sds_controller *controller
119 );
120
121/**
122 * struct scic_controller_handler_methods - This structure contains an
123 * interrupt handler and completion handler function pointers.
124 *
125 *
126 */
127struct scic_controller_handler_methods {
128 SCIC_CONTROLLER_INTERRUPT_HANDLER interrupt_handler;
129 SCIC_CONTROLLER_COMPLETION_HANDLER completion_handler;
130
131};
132
133/**
134 * scic_controller_construct() - This method will attempt to construct a
135 * controller object utilizing the supplied parameter information.
136 * @c: This parameter specifies the controller to be constructed.
137 * @scu_base: mapped base address of the scu registers
138 * @smu_base: mapped base address of the smu registers
139 *
140 * Indicate if the controller was successfully constructed or if it failed in
141 * some way. SCI_SUCCESS This value is returned if the controller was
142 * successfully constructed. SCI_WARNING_TIMER_CONFLICT This value is returned
143 * if the interrupt coalescence timer may cause SAS compliance issues for SMP
144 * Target mode response processing. SCI_FAILURE_UNSUPPORTED_CONTROLLER_TYPE
145 * This value is returned if the controller does not support the supplied type.
146 * SCI_FAILURE_UNSUPPORTED_INIT_DATA_VERSION This value is returned if the
147 * controller does not support the supplied initialization data version.
148 */
149enum sci_status scic_controller_construct(struct scic_sds_controller *c,
150 void __iomem *scu_base,
151 void __iomem *smu_base);
152
153/**
154 * scic_controller_enable_interrupts() - This method will enable all controller
155 * interrupts.
156 * @controller: This parameter specifies the controller for which to enable
157 * interrupts.
158 *
159 */
160void scic_controller_enable_interrupts(
161 struct scic_sds_controller *controller);
162
163/**
164 * scic_controller_disable_interrupts() - This method will disable all
165 * controller interrupts.
166 * @controller: This parameter specifies the controller for which to disable
167 * interrupts.
168 *
169 */
170void scic_controller_disable_interrupts(
171 struct scic_sds_controller *controller);
172
173/**
174 * scic_controller_get_handler_methods() - This method will return provide
175 * function pointers for the interrupt handler and completion handler. The
176 * interrupt handler is expected to be invoked at interrupt time. The
177 * completion handler is scheduled to run as a result of the interrupt
178 * handler. The completion handler performs the bulk work for processing
179 * silicon events.
180 * @interrupt_type: This parameter informs the core which type of
181 * interrupt/completion methods are being requested. These are the types:
182 * SCIC_LEGACY_LINE_INTERRUPT_TYPE, SCIC_MSIX_INTERRUPT_TYPE,
183 * SCIC_NO_INTERRUPTS (POLLING)
184 * @message_count: This parameter informs the core the number of MSI-X messages
185 * to be utilized. This parameter must be 0 when requesting legacy line
186 * based handlers.
187 * @handler_methods: The caller provides a pointer to a buffer of type
188 * struct scic_controller_handler_methods. The size depends on the combination of
189 * the interrupt_type and message_count input parameters:
190 * SCIC_LEGACY_LINE_INTERRUPT_TYPE: - size =
191 * sizeof(struct scic_controller_handler_methods) SCIC_MSIX_INTERRUPT_TYPE:
192 * sizeof(struct scic_controller_handler_methods)
193 * @handler_methods: SCIC fills out the caller's buffer with the appropriate
194 * interrupt and completion handlers based on the info provided in the
195 * interrupt_type and message_count input parameters. For
196 * SCIC_LEGACY_LINE_INTERRUPT_TYPE, the buffer receives a single
197 * struct scic_controller_handler_methods element regardless that the
198 * message_count parameter is zero. For SCIC_MSIX_INTERRUPT_TYPE, the buffer
199 * receives an array of elements of type struct scic_controller_handler_methods
200 * where the array size is equivalent to the message_count parameter. The
201 * array is zero-relative where entry zero corresponds to message-vector
202 * zero, entry one corresponds to message-vector one, and so forth.
203 *
204 * Indicate if the handler retrieval operation was successful. SCI_SUCCESS This
205 * value is returned if retrieval succeeded.
206 * SCI_FAILURE_UNSUPPORTED_MESSAGE_COUNT This value is returned if the user
207 * supplied an unsupported number of MSI-X messages. For legacy line interrupts
208 * the only valid value is 0.
209 */
210enum sci_status scic_controller_get_handler_methods(
211 enum scic_interrupt_type interrupt_type,
212 u16 message_count,
213 struct scic_controller_handler_methods *handler_methods);
214
215/**
216 * scic_controller_initialize() - This method will initialize the controller
217 * hardware managed by the supplied core controller object. This method
218 * will bring the physical controller hardware out of reset and enable the
219 * core to determine the capabilities of the hardware being managed. Thus,
220 * the core controller can determine it's exact physical (DMA capable)
221 * memory requirements.
222 * @controller: This parameter specifies the controller to be initialized.
223 *
224 * The SCI Core user must have called scic_controller_construct() on the
225 * supplied controller object previously. Indicate if the controller was
226 * successfully initialized or if it failed in some way. SCI_SUCCESS This value
227 * is returned if the controller hardware was successfully initialized.
228 */
229enum sci_status scic_controller_initialize(
230 struct scic_sds_controller *controller);
231
232/**
233 * scic_controller_get_suggested_start_timeout() - This method returns the
234 * suggested scic_controller_start() timeout amount. The user is free to
235 * use any timeout value, but this method provides the suggested minimum
236 * start timeout value. The returned value is based upon empirical
237 * information determined as a result of interoperability testing.
238 * @controller: the handle to the controller object for which to return the
239 * suggested start timeout.
240 *
241 * This method returns the number of milliseconds for the suggested start
242 * operation timeout.
243 */
244u32 scic_controller_get_suggested_start_timeout(
245 struct scic_sds_controller *controller);
246
247/**
248 * scic_controller_start() - This method will start the supplied core
249 * controller. This method will start the staggered spin up operation. The
250 * SCI User completion callback is called when the following conditions are
251 * met: -# the return status of this method is SCI_SUCCESS. -# after all of
252 * the phys have successfully started or been given the opportunity to start.
253 * @controller: the handle to the controller object to start.
254 * @timeout: This parameter specifies the number of milliseconds in which the
255 * start operation should complete.
256 *
257 * The SCI Core user must have filled in the physical memory descriptor
258 * structure via the sci_controller_get_memory_descriptor_list() method. The
259 * SCI Core user must have invoked the scic_controller_initialize() method
260 * prior to invoking this method. The controller must be in the INITIALIZED or
261 * STARTED state. Indicate if the controller start method succeeded or failed
262 * in some way. SCI_SUCCESS if the start operation succeeded.
263 * SCI_WARNING_ALREADY_IN_STATE if the controller is already in the STARTED
264 * state. SCI_FAILURE_INVALID_STATE if the controller is not either in the
265 * INITIALIZED or STARTED states. SCI_FAILURE_INVALID_MEMORY_DESCRIPTOR if
266 * there are inconsistent or invalid values in the supplied
267 * struct sci_physical_memory_descriptor array.
268 */
269enum sci_status scic_controller_start(
270 struct scic_sds_controller *controller,
271 u32 timeout);
272
273/**
274 * scic_controller_stop() - This method will stop an individual controller
275 * object.This method will invoke the associated user callback upon
276 * completion. The completion callback is called when the following
277 * conditions are met: -# the method return status is SCI_SUCCESS. -# the
278 * controller has been quiesced. This method will ensure that all IO
279 * requests are quiesced, phys are stopped, and all additional operation by
280 * the hardware is halted.
281 * @controller: the handle to the controller object to stop.
282 * @timeout: This parameter specifies the number of milliseconds in which the
283 * stop operation should complete.
284 *
285 * The controller must be in the STARTED or STOPPED state. Indicate if the
286 * controller stop method succeeded or failed in some way. SCI_SUCCESS if the
287 * stop operation successfully began. SCI_WARNING_ALREADY_IN_STATE if the
288 * controller is already in the STOPPED state. SCI_FAILURE_INVALID_STATE if the
289 * controller is not either in the STARTED or STOPPED states.
290 */
291enum sci_status scic_controller_stop(
292 struct scic_sds_controller *controller,
293 u32 timeout);
294
295/**
296 * scic_controller_reset() - This method will reset the supplied core
297 * controller regardless of the state of said controller. This operation is
298 * considered destructive. In other words, all current operations are wiped
299 * out. No IO completions for outstanding devices occur. Outstanding IO
300 * requests are not aborted or completed at the actual remote device.
301 * @controller: the handle to the controller object to reset.
302 *
303 * Indicate if the controller reset method succeeded or failed in some way.
304 * SCI_SUCCESS if the reset operation successfully started. SCI_FATAL_ERROR if
305 * the controller reset operation is unable to complete.
306 */
307enum sci_status scic_controller_reset(
308 struct scic_sds_controller *controller);
309
310/**
311 * scic_controller_start_io() - This method is called by the SCI user to
312 * send/start an IO request. If the method invocation is successful, then
313 * the IO request has been queued to the hardware for processing.
314 * @controller: the handle to the controller object for which to start an IO
315 * request.
316 * @remote_device: the handle to the remote device object for which to start an
317 * IO request.
318 * @io_request: the handle to the io request object to start.
319 * @io_tag: This parameter specifies a previously allocated IO tag that the
320 * user desires to be utilized for this request. This parameter is optional.
321 * The user is allowed to supply SCI_CONTROLLER_INVALID_IO_TAG as the value
322 * for this parameter.
323 *
324 * - IO tags are a protected resource. It is incumbent upon the SCI Core user
325 * to ensure that each of the methods that may allocate or free available IO
326 * tags are handled in a mutually exclusive manner. This method is one of said
327 * methods requiring proper critical code section protection (e.g. semaphore,
328 * spin-lock, etc.). - For SATA, the user is required to manage NCQ tags. As a
329 * result, it is expected the user will have set the NCQ tag field in the host
330 * to device register FIS prior to calling this method. There is also a
331 * requirement for the user to call scic_stp_io_set_ncq_tag() prior to invoking
332 * the scic_controller_start_io() method. scic_controller_allocate_tag() for
333 * more information on allocating a tag. Indicate if the controller
334 * successfully started the IO request. SCI_IO_SUCCESS if the IO request was
335 * successfully started. Determine the failure situations and return values.
336 */
337enum sci_io_status scic_controller_start_io(
338 struct scic_sds_controller *controller,
339 struct scic_sds_remote_device *remote_device,
340 struct scic_sds_request *io_request,
341 u16 io_tag);
342
343
344/**
345 * scic_controller_start_task() - This method is called by the SCIC user to
346 * send/start a framework task management request.
347 * @controller: the handle to the controller object for which to start the task
348 * management request.
349 * @remote_device: the handle to the remote device object for which to start
350 * the task management request.
351 * @task_request: the handle to the task request object to start.
352 * @io_tag: This parameter specifies a previously allocated IO tag that the
353 * user desires to be utilized for this request. Note this not the io_tag
354 * of the request being managed. It is to be utilized for the task request
355 * itself. This parameter is optional. The user is allowed to supply
356 * SCI_CONTROLLER_INVALID_IO_TAG as the value for this parameter.
357 *
358 * - IO tags are a protected resource. It is incumbent upon the SCI Core user
359 * to ensure that each of the methods that may allocate or free available IO
360 * tags are handled in a mutually exclusive manner. This method is one of said
361 * methods requiring proper critical code section protection (e.g. semaphore,
362 * spin-lock, etc.). - The user must synchronize this task with completion
363 * queue processing. If they are not synchronized then it is possible for the
364 * io requests that are being managed by the task request can complete before
365 * starting the task request. scic_controller_allocate_tag() for more
366 * information on allocating a tag. Indicate if the controller successfully
367 * started the IO request. SCI_TASK_SUCCESS if the task request was
368 * successfully started. SCI_TASK_FAILURE_REQUIRES_SCSI_ABORT This value is
369 * returned if there is/are task(s) outstanding that require termination or
370 * completion before this request can succeed.
371 */
372enum sci_task_status scic_controller_start_task(
373 struct scic_sds_controller *controller,
374 struct scic_sds_remote_device *remote_device,
375 struct scic_sds_request *task_request,
376 u16 io_tag);
377
378/**
379 * scic_controller_complete_task() - This method will perform core specific
380 * completion operations for task management request. After this method is
381 * invoked, the user should consider the task request as invalid until it is
382 * properly reused (i.e. re-constructed).
383 * @controller: The handle to the controller object for which to complete the
384 * task management request.
385 * @remote_device: The handle to the remote device object for which to complete
386 * the task management request.
387 * @task_request: the handle to the task management request object to complete.
388 *
389 * Indicate if the controller successfully completed the task management
390 * request. SCI_SUCCESS if the completion process was successful.
391 */
392enum sci_status scic_controller_complete_task(
393 struct scic_sds_controller *controller,
394 struct scic_sds_remote_device *remote_device,
395 struct scic_sds_request *task_request);
396
397
398/**
399 * scic_controller_terminate_request() - This method is called by the SCI Core
400 * user to terminate an ongoing (i.e. started) core IO request. This does
401 * not abort the IO request at the target, but rather removes the IO request
402 * from the host controller.
403 * @controller: the handle to the controller object for which to terminate a
404 * request.
405 * @remote_device: the handle to the remote device object for which to
406 * terminate a request.
407 * @request: the handle to the io or task management request object to
408 * terminate.
409 *
410 * Indicate if the controller successfully began the terminate process for the
411 * IO request. SCI_SUCCESS if the terminate process was successfully started
412 * for the request. Determine the failure situations and return values.
413 */
414enum sci_status scic_controller_terminate_request(
415 struct scic_sds_controller *controller,
416 struct scic_sds_remote_device *remote_device,
417 struct scic_sds_request *request);
418
419/**
420 * scic_controller_complete_io() - This method will perform core specific
421 * completion operations for an IO request. After this method is invoked,
422 * the user should consider the IO request as invalid until it is properly
423 * reused (i.e. re-constructed).
424 * @controller: The handle to the controller object for which to complete the
425 * IO request.
426 * @remote_device: The handle to the remote device object for which to complete
427 * the IO request.
428 * @io_request: the handle to the io request object to complete.
429 *
430 * - IO tags are a protected resource. It is incumbent upon the SCI Core user
431 * to ensure that each of the methods that may allocate or free available IO
432 * tags are handled in a mutually exclusive manner. This method is one of said
433 * methods requiring proper critical code section protection (e.g. semaphore,
434 * spin-lock, etc.). - If the IO tag for a request was allocated, by the SCI
435 * Core user, using the scic_controller_allocate_io_tag() method, then it is
436 * the responsibility of the caller to invoke the scic_controller_free_io_tag()
437 * method to free the tag (i.e. this method will not free the IO tag). Indicate
438 * if the controller successfully completed the IO request. SCI_SUCCESS if the
439 * completion process was successful.
440 */
441enum sci_status scic_controller_complete_io(
442 struct scic_sds_controller *controller,
443 struct scic_sds_remote_device *remote_device,
444 struct scic_sds_request *io_request);
445
446
447/**
448 * scic_controller_get_port_handle() - This method simply provides the user
449 * with a unique handle for a given SAS/SATA core port index.
450 * @controller: This parameter represents the handle to the controller object
451 * from which to retrieve a port (SAS or SATA) handle.
452 * @port_index: This parameter specifies the port index in the controller for
453 * which to retrieve the port handle. 0 <= port_index < maximum number of
454 * phys.
455 * @port_handle: This parameter specifies the retrieved port handle to be
456 * provided to the caller.
457 *
458 * Indicate if the retrieval of the port handle was successful. SCI_SUCCESS
459 * This value is returned if the retrieval was successful.
460 * SCI_FAILURE_INVALID_PORT This value is returned if the supplied port id is
461 * not in the supported range.
462 */
463enum sci_status scic_controller_get_port_handle(
464 struct scic_sds_controller *controller,
465 u8 port_index,
466 struct scic_sds_port **port_handle);
467
468/**
469 * scic_controller_get_phy_handle() - This method simply provides the user with
470 * a unique handle for a given SAS/SATA phy index/identifier.
471 * @controller: This parameter represents the handle to the controller object
472 * from which to retrieve a phy (SAS or SATA) handle.
473 * @phy_index: This parameter specifies the phy index in the controller for
474 * which to retrieve the phy handle. 0 <= phy_index < maximum number of phys.
475 * @phy_handle: This parameter specifies the retrieved phy handle to be
476 * provided to the caller.
477 *
478 * Indicate if the retrieval of the phy handle was successful. SCI_SUCCESS This
479 * value is returned if the retrieval was successful. SCI_FAILURE_INVALID_PHY
480 * This value is returned if the supplied phy id is not in the supported range.
481 */
482enum sci_status scic_controller_get_phy_handle(
483 struct scic_sds_controller *controller,
484 u8 phy_index,
485 struct scic_sds_phy **phy_handle);
486
487/**
488 * scic_controller_allocate_io_tag() - This method will allocate a tag from the
489 * pool of free IO tags. Direct allocation of IO tags by the SCI Core user
490 * is optional. The scic_controller_start_io() method will allocate an IO
491 * tag if this method is not utilized and the tag is not supplied to the IO
492 * construct routine. Direct allocation of IO tags may provide additional
493 * performance improvements in environments capable of supporting this usage
494 * model. Additionally, direct allocation of IO tags also provides
495 * additional flexibility to the SCI Core user. Specifically, the user may
496 * retain IO tags across the lives of multiple IO requests.
497 * @controller: the handle to the controller object for which to allocate the
498 * tag.
499 *
500 * IO tags are a protected resource. It is incumbent upon the SCI Core user to
501 * ensure that each of the methods that may allocate or free available IO tags
502 * are handled in a mutually exclusive manner. This method is one of said
503 * methods requiring proper critical code section protection (e.g. semaphore,
504 * spin-lock, etc.). An unsigned integer representing an available IO tag.
505 * SCI_CONTROLLER_INVALID_IO_TAG This value is returned if there are no
506 * currently available tags to be allocated. All return other values indicate a
507 * legitimate tag.
508 */
509u16 scic_controller_allocate_io_tag(
510 struct scic_sds_controller *controller);
511
512/**
513 * scic_controller_free_io_tag() - This method will free an IO tag to the pool
514 * of free IO tags. This method provides the SCI Core user more flexibility
515 * with regards to IO tags. The user may desire to keep an IO tag after an
516 * IO request has completed, because they plan on re-using the tag for a
517 * subsequent IO request. This method is only legal if the tag was
518 * allocated via scic_controller_allocate_io_tag().
519 * @controller: This parameter specifies the handle to the controller object
520 * for which to free/return the tag.
521 * @io_tag: This parameter represents the tag to be freed to the pool of
522 * available tags.
523 *
524 * - IO tags are a protected resource. It is incumbent upon the SCI Core user
525 * to ensure that each of the methods that may allocate or free available IO
526 * tags are handled in a mutually exclusive manner. This method is one of said
527 * methods requiring proper critical code section protection (e.g. semaphore,
528 * spin-lock, etc.). - If the IO tag for a request was allocated, by the SCI
529 * Core user, using the scic_controller_allocate_io_tag() method, then it is
530 * the responsibility of the caller to invoke this method to free the tag. This
531 * method returns an indication of whether the tag was successfully put back
532 * (freed) to the pool of available tags. SCI_SUCCESS This return value
533 * indicates the tag was successfully placed into the pool of available IO
534 * tags. SCI_FAILURE_INVALID_IO_TAG This value is returned if the supplied tag
535 * is not a valid IO tag value.
536 */
537enum sci_status scic_controller_free_io_tag(
538 struct scic_sds_controller *controller,
539 u16 io_tag);
540
541
542
543
544/**
545 * scic_controller_set_mode() - This method allows the user to configure the
546 * SCI core into either a performance mode or a memory savings mode.
547 * @controller: This parameter represents the handle to the controller object
548 * for which to update the operating mode.
549 * @mode: This parameter specifies the new mode for the controller.
550 *
551 * Indicate if the user successfully change the operating mode of the
552 * controller. SCI_SUCCESS The user successfully updated the mode.
553 */
554enum sci_status scic_controller_set_mode(
555 struct scic_sds_controller *controller,
556 enum sci_controller_mode mode);
557
558
559/**
560 * scic_controller_set_interrupt_coalescence() - This method allows the user to
561 * configure the interrupt coalescence.
562 * @controller: This parameter represents the handle to the controller object
563 * for which its interrupt coalesce register is overridden.
564 * @coalesce_number: Used to control the number of entries in the Completion
565 * Queue before an interrupt is generated. If the number of entries exceed
566 * this number, an interrupt will be generated. The valid range of the input
567 * is [0, 256]. A setting of 0 results in coalescing being disabled.
568 * @coalesce_timeout: Timeout value in microseconds. The valid range of the
569 * input is [0, 2700000] . A setting of 0 is allowed and results in no
570 * interrupt coalescing timeout.
571 *
572 * Indicate if the user successfully set the interrupt coalesce parameters.
573 * SCI_SUCCESS The user successfully updated the interrutp coalescence.
574 * SCI_FAILURE_INVALID_PARAMETER_VALUE The user input value is out of range.
575 */
576enum sci_status scic_controller_set_interrupt_coalescence(
577 struct scic_sds_controller *controller,
578 u32 coalesce_number,
579 u32 coalesce_timeout);
580
581struct device;
582struct scic_sds_controller *scic_controller_alloc(struct device *dev);
583
584
585#endif /* _SCIC_CONTROLLER_H_ */
586
diff --git a/drivers/scsi/isci/core/scic_io_request.h b/drivers/scsi/isci/core/scic_io_request.h
new file mode 100644
index 000000000000..7378f335066c
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_io_request.h
@@ -0,0 +1,512 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_IO_REQUEST_H_
57#define _SCIC_IO_REQUEST_H_
58
59/**
60 * This file contains the structures and interface methods that can be
61 * referenced and used by the SCI user for the SCI IO request object.
62 *
63 * Determine the failure situations and return values.
64 */
65
66
67#include "sci_types.h"
68#include "sci_status.h"
69#include "intel_sas.h"
70
71struct scic_sds_request;
72struct scic_sds_remote_device;
73struct scic_sds_controller;
74
75/**
76 * struct scic_io_parameters - This structure contains additional optional
77 * parameters for SSP IO requests. These parameters are utilized with the
78 * scic_io_request_construct_advanced_ssp() method.
79 *
80 * Add Block-guard/DIF, TLR
81 */
82struct scic_io_parameters {
83 /**
84 * This sub-structure contains SCSI specific features (for use with SSP
85 * IO requests).
86 */
87 struct {
88 /**
89 * Data Integrity Format (DIF) is also known as protection information
90 * or block-guard. This sub-structure contains DIF specific feature
91 * information for SSP IO requests.
92 */
93 struct {
94 void *placeholder;
95 } dif;
96
97 /**
98 * Transport Layer Retries (TLR) is an SSP protocol specific feature.
99 * This sub-structure contains Transport Layer Retries (TLR) specific
100 * feature information for SSP IO requests.
101 */
102 struct {
103 void *placeholder;
104 } tlr;
105
106 } scsi;
107
108};
109
110/**
111 * struct scic_passthru_request_callbacks - This structure contains the pointer
112 * to the callback functions for constructing the passthrough request common
113 * to SSP, SMP and STP. This structure must be set by the win sci layer
114 * before the passthrough build is called
115 *
116 *
117 */
118struct scic_passthru_request_callbacks {
119 /**
120 * Function pointer to get the phy identifier for passthrough request.
121 */
122 u32 (*scic_cb_passthru_get_phy_identifier)(void *, u8 *);
123 /**
124 * Function pointer to get the port identifier for passthrough request.
125 */
126 u32 (*scic_cb_passthru_get_port_identifier)(void *, u8 *);
127 /**
128 * Function pointer to get the connection rate for passthrough request.
129 */
130 u32 (*scic_cb_passthru_get_connection_rate)(void *, void *);
131 /**
132 * Function pointer to get the destination sas address for passthrough request.
133 */
134 void (*scic_cb_passthru_get_destination_sas_address)(void *, u8 **);
135 /**
136 * Function pointer to get the transfer length for passthrough request.
137 */
138 u32 (*scic_cb_passthru_get_transfer_length)(void *);
139 /**
140 * Function pointer to get the data direction for passthrough request.
141 */
142 u32 (*scic_cb_passthru_get_data_direction)(void *);
143
144};
145
146/**
147 * struct scic_ssp_passthru_request_callbacks - This structure contains the
148 * pointer to the callback functions for constructing the passthrough
149 * request specific to SSP. This structure must be set by the win sci layer
150 * before the passthrough build is called
151 *
152 *
153 */
154struct scic_ssp_passthru_request_callbacks {
155 /**
156 * Common callbacks for all Passthru requests
157 */
158 struct scic_passthru_request_callbacks common_callbacks;
159 /**
160 * Function pointer to get the lun for passthrough request.
161 */
162 void (*scic_cb_ssp_passthru_get_lun)(void *, u8 **);
163 /**
164 * Function pointer to get the cdb
165 */
166 void (*scic_cb_ssp_passthru_get_cdb)(void *, u32 *, u8 **, u32 *, u8 **);
167 /**
168 * Function pointer to get the task attribute for passthrough request.
169 */
170 u32 (*scic_cb_ssp_passthru_get_task_attribute)(void *);
171};
172
173/**
174 * struct scic_stp_passthru_request_callbacks - This structure contains the
175 * pointer to the callback functions for constructing the passthrough
176 * request specific to STP. This structure must be set by the win sci layer
177 * before the passthrough build is called
178 *
179 *
180 */
181struct scic_stp_passthru_request_callbacks {
182 /**
183 * Common callbacks for all Passthru requests
184 */
185 struct scic_passthru_request_callbacks common_callbacks;
186 /**
187 * Function pointer to get the protocol for passthrough request.
188 */
189 u8 (*scic_cb_stp_passthru_get_protocol)(void *);
190 /**
191 * Function pointer to get the resgister fis
192 */
193 void (*scic_cb_stp_passthru_get_register_fis)(void *, u8 **);
194 /**
195 * Function pointer to get the MULTIPLE_COUNT (bits 5,6,7 in Byte 1 in the SAT-specific SCSI extenstion in ATA Pass-through (0x85))
196 */
197 u8 (*scic_cb_stp_passthru_get_multiplecount)(void *);
198 /**
199 * Function pointer to get the EXTEND (bit 0 in Byte 1 the SAT-specific SCSI extenstion in ATA Pass-through (0x85))
200 */
201 u8 (*scic_cb_stp_passthru_get_extend)(void *);
202 /**
203 * Function pointer to get the CK_COND (bit 5 in Byte 2 the SAT-specific SCSI extenstion in ATA Pass-through (0x85))
204 */
205 u8 (*scic_cb_stp_passthru_get_ckcond)(void *);
206 /**
207 * Function pointer to get the T_DIR (bit 3 in Byte 2 the SAT-specific SCSI extenstion in ATA Pass-through (0x85))
208 */
209 u8 (*scic_cb_stp_passthru_get_tdir)(void *);
210 /**
211 * Function pointer to get the BYTE_BLOCK (bit 2 in Byte 2 the SAT-specific SCSI extenstion in ATA Pass-through (0x85))
212 */
213 u8 (*scic_cb_stp_passthru_get_byteblock)(void *);
214 /**
215 * Function pointer to get the T_LENGTH (bits 0,1 in Byte 2 the SAT-specific SCSI extenstion in ATA Pass-through (0x85))
216 */
217 u8 (*scic_cb_stp_passthru_get_tlength)(void *);
218
219};
220
221/**
222 * struct scic_smp_passthru_request_callbacks - This structure contains the
223 * pointer to the callback functions for constructing the passthrough
224 * request specific to SMP. This structure must be set by the win sci layer
225 * before the passthrough build is called
226 *
227 *
228 */
229struct scic_smp_passthru_request_callbacks {
230 /**
231 * Common callbacks for all Passthru requests
232 */
233 struct scic_passthru_request_callbacks common_callbacks;
234
235 /**
236 * Function pointer to get the length of the smp request and its length
237 */
238 u32 (*scic_cb_smp_passthru_get_request)(void *, u8 **);
239 /**
240 * Function pointer to get the frame type of the smp request
241 */
242 u8 (*scic_cb_smp_passthru_get_frame_type)(void *);
243 /**
244 * Function pointer to get the function in the the smp request
245 */
246 u8 (*scic_cb_smp_passthru_get_function)(void *);
247
248 /**
249 * Function pointer to get the "allocated response length" in the the smp request
250 */
251 u8 (*scic_cb_smp_passthru_get_allocated_response_length)(void *);
252
253};
254
255/**
256 * This enumeration specifies the transport protocol utilized for the request.
257 *
258 *
259 */
260typedef enum {
261 /**
262 * This enumeration constant indicates that no protocol has yet been
263 * set.
264 */
265 SCIC_NO_PROTOCOL,
266
267 /**
268 * This enumeration constant indicates that the protocol utilized
269 * is the Serial Management Protocol.
270 */
271 SCIC_SMP_PROTOCOL,
272
273 /**
274 * This enumeration constant indicates that the protocol utilized
275 * is the Serial SCSI Protocol.
276 */
277 SCIC_SSP_PROTOCOL,
278
279 /**
280 * This enumeration constant indicates that the protocol utilized
281 * is the Serial-ATA Tunneling Protocol.
282 */
283 SCIC_STP_PROTOCOL
284
285} SCIC_TRANSPORT_PROTOCOL;
286
287
288/**
289 * scic_io_request_get_object_size() - This method simply returns the size
290 * required to build an SCI based IO request object.
291 *
292 * Return the size of the SCI IO request object.
293 */
294u32 scic_io_request_get_object_size(
295 void);
296
297/**
298 * scic_io_request_construct() - This method is called by the SCI user to
299 * construct all SCI Core IO requests. Memory initialization and
300 * functionality common to all IO request types is performed in this method.
301 * @scic_controller: the handle to the core controller object for which to
302 * build an IO request.
303 * @scic_remote_device: the handle to the core remote device object for which
304 * to build an IO request.
305 * @io_tag: This parameter specifies the IO tag to be associated with this
306 * request. If SCI_CONTROLLER_INVALID_IO_TAG is passed, then a copy of the
307 * request is built internally. The request will be copied into the actual
308 * controller request memory when the IO tag is allocated internally during
309 * the scic_controller_start_io() method.
310 * @user_io_request_object: This parameter specifies the user IO request to be
311 * utilized during IO construction. This IO pointer will become the
312 * associated object for the core IO request object.
313 * @scic_io_request_memory: This parameter specifies the memory location to be
314 * utilized when building the core request.
315 * @new_scic_io_request_handle: This parameter specifies a pointer to the
316 * handle the core will expect in further interactions with the core IO
317 * request object.
318 *
319 * The SCI core implementation will create an association between the user IO
320 * request object and the core IO request object. Indicate if the controller
321 * successfully built the IO request. SCI_SUCCESS This value is returned if the
322 * IO request was successfully built.
323 */
324enum sci_status scic_io_request_construct(
325 struct scic_sds_controller *scic_controller,
326 struct scic_sds_remote_device *scic_remote_device,
327 u16 io_tag,
328 void *user_io_request_object,
329 void *scic_io_request_memory,
330 struct scic_sds_request **new_scic_io_request_handle);
331
332/**
333 * scic_io_request_construct_basic_ssp() - This method is called by the SCI
334 * user to build an SSP IO request.
335 * @scic_io_request: This parameter specifies the handle to the io request
336 * object to be built.
337 *
338 * - The user must have previously called scic_io_request_construct() on the
339 * supplied IO request. Indicate if the controller successfully built the IO
340 * request. SCI_SUCCESS This value is returned if the IO request was
341 * successfully built. SCI_FAILURE_UNSUPPORTED_PROTOCOL This value is returned
342 * if the remote_device does not support the SSP protocol.
343 * SCI_FAILURE_INVALID_ASSOCIATION This value is returned if the user did not
344 * properly set the association between the SCIC IO request and the user's IO
345 * request. Please refer to the sci_object_set_association() routine for more
346 * information.
347 */
348enum sci_status scic_io_request_construct_basic_ssp(
349 struct scic_sds_request *scic_io_request);
350
351
352
353
354
355/**
356 * scic_io_request_construct_basic_sata() - This method is called by the SCI
357 * Core user to build an STP IO request.
358 * @scic_io_request: This parameter specifies the handle to the io request
359 * object to be built.
360 *
361 * - The user must have previously called scic_io_request_construct() on the
362 * supplied IO request. Indicate if the controller successfully built the IO
363 * request. SCI_SUCCESS This value is returned if the IO request was
364 * successfully built. SCI_FAILURE_UNSUPPORTED_PROTOCOL This value is returned
365 * if the remote_device does not support the STP protocol.
366 * SCI_FAILURE_INVALID_ASSOCIATION This value is returned if the user did not
367 * properly set the association between the SCIC IO request and the user's IO
368 * request. Please refer to the sci_object_set_association() routine for more
369 * information.
370 */
371enum sci_status scic_io_request_construct_basic_sata(
372 struct scic_sds_request *scic_io_request);
373
374
375
376
377/**
378 * scic_io_request_construct_smp() - This method is called by the SCI user to
379 * build an SMP IO request.
380 * @scic_io_request: This parameter specifies the handle to the io request
381 * object to be built.
382 *
383 * - The user must have previously called scic_io_request_construct() on the
384 * supplied IO request. Indicate if the controller successfully built the IO
385 * request. SCI_SUCCESS This value is returned if the IO request was
386 * successfully built. SCI_FAILURE_UNSUPPORTED_PROTOCOL This value is returned
387 * if the remote_device does not support the SMP protocol.
388 * SCI_FAILURE_INVALID_ASSOCIATION This value is returned if the user did not
389 * properly set the association between the SCIC IO request and the user's IO
390 * request. Please refer to the sci_object_set_association() routine for more
391 * information.
392 */
393enum sci_status scic_io_request_construct_smp(
394 struct scic_sds_request *scic_io_request);
395
396
397
398/**
399 * scic_request_get_controller_status() - This method returns the controller
400 * specific IO/Task request status. These status values are unique to the
401 * specific controller being managed by the SCIC.
402 * @io_request: the handle to the IO or task management request object for
403 * which to retrieve the status.
404 *
405 * This method returns a value indicating the controller specific request
406 * status.
407 */
408u32 scic_request_get_controller_status(
409 struct scic_sds_request *io_request);
410
411
412
413/**
414 * scic_io_request_get_command_iu_address() - This method will return the
415 * address to the command information unit.
416 * @scic_io_request: This parameter specifies the handle to the io request
417 * object to be built.
418 *
419 * The address of the SSP/SMP command information unit.
420 */
421void *scic_io_request_get_command_iu_address(
422 struct scic_sds_request *scic_io_request);
423
424/**
425 * scic_io_request_get_response_iu_address() - This method will return the
426 * address to the response information unit. For an SSP request this buffer
427 * is only valid if the IO request is completed with the status
428 * SCI_FAILURE_IO_RESPONSE_VALID.
429 * @scic_io_request: This parameter specifies the handle to the io request
430 * object to be built.
431 *
432 * The address of the SSP/SMP response information unit.
433 */
434void *scic_io_request_get_response_iu_address(
435 struct scic_sds_request *scic_io_request);
436
437/**
438 * scic_io_request_get_io_tag() - This method will return the IO tag utilized
439 * by the IO request.
440 * @scic_io_request: This parameter specifies the handle to the io request
441 * object for which to return the IO tag.
442 *
443 * An unsigned integer representing the IO tag being utilized.
444 * SCI_CONTROLLER_INVALID_IO_TAG This value is returned if the IO does not
445 * currently have an IO tag allocated to it. All return other values indicate a
446 * legitimate tag.
447 */
448u16 scic_io_request_get_io_tag(
449 struct scic_sds_request *scic_io_request);
450
451
452/**
453 * scic_stp_io_request_set_ncq_tag() - This method will assign an NCQ tag to
454 * the io request object. The caller of this function must make sure that
455 * only valid NCQ tags are assigned to the io request object.
456 * @scic_io_request: This parameter specifies the handle to the io request
457 * object to which to assign the ncq tag.
458 * @ncq_tag: This parameter specifies the NCQ tag to be utilized for the
459 * supplied core IO request. It is up to the user to make sure that this is
460 * a valid NCQ tag.
461 *
462 * none This function is only valid for SATA NCQ requests.
463 */
464void scic_stp_io_request_set_ncq_tag(
465 struct scic_sds_request *scic_io_request,
466 u16 ncq_tag);
467
468/**
469 * scic_stp_io_request_get_h2d_reg_address() - This method will return the
470 * address of the host to device register fis region for the io request
471 * object.
472 * @scic_io_request: This parameter specifies the handle to the io request
473 * object from which to get the host to device register fis buffer.
474 *
475 * The address of the host to device register fis buffer in the io request
476 * object. This function is only valid for SATA requests.
477 */
478void *scic_stp_io_request_get_h2d_reg_address(
479 struct scic_sds_request *scic_io_request);
480
481/**
482 * scic_stp_io_request_get_d2h_reg_address() - This method will return the
483 * address of the device to host register fis region for the io request
484 * object.
485 * @scic_io_request: This parameter specifies teh handle to the io request
486 * object from which to get the device to host register fis buffer.
487 *
488 * The address fo the device to host register fis ending the io request. This
489 * function is only valid for SATA requests.
490 */
491void *scic_stp_io_request_get_d2h_reg_address(
492 struct scic_sds_request *scic_io_request);
493
494
495/**
496 * scic_io_request_get_number_of_bytes_transferred() - This method will return
497 * the number of bytes transferred from the SCU
498 * @scic_io_request: This parameter specifies the handle to the io request
499 * whose data length was not eqaul to the data length specified in the
500 * request. When the driver gets an early io completion status from the
501 * hardware, this routine should be called to get the actual number of bytes
502 * transferred
503 *
504 * The return is the number of bytes transferred when the data legth is not
505 * equal to the specified length in the io request
506 */
507u32 scic_io_request_get_number_of_bytes_transferred(
508 struct scic_sds_request *scic_io_request);
509
510
511#endif /* _SCIC_IO_REQUEST_H_ */
512
diff --git a/drivers/scsi/isci/core/scic_phy.h b/drivers/scsi/isci/core/scic_phy.h
new file mode 100644
index 000000000000..25a6140fa9e4
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_phy.h
@@ -0,0 +1,303 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_PHY_H_
57#define _SCIC_PHY_H_
58
59/**
60 * This file contains all of the interface methods that can be called by an
61 * SCIC user on a phy (SAS or SATA) object.
62 *
63 *
64 */
65
66
67#include "sci_types.h"
68#include "sci_status.h"
69
70#include "intel_sata.h"
71#include "intel_sas.h"
72
73struct scic_sds_phy;
74struct scic_sds_port;
75
76/**
77 * struct scic_phy_properties - This structure defines the properties common to
78 * all phys that can be retrieved.
79 *
80 *
81 */
82struct scic_phy_properties {
83 /**
84 * This field specifies the port that currently contains the
85 * supplied phy. This field may be set to SCI_INVALID_HANDLE
86 * if the phy is not currently contained in a port.
87 */
88 struct scic_sds_port *owning_port;
89
90 /**
91 * This field specifies the link rate at which the phy is
92 * currently operating.
93 */
94 enum sci_sas_link_rate negotiated_link_rate;
95
96 /**
97 * This field indicates the protocols supported by the phy.
98 */
99 struct sci_sas_identify_address_frame_protocols protocols;
100
101 /**
102 * This field specifies the index of the phy in relation to other
103 * phys within the controller. This index is zero relative.
104 */
105 u8 index;
106
107};
108
109/**
110 * struct scic_sas_phy_properties - This structure defines the properties,
111 * specific to a SAS phy, that can be retrieved.
112 *
113 *
114 */
115struct scic_sas_phy_properties {
116 /**
117 * This field delineates the Identify Address Frame received
118 * from the remote end point.
119 */
120 struct sci_sas_identify_address_frame received_iaf;
121
122 /**
123 * This field delineates the Phy capabilities structure received
124 * from the remote end point.
125 */
126 struct sas_capabilities received_capabilities;
127
128};
129
130/**
131 * struct scic_sata_phy_properties - This structure defines the properties,
132 * specific to a SATA phy, that can be retrieved.
133 *
134 *
135 */
136struct scic_sata_phy_properties {
137 /**
138 * This field delineates the signature FIS received from the
139 * attached target.
140 */
141 struct sata_fis_reg_d2h signature_fis;
142
143 /**
144 * This field specifies to the user if a port selector is connected
145 * on the specified phy.
146 */
147 bool is_port_selector_present;
148
149};
150
151/**
152 * enum scic_phy_counter_id - This enumeration depicts the various pieces of
153 * optional information that can be retrieved for a specific phy.
154 *
155 *
156 */
157enum scic_phy_counter_id {
158 /**
159 * This PHY information field tracks the number of frames received.
160 */
161 SCIC_PHY_COUNTER_RECEIVED_FRAME,
162
163 /**
164 * This PHY information field tracks the number of frames transmitted.
165 */
166 SCIC_PHY_COUNTER_TRANSMITTED_FRAME,
167
168 /**
169 * This PHY information field tracks the number of DWORDs received.
170 */
171 SCIC_PHY_COUNTER_RECEIVED_FRAME_WORD,
172
173 /**
174 * This PHY information field tracks the number of DWORDs transmitted.
175 */
176 SCIC_PHY_COUNTER_TRANSMITTED_FRAME_DWORD,
177
178 /**
179 * This PHY information field tracks the number of times DWORD
180 * synchronization was lost.
181 */
182 SCIC_PHY_COUNTER_LOSS_OF_SYNC_ERROR,
183
184 /**
185 * This PHY information field tracks the number of received DWORDs with
186 * running disparity errors.
187 */
188 SCIC_PHY_COUNTER_RECEIVED_DISPARITY_ERROR,
189
190 /**
191 * This PHY information field tracks the number of received frames with a
192 * CRC error (not including short or truncated frames).
193 */
194 SCIC_PHY_COUNTER_RECEIVED_FRAME_CRC_ERROR,
195
196 /**
197 * This PHY information field tracks the number of DONE (ACK/NAK TIMEOUT)
198 * primitives received.
199 */
200 SCIC_PHY_COUNTER_RECEIVED_DONE_ACK_NAK_TIMEOUT,
201
202 /**
203 * This PHY information field tracks the number of DONE (ACK/NAK TIMEOUT)
204 * primitives transmitted.
205 */
206 SCIC_PHY_COUNTER_TRANSMITTED_DONE_ACK_NAK_TIMEOUT,
207
208 /**
209 * This PHY information field tracks the number of times the inactivity
210 * timer for connections on the phy has been utilized.
211 */
212 SCIC_PHY_COUNTER_INACTIVITY_TIMER_EXPIRED,
213
214 /**
215 * This PHY information field tracks the number of DONE (CREDIT TIMEOUT)
216 * primitives received.
217 */
218 SCIC_PHY_COUNTER_RECEIVED_DONE_CREDIT_TIMEOUT,
219
220 /**
221 * This PHY information field tracks the number of DONE (CREDIT TIMEOUT)
222 * primitives transmitted.
223 */
224 SCIC_PHY_COUNTER_TRANSMITTED_DONE_CREDIT_TIMEOUT,
225
226 /**
227 * This PHY information field tracks the number of CREDIT BLOCKED
228 * primitives received.
229 * @note Depending on remote device implementation, credit blocks
230 * may occur regularly.
231 */
232 SCIC_PHY_COUNTER_RECEIVED_CREDIT_BLOCKED,
233
234 /**
235 * This PHY information field contains the number of short frames
236 * received. A short frame is simply a frame smaller then what is
237 * allowed by either the SAS or SATA specification.
238 */
239 SCIC_PHY_COUNTER_RECEIVED_SHORT_FRAME,
240
241 /**
242 * This PHY information field contains the number of frames received after
243 * credit has been exhausted.
244 */
245 SCIC_PHY_COUNTER_RECEIVED_FRAME_WITHOUT_CREDIT,
246
247 /**
248 * This PHY information field contains the number of frames received after
249 * a DONE has been received.
250 */
251 SCIC_PHY_COUNTER_RECEIVED_FRAME_AFTER_DONE,
252
253 /**
254 * This PHY information field contains the number of times the phy
255 * failed to achieve DWORD synchronization during speed negotiation.
256 */
257 SCIC_PHY_COUNTER_SN_DWORD_SYNC_ERROR
258};
259
260
261/**
262 * scic_sas_phy_get_properties() - This method will enable the user to retrieve
263 * information specific to a SAS phy, such as: the received identify address
264 * frame, received phy capabilities, etc.
265 * @phy: this parameter specifies the phy for which to retrieve properties.
266 * @properties: This parameter specifies the properties structure into which to
267 * copy the requested information.
268 *
269 * This method returns an indication as to whether the SAS phy properties were
270 * successfully retrieved. SCI_SUCCESS This value is returned if the SAS
271 * properties are successfully retrieved. SCI_FAILURE This value is returned if
272 * the SAS properties are not successfully retrieved (e.g. It's not a SAS Phy).
273 */
274enum sci_status scic_sas_phy_get_properties(
275 struct scic_sds_phy *phy,
276 struct scic_sas_phy_properties *properties);
277
278/**
279 * scic_sata_phy_get_properties() - This method will enable the user to
280 * retrieve information specific to a SATA phy, such as: the received
281 * signature FIS, if a port selector is present, etc.
282 * @phy: this parameter specifies the phy for which to retrieve properties.
283 * @properties: This parameter specifies the properties structure into which to
284 * copy the requested information.
285 *
286 * This method returns an indication as to whether the SATA phy properties were
287 * successfully retrieved. SCI_SUCCESS This value is returned if the SATA
288 * properties are successfully retrieved. SCI_FAILURE This value is returned if
289 * the SATA properties are not successfully retrieved (e.g. It's not a SATA
290 * Phy).
291 */
292enum sci_status scic_sata_phy_get_properties(
293 struct scic_sds_phy *phy,
294 struct scic_sata_phy_properties *properties);
295
296
297
298
299
300
301
302#endif /* _SCIC_PHY_H_ */
303
diff --git a/drivers/scsi/isci/core/scic_port.h b/drivers/scsi/isci/core/scic_port.h
new file mode 100644
index 000000000000..34d22c04aa56
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_port.h
@@ -0,0 +1,213 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_PORT_H_
57#define _SCIC_PORT_H_
58
59/**
60 * This file contains all of the interface methods that can be called by an SCI
61 * Core user on a SAS or SATA port.
62 *
63 *
64 */
65
66
67#include "sci_types.h"
68#include "sci_status.h"
69#include "intel_sas.h"
70
71struct scic_sds_port;
72
73enum SCIC_PORT_NOT_READY_REASON_CODE {
74 SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS,
75 SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED,
76 SCIC_PORT_NOT_READY_INVALID_PORT_CONFIGURATION,
77 SCIC_PORT_NOT_READY_RECONFIGURING,
78
79 SCIC_PORT_NOT_READY_REASON_CODE_MAX
80};
81
82/**
83 * struct scic_port_end_point_properties - This structure defines the
84 * properties that can be retrieved for each end-point local or remote
85 * (attached) port in the controller.
86 *
87 *
88 */
89struct scic_port_end_point_properties {
90 /**
91 * This field indicates the SAS address for the associated end
92 * point in the port.
93 */
94 struct sci_sas_address sas_address;
95
96 /**
97 * This field indicates the protocols supported by the associated
98 * end-point in the port.
99 */
100 struct sci_sas_identify_address_frame_protocols protocols;
101
102};
103
104/**
105 * struct scic_port_properties - This structure defines the properties that can
106 * be retrieved for each port in the controller.
107 *
108 *
109 */
110struct scic_port_properties {
111 /**
112 * This field specifies the logical index of the port (0 relative).
113 */
114 u32 index;
115
116 /**
117 * This field indicates the local end-point properties for port.
118 */
119 struct scic_port_end_point_properties local;
120
121 /**
122 * This field indicates the remote (attached) end-point properties
123 * for the port.
124 */
125 struct scic_port_end_point_properties remote;
126
127 /**
128 * This field specifies the phys contained inside the port.
129 */
130 u32 phy_mask;
131
132};
133
134/**
135 * scic_port_get_properties() - This method simply returns the properties
136 * regarding the port, such as: physical index, protocols, sas address, etc.
137 * @port: this parameter specifies the port for which to retrieve the physical
138 * index.
139 * @properties: This parameter specifies the properties structure into which to
140 * copy the requested information.
141 *
142 * Indicate if the user specified a valid port. SCI_SUCCESS This value is
143 * returned if the specified port was valid. SCI_FAILURE_INVALID_PORT This
144 * value is returned if the specified port is not valid. When this value is
145 * returned, no data is copied to the properties output parameter.
146 */
147enum sci_status scic_port_get_properties(
148 struct scic_sds_port *port,
149 struct scic_port_properties *properties);
150
151
152
153/**
154 * scic_port_start() - This method will make the port ready for operation.
155 * Prior to calling the start method IO operation is not possible.
156 * @port: This parameter specifies the port to be started.
157 *
158 * Indicate if the port was successfully started. SCI_SUCCESS This value is
159 * returned if the port was successfully started. SCI_WARNING_ALREADY_IN_STATE
160 * This value is returned if the port is in the process of starting.
161 * SCI_FAILURE_INVALID_PORT This value is returned if the supplied port is not
162 * valid. SCI_FAILURE_INVALID_STATE This value is returned if a start operation
163 * can't be completed due to the state of port.
164 */
165enum sci_status scic_port_start(
166 struct scic_sds_port *port);
167
168/**
169 * scic_port_stop() - This method will make the port no longer ready for
170 * operation. After invoking this method IO operation is not possible.
171 * @port: This parameter specifies the port to be stopped.
172 *
173 * Indicate if the port was successfully stopped. SCI_SUCCESS This value is
174 * returned if the port was successfully stopped. SCI_WARNING_ALREADY_IN_STATE
175 * This value is returned if the port is already stopped or in the process of
176 * stopping. SCI_FAILURE_INVALID_PORT This value is returned if the supplied
177 * port is not valid. SCI_FAILURE_INVALID_STATE This value is returned if a
178 * stop operation can't be completed due to the state of port.
179 */
180enum sci_status scic_port_stop(
181 struct scic_sds_port *port);
182
183/**
184 * scic_port_hard_reset() - This method will request the SCI implementation to
185 * perform a HARD RESET on the SAS Port. If/When the HARD RESET completes
186 * the SCI user will be notified via an SCI OS callback indicating a direct
187 * attached device was found.
188 * @port: a handle corresponding to the SAS port to be hard reset.
189 * @reset_timeout: This parameter specifies the number of milliseconds in which
190 * the port reset operation should complete.
191 *
192 * The SCI User callback in SCIC_USER_CALLBACKS_T will only be called once for
193 * each phy in the SAS Port at completion of the hard reset sequence. Return a
194 * status indicating whether the hard reset started successfully. SCI_SUCCESS
195 * This value is returned if the hard reset operation started successfully.
196 */
197enum sci_status scic_port_hard_reset(
198 struct scic_sds_port *port,
199 u32 reset_timeout);
200
201/**
202 * scic_port_enable_broadcast_change_notification() - This API method enables
203 * the broadcast change notification from underneath hardware.
204 * @port: The port upon which broadcast change notifications (BCN) are to be
205 * enabled.
206 *
207 */
208void scic_port_enable_broadcast_change_notification(
209 struct scic_sds_port *port);
210
211
212#endif /* _SCIC_PORT_H_ */
213
diff --git a/drivers/scsi/isci/core/scic_remote_device.h b/drivers/scsi/isci/core/scic_remote_device.h
new file mode 100644
index 000000000000..e8c04592763e
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_remote_device.h
@@ -0,0 +1,295 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_REMOTE_DEVICE_H_
57#define _SCIC_REMOTE_DEVICE_H_
58
59/**
60 * This file contains all of the interface methods that can be called by an
61 * SCIC user on the device object.
62 *
63 *
64 */
65
66
67#include "sci_types.h"
68#include "sci_status.h"
69#include "intel_sas.h"
70
71struct scic_sds_port;
72struct scic_sds_remote_device;
73
74/**
75 *
76 *
77 *
78 */
79enum scic_remote_device_not_ready_reason_code {
80 SCIC_REMOTE_DEVICE_NOT_READY_START_REQUESTED,
81 SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED,
82 SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED,
83 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED,
84 SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED,
85
86 SCIC_REMOTE_DEVICE_NOT_READY_REASON_CODE_MAX
87
88};
89
90/**
91 * scic_remote_device_get_object_size() - This method simply returns the
92 * maximum memory space needed to store a remote device object.
93 *
94 * a positive integer value indicating the size (in bytes) of the remote device
95 * object.
96 */
97u32 scic_remote_device_get_object_size(
98 void);
99
100struct scic_sds_port;
101struct scic_sds_remote_device;
102/**
103 * scic_remote_device_construct() - This method will perform the construction
104 * common to all remote device objects.
105 * @sci_port: SAS/SATA port through which this device is accessed.
106 * @sci_dev: remote device to construct
107 *
108 * It isn't necessary to call scic_remote_device_destruct() for device objects
109 * that have only called this method for construction. Once subsequent
110 * construction methods have been invoked (e.g.
111 * scic_remote_device_da_construct()), then destruction should occur. none
112 */
113void scic_remote_device_construct(struct scic_sds_port *sci_port,
114 struct scic_sds_remote_device *sci_dev);
115
116/**
117 * scic_remote_device_da_construct() - This method will construct a
118 * SCIC_REMOTE_DEVICE object for a direct attached (da) device. The
119 * information (e.g. IAF, Signature FIS, etc.) necessary to build the device
120 * is known to the SCI Core since it is contained in the scic_phy object.
121 * @remote_device: This parameter specifies the remote device to be destructed.
122 *
123 * The user must have previously called scic_remote_device_construct() Remote
124 * device objects are a limited resource. As such, they must be protected.
125 * Thus calls to construct and destruct are mutually exclusive and
126 * non-reentrant. Indicate if the remote device was successfully constructed.
127 * SCI_SUCCESS Returned if the device was successfully constructed.
128 * SCI_FAILURE_DEVICE_EXISTS Returned if the device has already been
129 * constructed. If it's an additional phy for the target, then call
130 * scic_remote_device_da_add_phy(). SCI_FAILURE_UNSUPPORTED_PROTOCOL Returned
131 * if the supplied parameters necessitate creation of a remote device for which
132 * the protocol is not supported by the underlying controller hardware.
133 * SCI_FAILURE_INSUFFICIENT_RESOURCES This value is returned if the core
134 * controller associated with the supplied parameters is unable to support
135 * additional remote devices.
136 */
137enum sci_status scic_remote_device_da_construct(
138 struct scic_sds_remote_device *remote_device);
139
140/**
141 * scic_remote_device_ea_construct() - This method will construct an
142 * SCIC_REMOTE_DEVICE object for an expander attached (ea) device from an
143 * SMP Discover Response.
144 * @remote_device: This parameter specifies the remote device to be destructed.
145 * @discover_response: This parameter specifies the SMP Discovery Response to
146 * be used in device creation.
147 *
148 * The user must have previously called scic_remote_device_construct() Remote
149 * device objects are a limited resource. As such, they must be protected.
150 * Thus calls to construct and destruct are mutually exclusive and
151 * non-reentrant. Indicate if the remote device was successfully constructed.
152 * SCI_SUCCESS Returned if the device was successfully constructed.
153 * SCI_FAILURE_DEVICE_EXISTS Returned if the device has already been
154 * constructed. If it's an additional phy for the target, then call
155 * scic_ea_remote_device_add_phy(). SCI_FAILURE_UNSUPPORTED_PROTOCOL Returned
156 * if the supplied parameters necessitate creation of a remote device for which
157 * the protocol is not supported by the underlying controller hardware.
158 * SCI_FAILURE_INSUFFICIENT_RESOURCES This value is returned if the core
159 * controller associated with the supplied parameters is unable to support
160 * additional remote devices.
161 */
162enum sci_status scic_remote_device_ea_construct(
163 struct scic_sds_remote_device *remote_device,
164 struct smp_response_discover *discover_response);
165
166/**
167 * scic_remote_device_destruct() - This method is utilized to free up a core's
168 * remote device object.
169 * @remote_device: This parameter specifies the remote device to be destructed.
170 *
171 * Remote device objects are a limited resource. As such, they must be
172 * protected. Thus calls to construct and destruct are mutually exclusive and
173 * non-reentrant. The return value shall indicate if the device was
174 * successfully destructed or if some failure occurred. enum sci_status This value
175 * is returned if the device is successfully destructed.
176 * SCI_FAILURE_INVALID_REMOTE_DEVICE This value is returned if the supplied
177 * device isn't valid (e.g. it's already been destoryed, the handle isn't
178 * valid, etc.).
179 */
180enum sci_status scic_remote_device_destruct(
181 struct scic_sds_remote_device *remote_device);
182
183
184
185
186
187/**
188 * scic_remote_device_start() - This method will start the supplied remote
189 * device. This method enables normal IO requests to flow through to the
190 * remote device.
191 * @remote_device: This parameter specifies the device to be started.
192 * @timeout: This parameter specifies the number of milliseconds in which the
193 * start operation should complete.
194 *
195 * An indication of whether the device was successfully started. SCI_SUCCESS
196 * This value is returned if the device was successfully started.
197 * SCI_FAILURE_INVALID_PHY This value is returned if the user attempts to start
198 * the device when there have been no phys added to it.
199 */
200enum sci_status scic_remote_device_start(
201 struct scic_sds_remote_device *remote_device,
202 u32 timeout);
203
204/**
205 * scic_remote_device_stop() - This method will stop both transmission and
206 * reception of link activity for the supplied remote device. This method
207 * disables normal IO requests from flowing through to the remote device.
208 * @remote_device: This parameter specifies the device to be stopped.
209 * @timeout: This parameter specifies the number of milliseconds in which the
210 * stop operation should complete.
211 *
212 * An indication of whether the device was successfully stopped. SCI_SUCCESS
213 * This value is returned if the transmission and reception for the device was
214 * successfully stopped.
215 */
216enum sci_status scic_remote_device_stop(
217 struct scic_sds_remote_device *remote_device,
218 u32 timeout);
219
220/**
221 * scic_remote_device_reset() - This method will reset the device making it
222 * ready for operation. This method must be called anytime the device is
223 * reset either through a SMP phy control or a port hard reset request.
224 * @remote_device: This parameter specifies the device to be reset.
225 *
226 * This method does not actually cause the device hardware to be reset. This
227 * method resets the software object so that it will be operational after a
228 * device hardware reset completes. An indication of whether the device reset
229 * was accepted. SCI_SUCCESS This value is returned if the device reset is
230 * started.
231 */
232enum sci_status scic_remote_device_reset(
233 struct scic_sds_remote_device *remote_device);
234
235/**
236 * scic_remote_device_reset_complete() - This method informs the device object
237 * that the reset operation is complete and the device can resume operation
238 * again.
239 * @remote_device: This parameter specifies the device which is to be informed
240 * of the reset complete operation.
241 *
242 * An indication that the device is resuming operation. SCI_SUCCESS the device
243 * is resuming operation.
244 */
245enum sci_status scic_remote_device_reset_complete(
246 struct scic_sds_remote_device *remote_device);
247
248
249
250/**
251 * scic_remote_device_get_connection_rate() - This method simply returns the
252 * link rate at which communications to the remote device occur.
253 * @remote_device: This parameter specifies the device for which to get the
254 * connection rate.
255 *
256 * Return the link rate at which we transfer for the supplied remote device.
257 */
258enum sci_sas_link_rate scic_remote_device_get_connection_rate(
259 struct scic_sds_remote_device *remote_device);
260
261/**
262 * scic_remote_device_get_protocols() - This method will indicate which
263 * protocols are supported by this remote device.
264 * @remote_device: This parameter specifies the device for which to return the
265 * protocol.
266 * @protocols: This parameter specifies the output values, from the remote
267 * device object, which indicate the protocols supported by the supplied
268 * remote_device.
269 *
270 * The type of protocols supported by this device. The values are returned as
271 * part of a bit mask in order to allow for multi-protocol support.
272 */
273void scic_remote_device_get_protocols(
274 struct scic_sds_remote_device *remote_device,
275 struct smp_discover_response_protocols *protocols);
276
277
278#if !defined(DISABLE_ATAPI)
279/**
280 * scic_remote_device_is_atapi() -
281 * @this_device: The device whose type is to be decided.
282 *
283 * This method first decide whether a device is a stp target, then decode the
284 * signature fis of a DA STP device to tell whether it is a standard end disk
285 * or an ATAPI device. bool Indicate a device is ATAPI device or not.
286 */
287bool scic_remote_device_is_atapi(
288 struct scic_sds_remote_device *device_handle);
289#else /* !defined(DISABLE_ATAPI) */
290#define scic_remote_device_is_atapi(device_handle) false
291#endif /* !defined(DISABLE_ATAPI) */
292
293
294#endif /* _SCIC_REMOTE_DEVICE_H_ */
295
diff --git a/drivers/scsi/isci/core/scic_sds_controller.c b/drivers/scsi/isci/core/scic_sds_controller.c
new file mode 100644
index 000000000000..35f7796df661
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_controller.c
@@ -0,0 +1,4147 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include <linux/device.h>
57#include "scic_controller.h"
58#include "scic_phy.h"
59#include "scic_port.h"
60#include "scic_remote_device.h"
61#include "scic_sds_controller.h"
62#include "scic_sds_controller_registers.h"
63#include "scic_sds_pci.h"
64#include "scic_sds_phy.h"
65#include "scic_sds_port_configuration_agent.h"
66#include "scic_sds_port.h"
67#include "scic_sds_remote_device.h"
68#include "scic_sds_request.h"
69#include "scic_user_callback.h"
70#include "sci_environment.h"
71#include "sci_util.h"
72#include "scu_completion_codes.h"
73#include "scu_constants.h"
74#include "scu_event_codes.h"
75#include "scu_remote_node_context.h"
76#include "scu_task_context.h"
77#include "scu_unsolicited_frame.h"
78
79#define SCU_CONTEXT_RAM_INIT_STALL_TIME 200
80
81/**
82 * smu_dcc_get_max_ports() -
83 *
84 * This macro returns the maximum number of logical ports supported by the
85 * hardware. The caller passes in the value read from the device context
86 * capacity register and this macro will mash and shift the value appropriately.
87 */
88#define smu_dcc_get_max_ports(dcc_value) \
89 (\
90 (((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_MASK) \
91 >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_SHIFT) + 1 \
92 )
93
94/**
95 * smu_dcc_get_max_task_context() -
96 *
97 * This macro returns the maximum number of task contexts supported by the
98 * hardware. The caller passes in the value read from the device context
99 * capacity register and this macro will mash and shift the value appropriately.
100 */
101#define smu_dcc_get_max_task_context(dcc_value) \
102 (\
103 (((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_MASK) \
104 >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_SHIFT) + 1 \
105 )
106
107/**
108 * smu_dcc_get_max_remote_node_context() -
109 *
110 * This macro returns the maximum number of remote node contexts supported by
111 * the hardware. The caller passes in the value read from the device context
112 * capacity register and this macro will mash and shift the value appropriately.
113 */
114#define smu_dcc_get_max_remote_node_context(dcc_value) \
115 (\
116 (((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_MASK) \
117 >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_SHIFT) + 1 \
118 )
119
120
121static void scic_sds_controller_power_control_timer_handler(
122 void *controller);
123#define SCIC_SDS_CONTROLLER_MIN_TIMER_COUNT 3
124#define SCIC_SDS_CONTROLLER_MAX_TIMER_COUNT 3
125
126/**
127 *
128 *
129 * The number of milliseconds to wait for a phy to start.
130 */
131#define SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT 100
132
133/**
134 *
135 *
136 * The number of milliseconds to wait while a given phy is consuming power
137 * before allowing another set of phys to consume power. Ultimately, this will
138 * be specified by OEM parameter.
139 */
140#define SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL 500
141
142/**
143 * COMPLETION_QUEUE_CYCLE_BIT() -
144 *
145 * This macro will return the cycle bit of the completion queue entry
146 */
147#define COMPLETION_QUEUE_CYCLE_BIT(x) ((x) & 0x80000000)
148
149/**
150 * NORMALIZE_GET_POINTER() -
151 *
152 * This macro will normalize the completion queue get pointer so its value can
153 * be used as an index into an array
154 */
155#define NORMALIZE_GET_POINTER(x) \
156 ((x) & SMU_COMPLETION_QUEUE_GET_POINTER_MASK)
157
158/**
159 * NORMALIZE_PUT_POINTER() -
160 *
161 * This macro will normalize the completion queue put pointer so its value can
162 * be used as an array inde
163 */
164#define NORMALIZE_PUT_POINTER(x) \
165 ((x) & SMU_COMPLETION_QUEUE_PUT_POINTER_MASK)
166
167
168/**
169 * NORMALIZE_GET_POINTER_CYCLE_BIT() -
170 *
171 * This macro will normalize the completion queue cycle pointer so it matches
172 * the completion queue cycle bit
173 */
174#define NORMALIZE_GET_POINTER_CYCLE_BIT(x) \
175 ((SMU_CQGR_CYCLE_BIT & (x)) << (31 - SMU_COMPLETION_QUEUE_GET_CYCLE_BIT_SHIFT))
176
177/**
178 * NORMALIZE_EVENT_POINTER() -
179 *
180 * This macro will normalize the completion queue event entry so its value can
181 * be used as an index.
182 */
183#define NORMALIZE_EVENT_POINTER(x) \
184 (\
185 ((x) & SMU_COMPLETION_QUEUE_GET_EVENT_POINTER_MASK) \
186 >> SMU_COMPLETION_QUEUE_GET_EVENT_POINTER_SHIFT \
187 )
188
189/**
190 * INCREMENT_COMPLETION_QUEUE_GET() -
191 *
192 * This macro will increment the controllers completion queue index value and
193 * possibly toggle the cycle bit if the completion queue index wraps back to 0.
194 */
195#define INCREMENT_COMPLETION_QUEUE_GET(controller, index, cycle) \
196 INCREMENT_QUEUE_GET(\
197 (index), \
198 (cycle), \
199 (controller)->completion_queue_entries, \
200 SMU_CQGR_CYCLE_BIT \
201 )
202
203/**
204 * INCREMENT_EVENT_QUEUE_GET() -
205 *
206 * This macro will increment the controllers event queue index value and
207 * possibly toggle the event cycle bit if the event queue index wraps back to 0.
208 */
209#define INCREMENT_EVENT_QUEUE_GET(controller, index, cycle) \
210 INCREMENT_QUEUE_GET(\
211 (index), \
212 (cycle), \
213 (controller)->completion_event_entries, \
214 SMU_CQGR_EVENT_CYCLE_BIT \
215 )
216
217struct sci_base_memory_descriptor_list *
218sci_controller_get_memory_descriptor_list_handle(struct scic_sds_controller *scic)
219{
220 return &scic->parent.mdl;
221}
222
223/*
224 * ****************************************************************************-
225 * * SCIC SDS Controller Initialization Methods
226 * ****************************************************************************- */
227
228/**
229 * This timer is used to start another phy after we have given up on the
230 * previous phy to transition to the ready state.
231 *
232 *
233 */
234static void scic_sds_controller_phy_startup_timeout_handler(
235 void *controller)
236{
237 enum sci_status status;
238 struct scic_sds_controller *this_controller;
239
240 this_controller = (struct scic_sds_controller *)controller;
241
242 this_controller->phy_startup_timer_pending = false;
243
244 status = SCI_FAILURE;
245
246 while (status != SCI_SUCCESS) {
247 status = scic_sds_controller_start_next_phy(this_controller);
248 }
249}
250
251/**
252 *
253 *
254 * This method initializes the phy startup operations for controller start.
255 */
256void scic_sds_controller_initialize_phy_startup(
257 struct scic_sds_controller *this_controller)
258{
259 this_controller->phy_startup_timer = scic_cb_timer_create(
260 this_controller,
261 scic_sds_controller_phy_startup_timeout_handler,
262 this_controller
263 );
264
265 this_controller->next_phy_to_start = 0;
266 this_controller->phy_startup_timer_pending = false;
267}
268
269/**
270 *
271 *
272 * This method initializes the power control operations for the controller
273 * object.
274 */
275void scic_sds_controller_initialize_power_control(
276 struct scic_sds_controller *this_controller)
277{
278 this_controller->power_control.timer = scic_cb_timer_create(
279 this_controller,
280 scic_sds_controller_power_control_timer_handler,
281 this_controller
282 );
283
284 memset(
285 this_controller->power_control.requesters,
286 0,
287 sizeof(this_controller->power_control.requesters)
288 );
289
290 this_controller->power_control.phys_waiting = 0;
291}
292
293/* --------------------------------------------------------------------------- */
294
295#define SCU_REMOTE_NODE_CONTEXT_ALIGNMENT (32)
296#define SCU_TASK_CONTEXT_ALIGNMENT (256)
297#define SCU_UNSOLICITED_FRAME_ADDRESS_ALIGNMENT (64)
298#define SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT (1024)
299#define SCU_UNSOLICITED_FRAME_HEADER_ALIGNMENT (64)
300
301/* --------------------------------------------------------------------------- */
302
303/**
304 * This method builds the memory descriptor table for this controller.
305 * @this_controller: This parameter specifies the controller object for which
306 * to build the memory table.
307 *
308 */
309static void scic_sds_controller_build_memory_descriptor_table(
310 struct scic_sds_controller *this_controller)
311{
312 sci_base_mde_construct(
313 &this_controller->memory_descriptors[SCU_MDE_COMPLETION_QUEUE],
314 SCU_COMPLETION_RAM_ALIGNMENT,
315 (sizeof(u32) * this_controller->completion_queue_entries),
316 (SCI_MDE_ATTRIBUTE_CACHEABLE | SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS)
317 );
318
319 sci_base_mde_construct(
320 &this_controller->memory_descriptors[SCU_MDE_REMOTE_NODE_CONTEXT],
321 SCU_REMOTE_NODE_CONTEXT_ALIGNMENT,
322 this_controller->remote_node_entries * sizeof(union scu_remote_node_context),
323 SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
324 );
325
326 sci_base_mde_construct(
327 &this_controller->memory_descriptors[SCU_MDE_TASK_CONTEXT],
328 SCU_TASK_CONTEXT_ALIGNMENT,
329 this_controller->task_context_entries * sizeof(struct scu_task_context),
330 SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
331 );
332
333 /*
334 * The UF buffer address table size must be programmed to a power
335 * of 2. Find the first power of 2 that is equal to or greater then
336 * the number of unsolicited frame buffers to be utilized. */
337 scic_sds_unsolicited_frame_control_set_address_table_count(
338 &this_controller->uf_control
339 );
340
341 sci_base_mde_construct(
342 &this_controller->memory_descriptors[SCU_MDE_UF_BUFFER],
343 SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT,
344 scic_sds_unsolicited_frame_control_get_mde_size(this_controller->uf_control),
345 SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
346 );
347}
348
349/**
350 * This method validates the driver supplied memory descriptor table.
351 * @this_controller:
352 *
353 * enum sci_status
354 */
355enum sci_status scic_sds_controller_validate_memory_descriptor_table(
356 struct scic_sds_controller *this_controller)
357{
358 bool mde_list_valid;
359
360 mde_list_valid = sci_base_mde_is_valid(
361 &this_controller->memory_descriptors[SCU_MDE_COMPLETION_QUEUE],
362 SCU_COMPLETION_RAM_ALIGNMENT,
363 (sizeof(u32) * this_controller->completion_queue_entries),
364 (SCI_MDE_ATTRIBUTE_CACHEABLE | SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS)
365 );
366
367 if (mde_list_valid == false)
368 return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD;
369
370 mde_list_valid = sci_base_mde_is_valid(
371 &this_controller->memory_descriptors[SCU_MDE_REMOTE_NODE_CONTEXT],
372 SCU_REMOTE_NODE_CONTEXT_ALIGNMENT,
373 this_controller->remote_node_entries * sizeof(union scu_remote_node_context),
374 SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
375 );
376
377 if (mde_list_valid == false)
378 return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD;
379
380 mde_list_valid = sci_base_mde_is_valid(
381 &this_controller->memory_descriptors[SCU_MDE_TASK_CONTEXT],
382 SCU_TASK_CONTEXT_ALIGNMENT,
383 this_controller->task_context_entries * sizeof(struct scu_task_context),
384 SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
385 );
386
387 if (mde_list_valid == false)
388 return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD;
389
390 mde_list_valid = sci_base_mde_is_valid(
391 &this_controller->memory_descriptors[SCU_MDE_UF_BUFFER],
392 SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT,
393 scic_sds_unsolicited_frame_control_get_mde_size(this_controller->uf_control),
394 SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
395 );
396
397 if (mde_list_valid == false)
398 return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD;
399
400 return SCI_SUCCESS;
401}
402
403/**
404 * This method initializes the controller with the physical memory addresses
405 * that are used to communicate with the driver.
406 * @this_controller:
407 *
408 */
409void scic_sds_controller_ram_initialization(
410 struct scic_sds_controller *this_controller)
411{
412 struct sci_physical_memory_descriptor *mde;
413
414 /*
415 * The completion queue is actually placed in cacheable memory
416 * Therefore it no longer comes out of memory in the MDL. */
417 mde = &this_controller->memory_descriptors[SCU_MDE_COMPLETION_QUEUE];
418 this_controller->completion_queue = (u32 *)mde->virtual_address;
419 SMU_CQBAR_WRITE(this_controller, mde->physical_address);
420
421 /*
422 * Program the location of the Remote Node Context table
423 * into the SCU. */
424 mde = &this_controller->memory_descriptors[SCU_MDE_REMOTE_NODE_CONTEXT];
425 this_controller->remote_node_context_table = (union scu_remote_node_context *)
426 mde->virtual_address;
427 SMU_RNCBAR_WRITE(this_controller, mde->physical_address);
428
429 /* Program the location of the Task Context table into the SCU. */
430 mde = &this_controller->memory_descriptors[SCU_MDE_TASK_CONTEXT];
431 this_controller->task_context_table = (struct scu_task_context *)
432 mde->virtual_address;
433 SMU_HTTBAR_WRITE(this_controller, mde->physical_address);
434
435 mde = &this_controller->memory_descriptors[SCU_MDE_UF_BUFFER];
436 scic_sds_unsolicited_frame_control_construct(
437 &this_controller->uf_control, mde, this_controller
438 );
439
440 /*
441 * Inform the silicon as to the location of the UF headers and
442 * address table. */
443 SCU_UFHBAR_WRITE(
444 this_controller,
445 this_controller->uf_control.headers.physical_address);
446 SCU_PUFATHAR_WRITE(
447 this_controller,
448 this_controller->uf_control.address_table.physical_address);
449}
450
451/**
452 * This method initializes the task context data for the controller.
453 * @this_controller:
454 *
455 */
456void scic_sds_controller_assign_task_entries(
457 struct scic_sds_controller *this_controller)
458{
459 u32 task_assignment;
460
461 /*
462 * Assign all the TCs to function 0
463 * TODO: Do we actually need to read this register to write it back? */
464 task_assignment = SMU_TCA_READ(this_controller, 0);
465
466 task_assignment =
467 (
468 task_assignment
469 | (SMU_TCA_GEN_VAL(STARTING, 0))
470 | (SMU_TCA_GEN_VAL(ENDING, this_controller->task_context_entries - 1))
471 | (SMU_TCA_GEN_BIT(RANGE_CHECK_ENABLE))
472 );
473
474 SMU_TCA_WRITE(this_controller, 0, task_assignment);
475}
476
477/**
478 * This method initializes the hardware completion queue.
479 *
480 *
481 */
482void scic_sds_controller_initialize_completion_queue(
483 struct scic_sds_controller *this_controller)
484{
485 u32 index;
486 u32 completion_queue_control_value;
487 u32 completion_queue_get_value;
488 u32 completion_queue_put_value;
489
490 this_controller->completion_queue_get = 0;
491
492 completion_queue_control_value = (
493 SMU_CQC_QUEUE_LIMIT_SET(this_controller->completion_queue_entries - 1)
494 | SMU_CQC_EVENT_LIMIT_SET(this_controller->completion_event_entries - 1)
495 );
496
497 SMU_CQC_WRITE(this_controller, completion_queue_control_value);
498
499 /* Set the completion queue get pointer and enable the queue */
500 completion_queue_get_value = (
501 (SMU_CQGR_GEN_VAL(POINTER, 0))
502 | (SMU_CQGR_GEN_VAL(EVENT_POINTER, 0))
503 | (SMU_CQGR_GEN_BIT(ENABLE))
504 | (SMU_CQGR_GEN_BIT(EVENT_ENABLE))
505 );
506
507 SMU_CQGR_WRITE(this_controller, completion_queue_get_value);
508
509 /* Set the completion queue put pointer */
510 completion_queue_put_value = (
511 (SMU_CQPR_GEN_VAL(POINTER, 0))
512 | (SMU_CQPR_GEN_VAL(EVENT_POINTER, 0))
513 );
514
515 SMU_CQPR_WRITE(this_controller, completion_queue_put_value);
516
517 /* Initialize the cycle bit of the completion queue entries */
518 for (index = 0; index < this_controller->completion_queue_entries; index++) {
519 /*
520 * If get.cycle_bit != completion_queue.cycle_bit
521 * its not a valid completion queue entry
522 * so at system start all entries are invalid */
523 this_controller->completion_queue[index] = 0x80000000;
524 }
525}
526
527/**
528 * This method initializes the hardware unsolicited frame queue.
529 *
530 *
531 */
532void scic_sds_controller_initialize_unsolicited_frame_queue(
533 struct scic_sds_controller *this_controller)
534{
535 u32 frame_queue_control_value;
536 u32 frame_queue_get_value;
537 u32 frame_queue_put_value;
538
539 /* Write the queue size */
540 frame_queue_control_value =
541 SCU_UFQC_GEN_VAL(QUEUE_SIZE, this_controller->uf_control.address_table.count);
542
543 SCU_UFQC_WRITE(this_controller, frame_queue_control_value);
544
545 /* Setup the get pointer for the unsolicited frame queue */
546 frame_queue_get_value = (
547 SCU_UFQGP_GEN_VAL(POINTER, 0)
548 | SCU_UFQGP_GEN_BIT(ENABLE_BIT)
549 );
550
551 SCU_UFQGP_WRITE(this_controller, frame_queue_get_value);
552
553 /* Setup the put pointer for the unsolicited frame queue */
554 frame_queue_put_value = SCU_UFQPP_GEN_VAL(POINTER, 0);
555
556 SCU_UFQPP_WRITE(this_controller, frame_queue_put_value);
557}
558
559/**
560 * This method enables the hardware port task scheduler.
561 *
562 *
563 */
564void scic_sds_controller_enable_port_task_scheduler(
565 struct scic_sds_controller *this_controller)
566{
567 u32 port_task_scheduler_value;
568
569 port_task_scheduler_value = SCU_PTSGCR_READ(this_controller);
570
571 port_task_scheduler_value |=
572 (SCU_PTSGCR_GEN_BIT(ETM_ENABLE) | SCU_PTSGCR_GEN_BIT(PTSG_ENABLE));
573
574 SCU_PTSGCR_WRITE(this_controller, port_task_scheduler_value);
575}
576
577/* --------------------------------------------------------------------------- */
578
579/**
580 *
581 *
582 * This macro is used to delay between writes to the AFE registers during AFE
583 * initialization.
584 */
585#define AFE_REGISTER_WRITE_DELAY 10
586
587static bool is_a0(void)
588{
589 return isci_si_rev == ISCI_SI_REVA0;
590}
591
592static bool is_a2(void)
593{
594 return isci_si_rev == ISCI_SI_REVA2;
595}
596
597static bool is_b0(void)
598{
599 return isci_si_rev > ISCI_SI_REVA2;
600}
601
602/* Initialize the AFE for this phy index. We need to read the AFE setup from
603 * the OEM parameters none
604 */
605void scic_sds_controller_afe_initialization(struct scic_sds_controller *scic)
606{
607 u32 afe_status;
608 u32 phy_id;
609
610 /* Clear DFX Status registers */
611 scu_afe_register_write(scic, afe_dfx_master_control0, 0x0081000f);
612 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
613
614 /* Configure bias currents to normal */
615 if (is_a0())
616 scu_afe_register_write(scic, afe_bias_control, 0x00005500);
617 else
618 scu_afe_register_write(scic, afe_bias_control, 0x00005A00);
619
620
621 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
622
623 /* Enable PLL */
624 if (is_b0())
625 scu_afe_register_write(scic, afe_pll_control0, 0x80040A08);
626 else
627 scu_afe_register_write(scic, afe_pll_control0, 0x80040908);
628
629 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
630
631 /* Wait for the PLL to lock */
632 do {
633 afe_status = scu_afe_register_read(
634 scic, afe_common_block_status);
635 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
636 } while ((afe_status & 0x00001000) == 0);
637
638 if (is_b0()) {
639 /* Shorten SAS SNW lock time (RxLock timer value from 76 us to 50 us) */
640 scu_afe_register_write(scic, afe_pmsn_master_control0, 0x7bcc96ad);
641 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
642 }
643
644 for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++) {
645 if (is_b0()) {
646 /* Configure transmitter SSC parameters */
647 scu_afe_txreg_write(scic, phy_id, afe_tx_ssc_control, 0x00030000);
648 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
649 } else {
650 /*
651 * All defaults, except the Receive Word Alignament/Comma Detect
652 * Enable....(0xe800) */
653 scu_afe_txreg_write(scic, phy_id, afe_xcvr_control0, 0x00004512);
654 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
655
656 scu_afe_txreg_write(scic, phy_id, afe_xcvr_control1, 0x0050100F);
657 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
658 }
659
660 /*
661 * Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
662 * & increase TX int & ext bias 20%....(0xe85c) */
663 if (is_a0())
664 scu_afe_txreg_write(scic, phy_id, afe_channel_control, 0x000003D4);
665 else if (is_a2())
666 scu_afe_txreg_write(scic, phy_id, afe_channel_control, 0x000003F0);
667 else {
668 /* Power down TX and RX (PWRDNTX and PWRDNRX) */
669 scu_afe_txreg_write(scic, phy_id, afe_channel_control, 0x000003d7);
670 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
671
672 /*
673 * Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
674 * & increase TX int & ext bias 20%....(0xe85c) */
675 scu_afe_txreg_write(scic, phy_id, afe_channel_control, 0x000003d4);
676 }
677 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
678
679 if (is_a0() || is_a2()) {
680 /* Enable TX equalization (0xe824) */
681 scu_afe_txreg_write(scic, phy_id, afe_tx_control, 0x00040000);
682 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
683 }
684
685 /*
686 * RDPI=0x0(RX Power On), RXOOBDETPDNC=0x0, TPD=0x0(TX Power On),
687 * RDD=0x0(RX Detect Enabled) ....(0xe800) */
688 scu_afe_txreg_write(scic, phy_id, afe_xcvr_control0, 0x00004100);
689 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
690
691 /* Leave DFE/FFE on */
692 if (is_a0())
693 scu_afe_txreg_write(scic, phy_id, afe_rx_ssc_control0, 0x3F09983F);
694 else if (is_a2())
695 scu_afe_txreg_write(scic, phy_id, afe_rx_ssc_control0, 0x3F11103F);
696 else {
697 scu_afe_txreg_write(scic, phy_id, afe_rx_ssc_control0, 0x3F11103F);
698 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
699 /* Enable TX equalization (0xe824) */
700 scu_afe_txreg_write(scic, phy_id, afe_tx_control, 0x00040000);
701 }
702 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
703
704 scu_afe_txreg_write(scic, phy_id, afe_tx_amp_control0, 0x000E7C03);
705 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
706
707 scu_afe_txreg_write(scic, phy_id, afe_tx_amp_control1, 0x000E7C03);
708 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
709
710 scu_afe_txreg_write(scic, phy_id, afe_tx_amp_control2, 0x000E7C03);
711 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
712
713 scu_afe_txreg_write(scic, phy_id, afe_tx_amp_control3, 0x000E7C03);
714 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
715 }
716
717 /* Transfer control to the PEs */
718 scu_afe_register_write(scic, afe_dfx_master_control0, 0x00010f00);
719 scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
720}
721
722/*
723 * ****************************************************************************-
724 * * SCIC SDS Controller Internal Start/Stop Routines
725 * ****************************************************************************- */
726
727
728/**
729 * This method will attempt to transition into the ready state for the
730 * controller and indicate that the controller start operation has completed
731 * if all criteria are met.
732 * @this_controller: This parameter indicates the controller object for which
733 * to transition to ready.
734 * @status: This parameter indicates the status value to be pass into the call
735 * to scic_cb_controller_start_complete().
736 *
737 * none.
738 */
739static void scic_sds_controller_transition_to_ready(
740 struct scic_sds_controller *this_controller,
741 enum sci_status status)
742{
743 if (this_controller->parent.state_machine.current_state_id
744 == SCI_BASE_CONTROLLER_STATE_STARTING) {
745 /*
746 * We move into the ready state, because some of the phys/ports
747 * may be up and operational. */
748 sci_base_state_machine_change_state(
749 scic_sds_controller_get_base_state_machine(this_controller),
750 SCI_BASE_CONTROLLER_STATE_READY
751 );
752
753 scic_cb_controller_start_complete(this_controller, status);
754 }
755}
756
757/**
758 * This method is the general timeout handler for the controller. It will take
759 * the correct timetout action based on the current controller state
760 */
761void scic_sds_controller_timeout_handler(
762 struct scic_sds_controller *scic)
763{
764 enum sci_base_controller_states current_state;
765
766 current_state = sci_base_state_machine_get_state(
767 scic_sds_controller_get_base_state_machine(scic));
768
769 if (current_state == SCI_BASE_CONTROLLER_STATE_STARTING) {
770 scic_sds_controller_transition_to_ready(
771 scic, SCI_FAILURE_TIMEOUT);
772 } else if (current_state == SCI_BASE_CONTROLLER_STATE_STOPPING) {
773 sci_base_state_machine_change_state(
774 scic_sds_controller_get_base_state_machine(scic),
775 SCI_BASE_CONTROLLER_STATE_FAILED);
776 scic_cb_controller_stop_complete(scic, SCI_FAILURE_TIMEOUT);
777 } else /* / @todo Now what do we want to do in this case? */
778 dev_err(scic_to_dev(scic),
779 "%s: Controller timer fired when controller was not "
780 "in a state being timed.\n",
781 __func__);
782}
783
784/**
785 * scic_sds_controller_get_port_configuration_mode
786 * @this_controller: This is the controller to use to determine if we are using
787 * manual or automatic port configuration.
788 *
789 * SCIC_PORT_CONFIGURATION_MODE
790 */
791enum SCIC_PORT_CONFIGURATION_MODE scic_sds_controller_get_port_configuration_mode(
792 struct scic_sds_controller *this_controller)
793{
794 u32 index;
795 enum SCIC_PORT_CONFIGURATION_MODE mode;
796
797 mode = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE;
798
799 for (index = 0; index < SCI_MAX_PORTS; index++) {
800 if (this_controller->oem_parameters.sds1.ports[index].phy_mask != 0) {
801 mode = SCIC_PORT_MANUAL_CONFIGURATION_MODE;
802 break;
803 }
804 }
805
806 return mode;
807}
808
809enum sci_status scic_sds_controller_stop_ports(struct scic_sds_controller *scic)
810{
811 u32 index;
812 enum sci_status port_status;
813 enum sci_status status = SCI_SUCCESS;
814
815 for (index = 0; index < scic->logical_port_entries; index++) {
816 port_status = scic_port_stop(&scic->port_table[index]);
817
818 if ((port_status != SCI_SUCCESS) &&
819 (port_status != SCI_FAILURE_INVALID_STATE)) {
820 status = SCI_FAILURE;
821
822 dev_warn(scic_to_dev(scic),
823 "%s: Controller stop operation failed to "
824 "stop port %d because of status %d.\n",
825 __func__,
826 scic->port_table[index].logical_port_index,
827 port_status);
828 }
829 }
830
831 return status;
832}
833
834/**
835 *
836 *
837 *
838 */
839static void scic_sds_controller_phy_timer_start(
840 struct scic_sds_controller *this_controller)
841{
842 scic_cb_timer_start(
843 this_controller,
844 this_controller->phy_startup_timer,
845 SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT
846 );
847
848 this_controller->phy_startup_timer_pending = true;
849}
850
851/**
852 *
853 *
854 *
855 */
856void scic_sds_controller_phy_timer_stop(
857 struct scic_sds_controller *this_controller)
858{
859 scic_cb_timer_stop(
860 this_controller,
861 this_controller->phy_startup_timer
862 );
863
864 this_controller->phy_startup_timer_pending = false;
865}
866
867/**
868 * This method is called internally by the controller object to start the next
869 * phy on the controller. If all the phys have been starte, then this
870 * method will attempt to transition the controller to the READY state and
871 * inform the user (scic_cb_controller_start_complete()).
872 * @this_controller: This parameter specifies the controller object for which
873 * to start the next phy.
874 *
875 * enum sci_status
876 */
877enum sci_status scic_sds_controller_start_next_phy(
878 struct scic_sds_controller *this_controller)
879{
880 enum sci_status status;
881
882 status = SCI_SUCCESS;
883
884 if (this_controller->phy_startup_timer_pending == false) {
885 if (this_controller->next_phy_to_start == SCI_MAX_PHYS) {
886 bool is_controller_start_complete = true;
887 struct scic_sds_phy *the_phy;
888 u8 index;
889
890 for (index = 0; index < SCI_MAX_PHYS; index++) {
891 the_phy = &this_controller->phy_table[index];
892
893 if (scic_sds_phy_get_port(the_phy) != SCI_INVALID_HANDLE) {
894 /**
895 * The controller start operation is complete if and only
896 * if:
897 * - all links have been given an opportunity to start
898 * - have no indication of a connected device
899 * - have an indication of a connected device and it has
900 * finished the link training process.
901 */
902 if (
903 (
904 (the_phy->is_in_link_training == false)
905 && (the_phy->parent.state_machine.current_state_id
906 == SCI_BASE_PHY_STATE_INITIAL)
907 )
908 || (
909 (the_phy->is_in_link_training == false)
910 && (the_phy->parent.state_machine.current_state_id
911 == SCI_BASE_PHY_STATE_STOPPED)
912 )
913 || (
914 (the_phy->is_in_link_training == true)
915 && (the_phy->parent.state_machine.current_state_id
916 == SCI_BASE_PHY_STATE_STARTING)
917 )
918 ) {
919 is_controller_start_complete = false;
920 break;
921 }
922 }
923 }
924
925 /*
926 * The controller has successfully finished the start process.
927 * Inform the SCI Core user and transition to the READY state. */
928 if (is_controller_start_complete == true) {
929 scic_sds_controller_transition_to_ready(
930 this_controller, SCI_SUCCESS
931 );
932 scic_sds_controller_phy_timer_stop(this_controller);
933 }
934 } else {
935 struct scic_sds_phy *the_phy;
936
937 the_phy = &this_controller->phy_table[this_controller->next_phy_to_start];
938
939 if (
940 scic_sds_controller_get_port_configuration_mode(this_controller)
941 == SCIC_PORT_MANUAL_CONFIGURATION_MODE
942 ) {
943 if (scic_sds_phy_get_port(the_phy) == SCI_INVALID_HANDLE) {
944 this_controller->next_phy_to_start++;
945
946 /*
947 * Caution recursion ahead be forwarned
948 *
949 * The PHY was never added to a PORT in MPC mode so start the next phy in sequence
950 * This phy will never go link up and will not draw power the OEM parameters either
951 * configured the phy incorrectly for the PORT or it was never assigned to a PORT */
952 return scic_sds_controller_start_next_phy(this_controller);
953 }
954 }
955
956 status = scic_sds_phy_start(the_phy);
957
958 if (status == SCI_SUCCESS) {
959 scic_sds_controller_phy_timer_start(this_controller);
960 } else {
961 dev_warn(scic_to_dev(this_controller),
962 "%s: Controller stop operation failed "
963 "to stop phy %d because of status "
964 "%d.\n",
965 __func__,
966 this_controller->phy_table[this_controller->next_phy_to_start].phy_index,
967 status);
968 }
969
970 this_controller->next_phy_to_start++;
971 }
972 }
973
974 return status;
975}
976
977/**
978 *
979 * @this_controller:
980 *
981 * enum sci_status
982 */
983enum sci_status scic_sds_controller_stop_phys(
984 struct scic_sds_controller *this_controller)
985{
986 u32 index;
987 enum sci_status status;
988 enum sci_status phy_status;
989
990 status = SCI_SUCCESS;
991
992 for (index = 0; index < SCI_MAX_PHYS; index++) {
993 phy_status = scic_sds_phy_stop(&this_controller->phy_table[index]);
994
995 if (
996 (phy_status != SCI_SUCCESS)
997 && (phy_status != SCI_FAILURE_INVALID_STATE)
998 ) {
999 status = SCI_FAILURE;
1000
1001 dev_warn(scic_to_dev(this_controller),
1002 "%s: Controller stop operation failed to stop "
1003 "phy %d because of status %d.\n",
1004 __func__,
1005 this_controller->phy_table[index].phy_index, phy_status);
1006 }
1007 }
1008
1009 return status;
1010}
1011
1012/**
1013 *
1014 * @this_controller:
1015 *
1016 * enum sci_status
1017 */
1018enum sci_status scic_sds_controller_stop_devices(
1019 struct scic_sds_controller *this_controller)
1020{
1021 u32 index;
1022 enum sci_status status;
1023 enum sci_status device_status;
1024
1025 status = SCI_SUCCESS;
1026
1027 for (index = 0; index < this_controller->remote_node_entries; index++) {
1028 if (this_controller->device_table[index] != SCI_INVALID_HANDLE) {
1029 /* / @todo What timeout value do we want to provide to this request? */
1030 device_status = scic_remote_device_stop(this_controller->device_table[index], 0);
1031
1032 if ((device_status != SCI_SUCCESS) &&
1033 (device_status != SCI_FAILURE_INVALID_STATE)) {
1034 dev_warn(scic_to_dev(this_controller),
1035 "%s: Controller stop operation failed "
1036 "to stop device 0x%p because of "
1037 "status %d.\n",
1038 __func__,
1039 this_controller->device_table[index], device_status);
1040 }
1041 }
1042 }
1043
1044 return status;
1045}
1046
1047/*
1048 * ****************************************************************************-
1049 * * SCIC SDS Controller Power Control (Staggered Spinup)
1050 * ****************************************************************************- */
1051
1052/**
1053 *
1054 *
1055 * This method starts the power control timer for this controller object.
1056 */
1057static void scic_sds_controller_power_control_timer_start(
1058 struct scic_sds_controller *this_controller)
1059{
1060 scic_cb_timer_start(
1061 this_controller, this_controller->power_control.timer,
1062 SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL
1063 );
1064
1065 this_controller->power_control.timer_started = true;
1066}
1067
1068/**
1069 *
1070 *
1071 *
1072 */
1073static void scic_sds_controller_power_control_timer_handler(
1074 void *controller)
1075{
1076 struct scic_sds_controller *this_controller;
1077
1078 this_controller = (struct scic_sds_controller *)controller;
1079
1080 if (this_controller->power_control.phys_waiting == 0) {
1081 this_controller->power_control.timer_started = false;
1082 } else {
1083 struct scic_sds_phy *the_phy = NULL;
1084 u8 i;
1085
1086 for (i = 0;
1087 (i < SCI_MAX_PHYS)
1088 && (this_controller->power_control.phys_waiting != 0);
1089 i++) {
1090 if (this_controller->power_control.requesters[i] != NULL) {
1091 the_phy = this_controller->power_control.requesters[i];
1092 this_controller->power_control.requesters[i] = NULL;
1093 this_controller->power_control.phys_waiting--;
1094 break;
1095 }
1096 }
1097
1098 /*
1099 * It doesn't matter if the power list is empty, we need to start the
1100 * timer in case another phy becomes ready. */
1101 scic_sds_controller_power_control_timer_start(this_controller);
1102
1103 scic_sds_phy_consume_power_handler(the_phy);
1104 }
1105}
1106
1107/**
1108 * This method inserts the phy in the stagger spinup control queue.
1109 * @this_controller:
1110 *
1111 *
1112 */
1113void scic_sds_controller_power_control_queue_insert(
1114 struct scic_sds_controller *this_controller,
1115 struct scic_sds_phy *the_phy)
1116{
1117 BUG_ON(the_phy == NULL);
1118
1119 if (
1120 (this_controller->power_control.timer_started)
1121 && (this_controller->power_control.requesters[the_phy->phy_index] == NULL)
1122 ) {
1123 this_controller->power_control.requesters[the_phy->phy_index] = the_phy;
1124 this_controller->power_control.phys_waiting++;
1125 } else {
1126 scic_sds_controller_power_control_timer_start(this_controller);
1127 scic_sds_phy_consume_power_handler(the_phy);
1128 }
1129}
1130
1131/**
1132 * This method removes the phy from the stagger spinup control queue.
1133 * @this_controller:
1134 *
1135 *
1136 */
1137void scic_sds_controller_power_control_queue_remove(
1138 struct scic_sds_controller *this_controller,
1139 struct scic_sds_phy *the_phy)
1140{
1141 BUG_ON(the_phy == NULL);
1142
1143 if (this_controller->power_control.requesters[the_phy->phy_index] != NULL) {
1144 this_controller->power_control.phys_waiting--;
1145 }
1146
1147 this_controller->power_control.requesters[the_phy->phy_index] = NULL;
1148}
1149
1150/*
1151 * ****************************************************************************-
1152 * * SCIC SDS Controller Completion Routines
1153 * ****************************************************************************- */
1154
1155/**
1156 * This method returns a true value if the completion queue has entries that
1157 * can be processed
1158 * @this_controller:
1159 *
1160 * bool true if the completion queue has entries to process false if the
1161 * completion queue has no entries to process
1162 */
1163static bool scic_sds_controller_completion_queue_has_entries(
1164 struct scic_sds_controller *this_controller)
1165{
1166 u32 get_value = this_controller->completion_queue_get;
1167 u32 get_index = get_value & SMU_COMPLETION_QUEUE_GET_POINTER_MASK;
1168
1169 if (
1170 NORMALIZE_GET_POINTER_CYCLE_BIT(get_value)
1171 == COMPLETION_QUEUE_CYCLE_BIT(this_controller->completion_queue[get_index])
1172 ) {
1173 return true;
1174 }
1175
1176 return false;
1177}
1178
1179/* --------------------------------------------------------------------------- */
1180
1181/**
1182 * This method processes a task completion notification. This is called from
1183 * within the controller completion handler.
1184 * @this_controller:
1185 * @completion_entry:
1186 *
1187 */
1188static void scic_sds_controller_task_completion(
1189 struct scic_sds_controller *this_controller,
1190 u32 completion_entry)
1191{
1192 u32 index;
1193 struct scic_sds_request *io_request;
1194
1195 index = SCU_GET_COMPLETION_INDEX(completion_entry);
1196 io_request = this_controller->io_request_table[index];
1197
1198 /* Make sure that we really want to process this IO request */
1199 if (
1200 (io_request != SCI_INVALID_HANDLE)
1201 && (io_request->io_tag != SCI_CONTROLLER_INVALID_IO_TAG)
1202 && (
1203 scic_sds_io_tag_get_sequence(io_request->io_tag)
1204 == this_controller->io_request_sequence[index]
1205 )
1206 ) {
1207 /* Yep this is a valid io request pass it along to the io request handler */
1208 scic_sds_io_request_tc_completion(io_request, completion_entry);
1209 }
1210}
1211
1212/**
1213 * This method processes an SDMA completion event. This is called from within
1214 * the controller completion handler.
1215 * @this_controller:
1216 * @completion_entry:
1217 *
1218 */
1219static void scic_sds_controller_sdma_completion(
1220 struct scic_sds_controller *this_controller,
1221 u32 completion_entry)
1222{
1223 u32 index;
1224 struct scic_sds_request *io_request;
1225 struct scic_sds_remote_device *device;
1226
1227 index = SCU_GET_COMPLETION_INDEX(completion_entry);
1228
1229 switch (scu_get_command_request_type(completion_entry)) {
1230 case SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC:
1231 case SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_TC:
1232 io_request = this_controller->io_request_table[index];
1233 dev_warn(scic_to_dev(this_controller),
1234 "%s: SCIC SDS Completion type SDMA %x for io request "
1235 "%p\n",
1236 __func__,
1237 completion_entry,
1238 io_request);
1239 /* @todo For a post TC operation we need to fail the IO
1240 * request
1241 */
1242 break;
1243
1244 case SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_RNC:
1245 case SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC:
1246 case SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_RNC:
1247 device = this_controller->device_table[index];
1248 dev_warn(scic_to_dev(this_controller),
1249 "%s: SCIC SDS Completion type SDMA %x for remote "
1250 "device %p\n",
1251 __func__,
1252 completion_entry,
1253 device);
1254 /* @todo For a port RNC operation we need to fail the
1255 * device
1256 */
1257 break;
1258
1259 default:
1260 dev_warn(scic_to_dev(this_controller),
1261 "%s: SCIC SDS Completion unknown SDMA completion "
1262 "type %x\n",
1263 __func__,
1264 completion_entry);
1265 break;
1266
1267 }
1268}
1269
1270/**
1271 *
1272 * @this_controller:
1273 * @completion_entry:
1274 *
1275 * This method processes an unsolicited frame message. This is called from
1276 * within the controller completion handler. none
1277 */
1278static void scic_sds_controller_unsolicited_frame(
1279 struct scic_sds_controller *this_controller,
1280 u32 completion_entry)
1281{
1282 u32 index;
1283 u32 frame_index;
1284
1285 struct scu_unsolicited_frame_header *frame_header;
1286 struct scic_sds_phy *phy;
1287 struct scic_sds_remote_device *device;
1288
1289 enum sci_status result = SCI_FAILURE;
1290
1291 frame_index = SCU_GET_FRAME_INDEX(completion_entry);
1292
1293 frame_header
1294 = this_controller->uf_control.buffers.array[frame_index].header;
1295 this_controller->uf_control.buffers.array[frame_index].state
1296 = UNSOLICITED_FRAME_IN_USE;
1297
1298 if (SCU_GET_FRAME_ERROR(completion_entry)) {
1299 /*
1300 * / @todo If the IAF frame or SIGNATURE FIS frame has an error will
1301 * / this cause a problem? We expect the phy initialization will
1302 * / fail if there is an error in the frame. */
1303 scic_sds_controller_release_frame(this_controller, frame_index);
1304 return;
1305 }
1306
1307 if (frame_header->is_address_frame) {
1308 index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry);
1309 phy = &this_controller->phy_table[index];
1310 if (phy != NULL) {
1311 result = scic_sds_phy_frame_handler(phy, frame_index);
1312 }
1313 } else {
1314
1315 index = SCU_GET_COMPLETION_INDEX(completion_entry);
1316
1317 if (index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) {
1318 /*
1319 * This is a signature fis or a frame from a direct attached SATA
1320 * device that has not yet been created. In either case forwared
1321 * the frame to the PE and let it take care of the frame data. */
1322 index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry);
1323 phy = &this_controller->phy_table[index];
1324 result = scic_sds_phy_frame_handler(phy, frame_index);
1325 } else {
1326 if (index < this_controller->remote_node_entries)
1327 device = this_controller->device_table[index];
1328 else
1329 device = NULL;
1330
1331 if (device != NULL)
1332 result = scic_sds_remote_device_frame_handler(device, frame_index);
1333 else
1334 scic_sds_controller_release_frame(this_controller, frame_index);
1335 }
1336 }
1337
1338 if (result != SCI_SUCCESS) {
1339 /*
1340 * / @todo Is there any reason to report some additional error message
1341 * / when we get this failure notifiction? */
1342 }
1343}
1344
1345/**
1346 * This method processes an event completion entry. This is called from within
1347 * the controller completion handler.
1348 * @this_controller:
1349 * @completion_entry:
1350 *
1351 */
1352static void scic_sds_controller_event_completion(
1353 struct scic_sds_controller *this_controller,
1354 u32 completion_entry)
1355{
1356 u32 index;
1357 struct scic_sds_request *io_request;
1358 struct scic_sds_remote_device *device;
1359 struct scic_sds_phy *phy;
1360
1361 index = SCU_GET_COMPLETION_INDEX(completion_entry);
1362
1363 switch (scu_get_event_type(completion_entry)) {
1364 case SCU_EVENT_TYPE_SMU_COMMAND_ERROR:
1365 /* / @todo The driver did something wrong and we need to fix the condtion. */
1366 dev_err(scic_to_dev(this_controller),
1367 "%s: SCIC Controller 0x%p received SMU command error "
1368 "0x%x\n",
1369 __func__,
1370 this_controller,
1371 completion_entry);
1372 break;
1373
1374 case SCU_EVENT_TYPE_SMU_PCQ_ERROR:
1375 case SCU_EVENT_TYPE_SMU_ERROR:
1376 case SCU_EVENT_TYPE_FATAL_MEMORY_ERROR:
1377 /*
1378 * / @todo This is a hardware failure and its likely that we want to
1379 * / reset the controller. */
1380 dev_err(scic_to_dev(this_controller),
1381 "%s: SCIC Controller 0x%p received fatal controller "
1382 "event 0x%x\n",
1383 __func__,
1384 this_controller,
1385 completion_entry);
1386 break;
1387
1388 case SCU_EVENT_TYPE_TRANSPORT_ERROR:
1389 io_request = this_controller->io_request_table[index];
1390 scic_sds_io_request_event_handler(io_request, completion_entry);
1391 break;
1392
1393 case SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT:
1394 switch (scu_get_event_specifier(completion_entry)) {
1395 case SCU_EVENT_SPECIFIC_SMP_RESPONSE_NO_PE:
1396 case SCU_EVENT_SPECIFIC_TASK_TIMEOUT:
1397 io_request = this_controller->io_request_table[index];
1398 if (io_request != SCI_INVALID_HANDLE)
1399 scic_sds_io_request_event_handler(io_request, completion_entry);
1400 else
1401 dev_warn(scic_to_dev(this_controller),
1402 "%s: SCIC Controller 0x%p received "
1403 "event 0x%x for io request object "
1404 "that doesnt exist.\n",
1405 __func__,
1406 this_controller,
1407 completion_entry);
1408
1409 break;
1410
1411 case SCU_EVENT_SPECIFIC_IT_NEXUS_TIMEOUT:
1412 device = this_controller->device_table[index];
1413 if (device != SCI_INVALID_HANDLE)
1414 scic_sds_remote_device_event_handler(device, completion_entry);
1415 else
1416 dev_warn(scic_to_dev(this_controller),
1417 "%s: SCIC Controller 0x%p received "
1418 "event 0x%x for remote device object "
1419 "that doesnt exist.\n",
1420 __func__,
1421 this_controller,
1422 completion_entry);
1423
1424 break;
1425 }
1426 break;
1427
1428 case SCU_EVENT_TYPE_BROADCAST_CHANGE:
1429 /*
1430 * direct the broadcast change event to the phy first and then let
1431 * the phy redirect the broadcast change to the port object */
1432 case SCU_EVENT_TYPE_ERR_CNT_EVENT:
1433 /*
1434 * direct error counter event to the phy object since that is where
1435 * we get the event notification. This is a type 4 event. */
1436 case SCU_EVENT_TYPE_OSSP_EVENT:
1437 index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry);
1438 phy = &this_controller->phy_table[index];
1439 scic_sds_phy_event_handler(phy, completion_entry);
1440 break;
1441
1442 case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
1443 case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
1444 case SCU_EVENT_TYPE_RNC_OPS_MISC:
1445 if (index < this_controller->remote_node_entries) {
1446 device = this_controller->device_table[index];
1447
1448 if (device != NULL)
1449 scic_sds_remote_device_event_handler(device, completion_entry);
1450 } else
1451 dev_err(scic_to_dev(this_controller),
1452 "%s: SCIC Controller 0x%p received event 0x%x "
1453 "for remote device object 0x%0x that doesnt "
1454 "exist.\n",
1455 __func__,
1456 this_controller,
1457 completion_entry,
1458 index);
1459
1460 break;
1461
1462 default:
1463 dev_warn(scic_to_dev(this_controller),
1464 "%s: SCIC Controller received unknown event code %x\n",
1465 __func__,
1466 completion_entry);
1467 break;
1468 }
1469}
1470
1471/**
1472 * This method is a private routine for processing the completion queue entries.
1473 * @this_controller:
1474 *
1475 */
1476static void scic_sds_controller_process_completions(
1477 struct scic_sds_controller *this_controller)
1478{
1479 u32 completion_count = 0;
1480 u32 completion_entry;
1481 u32 get_index;
1482 u32 get_cycle;
1483 u32 event_index;
1484 u32 event_cycle;
1485
1486 dev_dbg(scic_to_dev(this_controller),
1487 "%s: completion queue begining get:0x%08x\n",
1488 __func__,
1489 this_controller->completion_queue_get);
1490
1491 /* Get the component parts of the completion queue */
1492 get_index = NORMALIZE_GET_POINTER(this_controller->completion_queue_get);
1493 get_cycle = SMU_CQGR_CYCLE_BIT & this_controller->completion_queue_get;
1494
1495 event_index = NORMALIZE_EVENT_POINTER(this_controller->completion_queue_get);
1496 event_cycle = SMU_CQGR_EVENT_CYCLE_BIT & this_controller->completion_queue_get;
1497
1498 while (
1499 NORMALIZE_GET_POINTER_CYCLE_BIT(get_cycle)
1500 == COMPLETION_QUEUE_CYCLE_BIT(this_controller->completion_queue[get_index])
1501 ) {
1502 completion_count++;
1503
1504 completion_entry = this_controller->completion_queue[get_index];
1505 INCREMENT_COMPLETION_QUEUE_GET(this_controller, get_index, get_cycle);
1506
1507 dev_dbg(scic_to_dev(this_controller),
1508 "%s: completion queue entry:0x%08x\n",
1509 __func__,
1510 completion_entry);
1511
1512 switch (SCU_GET_COMPLETION_TYPE(completion_entry)) {
1513 case SCU_COMPLETION_TYPE_TASK:
1514 scic_sds_controller_task_completion(this_controller, completion_entry);
1515 break;
1516
1517 case SCU_COMPLETION_TYPE_SDMA:
1518 scic_sds_controller_sdma_completion(this_controller, completion_entry);
1519 break;
1520
1521 case SCU_COMPLETION_TYPE_UFI:
1522 scic_sds_controller_unsolicited_frame(this_controller, completion_entry);
1523 break;
1524
1525 case SCU_COMPLETION_TYPE_EVENT:
1526 INCREMENT_EVENT_QUEUE_GET(this_controller, event_index, event_cycle);
1527 scic_sds_controller_event_completion(this_controller, completion_entry);
1528 break;
1529
1530 case SCU_COMPLETION_TYPE_NOTIFY:
1531 /*
1532 * Presently we do the same thing with a notify event that we do with the
1533 * other event codes. */
1534 INCREMENT_EVENT_QUEUE_GET(this_controller, event_index, event_cycle);
1535 scic_sds_controller_event_completion(this_controller, completion_entry);
1536 break;
1537
1538 default:
1539 dev_warn(scic_to_dev(this_controller),
1540 "%s: SCIC Controller received unknown "
1541 "completion type %x\n",
1542 __func__,
1543 completion_entry);
1544 break;
1545 }
1546 }
1547
1548 /* Update the get register if we completed one or more entries */
1549 if (completion_count > 0) {
1550 this_controller->completion_queue_get =
1551 SMU_CQGR_GEN_BIT(ENABLE)
1552 | SMU_CQGR_GEN_BIT(EVENT_ENABLE)
1553 | event_cycle | SMU_CQGR_GEN_VAL(EVENT_POINTER, event_index)
1554 | get_cycle | SMU_CQGR_GEN_VAL(POINTER, get_index);
1555
1556 SMU_CQGR_WRITE(this_controller,
1557 this_controller->completion_queue_get);
1558 }
1559
1560 dev_dbg(scic_to_dev(this_controller),
1561 "%s: completion queue ending get:0x%08x\n",
1562 __func__,
1563 this_controller->completion_queue_get);
1564
1565}
1566
1567/**
1568 * This method is a private routine for processing the completion queue entries.
1569 * @this_controller:
1570 *
1571 */
1572static void scic_sds_controller_transitioned_process_completions(
1573 struct scic_sds_controller *this_controller)
1574{
1575 u32 completion_count = 0;
1576 u32 completion_entry;
1577 u32 get_index;
1578 u32 get_cycle;
1579 u32 event_index;
1580 u32 event_cycle;
1581
1582 dev_dbg(scic_to_dev(this_controller),
1583 "%s: completion queue begining get:0x%08x\n",
1584 __func__,
1585 this_controller->completion_queue_get);
1586
1587 /* Get the component parts of the completion queue */
1588 get_index = NORMALIZE_GET_POINTER(this_controller->completion_queue_get);
1589 get_cycle = SMU_CQGR_CYCLE_BIT & this_controller->completion_queue_get;
1590
1591 event_index = NORMALIZE_EVENT_POINTER(this_controller->completion_queue_get);
1592 event_cycle = SMU_CQGR_EVENT_CYCLE_BIT & this_controller->completion_queue_get;
1593
1594 while (
1595 NORMALIZE_GET_POINTER_CYCLE_BIT(get_cycle)
1596 == COMPLETION_QUEUE_CYCLE_BIT(
1597 this_controller->completion_queue[get_index])
1598 ) {
1599 completion_count++;
1600
1601 completion_entry = this_controller->completion_queue[get_index];
1602 INCREMENT_COMPLETION_QUEUE_GET(this_controller, get_index, get_cycle);
1603
1604 dev_dbg(scic_to_dev(this_controller),
1605 "%s: completion queue entry:0x%08x\n",
1606 __func__,
1607 completion_entry);
1608
1609 switch (SCU_GET_COMPLETION_TYPE(completion_entry)) {
1610 case SCU_COMPLETION_TYPE_TASK:
1611 scic_sds_controller_task_completion(this_controller, completion_entry);
1612 break;
1613
1614 case SCU_COMPLETION_TYPE_NOTIFY:
1615 case SCU_COMPLETION_TYPE_EVENT:
1616 /*
1617 * Presently we do the same thing with a notify event that we
1618 * do with the other event codes. */
1619 INCREMENT_EVENT_QUEUE_GET(this_controller, event_index, event_cycle);
1620 /* Fall-through */
1621
1622 case SCU_COMPLETION_TYPE_SDMA:
1623 case SCU_COMPLETION_TYPE_UFI:
1624 default:
1625 dev_warn(scic_to_dev(this_controller),
1626 "%s: SCIC Controller ignoring completion type "
1627 "%x\n",
1628 __func__,
1629 completion_entry);
1630 break;
1631 }
1632 }
1633
1634 /* Update the get register if we completed one or more entries */
1635 if (completion_count > 0) {
1636 this_controller->completion_queue_get =
1637 SMU_CQGR_GEN_BIT(ENABLE)
1638 | SMU_CQGR_GEN_BIT(EVENT_ENABLE)
1639 | event_cycle | SMU_CQGR_GEN_VAL(EVENT_POINTER, event_index)
1640 | get_cycle | SMU_CQGR_GEN_VAL(POINTER, get_index);
1641
1642 SMU_CQGR_WRITE(this_controller, this_controller->completion_queue_get);
1643 }
1644
1645 dev_dbg(scic_to_dev(this_controller),
1646 "%s: completion queue ending get:0x%08x\n",
1647 __func__,
1648 this_controller->completion_queue_get);
1649}
1650
1651/*
1652 * ****************************************************************************-
1653 * * SCIC SDS Controller Interrupt and Completion functions
1654 * ****************************************************************************- */
1655
1656/**
1657 * This method provides standard (common) processing of interrupts for polling
1658 * and legacy based interrupts.
1659 * @controller:
1660 * @interrupt_status:
1661 *
1662 * This method returns a boolean (bool) indication as to whether an completions
1663 * are pending to be processed. true if an interrupt is to be processed false
1664 * if no interrupt was pending
1665 */
1666static bool scic_sds_controller_standard_interrupt_handler(
1667 struct scic_sds_controller *this_controller,
1668 u32 interrupt_status)
1669{
1670 bool is_completion_needed = false;
1671
1672 if ((interrupt_status & SMU_ISR_QUEUE_ERROR) ||
1673 ((interrupt_status & SMU_ISR_QUEUE_SUSPEND) &&
1674 (!scic_sds_controller_completion_queue_has_entries(
1675 this_controller)))) {
1676 /*
1677 * We have a fatal error on the read of the completion queue bar
1678 * OR
1679 * We have a fatal error there is nothing in the completion queue
1680 * but we have a report from the hardware that the queue is full
1681 * / @todo how do we request the a controller reset */
1682 is_completion_needed = true;
1683 this_controller->encountered_fatal_error = true;
1684 }
1685
1686 if (scic_sds_controller_completion_queue_has_entries(this_controller)) {
1687 is_completion_needed = true;
1688 }
1689
1690 return is_completion_needed;
1691}
1692
1693/**
1694 * This is the method provided to handle polling for interrupts for the
1695 * controller object.
1696 *
1697 * bool true if an interrupt is to be processed false if no interrupt was
1698 * pending
1699 */
1700static bool scic_sds_controller_polling_interrupt_handler(
1701 struct scic_sds_controller *scic)
1702{
1703 u32 interrupt_status;
1704
1705 /*
1706 * In INTERRUPT_POLLING_MODE we exit the interrupt handler if the
1707 * hardware indicates nothing is pending. Since we are not being
1708 * called from a real interrupt, we don't want to confuse the hardware
1709 * by servicing the completion queue before the hardware indicates it
1710 * is ready. We'll simply wait for another polling interval and check
1711 * again.
1712 */
1713 interrupt_status = SMU_ISR_READ(scic);
1714 if ((interrupt_status &
1715 (SMU_ISR_COMPLETION |
1716 SMU_ISR_QUEUE_ERROR |
1717 SMU_ISR_QUEUE_SUSPEND)) == 0) {
1718 return false;
1719 }
1720
1721 return scic_sds_controller_standard_interrupt_handler(
1722 scic, interrupt_status);
1723}
1724
1725/**
1726 * This is the method provided to handle completions when interrupt polling is
1727 * in use.
1728 */
1729static void scic_sds_controller_polling_completion_handler(
1730 struct scic_sds_controller *scic)
1731{
1732 if (scic->encountered_fatal_error == true) {
1733 dev_err(scic_to_dev(scic),
1734 "%s: SCIC Controller has encountered a fatal error.\n",
1735 __func__);
1736
1737 sci_base_state_machine_change_state(
1738 scic_sds_controller_get_base_state_machine(scic),
1739 SCI_BASE_CONTROLLER_STATE_FAILED);
1740 } else if (scic_sds_controller_completion_queue_has_entries(scic)) {
1741 if (scic->restrict_completions == false)
1742 scic_sds_controller_process_completions(scic);
1743 else
1744 scic_sds_controller_transitioned_process_completions(
1745 scic);
1746 }
1747
1748 /*
1749 * The interrupt handler does not adjust the CQ's
1750 * get pointer. So, SCU's INTx pin stays asserted during the
1751 * interrupt handler even though it tries to clear the interrupt
1752 * source. Therefore, the completion handler must ensure that the
1753 * interrupt source is cleared. Otherwise, we get a spurious
1754 * interrupt for which the interrupt handler will not issue a
1755 * corresponding completion event. Also, we unmask interrupts.
1756 */
1757 SMU_ISR_WRITE(
1758 scic,
1759 (u32)(SMU_ISR_COMPLETION | SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND)
1760 );
1761}
1762
1763/**
1764 * This is the method provided to handle legacy interrupts for the controller
1765 * object.
1766 *
1767 * bool true if an interrupt is processed false if no interrupt was processed
1768 */
1769static bool scic_sds_controller_legacy_interrupt_handler(
1770 struct scic_sds_controller *scic)
1771{
1772 u32 interrupt_status;
1773 bool is_completion_needed;
1774
1775 interrupt_status = SMU_ISR_READ(scic);
1776 is_completion_needed = scic_sds_controller_standard_interrupt_handler(
1777 scic, interrupt_status);
1778
1779 return is_completion_needed;
1780}
1781
1782
1783/**
1784 * This is the method provided to handle legacy completions it is expected that
1785 * the SCI User will call this completion handler anytime the interrupt
1786 * handler reports that it has handled an interrupt.
1787 */
1788static void scic_sds_controller_legacy_completion_handler(
1789 struct scic_sds_controller *scic)
1790{
1791 scic_sds_controller_polling_completion_handler(scic);
1792 SMU_IMR_WRITE(scic, 0x00000000);
1793}
1794
1795/**
1796 * This is the method provided to handle an MSIX interrupt message when there
1797 * is just a single MSIX message being provided by the hardware. This mode
1798 * of operation is single vector mode.
1799 *
1800 * bool true if an interrupt is processed false if no interrupt was processed
1801 */
1802static bool scic_sds_controller_single_vector_interrupt_handler(
1803 struct scic_sds_controller *scic)
1804{
1805 u32 interrupt_status;
1806
1807 /*
1808 * Mask the interrupts
1809 * There is a race in the hardware that could cause us not to be notified
1810 * of an interrupt completion if we do not take this step. We will unmask
1811 * the interrupts in the completion routine. */
1812 SMU_IMR_WRITE(scic, 0xFFFFFFFF);
1813
1814 interrupt_status = SMU_ISR_READ(scic);
1815 interrupt_status &= (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND);
1816
1817 if ((interrupt_status == 0) &&
1818 scic_sds_controller_completion_queue_has_entries(scic)) {
1819 /*
1820 * There is at least one completion queue entry to process so we can
1821 * return a success and ignore for now the case of an error interrupt */
1822 SMU_ISR_WRITE(scic, SMU_ISR_COMPLETION);
1823 return true;
1824 }
1825
1826 if (interrupt_status != 0) {
1827 /*
1828 * There is an error interrupt pending so let it through and handle
1829 * in the callback */
1830 return true;
1831 }
1832
1833 /*
1834 * Clear any offending interrupts since we could not find any to handle
1835 * and unmask them all */
1836 SMU_ISR_WRITE(scic, 0x00000000);
1837 SMU_IMR_WRITE(scic, 0x00000000);
1838
1839 return false;
1840}
1841
1842/**
1843 * This is the method provided to handle completions for a single MSIX message.
1844 */
1845static void scic_sds_controller_single_vector_completion_handler(
1846 struct scic_sds_controller *scic)
1847{
1848 u32 interrupt_status;
1849
1850 interrupt_status = SMU_ISR_READ(scic);
1851 interrupt_status &= (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND);
1852
1853 if (interrupt_status & SMU_ISR_QUEUE_ERROR) {
1854 dev_err(scic_to_dev(scic),
1855 "%s: SCIC Controller has encountered a fatal error.\n",
1856 __func__);
1857
1858 /*
1859 * We have a fatal condition and must reset the controller
1860 * Leave the interrupt mask in place and get the controller reset */
1861 sci_base_state_machine_change_state(
1862 scic_sds_controller_get_base_state_machine(scic),
1863 SCI_BASE_CONTROLLER_STATE_FAILED);
1864 return;
1865 }
1866
1867 if ((interrupt_status & SMU_ISR_QUEUE_SUSPEND) &&
1868 !scic_sds_controller_completion_queue_has_entries(scic)) {
1869 dev_err(scic_to_dev(scic),
1870 "%s: SCIC Controller has encountered a fatal error.\n",
1871 __func__);
1872
1873 /*
1874 * We have a fatal condtion and must reset the controller
1875 * Leave the interrupt mask in place and get the controller reset */
1876 sci_base_state_machine_change_state(
1877 scic_sds_controller_get_base_state_machine(scic),
1878 SCI_BASE_CONTROLLER_STATE_FAILED);
1879 return;
1880 }
1881
1882 if (scic_sds_controller_completion_queue_has_entries(scic)) {
1883 scic_sds_controller_process_completions(scic);
1884
1885 /*
1886 * We dont care which interrupt got us to processing the completion queu
1887 * so clear them both. */
1888 SMU_ISR_WRITE(
1889 scic,
1890 (SMU_ISR_COMPLETION | SMU_ISR_QUEUE_SUSPEND));
1891 }
1892
1893 SMU_IMR_WRITE(scic, 0x00000000);
1894}
1895
1896/**
1897 * This is the method provided to handle a MSIX message for a normal completion.
1898 *
1899 * bool true if an interrupt is processed false if no interrupt was processed
1900 */
1901static bool scic_sds_controller_normal_vector_interrupt_handler(
1902 struct scic_sds_controller *scic)
1903{
1904 if (scic_sds_controller_completion_queue_has_entries(scic)) {
1905 return true;
1906 } else {
1907 /*
1908 * we have a spurious interrupt it could be that we have already
1909 * emptied the completion queue from a previous interrupt */
1910 SMU_ISR_WRITE(scic, SMU_ISR_COMPLETION);
1911
1912 /*
1913 * There is a race in the hardware that could cause us not to be notified
1914 * of an interrupt completion if we do not take this step. We will mask
1915 * then unmask the interrupts so if there is another interrupt pending
1916 * the clearing of the interrupt source we get the next interrupt message. */
1917 SMU_IMR_WRITE(scic, 0xFF000000);
1918 SMU_IMR_WRITE(scic, 0x00000000);
1919 }
1920
1921 return false;
1922}
1923
1924/**
1925 * This is the method provided to handle the completions for a normal MSIX
1926 * message.
1927 */
1928static void scic_sds_controller_normal_vector_completion_handler(
1929 struct scic_sds_controller *scic)
1930{
1931 /* Empty out the completion queue */
1932 if (scic_sds_controller_completion_queue_has_entries(scic))
1933 scic_sds_controller_process_completions(scic);
1934
1935 /* Clear the interrupt and enable all interrupts again */
1936 SMU_ISR_WRITE(scic, SMU_ISR_COMPLETION);
1937 /* Could we write the value of SMU_ISR_COMPLETION? */
1938 SMU_IMR_WRITE(scic, 0xFF000000);
1939 SMU_IMR_WRITE(scic, 0x00000000);
1940}
1941
1942/**
1943 * This is the method provided to handle the error MSIX message interrupt.
1944 * This is the normal operating mode for the hardware if MSIX is enabled.
1945 *
1946 * bool true if an interrupt is processed false if no interrupt was processed
1947 */
1948static bool scic_sds_controller_error_vector_interrupt_handler(
1949 struct scic_sds_controller *scic)
1950{
1951 u32 interrupt_status;
1952
1953 interrupt_status = SMU_ISR_READ(scic);
1954 interrupt_status &= (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND);
1955
1956 if (interrupt_status != 0) {
1957 /*
1958 * There is an error interrupt pending so let it through and handle
1959 * in the callback */
1960 return true;
1961 }
1962
1963 /*
1964 * There is a race in the hardware that could cause us not to be notified
1965 * of an interrupt completion if we do not take this step. We will mask
1966 * then unmask the error interrupts so if there was another interrupt
1967 * pending we will be notified.
1968 * Could we write the value of (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND)? */
1969 SMU_IMR_WRITE(scic, 0x000000FF);
1970 SMU_IMR_WRITE(scic, 0x00000000);
1971
1972 return false;
1973}
1974
1975/**
1976 * This is the method provided to handle the error completions when the
1977 * hardware is using two MSIX messages.
1978 */
1979static void scic_sds_controller_error_vector_completion_handler(
1980 struct scic_sds_controller *scic)
1981{
1982 u32 interrupt_status;
1983
1984 interrupt_status = SMU_ISR_READ(scic);
1985
1986 if ((interrupt_status & SMU_ISR_QUEUE_SUSPEND) &&
1987 scic_sds_controller_completion_queue_has_entries(scic)) {
1988
1989 scic_sds_controller_process_completions(scic);
1990 SMU_ISR_WRITE(scic, SMU_ISR_QUEUE_SUSPEND);
1991
1992 } else {
1993 dev_err(scic_to_dev(scic),
1994 "%s: SCIC Controller reports CRC error on completion "
1995 "ISR %x\n",
1996 __func__,
1997 interrupt_status);
1998
1999 sci_base_state_machine_change_state(
2000 scic_sds_controller_get_base_state_machine(scic),
2001 SCI_BASE_CONTROLLER_STATE_FAILED);
2002
2003 return;
2004 }
2005
2006 /*
2007 * If we dont process any completions I am not sure that we want to do this.
2008 * We are in the middle of a hardware fault and should probably be reset. */
2009 SMU_IMR_WRITE(scic, 0x00000000);
2010}
2011
2012
2013/*
2014 * ****************************************************************************-
2015 * * SCIC SDS Controller External Methods
2016 * ****************************************************************************- */
2017
2018/**
2019 * This method returns the sizeof the SCIC SDS Controller Object
2020 */
2021u32 scic_sds_controller_get_object_size(void)
2022{
2023 return sizeof(struct scic_sds_controller);
2024}
2025
2026
2027void scic_sds_controller_link_up(
2028 struct scic_sds_controller *scic,
2029 struct scic_sds_port *sci_port,
2030 struct scic_sds_phy *sci_phy)
2031{
2032 scic_sds_controller_phy_handler_t link_up;
2033 u32 state;
2034
2035 state = scic->parent.state_machine.current_state_id;
2036 link_up = scic_sds_controller_state_handler_table[state].link_up;
2037
2038 if (link_up)
2039 link_up(scic, sci_port, sci_phy);
2040 else
2041 dev_warn(scic_to_dev(scic),
2042 "%s: SCIC Controller linkup event from phy %d in "
2043 "unexpected state %d\n",
2044 __func__,
2045 sci_phy->phy_index,
2046 sci_base_state_machine_get_state(
2047 scic_sds_controller_get_base_state_machine(
2048 scic)));
2049}
2050
2051
2052void scic_sds_controller_link_down(
2053 struct scic_sds_controller *scic,
2054 struct scic_sds_port *sci_port,
2055 struct scic_sds_phy *sci_phy)
2056{
2057 u32 state;
2058 scic_sds_controller_phy_handler_t link_down;
2059
2060 state = scic->parent.state_machine.current_state_id;
2061 link_down = scic_sds_controller_state_handler_table[state].link_down;
2062
2063 if (link_down)
2064 link_down(scic, sci_port, sci_phy);
2065 else
2066 dev_warn(scic_to_dev(scic),
2067 "%s: SCIC Controller linkdown event from phy %d in "
2068 "unexpected state %d\n",
2069 __func__,
2070 sci_phy->phy_index,
2071 sci_base_state_machine_get_state(
2072 scic_sds_controller_get_base_state_machine(
2073 scic)));
2074}
2075
2076/**
2077 * This method will write to the SCU PCP register the request value. The method
2078 * is used to suspend/resume ports, devices, and phys.
2079 * @this_controller:
2080 *
2081 *
2082 */
2083void scic_sds_controller_post_request(
2084 struct scic_sds_controller *this_controller,
2085 u32 request)
2086{
2087 dev_dbg(scic_to_dev(this_controller),
2088 "%s: SCIC Controller 0x%p post request 0x%08x\n",
2089 __func__,
2090 this_controller,
2091 request);
2092
2093 SMU_PCP_WRITE(this_controller, request);
2094}
2095
2096/**
2097 * This method will copy the soft copy of the task context into the physical
2098 * memory accessible by the controller.
2099 * @this_controller: This parameter specifies the controller for which to copy
2100 * the task context.
2101 * @this_request: This parameter specifies the request for which the task
2102 * context is being copied.
2103 *
2104 * After this call is made the SCIC_SDS_IO_REQUEST object will always point to
2105 * the physical memory version of the task context. Thus, all subsequent
2106 * updates to the task context are performed in the TC table (i.e. DMAable
2107 * memory). none
2108 */
2109void scic_sds_controller_copy_task_context(
2110 struct scic_sds_controller *this_controller,
2111 struct scic_sds_request *this_request)
2112{
2113 struct scu_task_context *task_context_buffer;
2114
2115 task_context_buffer = scic_sds_controller_get_task_context_buffer(
2116 this_controller, this_request->io_tag
2117 );
2118
2119 memcpy(
2120 task_context_buffer,
2121 this_request->task_context_buffer,
2122 SCI_FIELD_OFFSET(struct scu_task_context, sgl_snapshot_ac)
2123 );
2124
2125 /*
2126 * Now that the soft copy of the TC has been copied into the TC
2127 * table accessible by the silicon. Thus, any further changes to
2128 * the TC (e.g. TC termination) occur in the appropriate location. */
2129 this_request->task_context_buffer = task_context_buffer;
2130}
2131
2132/**
2133 * This method returns the task context buffer for the given io tag.
2134 * @this_controller:
2135 * @io_tag:
2136 *
2137 * struct scu_task_context*
2138 */
2139struct scu_task_context *scic_sds_controller_get_task_context_buffer(
2140 struct scic_sds_controller *this_controller,
2141 u16 io_tag
2142 ) {
2143 u16 task_index = scic_sds_io_tag_get_index(io_tag);
2144
2145 if (task_index < this_controller->task_context_entries) {
2146 return &this_controller->task_context_table[task_index];
2147 }
2148
2149 return NULL;
2150}
2151
2152/**
2153 * This method returnst the sequence value from the io tag value
2154 * @this_controller:
2155 * @io_tag:
2156 *
2157 * u16
2158 */
2159
2160/**
2161 * This method returns the IO request associated with the tag value
2162 * @this_controller:
2163 * @io_tag:
2164 *
2165 * SCIC_SDS_IO_REQUEST_T* NULL if there is no valid IO request at the tag value
2166 */
2167struct scic_sds_request *scic_sds_controller_get_io_request_from_tag(
2168 struct scic_sds_controller *this_controller,
2169 u16 io_tag
2170 ) {
2171 u16 task_index;
2172 u16 task_sequence;
2173
2174 task_index = scic_sds_io_tag_get_index(io_tag);
2175
2176 if (task_index < this_controller->task_context_entries) {
2177 if (this_controller->io_request_table[task_index] != SCI_INVALID_HANDLE) {
2178 task_sequence = scic_sds_io_tag_get_sequence(io_tag);
2179
2180 if (task_sequence == this_controller->io_request_sequence[task_index]) {
2181 return this_controller->io_request_table[task_index];
2182 }
2183 }
2184 }
2185
2186 return SCI_INVALID_HANDLE;
2187}
2188
2189/**
2190 * This method allocates remote node index and the reserves the remote node
2191 * context space for use. This method can fail if there are no more remote
2192 * node index available.
2193 * @this_controller: This is the controller object which contains the set of
2194 * free remote node ids
2195 * @the_devce: This is the device object which is requesting the a remote node
2196 * id
2197 * @node_id: This is the remote node id that is assinged to the device if one
2198 * is available
2199 *
2200 * enum sci_status SCI_FAILURE_OUT_OF_RESOURCES if there are no available remote
2201 * node index available.
2202 */
2203enum sci_status scic_sds_controller_allocate_remote_node_context(
2204 struct scic_sds_controller *this_controller,
2205 struct scic_sds_remote_device *the_device,
2206 u16 *node_id)
2207{
2208 u16 node_index;
2209 u32 remote_node_count = scic_sds_remote_device_node_count(the_device);
2210
2211 node_index = scic_sds_remote_node_table_allocate_remote_node(
2212 &this_controller->available_remote_nodes, remote_node_count
2213 );
2214
2215 if (node_index != SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) {
2216 this_controller->device_table[node_index] = the_device;
2217
2218 *node_id = node_index;
2219
2220 return SCI_SUCCESS;
2221 }
2222
2223 return SCI_FAILURE_INSUFFICIENT_RESOURCES;
2224}
2225
2226/**
2227 * This method frees the remote node index back to the available pool. Once
2228 * this is done the remote node context buffer is no longer valid and can
2229 * not be used.
2230 * @this_controller:
2231 * @the_device:
2232 * @node_id:
2233 *
2234 */
2235void scic_sds_controller_free_remote_node_context(
2236 struct scic_sds_controller *this_controller,
2237 struct scic_sds_remote_device *the_device,
2238 u16 node_id)
2239{
2240 u32 remote_node_count = scic_sds_remote_device_node_count(the_device);
2241
2242 if (this_controller->device_table[node_id] == the_device) {
2243 this_controller->device_table[node_id] = SCI_INVALID_HANDLE;
2244
2245 scic_sds_remote_node_table_release_remote_node_index(
2246 &this_controller->available_remote_nodes, remote_node_count, node_id
2247 );
2248 }
2249}
2250
2251/**
2252 * This method returns the union scu_remote_node_context for the specified remote
2253 * node id.
2254 * @this_controller:
2255 * @node_id:
2256 *
2257 * union scu_remote_node_context*
2258 */
2259union scu_remote_node_context *scic_sds_controller_get_remote_node_context_buffer(
2260 struct scic_sds_controller *this_controller,
2261 u16 node_id
2262 ) {
2263 if (
2264 (node_id < this_controller->remote_node_entries)
2265 && (this_controller->device_table[node_id] != SCI_INVALID_HANDLE)
2266 ) {
2267 return &this_controller->remote_node_context_table[node_id];
2268 }
2269
2270 return NULL;
2271}
2272
2273/**
2274 *
2275 * @resposne_buffer: This is the buffer into which the D2H register FIS will be
2276 * constructed.
2277 * @frame_header: This is the frame header returned by the hardware.
2278 * @frame_buffer: This is the frame buffer returned by the hardware.
2279 *
2280 * This method will combind the frame header and frame buffer to create a SATA
2281 * D2H register FIS none
2282 */
2283void scic_sds_controller_copy_sata_response(
2284 void *response_buffer,
2285 void *frame_header,
2286 void *frame_buffer)
2287{
2288 memcpy(
2289 response_buffer,
2290 frame_header,
2291 sizeof(u32)
2292 );
2293
2294 memcpy(
2295 (char *)((char *)response_buffer + sizeof(u32)),
2296 frame_buffer,
2297 sizeof(struct sata_fis_reg_d2h) - sizeof(u32)
2298 );
2299}
2300
2301/**
2302 * This method releases the frame once this is done the frame is available for
2303 * re-use by the hardware. The data contained in the frame header and frame
2304 * buffer is no longer valid. The UF queue get pointer is only updated if UF
2305 * control indicates this is appropriate.
2306 * @this_controller:
2307 * @frame_index:
2308 *
2309 */
2310void scic_sds_controller_release_frame(
2311 struct scic_sds_controller *this_controller,
2312 u32 frame_index)
2313{
2314 if (scic_sds_unsolicited_frame_control_release_frame(
2315 &this_controller->uf_control, frame_index) == true)
2316 SCU_UFQGP_WRITE(this_controller, this_controller->uf_control.get);
2317}
2318
2319/**
2320 * This method sets user parameters and OEM parameters to default values.
2321 * Users can override these values utilizing the scic_user_parameters_set()
2322 * and scic_oem_parameters_set() methods.
2323 * @controller: This parameter specifies the controller for which to set the
2324 * configuration parameters to their default values.
2325 *
2326 */
2327static void scic_sds_controller_set_default_config_parameters(
2328 struct scic_sds_controller *this_controller)
2329{
2330 u16 index;
2331
2332 /* Default to no SSC operation. */
2333 this_controller->oem_parameters.sds1.controller.do_enable_ssc = false;
2334
2335 /* Initialize all of the port parameter information to narrow ports. */
2336 for (index = 0; index < SCI_MAX_PORTS; index++) {
2337 this_controller->oem_parameters.sds1.ports[index].phy_mask = 0;
2338 }
2339
2340 /* Initialize all of the phy parameter information. */
2341 for (index = 0; index < SCI_MAX_PHYS; index++) {
2342 /*
2343 * Default to 3G (i.e. Gen 2) for now. User can override if
2344 * they choose. */
2345 this_controller->user_parameters.sds1.phys[index].max_speed_generation = 2;
2346
2347 /*
2348 * Previous Vitesse based expanders had a arbitration issue that
2349 * is worked around by having the upper 32-bits of SAS address
2350 * with a value greater then the Vitesse company identifier.
2351 * Hence, usage of 0x5FCFFFFF. */
2352 this_controller->oem_parameters.sds1.phys[index].sas_address.low
2353 = 0x00000001;
2354 this_controller->oem_parameters.sds1.phys[index].sas_address.high
2355 = 0x5FCFFFFF;
2356 }
2357
2358 this_controller->user_parameters.sds1.stp_inactivity_timeout = 5;
2359 this_controller->user_parameters.sds1.ssp_inactivity_timeout = 5;
2360 this_controller->user_parameters.sds1.stp_max_occupancy_timeout = 5;
2361 this_controller->user_parameters.sds1.ssp_max_occupancy_timeout = 20;
2362 this_controller->user_parameters.sds1.no_outbound_task_timeout = 5;
2363
2364}
2365
2366
2367enum sci_status scic_controller_construct(struct scic_sds_controller *controller,
2368 void __iomem *scu_base,
2369 void __iomem *smu_base)
2370{
2371 u8 index;
2372
2373 sci_base_controller_construct(
2374 &controller->parent,
2375 scic_sds_controller_state_table,
2376 controller->memory_descriptors,
2377 ARRAY_SIZE(controller->memory_descriptors),
2378 NULL
2379 );
2380
2381 controller->scu_registers = scu_base;
2382 controller->smu_registers = smu_base;
2383
2384 scic_sds_port_configuration_agent_construct(&controller->port_agent);
2385
2386 /* Construct the ports for this controller */
2387 for (index = 0; index < SCI_MAX_PORTS; index++)
2388 scic_sds_port_construct(&controller->port_table[index],
2389 index, controller);
2390 scic_sds_port_construct(&controller->port_table[index],
2391 SCIC_SDS_DUMMY_PORT, controller);
2392
2393 /* Construct the phys for this controller */
2394 for (index = 0; index < SCI_MAX_PHYS; index++) {
2395 /* Add all the PHYs to the dummy port */
2396 scic_sds_phy_construct(
2397 &controller->phy_table[index],
2398 &controller->port_table[SCI_MAX_PORTS],
2399 index
2400 );
2401 }
2402
2403 controller->invalid_phy_mask = 0;
2404
2405 /* Set the default maximum values */
2406 controller->completion_event_entries = SCU_EVENT_COUNT;
2407 controller->completion_queue_entries = SCU_COMPLETION_QUEUE_COUNT;
2408 controller->remote_node_entries = SCI_MAX_REMOTE_DEVICES;
2409 controller->logical_port_entries = SCI_MAX_PORTS;
2410 controller->task_context_entries = SCU_IO_REQUEST_COUNT;
2411 controller->uf_control.buffers.count = SCU_UNSOLICITED_FRAME_COUNT;
2412 controller->uf_control.address_table.count = SCU_UNSOLICITED_FRAME_COUNT;
2413
2414 /* Initialize the User and OEM parameters to default values. */
2415 scic_sds_controller_set_default_config_parameters(controller);
2416
2417 return SCI_SUCCESS;
2418}
2419
2420/* --------------------------------------------------------------------------- */
2421
2422enum sci_status scic_controller_initialize(
2423 struct scic_sds_controller *scic)
2424{
2425 enum sci_status status = SCI_FAILURE_INVALID_STATE;
2426 sci_base_controller_handler_t initialize;
2427 u32 state;
2428
2429 state = scic->parent.state_machine.current_state_id;
2430 initialize = scic_sds_controller_state_handler_table[state].base.initialize;
2431
2432 if (initialize)
2433 status = initialize(&scic->parent);
2434 else
2435 dev_warn(scic_to_dev(scic),
2436 "%s: SCIC Controller initialize operation requested "
2437 "in invalid state %d\n",
2438 __func__,
2439 sci_base_state_machine_get_state(
2440 scic_sds_controller_get_base_state_machine(
2441 scic)));
2442
2443 return status;
2444}
2445
2446/* --------------------------------------------------------------------------- */
2447
2448u32 scic_controller_get_suggested_start_timeout(
2449 struct scic_sds_controller *sc)
2450{
2451 /* Validate the user supplied parameters. */
2452 if (sc == SCI_INVALID_HANDLE)
2453 return 0;
2454
2455 /*
2456 * The suggested minimum timeout value for a controller start operation:
2457 *
2458 * Signature FIS Timeout
2459 * + Phy Start Timeout
2460 * + Number of Phy Spin Up Intervals
2461 * ---------------------------------
2462 * Number of milliseconds for the controller start operation.
2463 *
2464 * NOTE: The number of phy spin up intervals will be equivalent
2465 * to the number of phys divided by the number phys allowed
2466 * per interval - 1 (once OEM parameters are supported).
2467 * Currently we assume only 1 phy per interval. */
2468
2469 return (SCIC_SDS_SIGNATURE_FIS_TIMEOUT
2470 + SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT
2471 + ((SCI_MAX_PHYS - 1) * SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL));
2472}
2473
2474/* --------------------------------------------------------------------------- */
2475
2476enum sci_status scic_controller_start(
2477 struct scic_sds_controller *scic,
2478 u32 timeout)
2479{
2480 enum sci_status status = SCI_FAILURE_INVALID_STATE;
2481 sci_base_controller_timed_handler_t start;
2482 u32 state;
2483
2484 state = scic->parent.state_machine.current_state_id;
2485 start = scic_sds_controller_state_handler_table[state].base.start;
2486
2487 if (start)
2488 status = start(&scic->parent, timeout);
2489 else
2490 dev_warn(scic_to_dev(scic),
2491 "%s: SCIC Controller start operation requested in "
2492 "invalid state %d\n",
2493 __func__,
2494 sci_base_state_machine_get_state(
2495 scic_sds_controller_get_base_state_machine(
2496 scic)));
2497
2498 return status;
2499}
2500
2501/* --------------------------------------------------------------------------- */
2502
2503enum sci_status scic_controller_stop(
2504 struct scic_sds_controller *scic,
2505 u32 timeout)
2506{
2507 enum sci_status status = SCI_FAILURE_INVALID_STATE;
2508 sci_base_controller_timed_handler_t stop;
2509 u32 state;
2510
2511 state = scic->parent.state_machine.current_state_id;
2512 stop = scic_sds_controller_state_handler_table[state].base.stop;
2513
2514 if (stop)
2515 status = stop(&scic->parent, timeout);
2516 else
2517 dev_warn(scic_to_dev(scic),
2518 "%s: SCIC Controller stop operation requested in "
2519 "invalid state %d\n",
2520 __func__,
2521 sci_base_state_machine_get_state(
2522 scic_sds_controller_get_base_state_machine(
2523 scic)));
2524
2525 return status;
2526}
2527
2528/* --------------------------------------------------------------------------- */
2529
2530enum sci_status scic_controller_reset(
2531 struct scic_sds_controller *scic)
2532{
2533 enum sci_status status = SCI_FAILURE_INVALID_STATE;
2534 sci_base_controller_handler_t reset;
2535 u32 state;
2536
2537 state = scic->parent.state_machine.current_state_id;
2538 reset = scic_sds_controller_state_handler_table[state].base.reset;
2539
2540 if (reset)
2541 status = reset(&scic->parent);
2542 else
2543 dev_warn(scic_to_dev(scic),
2544 "%s: SCIC Controller reset operation requested in "
2545 "invalid state %d\n",
2546 __func__,
2547 sci_base_state_machine_get_state(
2548 scic_sds_controller_get_base_state_machine(
2549 scic)));
2550
2551 return status;
2552}
2553
2554/* --------------------------------------------------------------------------- */
2555
2556enum sci_status scic_controller_get_handler_methods(
2557 enum scic_interrupt_type interrupt_type,
2558 u16 message_count,
2559 struct scic_controller_handler_methods *handler_methods)
2560{
2561 enum sci_status status = SCI_FAILURE_UNSUPPORTED_MESSAGE_COUNT;
2562
2563 switch (interrupt_type) {
2564 case SCIC_LEGACY_LINE_INTERRUPT_TYPE:
2565 if (message_count == 0) {
2566 handler_methods[0].interrupt_handler
2567 = scic_sds_controller_legacy_interrupt_handler;
2568 handler_methods[0].completion_handler
2569 = scic_sds_controller_legacy_completion_handler;
2570
2571 status = SCI_SUCCESS;
2572 }
2573 break;
2574
2575 case SCIC_MSIX_INTERRUPT_TYPE:
2576 if (message_count == 1) {
2577 handler_methods[0].interrupt_handler
2578 = scic_sds_controller_single_vector_interrupt_handler;
2579 handler_methods[0].completion_handler
2580 = scic_sds_controller_single_vector_completion_handler;
2581
2582 status = SCI_SUCCESS;
2583 } else if (message_count == 2) {
2584 handler_methods[0].interrupt_handler
2585 = scic_sds_controller_normal_vector_interrupt_handler;
2586 handler_methods[0].completion_handler
2587 = scic_sds_controller_normal_vector_completion_handler;
2588
2589 handler_methods[1].interrupt_handler
2590 = scic_sds_controller_error_vector_interrupt_handler;
2591 handler_methods[1].completion_handler
2592 = scic_sds_controller_error_vector_completion_handler;
2593
2594 status = SCI_SUCCESS;
2595 }
2596 break;
2597
2598 case SCIC_NO_INTERRUPTS:
2599 if (message_count == 0) {
2600
2601 handler_methods[0].interrupt_handler
2602 = scic_sds_controller_polling_interrupt_handler;
2603 handler_methods[0].completion_handler
2604 = scic_sds_controller_polling_completion_handler;
2605
2606 status = SCI_SUCCESS;
2607 }
2608 break;
2609
2610 default:
2611 status = SCI_FAILURE_INVALID_PARAMETER_VALUE;
2612 break;
2613 }
2614
2615 return status;
2616}
2617
2618/* --------------------------------------------------------------------------- */
2619
2620enum sci_io_status scic_controller_start_io(
2621 struct scic_sds_controller *scic,
2622 struct scic_sds_remote_device *remote_device,
2623 struct scic_sds_request *io_request,
2624 u16 io_tag)
2625{
2626 u32 state;
2627 sci_base_controller_start_request_handler_t start_io;
2628
2629 state = scic->parent.state_machine.current_state_id;
2630 start_io = scic_sds_controller_state_handler_table[state].base.start_io;
2631
2632 return start_io(&scic->parent,
2633 (struct sci_base_remote_device *) remote_device,
2634 (struct sci_base_request *)io_request, io_tag);
2635}
2636
2637/* --------------------------------------------------------------------------- */
2638
2639enum sci_status scic_controller_terminate_request(
2640 struct scic_sds_controller *scic,
2641 struct scic_sds_remote_device *remote_device,
2642 struct scic_sds_request *request)
2643{
2644 sci_base_controller_request_handler_t terminate_request;
2645 u32 state;
2646
2647 state = scic->parent.state_machine.current_state_id;
2648 terminate_request = scic_sds_controller_state_handler_table[state].terminate_request;
2649
2650 return terminate_request(&scic->parent,
2651 (struct sci_base_remote_device *)remote_device,
2652 (struct sci_base_request *)request);
2653}
2654
2655/* --------------------------------------------------------------------------- */
2656
2657enum sci_status scic_controller_complete_io(
2658 struct scic_sds_controller *scic,
2659 struct scic_sds_remote_device *remote_device,
2660 struct scic_sds_request *io_request)
2661{
2662 u32 state;
2663 sci_base_controller_request_handler_t complete_io;
2664
2665 state = scic->parent.state_machine.current_state_id;
2666 complete_io = scic_sds_controller_state_handler_table[state].base.complete_io;
2667
2668 return complete_io(&scic->parent,
2669 (struct sci_base_remote_device *)remote_device,
2670 (struct sci_base_request *)io_request);
2671}
2672
2673/* --------------------------------------------------------------------------- */
2674
2675
2676enum sci_task_status scic_controller_start_task(
2677 struct scic_sds_controller *scic,
2678 struct scic_sds_remote_device *remote_device,
2679 struct scic_sds_request *task_request,
2680 u16 task_tag)
2681{
2682 u32 state;
2683 sci_base_controller_start_request_handler_t start_task;
2684 enum sci_task_status status = SCI_TASK_FAILURE_INVALID_STATE;
2685
2686 state = scic->parent.state_machine.current_state_id;
2687 start_task = scic_sds_controller_state_handler_table[state].base.start_task;
2688
2689 if (start_task)
2690 status = start_task(&scic->parent,
2691 (struct sci_base_remote_device *)remote_device,
2692 (struct sci_base_request *)task_request,
2693 task_tag);
2694 else
2695 dev_warn(scic_to_dev(scic),
2696 "%s: SCIC Controller starting task from invalid "
2697 "state\n",
2698 __func__);
2699
2700 return status;
2701}
2702
2703/* --------------------------------------------------------------------------- */
2704
2705enum sci_status scic_controller_complete_task(
2706 struct scic_sds_controller *scic,
2707 struct scic_sds_remote_device *remote_device,
2708 struct scic_sds_request *task_request)
2709{
2710 u32 state;
2711 sci_base_controller_request_handler_t complete_task;
2712 enum sci_status status = SCI_FAILURE_INVALID_STATE;
2713
2714 state = scic->parent.state_machine.current_state_id;
2715 complete_task = scic_sds_controller_state_handler_table[state].base.complete_task;
2716
2717 if (complete_task)
2718 status = complete_task(&scic->parent,
2719 (struct sci_base_remote_device *)remote_device,
2720 (struct sci_base_request *)task_request);
2721 else
2722 dev_warn(scic_to_dev(scic),
2723 "%s: SCIC Controller completing task from invalid "
2724 "state\n",
2725 __func__);
2726
2727 return status;
2728}
2729
2730
2731/* --------------------------------------------------------------------------- */
2732
2733enum sci_status scic_controller_get_port_handle(
2734 struct scic_sds_controller *scic,
2735 u8 port_index,
2736 struct scic_sds_port **port_handle)
2737{
2738 if (port_index < scic->logical_port_entries) {
2739 *port_handle = &scic->port_table[port_index];
2740
2741 return SCI_SUCCESS;
2742 }
2743
2744 return SCI_FAILURE_INVALID_PORT;
2745}
2746
2747/* --------------------------------------------------------------------------- */
2748
2749enum sci_status scic_controller_get_phy_handle(
2750 struct scic_sds_controller *scic,
2751 u8 phy_index,
2752 struct scic_sds_phy **phy_handle)
2753{
2754 if (phy_index < ARRAY_SIZE(scic->phy_table)) {
2755 *phy_handle = &scic->phy_table[phy_index];
2756
2757 return SCI_SUCCESS;
2758 }
2759
2760 dev_err(scic_to_dev(scic),
2761 "%s: Controller:0x%p PhyId:0x%x invalid phy index\n",
2762 __func__, scic, phy_index);
2763
2764 return SCI_FAILURE_INVALID_PHY;
2765}
2766
2767/* --------------------------------------------------------------------------- */
2768
2769u16 scic_controller_allocate_io_tag(
2770 struct scic_sds_controller *scic)
2771{
2772 u16 task_context;
2773 u16 sequence_count;
2774
2775 if (!sci_pool_empty(scic->tci_pool)) {
2776 sci_pool_get(scic->tci_pool, task_context);
2777
2778 sequence_count = scic->io_request_sequence[task_context];
2779
2780 return scic_sds_io_tag_construct(sequence_count, task_context);
2781 }
2782
2783 return SCI_CONTROLLER_INVALID_IO_TAG;
2784}
2785
2786/* --------------------------------------------------------------------------- */
2787
2788enum sci_status scic_controller_free_io_tag(
2789 struct scic_sds_controller *scic,
2790 u16 io_tag)
2791{
2792 u16 sequence;
2793 u16 index;
2794
2795 BUG_ON(io_tag == SCI_CONTROLLER_INVALID_IO_TAG);
2796
2797 sequence = scic_sds_io_tag_get_sequence(io_tag);
2798 index = scic_sds_io_tag_get_index(io_tag);
2799
2800 if (!sci_pool_full(scic->tci_pool)) {
2801 if (sequence == scic->io_request_sequence[index]) {
2802 scic_sds_io_sequence_increment(
2803 scic->io_request_sequence[index]);
2804
2805 sci_pool_put(scic->tci_pool, index);
2806
2807 return SCI_SUCCESS;
2808 }
2809 }
2810
2811 return SCI_FAILURE_INVALID_IO_TAG;
2812}
2813
2814/* --------------------------------------------------------------------------- */
2815
2816void scic_controller_enable_interrupts(
2817 struct scic_sds_controller *scic)
2818{
2819 BUG_ON(scic->smu_registers == NULL);
2820 SMU_IMR_WRITE(scic, 0x00000000);
2821}
2822
2823/* --------------------------------------------------------------------------- */
2824
2825void scic_controller_disable_interrupts(
2826 struct scic_sds_controller *scic)
2827{
2828 BUG_ON(scic->smu_registers == NULL);
2829 SMU_IMR_WRITE(scic, 0xffffffff);
2830}
2831
2832/* --------------------------------------------------------------------------- */
2833
2834enum sci_status scic_controller_set_mode(
2835 struct scic_sds_controller *scic,
2836 enum sci_controller_mode operating_mode)
2837{
2838 enum sci_status status = SCI_SUCCESS;
2839
2840 if ((scic->parent.state_machine.current_state_id ==
2841 SCI_BASE_CONTROLLER_STATE_INITIALIZING) ||
2842 (scic->parent.state_machine.current_state_id ==
2843 SCI_BASE_CONTROLLER_STATE_INITIALIZED)) {
2844 switch (operating_mode) {
2845 case SCI_MODE_SPEED:
2846 scic->remote_node_entries = SCI_MAX_REMOTE_DEVICES;
2847 scic->task_context_entries = SCU_IO_REQUEST_COUNT;
2848 scic->uf_control.buffers.count =
2849 SCU_UNSOLICITED_FRAME_COUNT;
2850 scic->completion_event_entries = SCU_EVENT_COUNT;
2851 scic->completion_queue_entries =
2852 SCU_COMPLETION_QUEUE_COUNT;
2853 scic_sds_controller_build_memory_descriptor_table(scic);
2854 break;
2855
2856 case SCI_MODE_SIZE:
2857 scic->remote_node_entries = SCI_MIN_REMOTE_DEVICES;
2858 scic->task_context_entries = SCI_MIN_IO_REQUESTS;
2859 scic->uf_control.buffers.count =
2860 SCU_MIN_UNSOLICITED_FRAMES;
2861 scic->completion_event_entries = SCU_MIN_EVENTS;
2862 scic->completion_queue_entries =
2863 SCU_MIN_COMPLETION_QUEUE_ENTRIES;
2864 scic_sds_controller_build_memory_descriptor_table(scic);
2865 break;
2866
2867 default:
2868 status = SCI_FAILURE_INVALID_PARAMETER_VALUE;
2869 break;
2870 }
2871 } else
2872 status = SCI_FAILURE_INVALID_STATE;
2873
2874 return status;
2875}
2876
2877/**
2878 * scic_sds_controller_reset_hardware() -
2879 *
2880 * This method will reset the controller hardware.
2881 */
2882void scic_sds_controller_reset_hardware(
2883 struct scic_sds_controller *scic)
2884{
2885 /* Disable interrupts so we dont take any spurious interrupts */
2886 scic_controller_disable_interrupts(scic);
2887
2888 /* Reset the SCU */
2889 SMU_SMUSRCR_WRITE(scic, 0xFFFFFFFF);
2890
2891 /* Delay for 1ms to before clearing the CQP and UFQPR. */
2892 scic_cb_stall_execution(1000);
2893
2894 /* The write to the CQGR clears the CQP */
2895 SMU_CQGR_WRITE(scic, 0x00000000);
2896
2897 /* The write to the UFQGP clears the UFQPR */
2898 SCU_UFQGP_WRITE(scic, 0x00000000);
2899}
2900
2901/* --------------------------------------------------------------------------- */
2902
2903enum sci_status scic_user_parameters_set(
2904 struct scic_sds_controller *scic,
2905 union scic_user_parameters *scic_parms)
2906{
2907 if (
2908 (scic->parent.state_machine.current_state_id
2909 == SCI_BASE_CONTROLLER_STATE_RESET)
2910 || (scic->parent.state_machine.current_state_id
2911 == SCI_BASE_CONTROLLER_STATE_INITIALIZING)
2912 || (scic->parent.state_machine.current_state_id
2913 == SCI_BASE_CONTROLLER_STATE_INITIALIZED)
2914 ) {
2915 u16 index;
2916
2917 /*
2918 * Validate the user parameters. If they are not legal, then
2919 * return a failure. */
2920 for (index = 0; index < SCI_MAX_PHYS; index++) {
2921 if (!
2922 (scic_parms->sds1.phys[index].max_speed_generation
2923 <= SCIC_SDS_PARM_MAX_SPEED
2924 && scic_parms->sds1.phys[index].max_speed_generation
2925 > SCIC_SDS_PARM_NO_SPEED
2926 )
2927 )
2928 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
2929 }
2930
2931 memcpy(&scic->user_parameters, scic_parms, sizeof(*scic_parms));
2932
2933 return SCI_SUCCESS;
2934 }
2935
2936 return SCI_FAILURE_INVALID_STATE;
2937}
2938
2939/* --------------------------------------------------------------------------- */
2940
2941void scic_user_parameters_get(
2942 struct scic_sds_controller *scic,
2943 union scic_user_parameters *scic_parms)
2944{
2945 memcpy(scic_parms, (&scic->user_parameters), sizeof(*scic_parms));
2946}
2947
2948/* --------------------------------------------------------------------------- */
2949
2950enum sci_status scic_oem_parameters_set(
2951 struct scic_sds_controller *scic,
2952 union scic_oem_parameters *scic_parms)
2953{
2954 if (
2955 (scic->parent.state_machine.current_state_id
2956 == SCI_BASE_CONTROLLER_STATE_RESET)
2957 || (scic->parent.state_machine.current_state_id
2958 == SCI_BASE_CONTROLLER_STATE_INITIALIZING)
2959 || (scic->parent.state_machine.current_state_id
2960 == SCI_BASE_CONTROLLER_STATE_INITIALIZED)
2961 ) {
2962 u16 index;
2963
2964 /*
2965 * Validate the oem parameters. If they are not legal, then
2966 * return a failure. */
2967 for (index = 0; index < SCI_MAX_PORTS; index++) {
2968 if (scic_parms->sds1.ports[index].phy_mask > SCIC_SDS_PARM_PHY_MASK_MAX) {
2969 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
2970 }
2971 }
2972
2973 for (index = 0; index < SCI_MAX_PHYS; index++) {
2974 if (
2975 scic_parms->sds1.phys[index].sas_address.high == 0
2976 && scic_parms->sds1.phys[index].sas_address.low == 0
2977 ) {
2978 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
2979 }
2980 }
2981
2982 memcpy(&scic->oem_parameters, scic_parms, sizeof(*scic_parms));
2983 return SCI_SUCCESS;
2984 }
2985
2986 return SCI_FAILURE_INVALID_STATE;
2987}
2988
2989/* --------------------------------------------------------------------------- */
2990
2991void scic_oem_parameters_get(
2992 struct scic_sds_controller *scic,
2993 union scic_oem_parameters *scic_parms)
2994{
2995 memcpy(scic_parms, (&scic->oem_parameters), sizeof(*scic_parms));
2996}
2997
2998/* --------------------------------------------------------------------------- */
2999
3000
3001#define INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_LOWER_BOUND_NS 853
3002#define INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_UPPER_BOUND_NS 1280
3003#define INTERRUPT_COALESCE_TIMEOUT_MAX_US 2700000
3004#define INTERRUPT_COALESCE_NUMBER_MAX 256
3005#define INTERRUPT_COALESCE_TIMEOUT_ENCODE_MIN 7
3006#define INTERRUPT_COALESCE_TIMEOUT_ENCODE_MAX 28
3007
3008enum sci_status scic_controller_set_interrupt_coalescence(
3009 struct scic_sds_controller *scic_controller,
3010 u32 coalesce_number,
3011 u32 coalesce_timeout)
3012{
3013 u8 timeout_encode = 0;
3014 u32 min = 0;
3015 u32 max = 0;
3016
3017 /* Check if the input parameters fall in the range. */
3018 if (coalesce_number > INTERRUPT_COALESCE_NUMBER_MAX)
3019 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
3020
3021 /*
3022 * Defined encoding for interrupt coalescing timeout:
3023 * Value Min Max Units
3024 * ----- --- --- -----
3025 * 0 - - Disabled
3026 * 1 13.3 20.0 ns
3027 * 2 26.7 40.0
3028 * 3 53.3 80.0
3029 * 4 106.7 160.0
3030 * 5 213.3 320.0
3031 * 6 426.7 640.0
3032 * 7 853.3 1280.0
3033 * 8 1.7 2.6 us
3034 * 9 3.4 5.1
3035 * 10 6.8 10.2
3036 * 11 13.7 20.5
3037 * 12 27.3 41.0
3038 * 13 54.6 81.9
3039 * 14 109.2 163.8
3040 * 15 218.5 327.7
3041 * 16 436.9 655.4
3042 * 17 873.8 1310.7
3043 * 18 1.7 2.6 ms
3044 * 19 3.5 5.2
3045 * 20 7.0 10.5
3046 * 21 14.0 21.0
3047 * 22 28.0 41.9
3048 * 23 55.9 83.9
3049 * 24 111.8 167.8
3050 * 25 223.7 335.5
3051 * 26 447.4 671.1
3052 * 27 894.8 1342.2
3053 * 28 1.8 2.7 s
3054 * Others Undefined */
3055
3056 /*
3057 * Use the table above to decide the encode of interrupt coalescing timeout
3058 * value for register writing. */
3059 if (coalesce_timeout == 0)
3060 timeout_encode = 0;
3061 else{
3062 /* make the timeout value in unit of (10 ns). */
3063 coalesce_timeout = coalesce_timeout * 100;
3064 min = INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_LOWER_BOUND_NS / 10;
3065 max = INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_UPPER_BOUND_NS / 10;
3066
3067 /* get the encode of timeout for register writing. */
3068 for (timeout_encode = INTERRUPT_COALESCE_TIMEOUT_ENCODE_MIN;
3069 timeout_encode <= INTERRUPT_COALESCE_TIMEOUT_ENCODE_MAX;
3070 timeout_encode++) {
3071 if (min <= coalesce_timeout && max > coalesce_timeout)
3072 break;
3073 else if (coalesce_timeout >= max && coalesce_timeout < min * 2
3074 && coalesce_timeout <= INTERRUPT_COALESCE_TIMEOUT_MAX_US * 100) {
3075 if ((coalesce_timeout - max) < (2 * min - coalesce_timeout))
3076 break;
3077 else{
3078 timeout_encode++;
3079 break;
3080 }
3081 } else {
3082 max = max * 2;
3083 min = min * 2;
3084 }
3085 }
3086
3087 if (timeout_encode == INTERRUPT_COALESCE_TIMEOUT_ENCODE_MAX + 1)
3088 /* the value is out of range. */
3089 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
3090 }
3091
3092 SMU_ICC_WRITE(
3093 scic_controller,
3094 (SMU_ICC_GEN_VAL(NUMBER, coalesce_number) |
3095 SMU_ICC_GEN_VAL(TIMER, timeout_encode))
3096 );
3097
3098 scic_controller->interrupt_coalesce_number = (u16)coalesce_number;
3099 scic_controller->interrupt_coalesce_timeout = coalesce_timeout / 100;
3100
3101 return SCI_SUCCESS;
3102}
3103
3104
3105struct scic_sds_controller *scic_controller_alloc(struct device *dev)
3106{
3107 return devm_kzalloc(dev, sizeof(struct scic_sds_controller), GFP_KERNEL);
3108}
3109
3110/*
3111 * *****************************************************************************
3112 * * DEFAULT STATE HANDLERS
3113 * ***************************************************************************** */
3114
3115/**
3116 *
3117 * @controller: This is struct sci_base_controller object which is cast into a
3118 * struct scic_sds_controller object.
3119 * @remote_device: This is struct sci_base_remote_device which, if it was used, would
3120 * be cast to a struct scic_sds_remote_device.
3121 * @io_request: This is the struct sci_base_request which, if it was used, would be
3122 * cast to a SCIC_SDS_IO_REQUEST.
3123 * @io_tag: This is the IO tag to be assigned to the IO request or
3124 * SCI_CONTROLLER_INVALID_IO_TAG.
3125 *
3126 * This method is called when the struct scic_sds_controller default start io/task
3127 * handler is in place. - Issue a warning message enum sci_status
3128 * SCI_FAILURE_INVALID_STATE
3129 */
3130static enum sci_status scic_sds_controller_default_start_operation_handler(
3131 struct sci_base_controller *controller,
3132 struct sci_base_remote_device *remote_device,
3133 struct sci_base_request *io_request,
3134 u16 io_tag)
3135{
3136 struct scic_sds_controller *this_controller;
3137
3138 this_controller = (struct scic_sds_controller *)controller;
3139
3140 dev_warn(scic_to_dev(this_controller),
3141 "%s: SCIC Controller requested to start an io/task from "
3142 "invalid state %d\n",
3143 __func__,
3144 sci_base_state_machine_get_state(
3145 scic_sds_controller_get_base_state_machine(
3146 this_controller)));
3147
3148 return SCI_FAILURE_INVALID_STATE;
3149}
3150
3151/**
3152 *
3153 * @controller: This is struct sci_base_controller object which is cast into a
3154 * struct scic_sds_controller object.
3155 * @remote_device: This is struct sci_base_remote_device which, if it was used, would
3156 * be cast to a struct scic_sds_remote_device.
3157 * @io_request: This is the struct sci_base_request which, if it was used, would be
3158 * cast to a SCIC_SDS_IO_REQUEST.
3159 *
3160 * This method is called when the struct scic_sds_controller default request handler
3161 * is in place. - Issue a warning message enum sci_status SCI_FAILURE_INVALID_STATE
3162 */
3163static enum sci_status scic_sds_controller_default_request_handler(
3164 struct sci_base_controller *controller,
3165 struct sci_base_remote_device *remote_device,
3166 struct sci_base_request *io_request)
3167{
3168 struct scic_sds_controller *this_controller;
3169
3170 this_controller = (struct scic_sds_controller *)controller;
3171
3172 dev_warn(scic_to_dev(this_controller),
3173 "%s: SCIC Controller request operation from invalid state %d\n",
3174 __func__,
3175 sci_base_state_machine_get_state(
3176 scic_sds_controller_get_base_state_machine(
3177 this_controller)));
3178
3179 return SCI_FAILURE_INVALID_STATE;
3180}
3181
3182/*
3183 * *****************************************************************************
3184 * * GENERAL (COMMON) STATE HANDLERS
3185 * ***************************************************************************** */
3186
3187/**
3188 *
3189 * @controller: The struct sci_base_controller object which is cast into a
3190 * struct scic_sds_controller object.
3191 *
3192 * This method is called when the struct scic_sds_controller is in the ready state
3193 * reset handler is in place. - Transition to
3194 * SCI_BASE_CONTROLLER_STATE_RESETTING enum sci_status SCI_SUCCESS
3195 */
3196static enum sci_status scic_sds_controller_general_reset_handler(
3197 struct sci_base_controller *controller)
3198{
3199 struct scic_sds_controller *this_controller;
3200
3201 this_controller = (struct scic_sds_controller *)controller;
3202
3203 /*
3204 * The reset operation is not a graceful cleanup just perform the state
3205 * transition. */
3206 sci_base_state_machine_change_state(
3207 scic_sds_controller_get_base_state_machine(this_controller),
3208 SCI_BASE_CONTROLLER_STATE_RESETTING
3209 );
3210
3211 return SCI_SUCCESS;
3212}
3213
3214/*
3215 * *****************************************************************************
3216 * * RESET STATE HANDLERS
3217 * ***************************************************************************** */
3218
3219/**
3220 *
3221 * @controller: This is the struct sci_base_controller object which is cast into a
3222 * struct scic_sds_controller object.
3223 *
3224 * This method is the struct scic_sds_controller initialize handler for the reset
3225 * state. - Currently this function does nothing enum sci_status SCI_FAILURE This
3226 * function is not yet implemented and is a valid request from the reset state.
3227 */
3228static enum sci_status scic_sds_controller_reset_state_initialize_handler(
3229 struct sci_base_controller *controller)
3230{
3231 u32 index;
3232 enum sci_status result = SCI_SUCCESS;
3233 struct scic_sds_controller *this_controller;
3234
3235 this_controller = (struct scic_sds_controller *)controller;
3236
3237 sci_base_state_machine_change_state(
3238 scic_sds_controller_get_base_state_machine(this_controller),
3239 SCI_BASE_CONTROLLER_STATE_INITIALIZING
3240 );
3241
3242 this_controller->timeout_timer = scic_cb_timer_create(
3243 this_controller,
3244 (void (*)(void *))scic_sds_controller_timeout_handler,
3245 (void (*)(void *))controller);
3246
3247 scic_sds_controller_initialize_phy_startup(this_controller);
3248
3249 scic_sds_controller_initialize_power_control(this_controller);
3250
3251 /*
3252 * There is nothing to do here for B0 since we do not have to
3253 * program the AFE registers.
3254 * / @todo The AFE settings are supposed to be correct for the B0 but
3255 * / presently they seem to be wrong. */
3256 scic_sds_controller_afe_initialization(this_controller);
3257
3258 if (SCI_SUCCESS == result) {
3259 u32 status;
3260 u32 terminate_loop;
3261
3262 /* Take the hardware out of reset */
3263 SMU_SMUSRCR_WRITE(this_controller, 0x00000000);
3264
3265 /*
3266 * / @todo Provide meaningfull error code for hardware failure
3267 * result = SCI_FAILURE_CONTROLLER_HARDWARE; */
3268 result = SCI_FAILURE;
3269 terminate_loop = 100;
3270
3271 while (terminate_loop-- && (result != SCI_SUCCESS)) {
3272 /* Loop until the hardware reports success */
3273 scic_cb_stall_execution(SCU_CONTEXT_RAM_INIT_STALL_TIME);
3274 status = SMU_SMUCSR_READ(this_controller);
3275
3276 if ((status & SCU_RAM_INIT_COMPLETED) == SCU_RAM_INIT_COMPLETED) {
3277 result = SCI_SUCCESS;
3278 }
3279 }
3280 }
3281
3282 if (result == SCI_SUCCESS) {
3283 u32 max_supported_ports;
3284 u32 max_supported_devices;
3285 u32 max_supported_io_requests;
3286 u32 device_context_capacity;
3287
3288 /*
3289 * Determine what are the actaul device capacities that the
3290 * hardware will support */
3291 device_context_capacity = SMU_DCC_READ(this_controller);
3292
3293 max_supported_ports =
3294 smu_dcc_get_max_ports(device_context_capacity);
3295 max_supported_devices =
3296 smu_dcc_get_max_remote_node_context(device_context_capacity);
3297 max_supported_io_requests =
3298 smu_dcc_get_max_task_context(device_context_capacity);
3299
3300 /* Make all PEs that are unassigned match up with the logical ports */
3301 for (index = 0; index < max_supported_ports; index++) {
3302 scu_register_write(
3303 this_controller,
3304 this_controller->scu_registers->peg0.ptsg.protocol_engine[index],
3305 index
3306 );
3307 }
3308
3309 /* Record the smaller of the two capacity values */
3310 this_controller->logical_port_entries =
3311 min(max_supported_ports, this_controller->logical_port_entries);
3312
3313 this_controller->task_context_entries =
3314 min(max_supported_io_requests, this_controller->task_context_entries);
3315
3316 this_controller->remote_node_entries =
3317 min(max_supported_devices, this_controller->remote_node_entries);
3318
3319 /*
3320 * Now that we have the correct hardware reported minimum values
3321 * build the MDL for the controller. Default to a performance
3322 * configuration. */
3323 scic_controller_set_mode(this_controller, SCI_MODE_SPEED);
3324 }
3325
3326 /* Initialize hardware PCI Relaxed ordering in DMA engines */
3327 if (result == SCI_SUCCESS) {
3328 u32 dma_configuration;
3329
3330 /* Configure the payload DMA */
3331 dma_configuration = SCU_PDMACR_READ(this_controller);
3332 dma_configuration |= SCU_PDMACR_GEN_BIT(PCI_RELAXED_ORDERING_ENABLE);
3333 SCU_PDMACR_WRITE(this_controller, dma_configuration);
3334
3335 /* Configure the control DMA */
3336 dma_configuration = SCU_CDMACR_READ(this_controller);
3337 dma_configuration |= SCU_CDMACR_GEN_BIT(PCI_RELAXED_ORDERING_ENABLE);
3338 SCU_CDMACR_WRITE(this_controller, dma_configuration);
3339 }
3340
3341 /*
3342 * Initialize the PHYs before the PORTs because the PHY registers
3343 * are accessed during the port initialization. */
3344 if (result == SCI_SUCCESS) {
3345 /* Initialize the phys */
3346 for (index = 0;
3347 (result == SCI_SUCCESS) && (index < SCI_MAX_PHYS);
3348 index++) {
3349 result = scic_sds_phy_initialize(
3350 &this_controller->phy_table[index],
3351 &this_controller->scu_registers->peg0.pe[index].ll
3352 );
3353 }
3354 }
3355
3356 if (result == SCI_SUCCESS) {
3357 /* Initialize the logical ports */
3358 for (index = 0;
3359 (index < this_controller->logical_port_entries)
3360 && (result == SCI_SUCCESS);
3361 index++) {
3362 result = scic_sds_port_initialize(
3363 &this_controller->port_table[index],
3364 &this_controller->scu_registers->peg0.pe[index].tl,
3365 &this_controller->scu_registers->peg0.ptsg.port[index],
3366 &this_controller->scu_registers->peg0.ptsg.protocol_engine,
3367 &this_controller->scu_registers->peg0.viit[index]
3368 );
3369 }
3370 }
3371
3372 if (SCI_SUCCESS == result) {
3373 result = scic_sds_port_configuration_agent_initialize(
3374 this_controller,
3375 &this_controller->port_agent
3376 );
3377 }
3378
3379 /* Advance the controller state machine */
3380 if (result == SCI_SUCCESS) {
3381 sci_base_state_machine_change_state(
3382 scic_sds_controller_get_base_state_machine(this_controller),
3383 SCI_BASE_CONTROLLER_STATE_INITIALIZED
3384 );
3385 } else {
3386 sci_base_state_machine_change_state(
3387 scic_sds_controller_get_base_state_machine(this_controller),
3388 SCI_BASE_CONTROLLER_STATE_FAILED
3389 );
3390 }
3391
3392 return result;
3393}
3394
3395/*
3396 * *****************************************************************************
3397 * * INITIALIZED STATE HANDLERS
3398 * ***************************************************************************** */
3399
3400/**
3401 *
3402 * @controller: This is the struct sci_base_controller object which is cast into a
3403 * struct scic_sds_controller object.
3404 * @timeout: This is the allowed time for the controller object to reach the
3405 * started state.
3406 *
3407 * This method is the struct scic_sds_controller start handler for the initialized
3408 * state. - Validate we have a good memory descriptor table - Initialze the
3409 * physical memory before programming the hardware - Program the SCU hardware
3410 * with the physical memory addresses passed in the memory descriptor table. -
3411 * Initialzie the TCi pool - Initialize the RNi pool - Initialize the
3412 * completion queue - Initialize the unsolicited frame data - Take the SCU port
3413 * task scheduler out of reset - Start the first phy object. - Transition to
3414 * SCI_BASE_CONTROLLER_STATE_STARTING. enum sci_status SCI_SUCCESS if all of the
3415 * controller start operations complete
3416 * SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD if one or more of the memory
3417 * descriptor fields is invalid.
3418 */
3419static enum sci_status scic_sds_controller_initialized_state_start_handler(
3420 struct sci_base_controller *controller,
3421 u32 timeout)
3422{
3423 u16 index;
3424 enum sci_status result;
3425 struct scic_sds_controller *this_controller;
3426
3427 this_controller = (struct scic_sds_controller *)controller;
3428
3429 /* Make sure that the SCI User filled in the memory descriptor table correctly */
3430 result = scic_sds_controller_validate_memory_descriptor_table(this_controller);
3431
3432 if (result == SCI_SUCCESS) {
3433 /* The memory descriptor list looks good so program the hardware */
3434 scic_sds_controller_ram_initialization(this_controller);
3435 }
3436
3437 if (SCI_SUCCESS == result) {
3438 /* Build the TCi free pool */
3439 sci_pool_initialize(this_controller->tci_pool);
3440 for (index = 0; index < this_controller->task_context_entries; index++) {
3441 sci_pool_put(this_controller->tci_pool, index);
3442 }
3443
3444 /* Build the RNi free pool */
3445 scic_sds_remote_node_table_initialize(
3446 &this_controller->available_remote_nodes,
3447 this_controller->remote_node_entries
3448 );
3449 }
3450
3451 if (SCI_SUCCESS == result) {
3452 /*
3453 * Before anything else lets make sure we will not be interrupted
3454 * by the hardware. */
3455 scic_controller_disable_interrupts(this_controller);
3456
3457 /* Enable the port task scheduler */
3458 scic_sds_controller_enable_port_task_scheduler(this_controller);
3459
3460 /* Assign all the task entries to this controller physical function */
3461 scic_sds_controller_assign_task_entries(this_controller);
3462
3463 /* Now initialze the completion queue */
3464 scic_sds_controller_initialize_completion_queue(this_controller);
3465
3466 /* Initialize the unsolicited frame queue for use */
3467 scic_sds_controller_initialize_unsolicited_frame_queue(this_controller);
3468 }
3469
3470 if (SCI_SUCCESS == result) {
3471 scic_sds_controller_start_next_phy(this_controller);
3472
3473 scic_cb_timer_start(this_controller,
3474 this_controller->timeout_timer,
3475 timeout);
3476
3477 sci_base_state_machine_change_state(
3478 scic_sds_controller_get_base_state_machine(this_controller),
3479 SCI_BASE_CONTROLLER_STATE_STARTING
3480 );
3481 }
3482
3483 return result;
3484}
3485
3486/*
3487 * *****************************************************************************
3488 * * INITIALIZED STATE HANDLERS
3489 * ***************************************************************************** */
3490
3491/**
3492 *
3493 * @controller: This is struct scic_sds_controller which receives the link up
3494 * notification.
3495 * @port: This is struct scic_sds_port with which the phy is associated.
3496 * @phy: This is the struct scic_sds_phy which has gone link up.
3497 *
3498 * This method is called when the struct scic_sds_controller is in the starting state
3499 * link up handler is called. This method will perform the following: - Stop
3500 * the phy timer - Start the next phy - Report the link up condition to the
3501 * port object none
3502 */
3503static void scic_sds_controller_starting_state_link_up_handler(
3504 struct scic_sds_controller *this_controller,
3505 struct scic_sds_port *port,
3506 struct scic_sds_phy *phy)
3507{
3508 scic_sds_controller_phy_timer_stop(this_controller);
3509
3510 this_controller->port_agent.link_up_handler(
3511 this_controller, &this_controller->port_agent, port, phy
3512 );
3513 /* scic_sds_port_link_up(port, phy); */
3514
3515 scic_sds_controller_start_next_phy(this_controller);
3516}
3517
3518/**
3519 *
3520 * @controller: This is struct scic_sds_controller which receives the link down
3521 * notification.
3522 * @port: This is struct scic_sds_port with which the phy is associated.
3523 * @phy: This is the struct scic_sds_phy which has gone link down.
3524 *
3525 * This method is called when the struct scic_sds_controller is in the starting state
3526 * link down handler is called. - Report the link down condition to the port
3527 * object none
3528 */
3529static void scic_sds_controller_starting_state_link_down_handler(
3530 struct scic_sds_controller *this_controller,
3531 struct scic_sds_port *port,
3532 struct scic_sds_phy *phy)
3533{
3534 this_controller->port_agent.link_down_handler(
3535 this_controller, &this_controller->port_agent, port, phy
3536 );
3537 /* scic_sds_port_link_down(port, phy); */
3538}
3539
3540/*
3541 * *****************************************************************************
3542 * * READY STATE HANDLERS
3543 * ***************************************************************************** */
3544
3545/**
3546 *
3547 * @controller: The struct sci_base_controller object which is cast into a
3548 * struct scic_sds_controller object.
3549 * @timeout: The timeout for when the stop operation should report a failure.
3550 *
3551 * This method is called when the struct scic_sds_controller is in the ready state
3552 * stop handler is called. - Start the timeout timer - Transition to
3553 * SCI_BASE_CONTROLLER_STATE_STOPPING. enum sci_status SCI_SUCCESS
3554 */
3555static enum sci_status scic_sds_controller_ready_state_stop_handler(
3556 struct sci_base_controller *controller,
3557 u32 timeout)
3558{
3559 struct scic_sds_controller *this_controller;
3560
3561 this_controller = (struct scic_sds_controller *)controller;
3562
3563 scic_cb_timer_start(this_controller,
3564 this_controller->timeout_timer,
3565 timeout);
3566
3567 sci_base_state_machine_change_state(
3568 scic_sds_controller_get_base_state_machine(this_controller),
3569 SCI_BASE_CONTROLLER_STATE_STOPPING
3570 );
3571
3572 return SCI_SUCCESS;
3573}
3574
3575/**
3576 *
3577 * @controller: This is struct sci_base_controller object which is cast into a
3578 * struct scic_sds_controller object.
3579 * @remote_device: This is struct sci_base_remote_device which is cast to a
3580 * struct scic_sds_remote_device object.
3581 * @io_request: This is the struct sci_base_request which is cast to a
3582 * SCIC_SDS_IO_REQUEST object.
3583 * @io_tag: This is the IO tag to be assigned to the IO request or
3584 * SCI_CONTROLLER_INVALID_IO_TAG.
3585 *
3586 * This method is called when the struct scic_sds_controller is in the ready state and
3587 * the start io handler is called. - Start the io request on the remote device
3588 * - if successful - assign the io_request to the io_request_table - post the
3589 * request to the hardware enum sci_status SCI_SUCCESS if the start io operation
3590 * succeeds SCI_FAILURE_INSUFFICIENT_RESOURCES if the IO tag could not be
3591 * allocated for the io request. SCI_FAILURE_INVALID_STATE if one or more
3592 * objects are not in a valid state to accept io requests. How does the io_tag
3593 * parameter get assigned to the io request?
3594 */
3595static enum sci_status scic_sds_controller_ready_state_start_io_handler(
3596 struct sci_base_controller *controller,
3597 struct sci_base_remote_device *remote_device,
3598 struct sci_base_request *io_request,
3599 u16 io_tag)
3600{
3601 enum sci_status status;
3602
3603 struct scic_sds_controller *this_controller;
3604 struct scic_sds_request *the_request;
3605 struct scic_sds_remote_device *the_device;
3606
3607 this_controller = (struct scic_sds_controller *)controller;
3608 the_request = (struct scic_sds_request *)io_request;
3609 the_device = (struct scic_sds_remote_device *)remote_device;
3610
3611 status = scic_sds_remote_device_start_io(this_controller, the_device, the_request);
3612
3613 if (status == SCI_SUCCESS) {
3614 this_controller->io_request_table[
3615 scic_sds_io_tag_get_index(the_request->io_tag)] = the_request;
3616
3617 scic_sds_controller_post_request(
3618 this_controller,
3619 scic_sds_request_get_post_context(the_request)
3620 );
3621 }
3622
3623 return status;
3624}
3625
3626/**
3627 *
3628 * @controller: This is struct sci_base_controller object which is cast into a
3629 * struct scic_sds_controller object.
3630 * @remote_device: This is struct sci_base_remote_device which is cast to a
3631 * struct scic_sds_remote_device object.
3632 * @io_request: This is the struct sci_base_request which is cast to a
3633 * SCIC_SDS_IO_REQUEST object.
3634 *
3635 * This method is called when the struct scic_sds_controller is in the ready state and
3636 * the complete io handler is called. - Complete the io request on the remote
3637 * device - if successful - remove the io_request to the io_request_table
3638 * enum sci_status SCI_SUCCESS if the start io operation succeeds
3639 * SCI_FAILURE_INVALID_STATE if one or more objects are not in a valid state to
3640 * accept io requests.
3641 */
3642static enum sci_status scic_sds_controller_ready_state_complete_io_handler(
3643 struct sci_base_controller *controller,
3644 struct sci_base_remote_device *remote_device,
3645 struct sci_base_request *io_request)
3646{
3647 u16 index;
3648 enum sci_status status;
3649 struct scic_sds_controller *this_controller;
3650 struct scic_sds_request *the_request;
3651 struct scic_sds_remote_device *the_device;
3652
3653 this_controller = (struct scic_sds_controller *)controller;
3654 the_request = (struct scic_sds_request *)io_request;
3655 the_device = (struct scic_sds_remote_device *)remote_device;
3656
3657 status = scic_sds_remote_device_complete_io(
3658 this_controller, the_device, the_request);
3659
3660 if (status == SCI_SUCCESS) {
3661 index = scic_sds_io_tag_get_index(the_request->io_tag);
3662 this_controller->io_request_table[index] = SCI_INVALID_HANDLE;
3663 }
3664
3665 return status;
3666}
3667
3668/**
3669 *
3670 * @controller: This is struct sci_base_controller object which is cast into a
3671 * struct scic_sds_controller object.
3672 * @remote_device: This is struct sci_base_remote_device which is cast to a
3673 * struct scic_sds_remote_device object.
3674 * @io_request: This is the struct sci_base_request which is cast to a
3675 * SCIC_SDS_IO_REQUEST object.
3676 *
3677 * This method is called when the struct scic_sds_controller is in the ready state and
3678 * the continue io handler is called. enum sci_status
3679 */
3680static enum sci_status scic_sds_controller_ready_state_continue_io_handler(
3681 struct sci_base_controller *controller,
3682 struct sci_base_remote_device *remote_device,
3683 struct sci_base_request *io_request)
3684{
3685 struct scic_sds_controller *this_controller;
3686 struct scic_sds_request *the_request;
3687
3688 the_request = (struct scic_sds_request *)io_request;
3689 this_controller = (struct scic_sds_controller *)controller;
3690
3691 this_controller->io_request_table[
3692 scic_sds_io_tag_get_index(the_request->io_tag)] = the_request;
3693
3694 scic_sds_controller_post_request(
3695 this_controller,
3696 scic_sds_request_get_post_context(the_request)
3697 );
3698
3699 return SCI_SUCCESS;
3700}
3701
3702/**
3703 *
3704 * @controller: This is struct sci_base_controller object which is cast into a
3705 * struct scic_sds_controller object.
3706 * @remote_device: This is struct sci_base_remote_device which is cast to a
3707 * struct scic_sds_remote_device object.
3708 * @io_request: This is the struct sci_base_request which is cast to a
3709 * SCIC_SDS_IO_REQUEST object.
3710 * @task_tag: This is the task tag to be assigned to the task request or
3711 * SCI_CONTROLLER_INVALID_IO_TAG.
3712 *
3713 * This method is called when the struct scic_sds_controller is in the ready state and
3714 * the start task handler is called. - The remote device is requested to start
3715 * the task request - if successful - assign the task to the io_request_table -
3716 * post the request to the SCU hardware enum sci_status SCI_SUCCESS if the start io
3717 * operation succeeds SCI_FAILURE_INSUFFICIENT_RESOURCES if the IO tag could
3718 * not be allocated for the io request. SCI_FAILURE_INVALID_STATE if one or
3719 * more objects are not in a valid state to accept io requests. How does the io
3720 * tag get assigned in this code path?
3721 */
3722static enum sci_status scic_sds_controller_ready_state_start_task_handler(
3723 struct sci_base_controller *controller,
3724 struct sci_base_remote_device *remote_device,
3725 struct sci_base_request *io_request,
3726 u16 task_tag)
3727{
3728 struct scic_sds_controller *this_controller = (struct scic_sds_controller *)
3729 controller;
3730 struct scic_sds_request *the_request = (struct scic_sds_request *)
3731 io_request;
3732 struct scic_sds_remote_device *the_device = (struct scic_sds_remote_device *)
3733 remote_device;
3734 enum sci_status status;
3735
3736 status = scic_sds_remote_device_start_task(
3737 this_controller, the_device, the_request
3738 );
3739
3740 if (status == SCI_SUCCESS) {
3741 this_controller->io_request_table[
3742 scic_sds_io_tag_get_index(the_request->io_tag)] = the_request;
3743
3744 scic_sds_controller_post_request(
3745 this_controller,
3746 scic_sds_request_get_post_context(the_request)
3747 );
3748 } else if (status == SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS) {
3749 this_controller->io_request_table[
3750 scic_sds_io_tag_get_index(the_request->io_tag)] = the_request;
3751
3752 /*
3753 * We will let framework know this task request started successfully,
3754 * although core is still woring on starting the request (to post tc when
3755 * RNC is resumed.) */
3756 status = SCI_SUCCESS;
3757 }
3758 return status;
3759}
3760
3761/**
3762 *
3763 * @controller: This is struct sci_base_controller object which is cast into a
3764 * struct scic_sds_controller object.
3765 * @remote_device: This is struct sci_base_remote_device which is cast to a
3766 * struct scic_sds_remote_device object.
3767 * @io_request: This is the struct sci_base_request which is cast to a
3768 * SCIC_SDS_IO_REQUEST object.
3769 *
3770 * This method is called when the struct scic_sds_controller is in the ready state and
3771 * the terminate request handler is called. - call the io request terminate
3772 * function - if successful - post the terminate request to the SCU hardware
3773 * enum sci_status SCI_SUCCESS if the start io operation succeeds
3774 * SCI_FAILURE_INVALID_STATE if one or more objects are not in a valid state to
3775 * accept io requests.
3776 */
3777static enum sci_status scic_sds_controller_ready_state_terminate_request_handler(
3778 struct sci_base_controller *controller,
3779 struct sci_base_remote_device *remote_device,
3780 struct sci_base_request *io_request)
3781{
3782 struct scic_sds_controller *this_controller = (struct scic_sds_controller *)
3783 controller;
3784 struct scic_sds_request *the_request = (struct scic_sds_request *)
3785 io_request;
3786 enum sci_status status;
3787
3788 status = scic_sds_io_request_terminate(the_request);
3789 if (status == SCI_SUCCESS) {
3790 /*
3791 * Utilize the original post context command and or in the POST_TC_ABORT
3792 * request sub-type. */
3793 scic_sds_controller_post_request(
3794 this_controller,
3795 scic_sds_request_get_post_context(the_request)
3796 | SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT
3797 );
3798 }
3799
3800 return status;
3801}
3802
3803/**
3804 *
3805 * @controller: This is struct scic_sds_controller which receives the link up
3806 * notification.
3807 * @port: This is struct scic_sds_port with which the phy is associated.
3808 * @phy: This is the struct scic_sds_phy which has gone link up.
3809 *
3810 * This method is called when the struct scic_sds_controller is in the starting state
3811 * link up handler is called. This method will perform the following: - Stop
3812 * the phy timer - Start the next phy - Report the link up condition to the
3813 * port object none
3814 */
3815static void scic_sds_controller_ready_state_link_up_handler(
3816 struct scic_sds_controller *this_controller,
3817 struct scic_sds_port *port,
3818 struct scic_sds_phy *phy)
3819{
3820 this_controller->port_agent.link_up_handler(
3821 this_controller, &this_controller->port_agent, port, phy
3822 );
3823}
3824
3825/**
3826 *
3827 * @controller: This is struct scic_sds_controller which receives the link down
3828 * notification.
3829 * @port: This is struct scic_sds_port with which the phy is associated.
3830 * @phy: This is the struct scic_sds_phy which has gone link down.
3831 *
3832 * This method is called when the struct scic_sds_controller is in the starting state
3833 * link down handler is called. - Report the link down condition to the port
3834 * object none
3835 */
3836static void scic_sds_controller_ready_state_link_down_handler(
3837 struct scic_sds_controller *this_controller,
3838 struct scic_sds_port *port,
3839 struct scic_sds_phy *phy)
3840{
3841 this_controller->port_agent.link_down_handler(
3842 this_controller, &this_controller->port_agent, port, phy
3843 );
3844}
3845
3846/*
3847 * *****************************************************************************
3848 * * STOPPING STATE HANDLERS
3849 * ***************************************************************************** */
3850
3851/**
3852 *
3853 * @controller: This is struct sci_base_controller object which is cast into a
3854 * struct scic_sds_controller object.
3855 * @remote_device: This is struct sci_base_remote_device which is cast to a
3856 * struct scic_sds_remote_device object.
3857 * @io_request: This is the struct sci_base_request which is cast to a
3858 * SCIC_SDS_IO_REQUEST object.
3859 *
3860 * This method is called when the struct scic_sds_controller is in a stopping state
3861 * and the complete io handler is called. - This function is not yet
3862 * implemented enum sci_status SCI_FAILURE
3863 */
3864static enum sci_status scic_sds_controller_stopping_state_complete_io_handler(
3865 struct sci_base_controller *controller,
3866 struct sci_base_remote_device *remote_device,
3867 struct sci_base_request *io_request)
3868{
3869 struct scic_sds_controller *this_controller;
3870
3871 this_controller = (struct scic_sds_controller *)controller;
3872
3873 /* / @todo Implement this function */
3874 return SCI_FAILURE;
3875}
3876
3877/**
3878 *
3879 * @controller: This is struct sci_base_controller object which is cast into a
3880 * struct scic_sds_controller object.
3881 * @remote_device: This is struct sci_base_remote_device which is cast to a
3882 * struct scic_sds_remote_device object.
3883 * @io_request: This is the struct sci_base_request which is cast to a
3884 * SCIC_SDS_IO_REQUEST object.
3885 *
3886 * This method is called when the struct scic_sds_controller is in a stopping state
3887 * and the complete task handler is called. - This function is not yet
3888 * implemented enum sci_status SCI_FAILURE
3889 */
3890
3891/*
3892 * *****************************************************************************
3893 * * STOPPED STATE HANDLERS
3894 * ***************************************************************************** */
3895
3896/*
3897 * *****************************************************************************
3898 * * FAILED STATE HANDLERS
3899 * ***************************************************************************** */
3900
3901const struct scic_sds_controller_state_handler scic_sds_controller_state_handler_table[] = {
3902 [SCI_BASE_CONTROLLER_STATE_INITIAL] = {
3903 .base.start_io = scic_sds_controller_default_start_operation_handler,
3904 .base.complete_io = scic_sds_controller_default_request_handler,
3905 .base.continue_io = scic_sds_controller_default_request_handler,
3906 .terminate_request = scic_sds_controller_default_request_handler,
3907 },
3908 [SCI_BASE_CONTROLLER_STATE_RESET] = {
3909 .base.initialize = scic_sds_controller_reset_state_initialize_handler,
3910 .base.start_io = scic_sds_controller_default_start_operation_handler,
3911 .base.complete_io = scic_sds_controller_default_request_handler,
3912 .base.continue_io = scic_sds_controller_default_request_handler,
3913 .terminate_request = scic_sds_controller_default_request_handler,
3914 },
3915 [SCI_BASE_CONTROLLER_STATE_INITIALIZING] = {
3916 .base.start_io = scic_sds_controller_default_start_operation_handler,
3917 .base.complete_io = scic_sds_controller_default_request_handler,
3918 .base.continue_io = scic_sds_controller_default_request_handler,
3919 .terminate_request = scic_sds_controller_default_request_handler,
3920 },
3921 [SCI_BASE_CONTROLLER_STATE_INITIALIZED] = {
3922 .base.start = scic_sds_controller_initialized_state_start_handler,
3923 .base.start_io = scic_sds_controller_default_start_operation_handler,
3924 .base.complete_io = scic_sds_controller_default_request_handler,
3925 .base.continue_io = scic_sds_controller_default_request_handler,
3926 .terminate_request = scic_sds_controller_default_request_handler,
3927 },
3928 [SCI_BASE_CONTROLLER_STATE_STARTING] = {
3929 .base.start_io = scic_sds_controller_default_start_operation_handler,
3930 .base.complete_io = scic_sds_controller_default_request_handler,
3931 .base.continue_io = scic_sds_controller_default_request_handler,
3932 .terminate_request = scic_sds_controller_default_request_handler,
3933 .link_up = scic_sds_controller_starting_state_link_up_handler,
3934 .link_down = scic_sds_controller_starting_state_link_down_handler
3935 },
3936 [SCI_BASE_CONTROLLER_STATE_READY] = {
3937 .base.stop = scic_sds_controller_ready_state_stop_handler,
3938 .base.reset = scic_sds_controller_general_reset_handler,
3939 .base.start_io = scic_sds_controller_ready_state_start_io_handler,
3940 .base.complete_io = scic_sds_controller_ready_state_complete_io_handler,
3941 .base.continue_io = scic_sds_controller_ready_state_continue_io_handler,
3942 .base.start_task = scic_sds_controller_ready_state_start_task_handler,
3943 .base.complete_task = scic_sds_controller_ready_state_complete_io_handler,
3944 .terminate_request = scic_sds_controller_ready_state_terminate_request_handler,
3945 .link_up = scic_sds_controller_ready_state_link_up_handler,
3946 .link_down = scic_sds_controller_ready_state_link_down_handler
3947 },
3948 [SCI_BASE_CONTROLLER_STATE_RESETTING] = {
3949 .base.start_io = scic_sds_controller_default_start_operation_handler,
3950 .base.complete_io = scic_sds_controller_default_request_handler,
3951 .base.continue_io = scic_sds_controller_default_request_handler,
3952 .terminate_request = scic_sds_controller_default_request_handler,
3953 },
3954 [SCI_BASE_CONTROLLER_STATE_STOPPING] = {
3955 .base.start_io = scic_sds_controller_default_start_operation_handler,
3956 .base.complete_io = scic_sds_controller_stopping_state_complete_io_handler,
3957 .base.continue_io = scic_sds_controller_default_request_handler,
3958 .terminate_request = scic_sds_controller_default_request_handler,
3959 },
3960 [SCI_BASE_CONTROLLER_STATE_STOPPED] = {
3961 .base.reset = scic_sds_controller_general_reset_handler,
3962 .base.start_io = scic_sds_controller_default_start_operation_handler,
3963 .base.complete_io = scic_sds_controller_default_request_handler,
3964 .base.continue_io = scic_sds_controller_default_request_handler,
3965 .terminate_request = scic_sds_controller_default_request_handler,
3966 },
3967 [SCI_BASE_CONTROLLER_STATE_FAILED] = {
3968 .base.reset = scic_sds_controller_general_reset_handler,
3969 .base.start_io = scic_sds_controller_default_start_operation_handler,
3970 .base.complete_io = scic_sds_controller_default_request_handler,
3971 .base.continue_io = scic_sds_controller_default_request_handler,
3972 .terminate_request = scic_sds_controller_default_request_handler,
3973 },
3974};
3975
3976/**
3977 *
3978 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_controller
3979 * object.
3980 *
3981 * This method implements the actions taken by the struct scic_sds_controller on entry
3982 * to the SCI_BASE_CONTROLLER_STATE_INITIAL. - Set the state handlers to the
3983 * controllers initial state. none This function should initialze the
3984 * controller object.
3985 */
3986static void scic_sds_controller_initial_state_enter(
3987 struct sci_base_object *object)
3988{
3989 struct scic_sds_controller *this_controller;
3990
3991 this_controller = (struct scic_sds_controller *)object;
3992
3993 sci_base_state_machine_change_state(
3994 &this_controller->parent.state_machine, SCI_BASE_CONTROLLER_STATE_RESET);
3995}
3996
3997/**
3998 *
3999 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_controller
4000 * object.
4001 *
4002 * This method implements the actions taken by the struct scic_sds_controller on exit
4003 * from the SCI_BASE_CONTROLLER_STATE_STARTING. - This function stops the
4004 * controller starting timeout timer. none
4005 */
4006static void scic_sds_controller_starting_state_exit(
4007 struct sci_base_object *object)
4008{
4009 struct scic_sds_controller *scic = (struct scic_sds_controller *)object;
4010
4011 scic_cb_timer_stop(scic, scic->timeout_timer);
4012}
4013
4014/**
4015 *
4016 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_controller
4017 * object.
4018 *
4019 * This method implements the actions taken by the struct scic_sds_controller on entry
4020 * to the SCI_BASE_CONTROLLER_STATE_READY. - Set the state handlers to the
4021 * controllers ready state. none
4022 */
4023static void scic_sds_controller_ready_state_enter(
4024 struct sci_base_object *object)
4025{
4026 struct scic_sds_controller *this_controller;
4027
4028 this_controller = (struct scic_sds_controller *)object;
4029
4030 /* set the default interrupt coalescence number and timeout value. */
4031 scic_controller_set_interrupt_coalescence(
4032 this_controller, 0x10, 250);
4033}
4034
4035/**
4036 *
4037 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_controller
4038 * object.
4039 *
4040 * This method implements the actions taken by the struct scic_sds_controller on exit
4041 * from the SCI_BASE_CONTROLLER_STATE_READY. - This function does nothing. none
4042 */
4043static void scic_sds_controller_ready_state_exit(
4044 struct sci_base_object *object)
4045{
4046 struct scic_sds_controller *this_controller;
4047
4048 this_controller = (struct scic_sds_controller *)object;
4049
4050 /* disable interrupt coalescence. */
4051 scic_controller_set_interrupt_coalescence(this_controller, 0, 0);
4052}
4053
4054/**
4055 *
4056 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_controller
4057 * object.
4058 *
4059 * This method implements the actions taken by the struct scic_sds_controller on entry
4060 * to the SCI_BASE_CONTROLLER_STATE_READY. - Set the state handlers to the
4061 * controllers ready state. - Stop the phys on this controller - Stop the ports
4062 * on this controller - Stop all of the remote devices on this controller none
4063 */
4064static void scic_sds_controller_stopping_state_enter(
4065 struct sci_base_object *object)
4066{
4067 struct scic_sds_controller *this_controller;
4068
4069 this_controller = (struct scic_sds_controller *)object;
4070
4071 /* Stop all of the components for this controller */
4072 scic_sds_controller_stop_phys(this_controller);
4073 scic_sds_controller_stop_ports(this_controller);
4074 scic_sds_controller_stop_devices(this_controller);
4075}
4076
4077/**
4078 *
4079 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_controller
4080 * object.
4081 *
4082 * This method implements the actions taken by the struct scic_sds_controller on exit
4083 * from the SCI_BASE_CONTROLLER_STATE_STOPPING. - This function stops the
4084 * controller stopping timeout timer. none
4085 */
4086static void scic_sds_controller_stopping_state_exit(
4087 struct sci_base_object *object)
4088{
4089 struct scic_sds_controller *this_controller;
4090
4091 this_controller = (struct scic_sds_controller *)object;
4092
4093 scic_cb_timer_stop(this_controller, this_controller->timeout_timer);
4094}
4095
4096/**
4097 *
4098 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_controller
4099 * object.
4100 *
4101 * This method implements the actions taken by the struct scic_sds_controller on entry
4102 * to the SCI_BASE_CONTROLLER_STATE_RESETTING. - Set the state handlers to the
4103 * controllers resetting state. - Write to the SCU hardware reset register to
4104 * force a reset - Transition to the SCI_BASE_CONTROLLER_STATE_RESET none
4105 */
4106static void scic_sds_controller_resetting_state_enter(
4107 struct sci_base_object *object)
4108{
4109 struct scic_sds_controller *this_controller;
4110
4111 this_controller = (struct scic_sds_controller *)object;
4112
4113 scic_sds_controller_reset_hardware(this_controller);
4114
4115 sci_base_state_machine_change_state(
4116 scic_sds_controller_get_base_state_machine(this_controller),
4117 SCI_BASE_CONTROLLER_STATE_RESET
4118 );
4119}
4120
4121/* --------------------------------------------------------------------------- */
4122
4123const struct sci_base_state scic_sds_controller_state_table[] = {
4124 [SCI_BASE_CONTROLLER_STATE_INITIAL] = {
4125 .enter_state = scic_sds_controller_initial_state_enter,
4126 },
4127 [SCI_BASE_CONTROLLER_STATE_RESET] = {},
4128 [SCI_BASE_CONTROLLER_STATE_INITIALIZING] = {},
4129 [SCI_BASE_CONTROLLER_STATE_INITIALIZED] = {},
4130 [SCI_BASE_CONTROLLER_STATE_STARTING] = {
4131 .exit_state = scic_sds_controller_starting_state_exit,
4132 },
4133 [SCI_BASE_CONTROLLER_STATE_READY] = {
4134 .enter_state = scic_sds_controller_ready_state_enter,
4135 .exit_state = scic_sds_controller_ready_state_exit,
4136 },
4137 [SCI_BASE_CONTROLLER_STATE_RESETTING] = {
4138 .enter_state = scic_sds_controller_resetting_state_enter,
4139 },
4140 [SCI_BASE_CONTROLLER_STATE_STOPPING] = {
4141 .enter_state = scic_sds_controller_stopping_state_enter,
4142 .exit_state = scic_sds_controller_stopping_state_exit,
4143 },
4144 [SCI_BASE_CONTROLLER_STATE_STOPPED] = {},
4145 [SCI_BASE_CONTROLLER_STATE_FAILED] = {}
4146};
4147
diff --git a/drivers/scsi/isci/core/scic_sds_controller.h b/drivers/scsi/isci/core/scic_sds_controller.h
new file mode 100644
index 000000000000..afa45f9874a4
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_controller.h
@@ -0,0 +1,706 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_SDS_CONTROLLER_H_
57#define _SCIC_SDS_CONTROLLER_H_
58
59/**
60 * This file contains the structures, constants and prototypes used for the
61 * core controller object.
62 *
63 *
64 */
65
66#include "sci_pool.h"
67#include "sci_controller_constants.h"
68#include "sci_memory_descriptor_list.h"
69#include "sci_base_controller.h"
70#include "scic_config_parameters.h"
71#include "scic_sds_port.h"
72#include "scic_sds_phy.h"
73#include "scic_sds_remote_node_table.h"
74#include "scu_registers.h"
75#include "scu_constants.h"
76#include "scu_remote_node_context.h"
77#include "scu_task_context.h"
78#include "scu_unsolicited_frame.h"
79#include "scic_sds_unsolicited_frame_control.h"
80#include "scic_sds_port_configuration_agent.h"
81#include "scic_sds_pci.h"
82
83struct scic_sds_remote_device;
84struct scic_sds_request;
85struct scic_sds_controller;
86
87
88#define SCU_COMPLETION_RAM_ALIGNMENT (64)
89
90/**
91 * enum SCIC_SDS_CONTROLLER_MEMORY_DESCRIPTORS -
92 *
93 * This enumeration depects the types of MDEs that are going to be created for
94 * the controller object.
95 */
96enum SCIC_SDS_CONTROLLER_MEMORY_DESCRIPTORS {
97 /**
98 * Completion queue MDE entry
99 */
100 SCU_MDE_COMPLETION_QUEUE,
101
102 /**
103 * Remote node context MDE entry
104 */
105 SCU_MDE_REMOTE_NODE_CONTEXT,
106
107 /**
108 * Task context MDE entry
109 */
110 SCU_MDE_TASK_CONTEXT,
111
112 /**
113 * Unsolicited frame buffer MDE entrys this is the start of the unsolicited
114 * frame buffer entries.
115 */
116 SCU_MDE_UF_BUFFER,
117
118 SCU_MAX_MDES
119};
120
121/**
122 *
123 *
124 * Allowed PORT configuration modes APC Automatic PORT configuration mode is
125 * defined by the OEM configuration parameters providing no PHY_MASK parameters
126 * for any PORT. i.e. There are no phys assigned to any of the ports at start.
127 * MPC Manual PORT configuration mode is defined by the OEM configuration
128 * parameters providing a PHY_MASK value for any PORT. It is assumed that any
129 * PORT with no PHY_MASK is an invalid port and not all PHYs must be assigned.
130 * A PORT_PHY mask that assigns just a single PHY to a port and no other PHYs
131 * being assigned is sufficient to declare manual PORT configuration.
132 */
133enum SCIC_PORT_CONFIGURATION_MODE {
134 SCIC_PORT_MANUAL_CONFIGURATION_MODE,
135 SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE
136};
137
138/**
139 * struct scic_power_control -
140 *
141 * This structure defines the fields for managing power control for direct
142 * attached disk devices.
143 */
144struct scic_power_control {
145 /**
146 * This field is set when the power control timer is running and cleared when
147 * it is not.
148 */
149 bool timer_started;
150
151 /**
152 * This field is the handle to the driver timer object. This timer is used to
153 * control when the directed attached disks can consume power.
154 */
155 void *timer;
156
157 /**
158 * This field is used to keep track of how many phys are put into the
159 * requesters field.
160 */
161 u8 phys_waiting;
162
163 /**
164 * This field is an array of phys that we are waiting on. The phys are direct
165 * mapped into requesters via struct scic_sds_phy.phy_index
166 */
167 struct scic_sds_phy *requesters[SCI_MAX_PHYS];
168
169};
170
171/**
172 * struct scic_sds_controller -
173 *
174 * This structure represents the SCU contoller object.
175 */
176struct scic_sds_controller {
177 /**
178 * The struct sci_base_controller is the parent object for the struct scic_sds_controller
179 * object.
180 */
181 struct sci_base_controller parent;
182
183 /**
184 * This field is the driver timer object handler used to time the controller
185 * object start and stop requests.
186 */
187 void *timeout_timer;
188
189 /**
190 * This field contains the user parameters to be utilized for this
191 * core controller object.
192 */
193 union scic_user_parameters user_parameters;
194
195 /**
196 * This field contains the OEM parameters to be utilized for this
197 * core controller object.
198 */
199 union scic_oem_parameters oem_parameters;
200
201 /**
202 * This field contains the port configuration agent for this controller.
203 */
204 struct scic_sds_port_configuration_agent port_agent;
205
206 /**
207 * This field is the array of port objects that are controlled by this
208 * controller object. There is one dummy port object also contained within
209 * this controller object.
210 */
211 struct scic_sds_port port_table[SCI_MAX_PORTS + 1];
212
213 /**
214 * This field is the array of phy objects that are controlled by this
215 * controller object.
216 */
217 struct scic_sds_phy phy_table[SCI_MAX_PHYS];
218
219 /**
220 * This field is the array of device objects that are currently constructed
221 * for this controller object. This table is used as a fast lookup of device
222 * objects that need to handle device completion notifications from the
223 * hardware. The table is RNi based.
224 */
225 struct scic_sds_remote_device *device_table[SCI_MAX_REMOTE_DEVICES];
226
227 /**
228 * This field is the array of IO request objects that are currently active for
229 * this controller object. This table is used as a fast lookup of the io
230 * request object that need to handle completion queue notifications. The
231 * table is TCi based.
232 */
233 struct scic_sds_request *io_request_table[SCI_MAX_IO_REQUESTS];
234
235 /**
236 * This field is the free RNi data structure
237 */
238 struct scic_remote_node_table available_remote_nodes;
239
240 /**
241 * This field is the TCi pool used to manage the task context index.
242 */
243 SCI_POOL_CREATE(tci_pool, u16, SCI_MAX_IO_REQUESTS);
244
245 /**
246 * This filed is the struct scic_power_control data used to controll when direct
247 * attached devices can consume power.
248 */
249 struct scic_power_control power_control;
250
251 /**
252 * This field is the array of sequence values for the IO Tag fields. Even
253 * though only 4 bits of the field is used for the sequence the sequence is 16
254 * bits in size so the sequence can be bitwise or'd with the TCi to build the
255 * IO Tag value.
256 */
257 u16 io_request_sequence[SCI_MAX_IO_REQUESTS];
258
259 /**
260 * This field in the array of sequence values for the RNi. These are used
261 * to control io request build to io request start operations. The sequence
262 * value is recorded into an io request when it is built and is checked on
263 * the io request start operation to make sure that there was not a device
264 * hot plug between the build and start operation.
265 */
266 u8 remote_device_sequence[SCI_MAX_REMOTE_DEVICES];
267
268 /**
269 * This field is a pointer to the memory allocated by the driver for the task
270 * context table. This data is shared between the hardware and software.
271 */
272 struct scu_task_context *task_context_table;
273
274 /**
275 * This field is a pointer to the memory allocated by the driver for the
276 * remote node context table. This table is shared between the hardware and
277 * software.
278 */
279 union scu_remote_node_context *remote_node_context_table;
280
281 /**
282 * This field is the array of physical memory requiremets for this controller
283 * object.
284 */
285 struct sci_physical_memory_descriptor memory_descriptors[SCU_MAX_MDES];
286
287 /**
288 * This field is a pointer to the completion queue. This memory is
289 * written to by the hardware and read by the software.
290 */
291 u32 *completion_queue;
292
293 /**
294 * This field is the software copy of the completion queue get pointer. The
295 * controller object writes this value to the hardware after processing the
296 * completion entries.
297 */
298 u32 completion_queue_get;
299
300 /**
301 * This field is the minimum of the number of hardware supported port entries
302 * and the software requested port entries.
303 */
304 u32 logical_port_entries;
305
306 /**
307 * This field is the minimum number of hardware supported completion queue
308 * entries and the software requested completion queue entries.
309 */
310 u32 completion_queue_entries;
311
312 /**
313 * This field is the minimum number of hardware supported event entries and
314 * the software requested event entries.
315 */
316 u32 completion_event_entries;
317
318 /**
319 * This field is the minimum number of devices supported by the hardware and
320 * the number of devices requested by the software.
321 */
322 u32 remote_node_entries;
323
324 /**
325 * This field is the minimum number of IO requests supported by the hardware
326 * and the number of IO requests requested by the software.
327 */
328 u32 task_context_entries;
329
330 /**
331 * This object contains all of the unsolicited frame specific
332 * data utilized by the core controller.
333 */
334 struct scic_sds_unsolicited_frame_control uf_control;
335
336 /**
337 * This field records the fact that the controller has encountered a fatal
338 * error and must be reset.
339 */
340 bool encountered_fatal_error;
341
342 /**
343 * This field specifies that the controller should ignore
344 * completion processing for non-fastpath events. This will
345 * cause the completions to be thrown away.
346 */
347 bool restrict_completions;
348
349 /* Phy Startup Data */
350 /**
351 * This field is the driver timer handle for controller phy request startup.
352 * On controller start the controller will start each PHY individually in
353 * order of phy index.
354 */
355 void *phy_startup_timer;
356
357 /**
358 * This field is set when the phy_startup_timer is running and is cleared when
359 * the phy_startup_timer is stopped.
360 */
361 bool phy_startup_timer_pending;
362
363 /**
364 * This field is the index of the next phy start. It is initialized to 0 and
365 * increments for each phy index that is started.
366 */
367 u32 next_phy_to_start;
368
369 /**
370 * This field controlls the invalid link up notifications to the SCI_USER. If
371 * an invalid_link_up notification is reported a bit for the PHY index is set
372 * so further notifications are not made. Once the PHY object reports link up
373 * and is made part of a port then this bit for the PHY index is cleared.
374 */
375 u8 invalid_phy_mask;
376
377 /*
378 * This field saves the current interrupt coalescing number of the controller.
379 */
380 u16 interrupt_coalesce_number;
381
382 /*
383 * This field saves the current interrupt coalescing timeout value in microseconds.
384 */
385 u32 interrupt_coalesce_timeout;
386
387 /**
388 * This field is a pointer to the memory mapped register space for the
389 * struct smu_registers.
390 */
391 struct smu_registers __iomem *smu_registers;
392
393 /**
394 * This field is a pointer to the memory mapped register space for the
395 * struct scu_registers.
396 */
397 struct scu_registers __iomem *scu_registers;
398
399};
400
401typedef void (*scic_sds_controller_phy_handler_t)(struct scic_sds_controller *,
402 struct scic_sds_port *,
403 struct scic_sds_phy *);
404/**
405 * struct scic_sds_controller_state_handler -
406 *
407 * This structure contains the SDS core specific definition for the state
408 * handlers.
409 */
410struct scic_sds_controller_state_handler {
411 struct sci_base_controller_state_handler base;
412
413 sci_base_controller_request_handler_t terminate_request;
414 scic_sds_controller_phy_handler_t link_up;
415 scic_sds_controller_phy_handler_t link_down;
416};
417
418extern const struct scic_sds_controller_state_handler
419 scic_sds_controller_state_handler_table[];
420extern const struct sci_base_state scic_sds_controller_state_table[];
421
422/**
423 * INCREMENT_QUEUE_GET() -
424 *
425 * This macro will increment the specified index to and if the index wraps to 0
426 * it will toggel the cycle bit.
427 */
428#define INCREMENT_QUEUE_GET(index, cycle, entry_count, bit_toggle) \
429 { \
430 if ((index) + 1 == entry_count) { \
431 (index) = 0; \
432 (cycle) = (cycle) ^ (bit_toggle); \
433 } else { \
434 index = index + 1; \
435 } \
436 }
437
438/**
439 * scic_sds_controller_get_base_state_machine() -
440 *
441 * This is a helper macro that gets the base state machine for the controller
442 * object
443 */
444#define scic_sds_controller_get_base_state_machine(this_controller) \
445 (&(this_controller)->parent.state_machine)
446
447/**
448 * scic_sds_controller_get_port_configuration_agent() -
449 *
450 * This is a helper macro to get the port configuration agent from the
451 * controller object.
452 */
453#define scic_sds_controller_get_port_configuration_agent(controller) \
454 (&(controller)->port_agent)
455
456/**
457 * smu_register_write() -
458 *
459 * This macro writes to the smu_register for this controller
460 */
461#define smu_register_write(controller, reg, value) \
462 scic_sds_pci_write_smu_dword((controller), &(reg), (value))
463
464/**
465 * smu_register_read() -
466 *
467 * This macro reads the smu_register for this controller
468 */
469#define smu_register_read(controller, reg) \
470 scic_sds_pci_read_smu_dword((controller), &(reg))
471
472/**
473 * scu_register_write() -
474 *
475 * This mcaro writes the scu_register for this controller
476 */
477#define scu_register_write(controller, reg, value) \
478 scic_sds_pci_write_scu_dword((controller), &(reg), (value))
479
480/**
481 * scu_register_read() -
482 *
483 * This macro reads the scu_register for this controller
484 */
485#define scu_register_read(controller, reg) \
486 scic_sds_pci_read_scu_dword((controller), &(reg))
487
488/**
489 * scic_sds_controller_get_protocol_engine_group() -
490 *
491 * This macro returns the protocol engine group for this controller object.
492 * Presently we only support protocol engine group 0 so just return that
493 */
494#define scic_sds_controller_get_protocol_engine_group(controller) 0
495
496/**
497 * scic_sds_io_tag_construct() -
498 *
499 * This macro constructs an IO tag from the sequence and index values.
500 */
501#define scic_sds_io_tag_construct(sequence, task_index) \
502 ((sequence) << 12 | (task_index))
503
504/**
505 * scic_sds_io_tag_get_sequence() -
506 *
507 * This macro returns the IO sequence from the IO tag value.
508 */
509#define scic_sds_io_tag_get_sequence(io_tag) \
510 (((io_tag) & 0xF000) >> 12)
511
512/**
513 * scic_sds_io_tag_get_index() -
514 *
515 * This macro returns the TCi from the io tag value
516 */
517#define scic_sds_io_tag_get_index(io_tag) \
518 ((io_tag) & 0x0FFF)
519
520/**
521 * scic_sds_io_sequence_increment() -
522 *
523 * This is a helper macro to increment the io sequence count. We may find in
524 * the future that it will be faster to store the sequence count in such a way
525 * as we dont perform the shift operation to build io tag values so therefore
526 * need a way to incrment them correctly
527 */
528#define scic_sds_io_sequence_increment(value) \
529 ((value) = (((value) + 1) & 0x000F))
530
531#define scic_sds_remote_device_node_count(device) \
532 (\
533 (\
534 (device)->target_protocols.u.bits.attached_stp_target \
535 && ((device)->is_direct_attached != true) \
536 ) \
537 ? SCU_STP_REMOTE_NODE_COUNT : SCU_SSP_REMOTE_NODE_COUNT \
538 )
539
540/**
541 * scic_sds_controller_set_invalid_phy() -
542 *
543 * This macro will set the bit in the invalid phy mask for this controller
544 * object. This is used to control messages reported for invalid link up
545 * notifications.
546 */
547#define scic_sds_controller_set_invalid_phy(controller, phy) \
548 ((controller)->invalid_phy_mask |= (1 << (phy)->phy_index))
549
550/**
551 * scic_sds_controller_clear_invalid_phy() -
552 *
553 * This macro will clear the bit in the invalid phy mask for this controller
554 * object. This is used to control messages reported for invalid link up
555 * notifications.
556 */
557#define scic_sds_controller_clear_invalid_phy(controller, phy) \
558 ((controller)->invalid_phy_mask &= ~(1 << (phy)->phy_index))
559
560/* --------------------------------------------------------------------------- */
561
562u32 scic_sds_controller_get_object_size(void);
563
564/* --------------------------------------------------------------------------- */
565
566
567/* --------------------------------------------------------------------------- */
568
569enum SCIC_PORT_CONFIGURATION_MODE scic_sds_controller_get_port_configuration_mode(
570 struct scic_sds_controller *this_controller);
571
572/* --------------------------------------------------------------------------- */
573
574void scic_sds_controller_post_request(
575 struct scic_sds_controller *this_controller,
576 u32 request);
577
578/* --------------------------------------------------------------------------- */
579
580void scic_sds_controller_release_frame(
581 struct scic_sds_controller *this_controller,
582 u32 frame_index);
583
584void scic_sds_controller_copy_sata_response(
585 void *response_buffer,
586 void *frame_header,
587 void *frame_buffer);
588
589/* --------------------------------------------------------------------------- */
590
591enum sci_status scic_sds_controller_allocate_remote_node_context(
592 struct scic_sds_controller *this_controller,
593 struct scic_sds_remote_device *the_device,
594 u16 *node_id);
595
596void scic_sds_controller_free_remote_node_context(
597 struct scic_sds_controller *this_controller,
598 struct scic_sds_remote_device *the_device,
599 u16 node_id);
600
601union scu_remote_node_context *scic_sds_controller_get_remote_node_context_buffer(
602 struct scic_sds_controller *this_controller,
603 u16 node_id);
604
605/* --------------------------------------------------------------------------- */
606
607struct scic_sds_request *scic_sds_controller_get_io_request_from_tag(
608 struct scic_sds_controller *this_controller,
609 u16 io_tag);
610
611
612struct scu_task_context *scic_sds_controller_get_task_context_buffer(
613 struct scic_sds_controller *this_controller,
614 u16 io_tag);
615
616/*
617 * *****************************************************************************
618 * * CORE CONTROLLER POWER CONTROL METHODS
619 * ***************************************************************************** */
620
621
622void scic_sds_controller_power_control_queue_insert(
623 struct scic_sds_controller *this_controller,
624 struct scic_sds_phy *the_phy);
625
626void scic_sds_controller_power_control_queue_remove(
627 struct scic_sds_controller *this_controller,
628 struct scic_sds_phy *the_phy);
629
630/*
631 * *****************************************************************************
632 * * CORE CONTROLLER PHY MESSAGE PROCESSING
633 * ***************************************************************************** */
634
635void scic_sds_controller_link_up(
636 struct scic_sds_controller *this_controller,
637 struct scic_sds_port *the_port,
638 struct scic_sds_phy *the_phy);
639
640void scic_sds_controller_link_down(
641 struct scic_sds_controller *this_controller,
642 struct scic_sds_port *the_port,
643 struct scic_sds_phy *the_phy);
644
645/*
646 * *****************************************************************************
647 * * CORE CONTROLLER PRIVATE METHODS
648 * ***************************************************************************** */
649
650enum sci_status scic_sds_controller_validate_memory_descriptor_table(
651 struct scic_sds_controller *this_controller);
652
653void scic_sds_controller_ram_initialization(
654 struct scic_sds_controller *this_controller);
655
656void scic_sds_controller_assign_task_entries(
657 struct scic_sds_controller *this_controller);
658
659void scic_sds_controller_afe_initialization(
660 struct scic_sds_controller *this_controller);
661
662void scic_sds_controller_enable_port_task_scheduler(
663 struct scic_sds_controller *this_controller);
664
665void scic_sds_controller_initialize_completion_queue(
666 struct scic_sds_controller *this_controller);
667
668void scic_sds_controller_initialize_unsolicited_frame_queue(
669 struct scic_sds_controller *this_controller);
670
671void scic_sds_controller_phy_timer_stop(
672 struct scic_sds_controller *this_controller);
673
674enum sci_status scic_sds_controller_start_next_phy(
675 struct scic_sds_controller *this_controller);
676
677enum sci_status scic_sds_controller_stop_phys(
678 struct scic_sds_controller *this_controller);
679
680enum sci_status scic_sds_controller_stop_ports(
681 struct scic_sds_controller *this_controller);
682
683enum sci_status scic_sds_controller_stop_devices(
684 struct scic_sds_controller *this_controller);
685
686void scic_sds_controller_copy_task_context(
687 struct scic_sds_controller *this_controller,
688 struct scic_sds_request *this_request);
689
690void scic_sds_controller_timeout_handler(
691 struct scic_sds_controller *controller);
692
693void scic_sds_controller_initialize_power_control(
694 struct scic_sds_controller *this_controller);
695
696void scic_sds_controller_register_setup(
697 struct scic_sds_controller *this_controller);
698
699void scic_sds_controller_reset_hardware(
700 struct scic_sds_controller *this_controller);
701
702
703void scic_sds_controller_initialize_phy_startup(
704 struct scic_sds_controller *this_controller);
705
706#endif /* _SCIC_SDS_CONTROLLER_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_controller_registers.h b/drivers/scsi/isci/core/scic_sds_controller_registers.h
new file mode 100644
index 000000000000..b7bec92ee59c
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_controller_registers.h
@@ -0,0 +1,463 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_SDS_CONTROLLER_REGISTERS_H_
57#define _SCIC_SDS_CONTROLLER_REGISTERS_H_
58
59/**
60 * This file contains macros used to perform the register reads/writes to the
61 * SCU hardware.
62 *
63 *
64 */
65
66#include "scu_registers.h"
67#include "scic_sds_controller.h"
68
69/**
70 * scic_sds_controller_smu_register_read() -
71 *
72 * SMU_REGISTER_ACCESS_MACROS
73 */
74#define scic_sds_controller_smu_register_read(controller, reg) \
75 smu_register_read(\
76 (controller), \
77 (controller)->smu_registers->reg \
78 )
79
80#define scic_sds_controller_smu_register_write(controller, reg, value) \
81 smu_register_write(\
82 (controller), \
83 (controller)->smu_registers->reg, \
84 (value) \
85 )
86
87/**
88 * scu_afe_register_write() -
89 *
90 * AFE_REGISTER_ACCESS_MACROS
91 */
92#define scu_afe_register_write(controller, reg, value) \
93 scu_register_write(\
94 (controller), \
95 (controller)->scu_registers->afe.reg, \
96 (value) \
97 )
98
99#define scu_afe_txreg_write(controller, phy, reg, value) \
100 scu_register_write(\
101 (controller), \
102 (controller)->scu_registers->afe.scu_afe_xcvr[phy].reg,\
103 (value) \
104 )
105
106#define scu_afe_register_read(controller, reg) \
107 scu_register_read(\
108 (controller), \
109 (controller)->scu_registers->afe.reg \
110 )
111
112/**
113 * scu_controller_viit_register_write() -
114 *
115 * VIIT_REGISTER_ACCESS_MACROS
116 */
117#define scu_controller_viit_register_write(controller, index, reg, value) \
118 scu_register_write(\
119 (controller), \
120 (controller)->scu_registers->peg0.viit[index].reg, \
121 value \
122 )
123
124/*
125 * *****************************************************************************
126 * * SMU REGISTERS
127 * ***************************************************************************** */
128
129/**
130 * SMU_PCP_WRITE() -
131 *
132 * struct smu_registers
133 */
134#define SMU_PCP_WRITE(controller, value) \
135 scic_sds_controller_smu_register_write(\
136 controller, post_context_port, value \
137 )
138
139#define SMU_TCR_READ(controller, value) \
140 scic_sds_controller_smu_register_read(\
141 controller, task_context_range \
142 )
143
144#define SMU_TCR_WRITE(controller, value) \
145 scic_sds_controller_smu_register_write(\
146 controller, task_context_range, value \
147 )
148
149#define SMU_HTTBAR_WRITE(controller, address) \
150 { \
151 scic_sds_controller_smu_register_write(\
152 controller, \
153 host_task_table_lower, \
154 lower_32_bits(address) \
155 ); \
156 scic_sds_controller_smu_register_write(\
157 controller, \
158 host_task_table_upper, \
159 upper_32_bits(address) \
160 ); \
161 }
162
163#define SMU_CQBAR_WRITE(controller, address) \
164 { \
165 scic_sds_controller_smu_register_write(\
166 controller, \
167 completion_queue_lower, \
168 lower_32_bits(address) \
169 ); \
170 scic_sds_controller_smu_register_write(\
171 controller, \
172 completion_queue_upper, \
173 upper_32_bits(address) \
174 ); \
175 }
176
177#define SMU_CQGR_WRITE(controller, value) \
178 scic_sds_controller_smu_register_write(\
179 controller, completion_queue_get, value \
180 )
181
182#define SMU_CQGR_READ(controller, value) \
183 scic_sds_controller_smu_register_read(\
184 controller, completion_queue_get \
185 )
186
187#define SMU_CQPR_WRITE(controller, value) \
188 scic_sds_controller_smu_register_write(\
189 controller, completion_queue_put, value \
190 )
191
192#define SMU_RNCBAR_WRITE(controller, address) \
193 { \
194 scic_sds_controller_smu_register_write(\
195 controller, \
196 remote_node_context_lower, \
197 lower_32_bits(address) \
198 ); \
199 scic_sds_controller_smu_register_write(\
200 controller, \
201 remote_node_context_upper, \
202 upper_32_bits(address) \
203 ); \
204 }
205
206#define SMU_AMR_READ(controller) \
207 scic_sds_controller_smu_register_read(\
208 controller, address_modifier \
209 )
210
211#define SMU_IMR_READ(controller) \
212 scic_sds_controller_smu_register_read(\
213 controller, interrupt_mask \
214 )
215
216#define SMU_IMR_WRITE(controller, mask) \
217 scic_sds_controller_smu_register_write(\
218 controller, interrupt_mask, mask \
219 )
220
221#define SMU_ISR_READ(controller) \
222 scic_sds_controller_smu_register_read(\
223 controller, interrupt_status \
224 )
225
226#define SMU_ISR_WRITE(controller, status) \
227 scic_sds_controller_smu_register_write(\
228 controller, interrupt_status, status \
229 )
230
231#define SMU_ICC_READ(controller) \
232 scic_sds_controller_smu_register_read(\
233 controller, interrupt_coalesce_control \
234 )
235
236#define SMU_ICC_WRITE(controller, value) \
237 scic_sds_controller_smu_register_write(\
238 controller, interrupt_coalesce_control, value \
239 )
240
241#define SMU_CQC_WRITE(controller, value) \
242 scic_sds_controller_smu_register_write(\
243 controller, completion_queue_control, value \
244 )
245
246#define SMU_SMUSRCR_WRITE(controller, value) \
247 scic_sds_controller_smu_register_write(\
248 controller, soft_reset_control, value \
249 )
250
251#define SMU_TCA_WRITE(controller, index, value) \
252 scic_sds_controller_smu_register_write(\
253 controller, task_context_assignment[index], value \
254 )
255
256#define SMU_TCA_READ(controller, index) \
257 scic_sds_controller_smu_register_read(\
258 controller, task_context_assignment[index] \
259 )
260
261#define SMU_DCC_READ(controller) \
262 scic_sds_controller_smu_register_read(\
263 controller, device_context_capacity \
264 )
265
266#define SMU_DFC_READ(controller) \
267 scic_sds_controller_smu_register_read(\
268 controller, device_function_capacity \
269 )
270
271#define SMU_SMUCSR_READ(controller) \
272 scic_sds_controller_smu_register_read(\
273 controller, control_status \
274 )
275
276#define SMU_CQPR_READ(controller) \
277 scic_sds_controller_smu_register_read(\
278 controller, completion_queue_put \
279 )
280
281
282/**
283 * scic_sds_controller_scu_register_read() -
284 *
285 * SCU_REGISTER_ACCESS_MACROS
286 */
287#define scic_sds_controller_scu_register_read(controller, reg) \
288 scu_register_read(\
289 (controller), \
290 (controller)->scu_registers->reg \
291 )
292
293#define scic_sds_controller_scu_register_write(controller, reg, value) \
294 scu_register_write(\
295 (controller), \
296 (controller)->scu_registers->reg, \
297 (value) \
298 )
299
300
301/*
302 * ****************************************************************************
303 * * SCU SDMA REGISTERS
304 * **************************************************************************** */
305
306/**
307 * scu_sdma_register_read() -
308 *
309 * SCU_SDMA_REGISTER_ACCESS_MACROS
310 */
311#define scu_sdma_register_read(controller, reg) \
312 scu_register_read(\
313 (controller), \
314 (controller)->scu_registers->sdma.reg \
315 )
316
317#define scu_sdma_register_write(controller, reg, value) \
318 scu_register_write(\
319 (controller), \
320 (controller)->scu_registers->sdma.reg, \
321 (value) \
322 )
323
324/**
325 * SCU_PUFATHAR_WRITE() -
326 *
327 * struct scu_sdma_registers
328 */
329#define SCU_PUFATHAR_WRITE(controller, address) \
330 { \
331 scu_sdma_register_write(\
332 controller, \
333 uf_address_table_lower, \
334 lower_32_bits(address) \
335 ); \
336 scu_sdma_register_write(\
337 controller, \
338 uf_address_table_upper, \
339 upper_32_bits(address) \
340 ); \
341 }
342
343#define SCU_UFHBAR_WRITE(controller, address) \
344 { \
345 scu_sdma_register_write(\
346 controller, \
347 uf_header_base_address_lower, \
348 lower_32_bits(address) \
349 ); \
350 scu_sdma_register_write(\
351 controller, \
352 uf_header_base_address_upper, \
353 upper_32_bits(address) \
354 ); \
355 }
356
357#define SCU_UFQC_READ(controller) \
358 scu_sdma_register_read(\
359 controller, \
360 unsolicited_frame_queue_control \
361 )
362
363#define SCU_UFQC_WRITE(controller, value) \
364 scu_sdma_register_write(\
365 controller, \
366 unsolicited_frame_queue_control, \
367 value \
368 )
369
370#define SCU_UFQPP_READ(controller) \
371 scu_sdma_register_read(\
372 controller, \
373 unsolicited_frame_put_pointer \
374 )
375
376#define SCU_UFQPP_WRITE(controller, value) \
377 scu_sdma_register_write(\
378 controller, \
379 unsolicited_frame_put_pointer, \
380 value \
381 )
382
383#define SCU_UFQGP_WRITE(controller, value) \
384 scu_sdma_register_write(\
385 controller, \
386 unsolicited_frame_get_pointer, \
387 value \
388 )
389
390#define SCU_PDMACR_READ(controller) \
391 scu_sdma_register_read(\
392 controller, \
393 pdma_configuration \
394 )
395
396#define SCU_PDMACR_WRITE(controller, value) \
397 scu_sdma_register_write(\
398 controller, \
399 pdma_configuration, \
400 value \
401 )
402
403#define SCU_CDMACR_READ(controller) \
404 scu_sdma_register_read(\
405 controller, \
406 cdma_configuration \
407 )
408
409#define SCU_CDMACR_WRITE(controller, value) \
410 scu_sdma_register_write(\
411 controller, \
412 cdma_configuration, \
413 value \
414 )
415
416/*
417 * *****************************************************************************
418 * * SCU Port Task Scheduler Group Registers
419 * ***************************************************************************** */
420
421/**
422 * scu_ptsg_register_read() -
423 *
424 * SCU_PTSG_REGISTER_ACCESS_MACROS
425 */
426#define scu_ptsg_register_read(controller, reg) \
427 scu_register_read(\
428 (controller), \
429 (controller)->scu_registers->peg0.ptsg.reg \
430 )
431
432#define scu_ptsg_register_write(controller, reg, value) \
433 scu_register_write(\
434 (controller), \
435 (controller)->scu_registers->peg0.ptsg.reg, \
436 (value) \
437 )
438
439/**
440 * SCU_PTSGCR_READ() -
441 *
442 * SCU_PTSG_REGISTERS
443 */
444#define SCU_PTSGCR_READ(controller) \
445 scu_ptsg_register_read(\
446 (controller), \
447 control \
448 )
449
450#define SCU_PTSGCR_WRITE(controller, value) \
451 scu_ptsg_register_write(\
452 (controller), \
453 control, \
454 value \
455 )
456
457#define SCU_PTSGRTC_READ(controller) \
458 scu_ptsg_register_read(\
459 contoller, \
460 real_time_clock \
461 )
462
463#endif /* _SCIC_SDS_CONTROLLER_REGISTERS_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_pci.h b/drivers/scsi/isci/core/scic_sds_pci.h
new file mode 100644
index 000000000000..21326777acc6
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_pci.h
@@ -0,0 +1,95 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_SDS_PCI_H_
57#define _SCIC_SDS_PCI_H_
58
59/**
60 * This file contains the prototypes/macros utilized in writing out PCI data
61 * for the SCI core.
62 *
63 *
64 */
65
66#include <asm/io.h>
67#include "sci_types.h"
68
69struct scic_sds_controller;
70
71void scic_sds_pci_bar_initialization(struct scic_sds_controller *scic);
72
73/* for debug we separate scu and smu accesses and require a controller */
74static inline u32 scic_sds_pci_read_smu_dword(struct scic_sds_controller *scic, void __iomem *addr)
75{
76 return readl(addr);
77}
78
79static inline void scic_sds_pci_write_smu_dword(struct scic_sds_controller *scic, void __iomem *addr, u32 value)
80{
81 writel(value, addr);
82}
83
84static inline u32 scic_sds_pci_read_scu_dword(struct scic_sds_controller *scic, void __iomem *addr)
85{
86 return readl(addr);
87}
88
89static inline void scic_sds_pci_write_scu_dword(struct scic_sds_controller *scic, void __iomem *addr, u32 value)
90{
91 writel(value, addr);
92}
93
94
95#endif /* _SCIC_SDS_PCI_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_phy.c b/drivers/scsi/isci/core/scic_sds_phy.c
new file mode 100644
index 000000000000..7d012b571b5b
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_phy.c
@@ -0,0 +1,2807 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include "intel_ata.h"
57#include "intel_sata.h"
58#include "sci_base_state.h"
59#include "sci_base_state_machine.h"
60#include "scic_phy.h"
61#include "scic_sds_controller.h"
62#include "scic_sds_phy.h"
63#include "scic_sds_phy_registers.h"
64#include "scic_sds_port.h"
65#include "scic_user_callback.h"
66#include "sci_environment.h"
67#include "sci_util.h"
68#include "scu_event_codes.h"
69
70#define SCIC_SDS_PHY_MIN_TIMER_COUNT (SCI_MAX_PHYS)
71#define SCIC_SDS_PHY_MAX_TIMER_COUNT (SCI_MAX_PHYS)
72
73/* Maximum arbitration wait time in micro-seconds */
74#define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME (700)
75
76/*
77 * *****************************************************************************
78 * * SCIC SDS PHY Internal Methods
79 * ***************************************************************************** */
80
81/**
82 * This method will initialize the phy link layer registers
83 * @this_phy:
84 * @link_layer_registers:
85 *
86 * enum sci_status
87 */
88static enum sci_status scic_sds_phy_link_layer_initialization(
89 struct scic_sds_phy *this_phy,
90 struct scu_link_layer_registers *link_layer_registers)
91{
92 u32 phy_configuration;
93 struct sas_capabilities phy_capabilities;
94 u32 parity_check = 0;
95 u32 parity_count = 0;
96 u32 link_layer_control;
97
98 this_phy->link_layer_registers = link_layer_registers;
99
100 /* Set our IDENTIFY frame data */
101 #define SCI_END_DEVICE 0x01
102
103 SCU_SAS_TIID_WRITE(
104 this_phy,
105 (SCU_SAS_TIID_GEN_BIT(SMP_INITIATOR)
106 | SCU_SAS_TIID_GEN_BIT(SSP_INITIATOR)
107 | SCU_SAS_TIID_GEN_BIT(STP_INITIATOR)
108 | SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST)
109 | SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE, SCI_END_DEVICE))
110 );
111
112 /* Write the device SAS Address */
113 SCU_SAS_TIDNH_WRITE(this_phy, 0xFEDCBA98);
114 SCU_SAS_TIDNL_WRITE(this_phy, this_phy->phy_index);
115
116 /* Write the source SAS Address */
117 SCU_SAS_TISSAH_WRITE(
118 this_phy,
119 this_phy->owning_port->owning_controller->oem_parameters.sds1.phys[
120 this_phy->phy_index].sas_address.high
121 );
122 SCU_SAS_TISSAL_WRITE(
123 this_phy,
124 this_phy->owning_port->owning_controller->oem_parameters.sds1.phys[
125 this_phy->phy_index].sas_address.low
126 );
127
128 /* Clear and Set the PHY Identifier */
129 SCU_SAS_TIPID_WRITE(this_phy, 0x00000000);
130 SCU_SAS_TIPID_WRITE(this_phy, SCU_SAS_TIPID_GEN_VALUE(ID, this_phy->phy_index));
131
132 /* Change the initial state of the phy configuration register */
133 phy_configuration = SCU_SAS_PCFG_READ(this_phy);
134
135 /* Hold OOB state machine in reset */
136 phy_configuration |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
137 SCU_SAS_PCFG_WRITE(this_phy, phy_configuration);
138
139 /* Configure the SNW capabilities */
140 phy_capabilities.u.all = 0;
141 phy_capabilities.u.bits.start = 1;
142 phy_capabilities.u.bits.gen3_without_ssc_supported = 1;
143 phy_capabilities.u.bits.gen2_without_ssc_supported = 1;
144 phy_capabilities.u.bits.gen1_without_ssc_supported = 1;
145 if (this_phy->owning_port->owning_controller->oem_parameters.sds1.
146 controller.do_enable_ssc == true) {
147 phy_capabilities.u.bits.gen3_with_ssc_supported = 1;
148 phy_capabilities.u.bits.gen2_with_ssc_supported = 1;
149 phy_capabilities.u.bits.gen1_with_ssc_supported = 1;
150 }
151
152 /*
153 * The SAS specification indicates that the phy_capabilities that
154 * are transmitted shall have an even parity. Calculate the parity. */
155 parity_check = phy_capabilities.u.all;
156 while (parity_check != 0) {
157 if (parity_check & 0x1)
158 parity_count++;
159 parity_check >>= 1;
160 }
161
162 /*
163 * If parity indicates there are an odd number of bits set, then
164 * set the parity bit to 1 in the phy capabilities. */
165 if ((parity_count % 2) != 0)
166 phy_capabilities.u.bits.parity = 1;
167
168 SCU_SAS_PHYCAP_WRITE(this_phy, phy_capabilities.u.all);
169
170 /* Set the enable spinup period but disable the ability to send notify enable spinup */
171 SCU_SAS_ENSPINUP_WRITE(this_phy, SCU_ENSPINUP_GEN_VAL(COUNT, 0x33));
172
173#if defined(CONFIG_PBG_HBA_A0) || defined(CONFIG_PBG_HBA_A2) || defined(CONFIG_PBG_HBA_BETA)
174 /* / @todo Provide a way to write this register correctly */
175 scu_link_layer_register_write(this_phy, afe_lookup_table_control, 0x02108421);
176#else
177 /* / @todo Provide a way to write this register correctly */
178 scu_link_layer_register_write(this_phy, afe_lookup_table_control, 0x0e739ce7);
179#endif
180
181 link_layer_control = SCU_SAS_LLCTL_GEN_VAL(
182 NO_OUTBOUND_TASK_TIMEOUT,
183 (u8)this_phy->owning_port->owning_controller->
184 user_parameters.sds1.no_outbound_task_timeout
185 );
186
187/* #define COMPILED_MAX_LINK_RATE SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1 */
188/* #define COMPILED_MAX_LINK_RATE SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2 */
189#define COMPILED_MAX_LINK_RATE SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3
190
191 if (this_phy->owning_port->owning_controller->user_parameters.sds1.
192 phys[this_phy->phy_index].max_speed_generation == SCIC_SDS_PARM_GEN3_SPEED) {
193 link_layer_control |= SCU_SAS_LLCTL_GEN_VAL(
194 MAX_LINK_RATE, COMPILED_MAX_LINK_RATE
195 );
196 } else if (this_phy->owning_port->owning_controller->user_parameters.sds1.
197 phys[this_phy->phy_index].max_speed_generation == SCIC_SDS_PARM_GEN2_SPEED) {
198 link_layer_control |= SCU_SAS_LLCTL_GEN_VAL(
199 MAX_LINK_RATE,
200 min(
201 SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2,
202 COMPILED_MAX_LINK_RATE)
203 );
204 } else {
205 link_layer_control |= SCU_SAS_LLCTL_GEN_VAL(
206 MAX_LINK_RATE,
207 min(
208 SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1,
209 COMPILED_MAX_LINK_RATE)
210 );
211 }
212
213 scu_link_layer_register_write(
214 this_phy, link_layer_control, link_layer_control
215 );
216
217 /*
218 * Program the max ARB time for the PHY to 700us so we inter-operate with
219 * the PMC expander which shuts down PHYs if the expander PHY generates too
220 * many breaks. This time value will guarantee that the initiator PHY will
221 * generate the break. */
222#if defined(CONFIG_PBG_HBA_A0) || defined(CONFIG_PBG_HBA_A2)
223 scu_link_layer_register_write(
224 this_phy,
225 maximum_arbitration_wait_timer_timeout,
226 SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME
227 );
228#endif /* defined(CONFIG_PBG_HBA_A0) || defined(CONFIG_PBG_HBA_A2) */
229
230 /*
231 * Set the link layer hang detection to 500ms (0x1F4) from its default
232 * value of 128ms. Max value is 511 ms. */
233 scu_link_layer_register_write(
234 this_phy, link_layer_hang_detection_timeout, 0x1F4
235 );
236
237 /* We can exit the initial state to the stopped state */
238 sci_base_state_machine_change_state(
239 scic_sds_phy_get_base_state_machine(this_phy),
240 SCI_BASE_PHY_STATE_STOPPED
241 );
242
243 return SCI_SUCCESS;
244}
245
246/**
247 * This function will handle the sata SIGNATURE FIS timeout condition. It will
248 * restart the starting substate machine since we dont know what has actually
249 * happening.
250 */
251static void scic_sds_phy_sata_timeout(void *phy)
252{
253 struct scic_sds_phy *sci_phy = phy;
254
255 dev_dbg(sciphy_to_dev(sci_phy),
256 "%s: SCIC SDS Phy 0x%p did not receive signature fis before "
257 "timeout.\n",
258 __func__,
259 sci_phy);
260
261 sci_base_state_machine_stop(
262 scic_sds_phy_get_starting_substate_machine(sci_phy));
263
264 sci_base_state_machine_change_state(
265 scic_sds_phy_get_base_state_machine(sci_phy),
266 SCI_BASE_PHY_STATE_STARTING
267 );
268}
269
270/*
271 * *****************************************************************************
272 * * SCIC SDS PHY External Methods
273 * ***************************************************************************** */
274
275/**
276 * This method returns the object size for a phy object.
277 *
278 * u32
279 */
280
281/**
282 * This method returns the minimum number of timers required for a phy object.
283 *
284 * u32
285 */
286
287/**
288 * This method returns the maximum number of timers required for a phy object.
289 *
290 * u32
291 */
292
293#ifdef SCIC_DEBUG_ENABLED
294/**
295 * scic_sds_phy_observe_state_change() -
296 * @our_observer:
297 *
298 * Debug code to record the state transitions in the phy
299 */
300void scic_sds_phy_observe_state_change(
301 struct sci_base_observer *our_observer,
302 struct sci_base_subject *the_subject)
303{
304 struct scic_sds_phy *this_phy;
305 struct sci_base_state_machine *the_state_machine;
306
307 u8 transition_requestor;
308 u32 base_state_id;
309 u32 starting_substate_id;
310
311 the_state_machine = (struct sci_base_state_machine *)the_subject;
312 this_phy = (struct scic_sds_phy *)the_state_machine->state_machine_owner;
313
314 if (the_state_machine == &this_phy->parent.state_machine) {
315 transition_requestor = 0x01;
316 } else if (the_state_machine == &this_phy->starting_substate_machine) {
317 transition_requestor = 0x02;
318 } else {
319 transition_requestor = 0xFF;
320 }
321
322 base_state_id =
323 sci_base_state_machine_get_state(&this_phy->parent.state_machine);
324 starting_substate_id =
325 sci_base_state_machine_get_state(&this_phy->starting_substate_machine);
326
327 this_phy->state_record.state_transition_table[
328 this_phy->state_record.index++] = ((transition_requestor << 24)
329 | ((u8)base_state_id << 8)
330 | ((u8)starting_substate_id));
331
332 this_phy->state_record.index =
333 this_phy->state_record.index & (MAX_STATE_TRANSITION_RECORD - 1);
334
335}
336#endif /* SCIC_DEBUG_ENABLED */
337
338#ifdef SCIC_DEBUG_ENABLED
339/**
340 * scic_sds_phy_initialize_state_recording() -
341 *
342 * This method initializes the state record debug information for the phy
343 * object. The state machines for the phy object must be constructed before
344 * this function is called.
345 */
346void scic_sds_phy_initialize_state_recording(
347 struct scic_sds_phy *this_phy)
348{
349 this_phy->state_record.index = 0;
350
351 sci_base_observer_initialize(
352 &this_phy->state_record.base_state_observer,
353 scic_sds_phy_observe_state_change,
354 &this_phy->parent.state_machine.parent
355 );
356
357 sci_base_observer_initialize(
358 &this_phy->state_record.starting_state_observer,
359 scic_sds_phy_observe_state_change,
360 &this_phy->starting_substate_machine.parent
361 );
362}
363#endif /* SCIC_DEBUG_ENABLED */
364
365/**
366 * This method will construct the struct scic_sds_phy object
367 * @this_phy:
368 * @owning_port:
369 * @phy_index:
370 *
371 */
372void scic_sds_phy_construct(
373 struct scic_sds_phy *this_phy,
374 struct scic_sds_port *owning_port,
375 u8 phy_index)
376{
377 /*
378 * Call the base constructor first
379 */
380 sci_base_phy_construct(
381 &this_phy->parent,
382 scic_sds_phy_state_table
383 );
384
385 /* Copy the rest of the input data to our locals */
386 this_phy->owning_port = owning_port;
387 this_phy->phy_index = phy_index;
388 this_phy->bcn_received_while_port_unassigned = false;
389 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
390 this_phy->link_layer_registers = NULL;
391 this_phy->max_negotiated_speed = SCI_SAS_NO_LINK_RATE;
392
393 /* Clear out the identification buffer data */
394 memset(&this_phy->phy_type, 0, sizeof(this_phy->phy_type));
395
396 /* Initialize the the substate machines */
397 sci_base_state_machine_construct(
398 &this_phy->starting_substate_machine,
399 &this_phy->parent.parent,
400 scic_sds_phy_starting_substates,
401 SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL
402 );
403
404 #ifdef SCIC_DEBUG_ENABLED
405 scic_sds_phy_initialize_state_recording(this_phy);
406 #endif /* SCIC_DEBUG_ENABLED */
407}
408
409/**
410 * This method returns the port currently containing this phy. If the phy is
411 * currently contained by the dummy port, then the phy is considered to not
412 * be part of a port.
413 * @this_phy: This parameter specifies the phy for which to retrieve the
414 * containing port.
415 *
416 * This method returns a handle to a port that contains the supplied phy.
417 * SCI_INVALID_HANDLE This value is returned if the phy is not part of a real
418 * port (i.e. it's contained in the dummy port). !SCI_INVALID_HANDLE All other
419 * values indicate a handle/pointer to the port containing the phy.
420 */
421struct scic_sds_port *scic_sds_phy_get_port(
422 struct scic_sds_phy *this_phy)
423{
424 if (scic_sds_port_get_index(this_phy->owning_port) == SCIC_SDS_DUMMY_PORT)
425 return SCI_INVALID_HANDLE;
426
427 return this_phy->owning_port;
428}
429
430/**
431 * This method will assign a port to the phy object.
432 * @out]: this_phy This parameter specifies the phy for which to assign a port
433 * object.
434 *
435 *
436 */
437void scic_sds_phy_set_port(
438 struct scic_sds_phy *this_phy,
439 struct scic_sds_port *the_port)
440{
441 this_phy->owning_port = the_port;
442
443 if (this_phy->bcn_received_while_port_unassigned) {
444 this_phy->bcn_received_while_port_unassigned = false;
445 scic_sds_port_broadcast_change_received(this_phy->owning_port, this_phy);
446 }
447}
448
449/**
450 * This method will initialize the constructed phy
451 * @sci_phy:
452 * @link_layer_registers:
453 *
454 * enum sci_status
455 */
456enum sci_status scic_sds_phy_initialize(
457 struct scic_sds_phy *sci_phy,
458 struct scu_link_layer_registers *link_layer_registers)
459{
460 /* Create the SIGNATURE FIS Timeout timer for this phy */
461 sci_phy->sata_timeout_timer = scic_cb_timer_create(
462 scic_sds_phy_get_controller(sci_phy),
463 scic_sds_phy_sata_timeout,
464 sci_phy
465 );
466
467 /* Perofrm the initialization of the PE hardware */
468 scic_sds_phy_link_layer_initialization(sci_phy, link_layer_registers);
469
470 /*
471 * There is nothing that needs to be done in this state just
472 * transition to the stopped state. */
473 sci_base_state_machine_change_state(
474 scic_sds_phy_get_base_state_machine(sci_phy),
475 SCI_BASE_PHY_STATE_STOPPED
476 );
477
478 return SCI_SUCCESS;
479}
480
481
482/**
483 *
484 * @this_phy: The phy object to be suspended.
485 *
486 * This function will perform the register reads/writes to suspend the SCU
487 * hardware protocol engine. none
488 */
489void scic_sds_phy_suspend(
490 struct scic_sds_phy *this_phy)
491{
492 u32 scu_sas_pcfg_value;
493
494 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
495
496 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
497
498 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
499}
500
501/**
502 *
503 * @this_phy: The phy object to resume.
504 *
505 * This function will perform the register reads/writes required to resume the
506 * SCU hardware protocol engine. none
507 */
508void scic_sds_phy_resume(
509 struct scic_sds_phy *this_phy)
510{
511 u32 scu_sas_pcfg_value;
512
513 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
514
515 scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
516
517 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
518}
519
520/**
521 * This method returns the local sas address assigned to this phy.
522 * @this_phy: This parameter specifies the phy for which to retrieve the local
523 * SAS address.
524 * @sas_address: This parameter specifies the location into which to copy the
525 * local SAS address.
526 *
527 */
528void scic_sds_phy_get_sas_address(
529 struct scic_sds_phy *this_phy,
530 struct sci_sas_address *sas_address)
531{
532 sas_address->high = SCU_SAS_TISSAH_READ(this_phy);
533 sas_address->low = SCU_SAS_TISSAL_READ(this_phy);
534}
535
536/**
537 * This method returns the remote end-point (i.e. attached) sas address
538 * assigned to this phy.
539 * @this_phy: This parameter specifies the phy for which to retrieve the remote
540 * end-point SAS address.
541 * @sas_address: This parameter specifies the location into which to copy the
542 * remote end-point SAS address.
543 *
544 */
545void scic_sds_phy_get_attached_sas_address(
546 struct scic_sds_phy *this_phy,
547 struct sci_sas_address *sas_address)
548{
549 sas_address->high
550 = this_phy->phy_type.sas.identify_address_frame_buffer.sas_address.high;
551 sas_address->low
552 = this_phy->phy_type.sas.identify_address_frame_buffer.sas_address.low;
553}
554
555/**
556 * This method returns the supported protocols assigned to this phy
557 * @this_phy:
558 *
559 *
560 */
561void scic_sds_phy_get_protocols(
562 struct scic_sds_phy *this_phy,
563 struct sci_sas_identify_address_frame_protocols *protocols)
564{
565 protocols->u.all = (u16)(SCU_SAS_TIID_READ(this_phy) & 0x0000FFFF);
566}
567
568/**
569 *
570 * @this_phy: The parameter is the phy object for which the attached phy
571 * protcols are to be returned.
572 *
573 * This method returns the supported protocols for the attached phy. If this
574 * is a SAS phy the protocols are returned from the identify address frame. If
575 * this is a SATA phy then protocols are made up and the target phy is an STP
576 * target phy. The caller will get the entire set of bits for the protocol
577 * value.
578 */
579void scic_sds_phy_get_attached_phy_protocols(
580 struct scic_sds_phy *this_phy,
581 struct sci_sas_identify_address_frame_protocols *protocols)
582{
583 protocols->u.all = 0;
584
585 if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
586 protocols->u.all =
587 this_phy->phy_type.sas.identify_address_frame_buffer.protocols.u.all;
588 } else if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) {
589 protocols->u.bits.stp_target = 1;
590 }
591}
592
593/*
594 * *****************************************************************************
595 * * SCIC SDS PHY Handler Redirects
596 * ***************************************************************************** */
597
598/**
599 * This method will attempt to start the phy object. This request is only valid
600 * when the phy is in the stopped state
601 * @this_phy:
602 *
603 * enum sci_status
604 */
605enum sci_status scic_sds_phy_start(
606 struct scic_sds_phy *this_phy)
607{
608 return this_phy->state_handlers->parent.start_handler(&this_phy->parent);
609}
610
611/**
612 * This method will attempt to stop the phy object.
613 * @this_phy:
614 *
615 * enum sci_status SCI_SUCCESS if the phy is going to stop SCI_INVALID_STATE if the
616 * phy is not in a valid state to stop
617 */
618enum sci_status scic_sds_phy_stop(
619 struct scic_sds_phy *this_phy)
620{
621 return this_phy->state_handlers->parent.stop_handler(&this_phy->parent);
622}
623
624/**
625 * This method will attempt to reset the phy. This request is only valid when
626 * the phy is in an ready state
627 * @this_phy:
628 *
629 * enum sci_status
630 */
631enum sci_status scic_sds_phy_reset(
632 struct scic_sds_phy *this_phy)
633{
634 return this_phy->state_handlers->parent.reset_handler(
635 &this_phy->parent
636 );
637}
638
639/**
640 * This method will process the event code received.
641 * @this_phy:
642 * @event_code:
643 *
644 * enum sci_status
645 */
646enum sci_status scic_sds_phy_event_handler(
647 struct scic_sds_phy *this_phy,
648 u32 event_code)
649{
650 return this_phy->state_handlers->event_handler(this_phy, event_code);
651}
652
653/**
654 * This method will process the frame index received.
655 * @this_phy:
656 * @frame_index:
657 *
658 * enum sci_status
659 */
660enum sci_status scic_sds_phy_frame_handler(
661 struct scic_sds_phy *this_phy,
662 u32 frame_index)
663{
664 return this_phy->state_handlers->frame_handler(this_phy, frame_index);
665}
666
667/**
668 * This method will give the phy permission to consume power
669 * @this_phy:
670 *
671 * enum sci_status
672 */
673enum sci_status scic_sds_phy_consume_power_handler(
674 struct scic_sds_phy *this_phy)
675{
676 return this_phy->state_handlers->consume_power_handler(this_phy);
677}
678
679/*
680 * *****************************************************************************
681 * * SCIC PHY Public Methods
682 * ***************************************************************************** */
683
684
685enum sci_status scic_sas_phy_get_properties(
686 struct scic_sds_phy *sci_phy,
687 struct scic_sas_phy_properties *properties)
688{
689 if (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
690 memcpy(
691 &properties->received_iaf,
692 &sci_phy->phy_type.sas.identify_address_frame_buffer,
693 sizeof(struct sci_sas_identify_address_frame)
694 );
695
696 properties->received_capabilities.u.all
697 = SCU_SAS_RECPHYCAP_READ(sci_phy);
698
699 return SCI_SUCCESS;
700 }
701
702 return SCI_FAILURE;
703}
704
705
706enum sci_status scic_sata_phy_get_properties(
707 struct scic_sds_phy *sci_phy,
708 struct scic_sata_phy_properties *properties)
709{
710 if (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) {
711 memcpy(
712 &properties->signature_fis,
713 &sci_phy->phy_type.sata.signature_fis_buffer,
714 sizeof(struct sata_fis_reg_d2h)
715 );
716
717 /* / @todo add support for port selectors. */
718 properties->is_port_selector_present = false;
719
720 return SCI_SUCCESS;
721 }
722
723 return SCI_FAILURE;
724}
725
726/*
727 * *****************************************************************************
728 * * SCIC SDS PHY HELPER FUNCTIONS
729 * ***************************************************************************** */
730
731
732/**
733 *
734 * @this_phy: The phy object that received SAS PHY DETECTED.
735 *
736 * This method continues the link training for the phy as if it were a SAS PHY
737 * instead of a SATA PHY. This is done because the completion queue had a SAS
738 * PHY DETECTED event when the state machine was expecting a SATA PHY event.
739 * none
740 */
741static void scic_sds_phy_start_sas_link_training(
742 struct scic_sds_phy *this_phy)
743{
744 u32 phy_control;
745
746 phy_control = SCU_SAS_PCFG_READ(this_phy);
747 phy_control |= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD);
748 SCU_SAS_PCFG_WRITE(this_phy, phy_control);
749
750 sci_base_state_machine_change_state(
751 &this_phy->starting_substate_machine,
752 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
753 );
754
755 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SAS;
756}
757
758/**
759 *
760 * @this_phy: The phy object that received a SATA SPINUP HOLD event
761 *
762 * This method continues the link training for the phy as if it were a SATA PHY
763 * instead of a SAS PHY. This is done because the completion queue had a SATA
764 * SPINUP HOLD event when the state machine was expecting a SAS PHY event. none
765 */
766static void scic_sds_phy_start_sata_link_training(
767 struct scic_sds_phy *this_phy)
768{
769 sci_base_state_machine_change_state(
770 &this_phy->starting_substate_machine,
771 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
772 );
773
774 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
775}
776
777/**
778 * This method performs processing common to all protocols upon completion of
779 * link training.
780 * @this_phy: This parameter specifies the phy object for which link training
781 * has completed.
782 * @max_link_rate: This parameter specifies the maximum link rate to be
783 * associated with this phy.
784 * @next_state: This parameter specifies the next state for the phy's starting
785 * sub-state machine.
786 *
787 */
788static void scic_sds_phy_complete_link_training(
789 struct scic_sds_phy *this_phy,
790 enum sci_sas_link_rate max_link_rate,
791 u32 next_state)
792{
793 this_phy->max_negotiated_speed = max_link_rate;
794
795 sci_base_state_machine_change_state(
796 scic_sds_phy_get_starting_substate_machine(this_phy), next_state
797 );
798}
799
800/**
801 *
802 * @this_phy: The struct scic_sds_phy object to restart.
803 *
804 * This method restarts the struct scic_sds_phy objects base state machine in the
805 * starting state from any starting substate. none
806 */
807static void scic_sds_phy_restart_starting_state(
808 struct scic_sds_phy *this_phy)
809{
810 /* Stop the current substate machine */
811 sci_base_state_machine_stop(
812 scic_sds_phy_get_starting_substate_machine(this_phy)
813 );
814
815 /* Re-enter the base state machine starting state */
816 sci_base_state_machine_change_state(
817 scic_sds_phy_get_base_state_machine(this_phy),
818 SCI_BASE_PHY_STATE_STARTING
819 );
820}
821
822/*
823 * *****************************************************************************
824 * * SCIC SDS PHY EVENT_HANDLERS
825 * ***************************************************************************** */
826
827/**
828 *
829 * @phy: This struct scic_sds_phy object which has received an event.
830 * @event_code: This is the event code which the phy object is to decode.
831 *
832 * This method is called when an event notification is received for the phy
833 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. -
834 * decode the event - sas phy detected causes a state transition to the wait
835 * for speed event notification. - any other events log a warning message and
836 * set a failure status enum sci_status SCI_SUCCESS on any valid event notification
837 * SCI_FAILURE on any unexpected event notifation
838 */
839static enum sci_status scic_sds_phy_starting_substate_await_ossp_event_handler(
840 struct scic_sds_phy *this_phy,
841 u32 event_code)
842{
843 u32 result = SCI_SUCCESS;
844
845 switch (scu_get_event_code(event_code)) {
846 case SCU_EVENT_SAS_PHY_DETECTED:
847 scic_sds_phy_start_sas_link_training(this_phy);
848 this_phy->is_in_link_training = true;
849 break;
850
851 case SCU_EVENT_SATA_SPINUP_HOLD:
852 scic_sds_phy_start_sata_link_training(this_phy);
853 this_phy->is_in_link_training = true;
854 break;
855
856 default:
857 dev_warn(sciphy_to_dev(this_phy),
858 "%s: PHY starting substate machine received "
859 "unexpected event_code %x\n",
860 __func__,
861 event_code);
862
863 result = SCI_FAILURE;
864 break;
865 }
866
867 return result;
868}
869
870/**
871 *
872 * @phy: This struct scic_sds_phy object which has received an event.
873 * @event_code: This is the event code which the phy object is to decode.
874 *
875 * This method is called when an event notification is received for the phy
876 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. -
877 * decode the event - sas phy detected returns us back to this state. - speed
878 * event detected causes a state transition to the wait for iaf. - identify
879 * timeout is an un-expected event and the state machine is restarted. - link
880 * failure events restart the starting state machine - any other events log a
881 * warning message and set a failure status enum sci_status SCI_SUCCESS on any valid
882 * event notification SCI_FAILURE on any unexpected event notifation
883 */
884static enum sci_status scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler(
885 struct scic_sds_phy *this_phy,
886 u32 event_code)
887{
888 u32 result = SCI_SUCCESS;
889
890 switch (scu_get_event_code(event_code)) {
891 case SCU_EVENT_SAS_PHY_DETECTED:
892 /*
893 * Why is this being reported again by the controller?
894 * We would re-enter this state so just stay here */
895 break;
896
897 case SCU_EVENT_SAS_15:
898 case SCU_EVENT_SAS_15_SSC:
899 scic_sds_phy_complete_link_training(
900 this_phy, SCI_SAS_150_GB, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
901 );
902 break;
903
904 case SCU_EVENT_SAS_30:
905 case SCU_EVENT_SAS_30_SSC:
906 scic_sds_phy_complete_link_training(
907 this_phy, SCI_SAS_300_GB, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
908 );
909 break;
910
911 case SCU_EVENT_SAS_60:
912 case SCU_EVENT_SAS_60_SSC:
913 scic_sds_phy_complete_link_training(
914 this_phy, SCI_SAS_600_GB, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
915 );
916 break;
917
918 case SCU_EVENT_SATA_SPINUP_HOLD:
919 /*
920 * We were doing SAS PHY link training and received a SATA PHY event
921 * continue OOB/SN as if this were a SATA PHY */
922 scic_sds_phy_start_sata_link_training(this_phy);
923 break;
924
925 case SCU_EVENT_LINK_FAILURE:
926 /* Link failure change state back to the starting state */
927 scic_sds_phy_restart_starting_state(this_phy);
928 break;
929
930 default:
931 dev_warn(sciphy_to_dev(this_phy),
932 "%s: PHY starting substate machine received "
933 "unexpected event_code %x\n",
934 __func__,
935 event_code);
936
937 result = SCI_FAILURE;
938 break;
939 }
940
941 return result;
942}
943
944/**
945 *
946 * @phy: This struct scic_sds_phy object which has received an event.
947 * @event_code: This is the event code which the phy object is to decode.
948 *
949 * This method is called when an event notification is received for the phy
950 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. -
951 * decode the event - sas phy detected event backs up the state machine to the
952 * await speed notification. - identify timeout is an un-expected event and the
953 * state machine is restarted. - link failure events restart the starting state
954 * machine - any other events log a warning message and set a failure status
955 * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any
956 * unexpected event notifation
957 */
958static enum sci_status scic_sds_phy_starting_substate_await_iaf_uf_event_handler(
959 struct scic_sds_phy *this_phy,
960 u32 event_code)
961{
962 u32 result = SCI_SUCCESS;
963
964 switch (scu_get_event_code(event_code)) {
965 case SCU_EVENT_SAS_PHY_DETECTED:
966 /* Backup the state machine */
967 scic_sds_phy_start_sas_link_training(this_phy);
968 break;
969
970 case SCU_EVENT_SATA_SPINUP_HOLD:
971 /*
972 * We were doing SAS PHY link training and received a SATA PHY event
973 * continue OOB/SN as if this were a SATA PHY */
974 scic_sds_phy_start_sata_link_training(this_phy);
975 break;
976
977 case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT:
978 case SCU_EVENT_LINK_FAILURE:
979 case SCU_EVENT_HARD_RESET_RECEIVED:
980 /* Start the oob/sn state machine over again */
981 scic_sds_phy_restart_starting_state(this_phy);
982 break;
983
984 default:
985 dev_warn(sciphy_to_dev(this_phy),
986 "%s: PHY starting substate machine received "
987 "unexpected event_code %x\n",
988 __func__,
989 event_code);
990
991 result = SCI_FAILURE;
992 break;
993 }
994
995 return result;
996}
997
998/**
999 *
1000 * @phy: This struct scic_sds_phy object which has received an event.
1001 * @event_code: This is the event code which the phy object is to decode.
1002 *
1003 * This method is called when an event notification is received for the phy
1004 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_POWER. -
1005 * decode the event - link failure events restart the starting state machine -
1006 * any other events log a warning message and set a failure status enum sci_status
1007 * SCI_SUCCESS on a link failure event SCI_FAILURE on any unexpected event
1008 * notifation
1009 */
1010static enum sci_status scic_sds_phy_starting_substate_await_sas_power_event_handler(
1011 struct scic_sds_phy *this_phy,
1012 u32 event_code)
1013{
1014 u32 result = SCI_SUCCESS;
1015
1016 switch (scu_get_event_code(event_code)) {
1017 case SCU_EVENT_LINK_FAILURE:
1018 /* Link failure change state back to the starting state */
1019 scic_sds_phy_restart_starting_state(this_phy);
1020 break;
1021
1022 default:
1023 dev_warn(sciphy_to_dev(this_phy),
1024 "%s: PHY starting substate machine received unexpected "
1025 "event_code %x\n",
1026 __func__,
1027 event_code);
1028
1029 result = SCI_FAILURE;
1030 break;
1031 }
1032
1033 return result;
1034}
1035
1036/**
1037 *
1038 * @phy: This struct scic_sds_phy object which has received an event.
1039 * @event_code: This is the event code which the phy object is to decode.
1040 *
1041 * This method is called when an event notification is received for the phy
1042 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. -
1043 * decode the event - link failure events restart the starting state machine -
1044 * sata spinup hold events are ignored since they are expected - any other
1045 * events log a warning message and set a failure status enum sci_status SCI_SUCCESS
1046 * on a link failure event SCI_FAILURE on any unexpected event notifation
1047 */
1048static enum sci_status scic_sds_phy_starting_substate_await_sata_power_event_handler(
1049 struct scic_sds_phy *this_phy,
1050 u32 event_code)
1051{
1052 u32 result = SCI_SUCCESS;
1053
1054 switch (scu_get_event_code(event_code)) {
1055 case SCU_EVENT_LINK_FAILURE:
1056 /* Link failure change state back to the starting state */
1057 scic_sds_phy_restart_starting_state(this_phy);
1058 break;
1059
1060 case SCU_EVENT_SATA_SPINUP_HOLD:
1061 /* These events are received every 10ms and are expected while in this state */
1062 break;
1063
1064 case SCU_EVENT_SAS_PHY_DETECTED:
1065 /*
1066 * There has been a change in the phy type before OOB/SN for the
1067 * SATA finished start down the SAS link traning path. */
1068 scic_sds_phy_start_sas_link_training(this_phy);
1069 break;
1070
1071 default:
1072 dev_warn(sciphy_to_dev(this_phy),
1073 "%s: PHY starting substate machine received "
1074 "unexpected event_code %x\n",
1075 __func__,
1076 event_code);
1077
1078 result = SCI_FAILURE;
1079 break;
1080 }
1081
1082 return result;
1083}
1084
1085/**
1086 *
1087 * @phy: This struct scic_sds_phy object which has received an event.
1088 * @event_code: This is the event code which the phy object is to decode.
1089 *
1090 * This method is called when an event notification is received for the phy
1091 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. -
1092 * decode the event - link failure events restart the starting state machine -
1093 * sata spinup hold events are ignored since they are expected - sata phy
1094 * detected event change to the wait speed event - any other events log a
1095 * warning message and set a failure status enum sci_status SCI_SUCCESS on a link
1096 * failure event SCI_FAILURE on any unexpected event notifation
1097 */
1098static enum sci_status scic_sds_phy_starting_substate_await_sata_phy_event_handler(
1099 struct scic_sds_phy *this_phy,
1100 u32 event_code)
1101{
1102 u32 result = SCI_SUCCESS;
1103
1104 switch (scu_get_event_code(event_code)) {
1105 case SCU_EVENT_LINK_FAILURE:
1106 /* Link failure change state back to the starting state */
1107 scic_sds_phy_restart_starting_state(this_phy);
1108 break;
1109
1110 case SCU_EVENT_SATA_SPINUP_HOLD:
1111 /*
1112 * These events might be received since we dont know how many may be in
1113 * the completion queue while waiting for power */
1114 break;
1115
1116 case SCU_EVENT_SATA_PHY_DETECTED:
1117 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
1118
1119 /* We have received the SATA PHY notification change state */
1120 sci_base_state_machine_change_state(
1121 scic_sds_phy_get_starting_substate_machine(this_phy),
1122 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
1123 );
1124 break;
1125
1126 case SCU_EVENT_SAS_PHY_DETECTED:
1127 /*
1128 * There has been a change in the phy type before OOB/SN for the
1129 * SATA finished start down the SAS link traning path. */
1130 scic_sds_phy_start_sas_link_training(this_phy);
1131 break;
1132
1133 default:
1134 dev_warn(sciphy_to_dev(this_phy),
1135 "%s: PHY starting substate machine received "
1136 "unexpected event_code %x\n",
1137 __func__,
1138 event_code);
1139
1140 result = SCI_FAILURE;
1141 break;
1142 }
1143
1144 return result;
1145}
1146
1147/**
1148 *
1149 * @phy: This struct scic_sds_phy object which has received an event.
1150 * @event_code: This is the event code which the phy object is to decode.
1151 *
1152 * This method is called when an event notification is received for the phy
1153 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN.
1154 * - decode the event - sata phy detected returns us back to this state. -
1155 * speed event detected causes a state transition to the wait for signature. -
1156 * link failure events restart the starting state machine - any other events
1157 * log a warning message and set a failure status enum sci_status SCI_SUCCESS on any
1158 * valid event notification SCI_FAILURE on any unexpected event notifation
1159 */
1160static enum sci_status scic_sds_phy_starting_substate_await_sata_speed_event_handler(
1161 struct scic_sds_phy *this_phy,
1162 u32 event_code)
1163{
1164 u32 result = SCI_SUCCESS;
1165
1166 switch (scu_get_event_code(event_code)) {
1167 case SCU_EVENT_SATA_PHY_DETECTED:
1168 /*
1169 * The hardware reports multiple SATA PHY detected events
1170 * ignore the extras */
1171 break;
1172
1173 case SCU_EVENT_SATA_15:
1174 case SCU_EVENT_SATA_15_SSC:
1175 scic_sds_phy_complete_link_training(
1176 this_phy,
1177 SCI_SAS_150_GB,
1178 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
1179 );
1180 break;
1181
1182 case SCU_EVENT_SATA_30:
1183 case SCU_EVENT_SATA_30_SSC:
1184 scic_sds_phy_complete_link_training(
1185 this_phy,
1186 SCI_SAS_300_GB,
1187 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
1188 );
1189 break;
1190
1191 case SCU_EVENT_SATA_60:
1192 case SCU_EVENT_SATA_60_SSC:
1193 scic_sds_phy_complete_link_training(
1194 this_phy,
1195 SCI_SAS_600_GB,
1196 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
1197 );
1198 break;
1199
1200 case SCU_EVENT_LINK_FAILURE:
1201 /* Link failure change state back to the starting state */
1202 scic_sds_phy_restart_starting_state(this_phy);
1203 break;
1204
1205 case SCU_EVENT_SAS_PHY_DETECTED:
1206 /*
1207 * There has been a change in the phy type before OOB/SN for the
1208 * SATA finished start down the SAS link traning path. */
1209 scic_sds_phy_start_sas_link_training(this_phy);
1210 break;
1211
1212 default:
1213 dev_warn(sciphy_to_dev(this_phy),
1214 "%s: PHY starting substate machine received "
1215 "unexpected event_code %x\n",
1216 __func__,
1217 event_code);
1218
1219 result = SCI_FAILURE;
1220 break;
1221 }
1222
1223 return result;
1224}
1225
1226/**
1227 *
1228 * @phy: This struct scic_sds_phy object which has received an event.
1229 * @event_code: This is the event code which the phy object is to decode.
1230 *
1231 * This method is called when an event notification is received for the phy
1232 * object when in the state SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. -
1233 * decode the event - sas phy detected event backs up the state machine to the
1234 * await speed notification. - identify timeout is an un-expected event and the
1235 * state machine is restarted. - link failure events restart the starting state
1236 * machine - any other events log a warning message and set a failure status
1237 * enum sci_status SCI_SUCCESS on any valid event notification SCI_FAILURE on any
1238 * unexpected event notifation
1239 */
1240static enum sci_status scic_sds_phy_starting_substate_await_sig_fis_event_handler(
1241 struct scic_sds_phy *this_phy,
1242 u32 event_code)
1243{
1244 u32 result = SCI_SUCCESS;
1245
1246 switch (scu_get_event_code(event_code)) {
1247 case SCU_EVENT_SATA_PHY_DETECTED:
1248 /* Backup the state machine */
1249 sci_base_state_machine_change_state(
1250 scic_sds_phy_get_starting_substate_machine(this_phy),
1251 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
1252 );
1253 break;
1254
1255 case SCU_EVENT_LINK_FAILURE:
1256 /* Link failure change state back to the starting state */
1257 scic_sds_phy_restart_starting_state(this_phy);
1258 break;
1259
1260 default:
1261 dev_warn(sciphy_to_dev(this_phy),
1262 "%s: PHY starting substate machine received "
1263 "unexpected event_code %x\n",
1264 __func__,
1265 event_code);
1266
1267 result = SCI_FAILURE;
1268 break;
1269 }
1270
1271 return result;
1272}
1273
1274
1275/*
1276 * *****************************************************************************
1277 * * SCIC SDS PHY FRAME_HANDLERS
1278 * ***************************************************************************** */
1279
1280/**
1281 *
1282 * @phy: This is struct scic_sds_phy object which is being requested to decode the
1283 * frame data.
1284 * @frame_index: This is the index of the unsolicited frame which was received
1285 * for this phy.
1286 *
1287 * This method decodes the unsolicited frame when the struct scic_sds_phy is in the
1288 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. - Get the UF Header - If the UF
1289 * is an IAF - Copy IAF data to local phy object IAF data buffer. - Change
1290 * starting substate to wait power. - else - log warning message of unexpected
1291 * unsolicted frame - release frame buffer enum sci_status SCI_SUCCESS
1292 */
1293static enum sci_status scic_sds_phy_starting_substate_await_iaf_uf_frame_handler(
1294 struct scic_sds_phy *this_phy,
1295 u32 frame_index)
1296{
1297 enum sci_status result;
1298 u32 *frame_words;
1299 struct sci_sas_identify_address_frame *identify_frame;
1300
1301 result = scic_sds_unsolicited_frame_control_get_header(
1302 &(scic_sds_phy_get_controller(this_phy)->uf_control),
1303 frame_index,
1304 (void **)&frame_words);
1305
1306 if (result != SCI_SUCCESS) {
1307 return result;
1308 }
1309
1310 frame_words[0] = SCIC_SWAP_DWORD(frame_words[0]);
1311 identify_frame = (struct sci_sas_identify_address_frame *)frame_words;
1312
1313 if (identify_frame->address_frame_type == 0) {
1314 /*
1315 * Byte swap the rest of the frame so we can make
1316 * a copy of the buffer */
1317 frame_words[1] = SCIC_SWAP_DWORD(frame_words[1]);
1318 frame_words[2] = SCIC_SWAP_DWORD(frame_words[2]);
1319 frame_words[3] = SCIC_SWAP_DWORD(frame_words[3]);
1320 frame_words[4] = SCIC_SWAP_DWORD(frame_words[4]);
1321 frame_words[5] = SCIC_SWAP_DWORD(frame_words[5]);
1322
1323 memcpy(
1324 &this_phy->phy_type.sas.identify_address_frame_buffer,
1325 identify_frame,
1326 sizeof(struct sci_sas_identify_address_frame)
1327 );
1328
1329 if (identify_frame->protocols.u.bits.smp_target) {
1330 /*
1331 * We got the IAF for an expander PHY go to the final state since
1332 * there are no power requirements for expander phys. */
1333 sci_base_state_machine_change_state(
1334 scic_sds_phy_get_starting_substate_machine(this_phy),
1335 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
1336 );
1337 } else {
1338 /* We got the IAF we can now go to the await spinup semaphore state */
1339 sci_base_state_machine_change_state(
1340 scic_sds_phy_get_starting_substate_machine(this_phy),
1341 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
1342 );
1343 }
1344
1345 result = SCI_SUCCESS;
1346 } else
1347 dev_warn(sciphy_to_dev(this_phy),
1348 "%s: PHY starting substate machine received "
1349 "unexpected frame id %x\n",
1350 __func__,
1351 frame_index);
1352
1353 /* Regardless of the result release this frame since we are done with it */
1354 scic_sds_controller_release_frame(
1355 scic_sds_phy_get_controller(this_phy), frame_index
1356 );
1357
1358 return result;
1359}
1360
1361/**
1362 *
1363 * @phy: This is struct scic_sds_phy object which is being requested to decode the
1364 * frame data.
1365 * @frame_index: This is the index of the unsolicited frame which was received
1366 * for this phy.
1367 *
1368 * This method decodes the unsolicited frame when the struct scic_sds_phy is in the
1369 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Get the UF Header - If
1370 * the UF is an SIGNATURE FIS - Copy IAF data to local phy object SIGNATURE FIS
1371 * data buffer. - else - log warning message of unexpected unsolicted frame -
1372 * release frame buffer enum sci_status SCI_SUCCESS Must decode the SIGNATURE FIS
1373 * data
1374 */
1375static enum sci_status scic_sds_phy_starting_substate_await_sig_fis_frame_handler(
1376 struct scic_sds_phy *this_phy,
1377 u32 frame_index)
1378{
1379 enum sci_status result;
1380 u32 *frame_words;
1381 struct sata_fis_header *fis_frame_header;
1382 u32 *fis_frame_data;
1383
1384 result = scic_sds_unsolicited_frame_control_get_header(
1385 &(scic_sds_phy_get_controller(this_phy)->uf_control),
1386 frame_index,
1387 (void **)&frame_words);
1388
1389 if (result != SCI_SUCCESS) {
1390 return result;
1391 }
1392
1393 fis_frame_header = (struct sata_fis_header *)frame_words;
1394
1395 if (
1396 (fis_frame_header->fis_type == SATA_FIS_TYPE_REGD2H)
1397 && !(fis_frame_header->status & ATA_STATUS_REG_BSY_BIT)
1398 ) {
1399 scic_sds_unsolicited_frame_control_get_buffer(
1400 &(scic_sds_phy_get_controller(this_phy)->uf_control),
1401 frame_index,
1402 (void **)&fis_frame_data
1403 );
1404
1405 scic_sds_controller_copy_sata_response(
1406 &this_phy->phy_type.sata.signature_fis_buffer,
1407 frame_words,
1408 fis_frame_data
1409 );
1410
1411 /* We got the IAF we can now go to the await spinup semaphore state */
1412 sci_base_state_machine_change_state(
1413 scic_sds_phy_get_starting_substate_machine(this_phy),
1414 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
1415 );
1416
1417 result = SCI_SUCCESS;
1418 } else
1419 dev_warn(sciphy_to_dev(this_phy),
1420 "%s: PHY starting substate machine received "
1421 "unexpected frame id %x\n",
1422 __func__,
1423 frame_index);
1424
1425 /* Regardless of the result release this frame since we are done with it */
1426 scic_sds_controller_release_frame(
1427 scic_sds_phy_get_controller(this_phy), frame_index
1428 );
1429
1430 return result;
1431}
1432
1433/*
1434 * *****************************************************************************
1435 * * SCIC SDS PHY POWER_HANDLERS
1436 * ***************************************************************************** */
1437
1438/**
1439 *
1440 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
1441 * object.
1442 *
1443 * This method is called by the struct scic_sds_controller when the phy object is
1444 * granted power. - The notify enable spinups are turned on for this phy object
1445 * - The phy state machine is transitioned to the
1446 * SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. enum sci_status SCI_SUCCESS
1447 */
1448static enum sci_status scic_sds_phy_starting_substate_await_sas_power_consume_power_handler(
1449 struct scic_sds_phy *this_phy)
1450{
1451 u32 enable_spinup;
1452
1453 enable_spinup = SCU_SAS_ENSPINUP_READ(this_phy);
1454 enable_spinup |= SCU_ENSPINUP_GEN_BIT(ENABLE);
1455 SCU_SAS_ENSPINUP_WRITE(this_phy, enable_spinup);
1456
1457 /* Change state to the final state this substate machine has run to completion */
1458 sci_base_state_machine_change_state(
1459 scic_sds_phy_get_starting_substate_machine(this_phy),
1460 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
1461 );
1462
1463 return SCI_SUCCESS;
1464}
1465
1466/**
1467 *
1468 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
1469 * object.
1470 *
1471 * This method is called by the struct scic_sds_controller when the phy object is
1472 * granted power. - The phy state machine is transitioned to the
1473 * SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. enum sci_status SCI_SUCCESS
1474 */
1475static enum sci_status scic_sds_phy_starting_substate_await_sata_power_consume_power_handler(
1476 struct scic_sds_phy *this_phy)
1477{
1478 u32 scu_sas_pcfg_value;
1479
1480 /* Release the spinup hold state and reset the OOB state machine */
1481 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
1482 scu_sas_pcfg_value &=
1483 ~(SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD) | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE));
1484 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
1485 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
1486
1487 /* Now restart the OOB operation */
1488 scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
1489 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
1490 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
1491
1492 /* Change state to the final state this substate machine has run to completion */
1493 sci_base_state_machine_change_state(
1494 scic_sds_phy_get_starting_substate_machine(this_phy),
1495 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
1496 );
1497
1498 return SCI_SUCCESS;
1499}
1500
1501/* --------------------------------------------------------------------------- */
1502
1503struct scic_sds_phy_state_handler
1504scic_sds_phy_starting_substate_handler_table[SCIC_SDS_PHY_STARTING_MAX_SUBSTATES] =
1505{
1506 /* SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL */
1507 {
1508 {
1509 scic_sds_phy_default_start_handler,
1510 scic_sds_phy_default_stop_handler,
1511 scic_sds_phy_default_reset_handler,
1512 scic_sds_phy_default_destroy_handler
1513 },
1514 scic_sds_phy_default_frame_handler,
1515 scic_sds_phy_default_event_handler,
1516 scic_sds_phy_default_consume_power_handler
1517 },
1518 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN */
1519 {
1520 {
1521 scic_sds_phy_default_start_handler,
1522 scic_sds_phy_default_stop_handler,
1523 scic_sds_phy_default_reset_handler,
1524 scic_sds_phy_default_destroy_handler
1525 },
1526 scic_sds_phy_default_frame_handler,
1527 scic_sds_phy_starting_substate_await_ossp_event_handler,
1528 scic_sds_phy_default_consume_power_handler
1529 },
1530 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN */
1531 {
1532 {
1533 scic_sds_phy_default_start_handler,
1534 scic_sds_phy_default_stop_handler,
1535 scic_sds_phy_default_reset_handler,
1536 scic_sds_phy_default_destroy_handler
1537 },
1538 scic_sds_phy_default_frame_handler,
1539 scic_sds_phy_starting_substate_await_sas_phy_speed_event_handler,
1540 scic_sds_phy_default_consume_power_handler
1541 },
1542 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF */
1543 {
1544 {
1545 scic_sds_phy_default_start_handler,
1546 scic_sds_phy_default_stop_handler,
1547 scic_sds_phy_default_reset_handler,
1548 scic_sds_phy_default_destroy_handler
1549 },
1550 scic_sds_phy_starting_substate_await_iaf_uf_frame_handler,
1551 scic_sds_phy_starting_substate_await_iaf_uf_event_handler,
1552 scic_sds_phy_default_consume_power_handler
1553 },
1554 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER */
1555 {
1556 {
1557 scic_sds_phy_default_start_handler,
1558 scic_sds_phy_default_stop_handler,
1559 scic_sds_phy_default_reset_handler,
1560 scic_sds_phy_default_destroy_handler
1561 },
1562 scic_sds_phy_default_frame_handler,
1563 scic_sds_phy_starting_substate_await_sas_power_event_handler,
1564 scic_sds_phy_starting_substate_await_sas_power_consume_power_handler
1565 },
1566 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER, */
1567 {
1568 {
1569 scic_sds_phy_default_start_handler,
1570 scic_sds_phy_default_stop_handler,
1571 scic_sds_phy_default_reset_handler,
1572 scic_sds_phy_default_destroy_handler
1573 },
1574 scic_sds_phy_default_frame_handler,
1575 scic_sds_phy_starting_substate_await_sata_power_event_handler,
1576 scic_sds_phy_starting_substate_await_sata_power_consume_power_handler
1577 },
1578 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN, */
1579 {
1580 {
1581 scic_sds_phy_default_start_handler,
1582 scic_sds_phy_default_stop_handler,
1583 scic_sds_phy_default_reset_handler,
1584 scic_sds_phy_default_destroy_handler
1585 },
1586 scic_sds_phy_default_frame_handler,
1587 scic_sds_phy_starting_substate_await_sata_phy_event_handler,
1588 scic_sds_phy_default_consume_power_handler
1589 },
1590 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN, */
1591 {
1592 {
1593 scic_sds_phy_default_start_handler,
1594 scic_sds_phy_default_stop_handler,
1595 scic_sds_phy_default_reset_handler,
1596 scic_sds_phy_default_destroy_handler
1597 },
1598 scic_sds_phy_default_frame_handler,
1599 scic_sds_phy_starting_substate_await_sata_speed_event_handler,
1600 scic_sds_phy_default_consume_power_handler
1601 },
1602 /* SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF, */
1603 {
1604 {
1605 scic_sds_phy_default_start_handler,
1606 scic_sds_phy_default_stop_handler,
1607 scic_sds_phy_default_reset_handler,
1608 scic_sds_phy_default_destroy_handler
1609 },
1610 scic_sds_phy_starting_substate_await_sig_fis_frame_handler,
1611 scic_sds_phy_starting_substate_await_sig_fis_event_handler,
1612 scic_sds_phy_default_consume_power_handler
1613 },
1614 /* SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL */
1615 {
1616 {
1617 scic_sds_phy_default_start_handler,
1618 scic_sds_phy_default_stop_handler,
1619 scic_sds_phy_default_reset_handler,
1620 scic_sds_phy_default_destroy_handler
1621 },
1622 scic_sds_phy_default_frame_handler,
1623 scic_sds_phy_default_event_handler,
1624 scic_sds_phy_default_consume_power_handler
1625 }
1626};
1627
1628/**
1629 * scic_sds_phy_set_starting_substate_handlers() -
1630 *
1631 * This macro sets the starting substate handlers by state_id
1632 */
1633#define scic_sds_phy_set_starting_substate_handlers(phy, state_id) \
1634 scic_sds_phy_set_state_handlers(\
1635 (phy), \
1636 &scic_sds_phy_starting_substate_handler_table[(state_id)] \
1637 )
1638
1639/*
1640 * ****************************************************************************
1641 * * PHY STARTING SUBSTATE METHODS
1642 * **************************************************************************** */
1643
1644/**
1645 *
1646 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1647 *
1648 * This method will perform the actions required by the struct scic_sds_phy on
1649 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL. - The initial state
1650 * handlers are put in place for the struct scic_sds_phy object. - The state is
1651 * changed to the wait phy type event notification. none
1652 */
1653static void scic_sds_phy_starting_initial_substate_enter(
1654 struct sci_base_object *object)
1655{
1656 struct scic_sds_phy *this_phy;
1657
1658 this_phy = (struct scic_sds_phy *)object;
1659
1660 scic_sds_phy_set_starting_substate_handlers(
1661 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL);
1662
1663 /* This is just an temporary state go off to the starting state */
1664 sci_base_state_machine_change_state(
1665 scic_sds_phy_get_starting_substate_machine(this_phy),
1666 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
1667 );
1668}
1669
1670/**
1671 *
1672 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1673 *
1674 * This method will perform the actions required by the struct scic_sds_phy on
1675 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_PHY_TYPE_EN. - Set the
1676 * struct scic_sds_phy object state handlers for this state. none
1677 */
1678static void scic_sds_phy_starting_await_ossp_en_substate_enter(
1679 struct sci_base_object *object)
1680{
1681 struct scic_sds_phy *this_phy;
1682
1683 this_phy = (struct scic_sds_phy *)object;
1684
1685 scic_sds_phy_set_starting_substate_handlers(
1686 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN
1687 );
1688}
1689
1690/**
1691 *
1692 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1693 *
1694 * This method will perform the actions required by the struct scic_sds_phy on
1695 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SPEED_EN. - Set the
1696 * struct scic_sds_phy object state handlers for this state. none
1697 */
1698static void scic_sds_phy_starting_await_sas_speed_en_substate_enter(
1699 struct sci_base_object *object)
1700{
1701 struct scic_sds_phy *this_phy;
1702
1703 this_phy = (struct scic_sds_phy *)object;
1704
1705 scic_sds_phy_set_starting_substate_handlers(
1706 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN
1707 );
1708}
1709
1710/**
1711 *
1712 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1713 *
1714 * This method will perform the actions required by the struct scic_sds_phy on
1715 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF. - Set the
1716 * struct scic_sds_phy object state handlers for this state. none
1717 */
1718static void scic_sds_phy_starting_await_iaf_uf_substate_enter(
1719 struct sci_base_object *object)
1720{
1721 struct scic_sds_phy *this_phy;
1722
1723 this_phy = (struct scic_sds_phy *)object;
1724
1725 scic_sds_phy_set_starting_substate_handlers(
1726 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF
1727 );
1728}
1729
1730/**
1731 *
1732 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1733 *
1734 * This method will perform the actions required by the struct scic_sds_phy on
1735 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. - Set the
1736 * struct scic_sds_phy object state handlers for this state. - Add this phy object to
1737 * the power control queue none
1738 */
1739static void scic_sds_phy_starting_await_sas_power_substate_enter(
1740 struct sci_base_object *object)
1741{
1742 struct scic_sds_phy *this_phy;
1743
1744 this_phy = (struct scic_sds_phy *)object;
1745
1746 scic_sds_phy_set_starting_substate_handlers(
1747 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER
1748 );
1749
1750 scic_sds_controller_power_control_queue_insert(
1751 scic_sds_phy_get_controller(this_phy),
1752 this_phy
1753 );
1754}
1755
1756/**
1757 *
1758 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1759 *
1760 * This method will perform the actions required by the struct scic_sds_phy on exiting
1761 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER. - Remove the
1762 * struct scic_sds_phy object from the power control queue. none
1763 */
1764static void scic_sds_phy_starting_await_sas_power_substate_exit(
1765 struct sci_base_object *object)
1766{
1767 struct scic_sds_phy *this_phy;
1768
1769 this_phy = (struct scic_sds_phy *)object;
1770
1771 scic_sds_controller_power_control_queue_remove(
1772 scic_sds_phy_get_controller(this_phy), this_phy
1773 );
1774}
1775
1776/**
1777 *
1778 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1779 *
1780 * This method will perform the actions required by the struct scic_sds_phy on
1781 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. - Set the
1782 * struct scic_sds_phy object state handlers for this state. - Add this phy object to
1783 * the power control queue none
1784 */
1785static void scic_sds_phy_starting_await_sata_power_substate_enter(
1786 struct sci_base_object *object)
1787{
1788 struct scic_sds_phy *this_phy;
1789
1790 this_phy = (struct scic_sds_phy *)object;
1791
1792 scic_sds_phy_set_starting_substate_handlers(
1793 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER
1794 );
1795
1796 scic_sds_controller_power_control_queue_insert(
1797 scic_sds_phy_get_controller(this_phy),
1798 this_phy
1799 );
1800}
1801
1802/**
1803 *
1804 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1805 *
1806 * This method will perform the actions required by the struct scic_sds_phy on exiting
1807 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER. - Remove the
1808 * struct scic_sds_phy object from the power control queue. none
1809 */
1810static void scic_sds_phy_starting_await_sata_power_substate_exit(
1811 struct sci_base_object *object)
1812{
1813 struct scic_sds_phy *this_phy;
1814
1815 this_phy = (struct scic_sds_phy *)object;
1816
1817 scic_sds_controller_power_control_queue_remove(
1818 scic_sds_phy_get_controller(this_phy),
1819 this_phy
1820 );
1821}
1822
1823/**
1824 *
1825 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1826 *
1827 * This method will perform the actions required by the struct scic_sds_phy on
1828 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN. - Set the
1829 * struct scic_sds_phy object state handlers for this state. none
1830 */
1831static void scic_sds_phy_starting_await_sata_phy_substate_enter(
1832 struct sci_base_object *object)
1833{
1834 struct scic_sds_phy *this_phy;
1835
1836 this_phy = (struct scic_sds_phy *)object;
1837
1838 scic_sds_phy_set_starting_substate_handlers(
1839 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN
1840 );
1841
1842 scic_cb_timer_start(
1843 scic_sds_phy_get_controller(this_phy),
1844 this_phy->sata_timeout_timer,
1845 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT
1846 );
1847}
1848
1849/**
1850 *
1851 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1852 *
1853 * This method will perform the actions required by the struct scic_sds_phy on exiting
1854 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - stop the timer
1855 * that was started on entry to await sata phy event notification none
1856 */
1857static void scic_sds_phy_starting_await_sata_phy_substate_exit(
1858 struct sci_base_object *object)
1859{
1860 struct scic_sds_phy *this_phy;
1861
1862 this_phy = (struct scic_sds_phy *)object;
1863
1864 scic_cb_timer_stop(
1865 scic_sds_phy_get_controller(this_phy),
1866 this_phy->sata_timeout_timer
1867 );
1868}
1869
1870/**
1871 *
1872 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1873 *
1874 * This method will perform the actions required by the struct scic_sds_phy on
1875 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - Set the
1876 * struct scic_sds_phy object state handlers for this state. none
1877 */
1878static void scic_sds_phy_starting_await_sata_speed_substate_enter(
1879 struct sci_base_object *object)
1880{
1881 struct scic_sds_phy *this_phy;
1882
1883 this_phy = (struct scic_sds_phy *)object;
1884
1885 scic_sds_phy_set_starting_substate_handlers(
1886 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN
1887 );
1888
1889 scic_cb_timer_start(
1890 scic_sds_phy_get_controller(this_phy),
1891 this_phy->sata_timeout_timer,
1892 SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT
1893 );
1894}
1895
1896/**
1897 *
1898 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1899 *
1900 * This method will perform the actions required by the struct scic_sds_phy on exiting
1901 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN. - stop the timer
1902 * that was started on entry to await sata phy event notification none
1903 */
1904static void scic_sds_phy_starting_await_sata_speed_substate_exit(
1905 struct sci_base_object *object)
1906{
1907 struct scic_sds_phy *this_phy;
1908
1909 this_phy = (struct scic_sds_phy *)object;
1910
1911 scic_cb_timer_stop(
1912 scic_sds_phy_get_controller(this_phy),
1913 this_phy->sata_timeout_timer
1914 );
1915}
1916
1917/**
1918 *
1919 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1920 *
1921 * This method will perform the actions required by the struct scic_sds_phy on
1922 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Set the
1923 * struct scic_sds_phy object state handlers for this state. - Start the SIGNATURE FIS
1924 * timeout timer none
1925 */
1926static void scic_sds_phy_starting_await_sig_fis_uf_substate_enter(
1927 struct sci_base_object *object)
1928{
1929 bool continue_to_ready_state;
1930 struct scic_sds_phy *this_phy;
1931
1932 this_phy = (struct scic_sds_phy *)object;
1933
1934 scic_sds_phy_set_starting_substate_handlers(
1935 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF
1936 );
1937
1938 continue_to_ready_state = scic_sds_port_link_detected(
1939 this_phy->owning_port,
1940 this_phy
1941 );
1942
1943 if (continue_to_ready_state) {
1944 /*
1945 * Clear the PE suspend condition so we can actually receive SIG FIS
1946 * The hardware will not respond to the XRDY until the PE suspend
1947 * condition is cleared. */
1948 scic_sds_phy_resume(this_phy);
1949
1950 scic_cb_timer_start(
1951 scic_sds_phy_get_controller(this_phy),
1952 this_phy->sata_timeout_timer,
1953 SCIC_SDS_SIGNATURE_FIS_TIMEOUT
1954 );
1955 } else {
1956 this_phy->is_in_link_training = false;
1957 }
1958}
1959
1960/**
1961 *
1962 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1963 *
1964 * This method will perform the actions required by the struct scic_sds_phy on exiting
1965 * the SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF. - Stop the SIGNATURE
1966 * FIS timeout timer. none
1967 */
1968static void scic_sds_phy_starting_await_sig_fis_uf_substate_exit(
1969 struct sci_base_object *object)
1970{
1971 struct scic_sds_phy *this_phy;
1972
1973 this_phy = (struct scic_sds_phy *)object;
1974
1975 scic_cb_timer_stop(
1976 scic_sds_phy_get_controller(this_phy),
1977 this_phy->sata_timeout_timer
1978 );
1979}
1980
1981/**
1982 *
1983 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
1984 *
1985 * This method will perform the actions required by the struct scic_sds_phy on
1986 * entering the SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL. - Set the struct scic_sds_phy
1987 * object state handlers for this state. - Change base state machine to the
1988 * ready state. none
1989 */
1990static void scic_sds_phy_starting_final_substate_enter(
1991 struct sci_base_object *object)
1992{
1993 struct scic_sds_phy *this_phy;
1994
1995 this_phy = (struct scic_sds_phy *)object;
1996
1997 scic_sds_phy_set_starting_substate_handlers(
1998 this_phy, SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL
1999 );
2000
2001 /*
2002 * State machine has run to completion so exit out and change
2003 * the base state machine to the ready state */
2004 sci_base_state_machine_change_state(
2005 scic_sds_phy_get_base_state_machine(this_phy),
2006 SCI_BASE_PHY_STATE_READY);
2007}
2008
2009/* --------------------------------------------------------------------------- */
2010
2011const struct sci_base_state scic_sds_phy_starting_substates[] = {
2012 [SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL] = {
2013 .enter_state = scic_sds_phy_starting_initial_substate_enter,
2014 },
2015 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN] = {
2016 .enter_state = scic_sds_phy_starting_await_ossp_en_substate_enter,
2017 },
2018 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN] = {
2019 .enter_state = scic_sds_phy_starting_await_sas_speed_en_substate_enter,
2020 },
2021 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF] = {
2022 .enter_state = scic_sds_phy_starting_await_iaf_uf_substate_enter,
2023 },
2024 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER] = {
2025 .enter_state = scic_sds_phy_starting_await_sas_power_substate_enter,
2026 .exit_state = scic_sds_phy_starting_await_sas_power_substate_exit,
2027 },
2028 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER] = {
2029 .enter_state = scic_sds_phy_starting_await_sata_power_substate_enter,
2030 .exit_state = scic_sds_phy_starting_await_sata_power_substate_exit
2031 },
2032 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN] = {
2033 .enter_state = scic_sds_phy_starting_await_sata_phy_substate_enter,
2034 .exit_state = scic_sds_phy_starting_await_sata_phy_substate_exit
2035 },
2036 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN] = {
2037 .enter_state = scic_sds_phy_starting_await_sata_speed_substate_enter,
2038 .exit_state = scic_sds_phy_starting_await_sata_speed_substate_exit
2039 },
2040 [SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF] = {
2041 .enter_state = scic_sds_phy_starting_await_sig_fis_uf_substate_enter,
2042 .exit_state = scic_sds_phy_starting_await_sig_fis_uf_substate_exit
2043 },
2044 [SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL] = {
2045 .enter_state = scic_sds_phy_starting_final_substate_enter,
2046 }
2047};
2048
2049/*
2050 * ***************************************************************************
2051 * * DEFAULT HANDLERS
2052 * *************************************************************************** */
2053
2054/**
2055 *
2056 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2057 * object.
2058 *
2059 * This is the default method for phy a start request. It will report a
2060 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2061 */
2062enum sci_status scic_sds_phy_default_start_handler(
2063 struct sci_base_phy *phy)
2064{
2065 struct scic_sds_phy *this_phy;
2066
2067 this_phy = (struct scic_sds_phy *)phy;
2068
2069 dev_warn(sciphy_to_dev(this_phy),
2070 "%s: SCIC Phy 0x%p requested to start from invalid "
2071 "state %d\n",
2072 __func__,
2073 this_phy,
2074 sci_base_state_machine_get_state(
2075 &this_phy->parent.state_machine));
2076
2077 return SCI_FAILURE_INVALID_STATE;
2078
2079}
2080
2081/**
2082 *
2083 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2084 * object.
2085 *
2086 * This is the default method for phy a stop request. It will report a warning
2087 * and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2088 */
2089enum sci_status scic_sds_phy_default_stop_handler(
2090 struct sci_base_phy *phy)
2091{
2092 struct scic_sds_phy *this_phy;
2093
2094 this_phy = (struct scic_sds_phy *)phy;
2095
2096 dev_warn(sciphy_to_dev(this_phy),
2097 "%s: SCIC Phy 0x%p requested to stop from invalid "
2098 "state %d\n",
2099 __func__,
2100 this_phy,
2101 sci_base_state_machine_get_state(
2102 &this_phy->parent.state_machine));
2103
2104 return SCI_FAILURE_INVALID_STATE;
2105}
2106
2107/**
2108 *
2109 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2110 * object.
2111 *
2112 * This is the default method for phy a reset request. It will report a
2113 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2114 */
2115enum sci_status scic_sds_phy_default_reset_handler(
2116 struct sci_base_phy *phy)
2117{
2118 struct scic_sds_phy *this_phy;
2119
2120 this_phy = (struct scic_sds_phy *)phy;
2121
2122 dev_warn(sciphy_to_dev(this_phy),
2123 "%s: SCIC Phy 0x%p requested to reset from invalid state "
2124 "%d\n",
2125 __func__,
2126 this_phy,
2127 sci_base_state_machine_get_state(
2128 &this_phy->parent.state_machine));
2129
2130 return SCI_FAILURE_INVALID_STATE;
2131}
2132
2133/**
2134 *
2135 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2136 * object.
2137 *
2138 * This is the default method for phy a destruct request. It will report a
2139 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2140 */
2141enum sci_status scic_sds_phy_default_destroy_handler(
2142 struct sci_base_phy *phy)
2143{
2144 struct scic_sds_phy *this_phy;
2145
2146 this_phy = (struct scic_sds_phy *)phy;
2147
2148 /* / @todo Implement something for the default */
2149 dev_warn(sciphy_to_dev(this_phy),
2150 "%s: SCIC Phy 0x%p requested to destroy from invalid "
2151 "state %d\n",
2152 __func__,
2153 this_phy,
2154 sci_base_state_machine_get_state(
2155 &this_phy->parent.state_machine));
2156
2157 return SCI_FAILURE_INVALID_STATE;
2158}
2159
2160/**
2161 *
2162 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2163 * object.
2164 * @frame_index: This is the frame index that was received from the SCU
2165 * hardware.
2166 *
2167 * This is the default method for a phy frame handling request. It will report
2168 * a warning, release the frame and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2169 */
2170enum sci_status scic_sds_phy_default_frame_handler(
2171 struct scic_sds_phy *this_phy,
2172 u32 frame_index)
2173{
2174 dev_warn(sciphy_to_dev(this_phy),
2175 "%s: SCIC Phy 0x%p received unexpected frame data %d "
2176 "while in state %d\n",
2177 __func__,
2178 this_phy,
2179 frame_index,
2180 sci_base_state_machine_get_state(
2181 &this_phy->parent.state_machine));
2182
2183 scic_sds_controller_release_frame(
2184 scic_sds_phy_get_controller(this_phy), frame_index);
2185
2186 return SCI_FAILURE_INVALID_STATE;
2187}
2188
2189/**
2190 *
2191 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2192 * object.
2193 * @event_code: This is the event code that was received from the SCU hardware.
2194 *
2195 * This is the default method for a phy event handler. It will report a
2196 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2197 */
2198enum sci_status scic_sds_phy_default_event_handler(
2199 struct scic_sds_phy *this_phy,
2200 u32 event_code)
2201{
2202 dev_warn(sciphy_to_dev(this_phy),
2203 "%s: SCIC Phy 0x%p received unexpected event status %x "
2204 "while in state %d\n",
2205 __func__,
2206 this_phy,
2207 event_code,
2208 sci_base_state_machine_get_state(
2209 &this_phy->parent.state_machine));
2210
2211 return SCI_FAILURE_INVALID_STATE;
2212}
2213
2214/**
2215 *
2216 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2217 * object.
2218 *
2219 * This is the default method for a phy consume power handler. It will report
2220 * a warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2221 */
2222enum sci_status scic_sds_phy_default_consume_power_handler(
2223 struct scic_sds_phy *this_phy)
2224{
2225 dev_warn(sciphy_to_dev(this_phy),
2226 "%s: SCIC Phy 0x%p given unexpected permission to consume "
2227 "power while in state %d\n",
2228 __func__,
2229 this_phy,
2230 sci_base_state_machine_get_state(
2231 &this_phy->parent.state_machine));
2232
2233 return SCI_FAILURE_INVALID_STATE;
2234}
2235
2236/*
2237 * ******************************************************************************
2238 * * PHY STOPPED STATE HANDLERS
2239 * ****************************************************************************** */
2240
2241/**
2242 *
2243 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2244 * object.
2245 *
2246 * This method takes the struct scic_sds_phy from a stopped state and attempts to
2247 * start it. - The phy state machine is transitioned to the
2248 * SCI_BASE_PHY_STATE_STARTING. enum sci_status SCI_SUCCESS
2249 */
2250static enum sci_status scic_sds_phy_stopped_state_start_handler(
2251 struct sci_base_phy *phy)
2252{
2253 struct scic_sds_phy *this_phy;
2254
2255 this_phy = (struct scic_sds_phy *)phy;
2256
2257 sci_base_state_machine_change_state(
2258 scic_sds_phy_get_base_state_machine(this_phy),
2259 SCI_BASE_PHY_STATE_STARTING
2260 );
2261
2262 return SCI_SUCCESS;
2263}
2264
2265/**
2266 *
2267 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2268 * object.
2269 *
2270 * This method takes the struct scic_sds_phy from a stopped state and destroys it. -
2271 * This function takes no action. Shouldnt this function transition the
2272 * struct sci_base_phy::state_machine to the SCI_BASE_PHY_STATE_FINAL? enum sci_status
2273 * SCI_SUCCESS
2274 */
2275static enum sci_status scic_sds_phy_stopped_state_destroy_handler(
2276 struct sci_base_phy *phy)
2277{
2278 struct scic_sds_phy *this_phy;
2279
2280 this_phy = (struct scic_sds_phy *)phy;
2281
2282 /* / @todo what do we actually need to do here? */
2283 return SCI_SUCCESS;
2284}
2285
2286/*
2287 * ******************************************************************************
2288 * * PHY STARTING STATE HANDLERS
2289 * ****************************************************************************** */
2290
2291/* All of these state handlers are mapped to the starting sub-state machine */
2292
2293/*
2294 * ******************************************************************************
2295 * * PHY READY STATE HANDLERS
2296 * ****************************************************************************** */
2297
2298/**
2299 *
2300 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2301 * object.
2302 *
2303 * This method takes the struct scic_sds_phy from a ready state and attempts to stop
2304 * it. - The phy state machine is transitioned to the
2305 * SCI_BASE_PHY_STATE_STOPPED. enum sci_status SCI_SUCCESS
2306 */
2307static enum sci_status scic_sds_phy_ready_state_stop_handler(
2308 struct sci_base_phy *phy)
2309{
2310 struct scic_sds_phy *this_phy;
2311
2312 this_phy = (struct scic_sds_phy *)phy;
2313
2314 sci_base_state_machine_change_state(
2315 scic_sds_phy_get_base_state_machine(this_phy),
2316 SCI_BASE_PHY_STATE_STOPPED
2317 );
2318
2319 return SCI_SUCCESS;
2320}
2321
2322/**
2323 *
2324 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2325 * object.
2326 *
2327 * This method takes the struct scic_sds_phy from a ready state and attempts to reset
2328 * it. - The phy state machine is transitioned to the
2329 * SCI_BASE_PHY_STATE_STARTING. enum sci_status SCI_SUCCESS
2330 */
2331static enum sci_status scic_sds_phy_ready_state_reset_handler(
2332 struct sci_base_phy *phy)
2333{
2334 struct scic_sds_phy *this_phy;
2335
2336 this_phy = (struct scic_sds_phy *)phy;
2337
2338 sci_base_state_machine_change_state(
2339 scic_sds_phy_get_base_state_machine(this_phy),
2340 SCI_BASE_PHY_STATE_RESETTING
2341 );
2342
2343 return SCI_SUCCESS;
2344}
2345
2346/**
2347 *
2348 * @phy: This is the struct scic_sds_phy object which has received the event.
2349 *
2350 * This method request the struct scic_sds_phy handle the received event. The only
2351 * event that we are interested in while in the ready state is the link failure
2352 * event. - decoded event is a link failure - transition the struct scic_sds_phy back
2353 * to the SCI_BASE_PHY_STATE_STARTING state. - any other event recived will
2354 * report a warning message enum sci_status SCI_SUCCESS if the event received is a
2355 * link failure SCI_FAILURE_INVALID_STATE for any other event received.
2356 */
2357static enum sci_status scic_sds_phy_ready_state_event_handler(
2358 struct scic_sds_phy *this_phy,
2359 u32 event_code)
2360{
2361 enum sci_status result = SCI_FAILURE;
2362
2363 switch (scu_get_event_code(event_code)) {
2364 case SCU_EVENT_LINK_FAILURE:
2365 /* Link failure change state back to the starting state */
2366 sci_base_state_machine_change_state(
2367 scic_sds_phy_get_base_state_machine(this_phy),
2368 SCI_BASE_PHY_STATE_STARTING
2369 );
2370
2371 result = SCI_SUCCESS;
2372 break;
2373
2374 case SCU_EVENT_BROADCAST_CHANGE:
2375 /* Broadcast change received. Notify the port. */
2376 if (scic_sds_phy_get_port(this_phy) != SCI_INVALID_HANDLE)
2377 scic_sds_port_broadcast_change_received(this_phy->owning_port, this_phy);
2378 else
2379 this_phy->bcn_received_while_port_unassigned = true;
2380 break;
2381
2382 default:
2383 dev_warn(sciphy_to_dev(this_phy),
2384 "%sP SCIC PHY 0x%p ready state machine received "
2385 "unexpected event_code %x\n",
2386 __func__,
2387 this_phy,
2388 event_code);
2389
2390 result = SCI_FAILURE_INVALID_STATE;
2391 break;
2392 }
2393
2394 return result;
2395}
2396
2397/* --------------------------------------------------------------------------- */
2398
2399/**
2400 *
2401 * @this_phy: This is the struct scic_sds_phy object which is receiving the event.
2402 * @event_code: This is the event code to be processed.
2403 *
2404 * This is the resetting state event handler. enum sci_status
2405 * SCI_FAILURE_INVALID_STATE
2406 */
2407static enum sci_status scic_sds_phy_resetting_state_event_handler(
2408 struct scic_sds_phy *this_phy,
2409 u32 event_code)
2410{
2411 enum sci_status result = SCI_FAILURE;
2412
2413 switch (scu_get_event_code(event_code)) {
2414 case SCU_EVENT_HARD_RESET_TRANSMITTED:
2415 /* Link failure change state back to the starting state */
2416 sci_base_state_machine_change_state(
2417 scic_sds_phy_get_base_state_machine(this_phy),
2418 SCI_BASE_PHY_STATE_STARTING
2419 );
2420
2421 result = SCI_SUCCESS;
2422 break;
2423
2424 default:
2425 dev_warn(sciphy_to_dev(this_phy),
2426 "%s: SCIC PHY 0x%p resetting state machine received "
2427 "unexpected event_code %x\n",
2428 __func__,
2429 this_phy,
2430 event_code);
2431
2432 result = SCI_FAILURE_INVALID_STATE;
2433 break;
2434 }
2435
2436 return result;
2437}
2438
2439/* --------------------------------------------------------------------------- */
2440
2441struct scic_sds_phy_state_handler
2442scic_sds_phy_state_handler_table[SCI_BASE_PHY_MAX_STATES] =
2443{
2444 /* SCI_BASE_PHY_STATE_INITIAL */
2445 {
2446 {
2447 scic_sds_phy_default_start_handler,
2448 scic_sds_phy_default_stop_handler,
2449 scic_sds_phy_default_reset_handler,
2450 scic_sds_phy_default_destroy_handler
2451 },
2452 scic_sds_phy_default_frame_handler,
2453 scic_sds_phy_default_event_handler,
2454 scic_sds_phy_default_consume_power_handler
2455 },
2456 /* SCI_BASE_PHY_STATE_STOPPED */
2457 {
2458 {
2459 scic_sds_phy_stopped_state_start_handler,
2460 scic_sds_phy_default_stop_handler,
2461 scic_sds_phy_default_reset_handler,
2462 scic_sds_phy_stopped_state_destroy_handler
2463 },
2464 scic_sds_phy_default_frame_handler,
2465 scic_sds_phy_default_event_handler,
2466 scic_sds_phy_default_consume_power_handler
2467 },
2468 /* SCI_BASE_PHY_STATE_STARTING */
2469 {
2470 {
2471 scic_sds_phy_default_start_handler,
2472 scic_sds_phy_default_stop_handler,
2473 scic_sds_phy_default_reset_handler,
2474 scic_sds_phy_default_destroy_handler
2475 },
2476 scic_sds_phy_default_frame_handler,
2477 scic_sds_phy_default_event_handler,
2478 scic_sds_phy_default_consume_power_handler
2479 },
2480 /* SCI_BASE_PHY_STATE_READY */
2481 {
2482 {
2483 scic_sds_phy_default_start_handler,
2484 scic_sds_phy_ready_state_stop_handler,
2485 scic_sds_phy_ready_state_reset_handler,
2486 scic_sds_phy_default_destroy_handler
2487 },
2488 scic_sds_phy_default_frame_handler,
2489 scic_sds_phy_ready_state_event_handler,
2490 scic_sds_phy_default_consume_power_handler
2491 },
2492 /* SCI_BASE_PHY_STATE_RESETTING */
2493 {
2494 {
2495 scic_sds_phy_default_start_handler,
2496 scic_sds_phy_default_stop_handler,
2497 scic_sds_phy_default_reset_handler,
2498 scic_sds_phy_default_destroy_handler
2499 },
2500 scic_sds_phy_default_frame_handler,
2501 scic_sds_phy_resetting_state_event_handler,
2502 scic_sds_phy_default_consume_power_handler
2503 },
2504 /* SCI_BASE_PHY_STATE_FINAL */
2505 {
2506 {
2507 scic_sds_phy_default_start_handler,
2508 scic_sds_phy_default_stop_handler,
2509 scic_sds_phy_default_reset_handler,
2510 scic_sds_phy_default_destroy_handler
2511 },
2512 scic_sds_phy_default_frame_handler,
2513 scic_sds_phy_default_event_handler,
2514 scic_sds_phy_default_consume_power_handler
2515 }
2516};
2517
2518/*
2519 * ****************************************************************************
2520 * * PHY STATE PRIVATE METHODS
2521 * **************************************************************************** */
2522
2523/**
2524 *
2525 * @this_phy: This is the struct scic_sds_phy object to stop.
2526 *
2527 * This method will stop the struct scic_sds_phy object. This does not reset the
2528 * protocol engine it just suspends it and places it in a state where it will
2529 * not cause the end device to power up. none
2530 */
2531static void scu_link_layer_stop_protocol_engine(
2532 struct scic_sds_phy *this_phy)
2533{
2534 u32 scu_sas_pcfg_value;
2535 u32 enable_spinup_value;
2536
2537 /* Suspend the protocol engine and place it in a sata spinup hold state */
2538 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
2539 scu_sas_pcfg_value |= (
2540 SCU_SAS_PCFG_GEN_BIT(OOB_RESET)
2541 | SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE)
2542 | SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD)
2543 );
2544 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
2545
2546 /* Disable the notify enable spinup primitives */
2547 enable_spinup_value = SCU_SAS_ENSPINUP_READ(this_phy);
2548 enable_spinup_value &= ~SCU_ENSPINUP_GEN_BIT(ENABLE);
2549 SCU_SAS_ENSPINUP_WRITE(this_phy, enable_spinup_value);
2550}
2551
2552/**
2553 *
2554 *
2555 * This method will start the OOB/SN state machine for this struct scic_sds_phy object.
2556 */
2557static void scu_link_layer_start_oob(
2558 struct scic_sds_phy *this_phy)
2559{
2560 u32 scu_sas_pcfg_value;
2561
2562 scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);
2563 scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
2564 scu_sas_pcfg_value &=
2565 ~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) | SCU_SAS_PCFG_GEN_BIT(HARD_RESET));
2566
2567 SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
2568}
2569
2570/**
2571 *
2572 *
2573 * This method will transmit a hard reset request on the specified phy. The SCU
2574 * hardware requires that we reset the OOB state machine and set the hard reset
2575 * bit in the phy configuration register. We then must start OOB over with the
2576 * hard reset bit set.
2577 */
2578static void scu_link_layer_tx_hard_reset(
2579 struct scic_sds_phy *this_phy)
2580{
2581 u32 phy_configuration_value;
2582
2583 /*
2584 * SAS Phys must wait for the HARD_RESET_TX event notification to transition
2585 * to the starting state. */
2586 phy_configuration_value = SCU_SAS_PCFG_READ(this_phy);
2587 phy_configuration_value |=
2588 (SCU_SAS_PCFG_GEN_BIT(HARD_RESET) | SCU_SAS_PCFG_GEN_BIT(OOB_RESET));
2589 SCU_SAS_PCFG_WRITE(this_phy, phy_configuration_value);
2590
2591 /* Now take the OOB state machine out of reset */
2592 phy_configuration_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
2593 phy_configuration_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
2594 SCU_SAS_PCFG_WRITE(this_phy, phy_configuration_value);
2595}
2596
2597/*
2598 * ****************************************************************************
2599 * * PHY BASE STATE METHODS
2600 * **************************************************************************** */
2601
2602/**
2603 *
2604 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2605 *
2606 * This method will perform the actions required by the struct scic_sds_phy on
2607 * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state
2608 * handlers for the phy object base state machine initial state. none
2609 */
2610static void scic_sds_phy_initial_state_enter(
2611 struct sci_base_object *object)
2612{
2613 struct scic_sds_phy *this_phy;
2614
2615 this_phy = (struct scic_sds_phy *)object;
2616
2617 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_STOPPED);
2618}
2619
2620/**
2621 *
2622 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2623 *
2624 * This method will perform the actions required by the struct scic_sds_phy on
2625 * entering the SCI_BASE_PHY_STATE_INITIAL. - This function sets the state
2626 * handlers for the phy object base state machine initial state. - The SCU
2627 * hardware is requested to stop the protocol engine. none
2628 */
2629static void scic_sds_phy_stopped_state_enter(
2630 struct sci_base_object *object)
2631{
2632 struct scic_sds_phy *this_phy;
2633
2634 this_phy = (struct scic_sds_phy *)object;
2635
2636 /* / @todo We need to get to the controller to place this PE in a reset state */
2637
2638 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_STOPPED);
2639
2640 scu_link_layer_stop_protocol_engine(this_phy);
2641}
2642
2643/**
2644 *
2645 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2646 *
2647 * This method will perform the actions required by the struct scic_sds_phy on
2648 * entering the SCI_BASE_PHY_STATE_STARTING. - This function sets the state
2649 * handlers for the phy object base state machine starting state. - The SCU
2650 * hardware is requested to start OOB/SN on this protocl engine. - The phy
2651 * starting substate machine is started. - If the previous state was the ready
2652 * state then the struct scic_sds_controller is informed that the phy has gone link
2653 * down. none
2654 */
2655static void scic_sds_phy_starting_state_enter(
2656 struct sci_base_object *object)
2657{
2658 struct scic_sds_phy *this_phy;
2659
2660 this_phy = (struct scic_sds_phy *)object;
2661
2662 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_STARTING);
2663
2664 scu_link_layer_stop_protocol_engine(this_phy);
2665 scu_link_layer_start_oob(this_phy);
2666
2667 /* We don't know what kind of phy we are going to be just yet */
2668 this_phy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
2669 this_phy->bcn_received_while_port_unassigned = false;
2670
2671 /* Change over to the starting substate machine to continue */
2672 sci_base_state_machine_start(&this_phy->starting_substate_machine);
2673
2674 if (this_phy->parent.state_machine.previous_state_id
2675 == SCI_BASE_PHY_STATE_READY) {
2676 scic_sds_controller_link_down(
2677 scic_sds_phy_get_controller(this_phy),
2678 scic_sds_phy_get_port(this_phy),
2679 this_phy
2680 );
2681 }
2682}
2683
2684/**
2685 *
2686 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2687 *
2688 * This method will perform the actions required by the struct scic_sds_phy on
2689 * entering the SCI_BASE_PHY_STATE_READY. - This function sets the state
2690 * handlers for the phy object base state machine ready state. - The SCU
2691 * hardware protocol engine is resumed. - The struct scic_sds_controller is informed
2692 * that the phy object has gone link up. none
2693 */
2694static void scic_sds_phy_ready_state_enter(
2695 struct sci_base_object *object)
2696{
2697 struct scic_sds_phy *this_phy;
2698
2699 this_phy = (struct scic_sds_phy *)object;
2700
2701 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_READY);
2702
2703 scic_sds_controller_link_up(
2704 scic_sds_phy_get_controller(this_phy),
2705 scic_sds_phy_get_port(this_phy),
2706 this_phy
2707 );
2708}
2709
2710/**
2711 *
2712 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2713 *
2714 * This method will perform the actions required by the struct scic_sds_phy on exiting
2715 * the SCI_BASE_PHY_STATE_INITIAL. This function suspends the SCU hardware
2716 * protocol engine represented by this struct scic_sds_phy object. none
2717 */
2718static void scic_sds_phy_ready_state_exit(
2719 struct sci_base_object *object)
2720{
2721 struct scic_sds_phy *this_phy;
2722
2723 this_phy = (struct scic_sds_phy *)object;
2724
2725 scic_sds_phy_suspend(this_phy);
2726}
2727
2728/**
2729 *
2730 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2731 *
2732 * This method will perform the actions required by the struct scic_sds_phy on
2733 * entering the SCI_BASE_PHY_STATE_RESETTING. - This function sets the state
2734 * handlers for the phy object base state machine resetting state. none
2735 */
2736static void scic_sds_phy_resetting_state_enter(
2737 struct sci_base_object *object)
2738{
2739 struct scic_sds_phy *this_phy;
2740
2741 this_phy = (struct scic_sds_phy *)object;
2742
2743 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_RESETTING);
2744
2745 /*
2746 * The phy is being reset, therefore deactivate it from the port.
2747 * In the resetting state we don't notify the user regarding
2748 * link up and link down notifications. */
2749 scic_sds_port_deactivate_phy(this_phy->owning_port, this_phy, false);
2750
2751 if (this_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
2752 scu_link_layer_tx_hard_reset(this_phy);
2753 } else {
2754 /*
2755 * The SCU does not need to have a descrete reset state so just go back to
2756 * the starting state. */
2757 sci_base_state_machine_change_state(
2758 &this_phy->parent.state_machine,
2759 SCI_BASE_PHY_STATE_STARTING
2760 );
2761 }
2762}
2763
2764/**
2765 *
2766 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_phy object.
2767 *
2768 * This method will perform the actions required by the struct scic_sds_phy on
2769 * entering the SCI_BASE_PHY_STATE_FINAL. - This function sets the state
2770 * handlers for the phy object base state machine final state. none
2771 */
2772static void scic_sds_phy_final_state_enter(
2773 struct sci_base_object *object)
2774{
2775 struct scic_sds_phy *this_phy;
2776
2777 this_phy = (struct scic_sds_phy *)object;
2778
2779 scic_sds_phy_set_base_state_handlers(this_phy, SCI_BASE_PHY_STATE_FINAL);
2780
2781 /* Nothing to do here */
2782}
2783
2784/* --------------------------------------------------------------------------- */
2785
2786const struct sci_base_state scic_sds_phy_state_table[] = {
2787 [SCI_BASE_PHY_STATE_INITIAL] = {
2788 .enter_state = scic_sds_phy_initial_state_enter,
2789 },
2790 [SCI_BASE_PHY_STATE_STOPPED] = {
2791 .enter_state = scic_sds_phy_stopped_state_enter,
2792 },
2793 [SCI_BASE_PHY_STATE_STARTING] = {
2794 .enter_state = scic_sds_phy_starting_state_enter,
2795 },
2796 [SCI_BASE_PHY_STATE_READY] = {
2797 .enter_state = scic_sds_phy_ready_state_enter,
2798 .exit_state = scic_sds_phy_ready_state_exit,
2799 },
2800 [SCI_BASE_PHY_STATE_RESETTING] = {
2801 .enter_state = scic_sds_phy_resetting_state_enter,
2802 },
2803 [SCI_BASE_PHY_STATE_FINAL] = {
2804 .enter_state = scic_sds_phy_final_state_enter,
2805 },
2806};
2807
diff --git a/drivers/scsi/isci/core/scic_sds_phy.h b/drivers/scsi/isci/core/scic_sds_phy.h
new file mode 100644
index 000000000000..d9691b30e457
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_phy.h
@@ -0,0 +1,491 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_SDS_PHY_H_
57#define _SCIC_SDS_PHY_H_
58
59/**
60 * This file contains the structures, constants and prototypes for the
61 * struct scic_sds_phy object.
62 *
63 *
64 */
65
66#include "intel_sata.h"
67#include "intel_sas.h"
68#include "sci_base_phy.h"
69#include "scu_registers.h"
70
71struct scic_sds_port;
72/**
73 *
74 *
75 * This is the timeout value for the SATA phy to wait for a SIGNATURE FIS
76 * before restarting the starting state machine. Technically, the old parallel
77 * ATA specification required up to 30 seconds for a device to issue its
78 * signature FIS as a result of a soft reset. Now we see that devices respond
79 * generally within 15 seconds, but we'll use 25 for now.
80 */
81#define SCIC_SDS_SIGNATURE_FIS_TIMEOUT 25000
82
83/**
84 *
85 *
86 * This is the timeout for the SATA OOB/SN because the hardware does not
87 * recognize a hot plug after OOB signal but before the SN signals. We need to
88 * make sure after a hotplug timeout if we have not received the speed event
89 * notification from the hardware that we restart the hardware OOB state
90 * machine.
91 */
92#define SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT 250
93
94/**
95 * enum SCIC_SDS_PHY_STARTING_SUBSTATES -
96 *
97 *
98 */
99enum SCIC_SDS_PHY_STARTING_SUBSTATES {
100 /**
101 * Initial state
102 */
103 SCIC_SDS_PHY_STARTING_SUBSTATE_INITIAL,
104
105 /**
106 * Wait state for the hardware OSSP event type notification
107 */
108 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_OSSP_EN,
109
110 /**
111 * Wait state for the PHY speed notification
112 */
113 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_SPEED_EN,
114
115 /**
116 * Wait state for the IAF Unsolicited frame notification
117 */
118 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_IAF_UF,
119
120 /**
121 * Wait state for the request to consume power
122 */
123 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SAS_POWER,
124
125 /**
126 * Wait state for request to consume power
127 */
128 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_POWER,
129
130 /**
131 * Wait state for the SATA PHY notification
132 */
133 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_PHY_EN,
134
135 /**
136 * Wait for the SATA PHY speed notification
137 */
138 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SATA_SPEED_EN,
139
140 /**
141 * Wait state for the SIGNATURE FIS unsolicited frame notification
142 */
143 SCIC_SDS_PHY_STARTING_SUBSTATE_AWAIT_SIG_FIS_UF,
144
145 /**
146 * Exit state for this state machine
147 */
148 SCIC_SDS_PHY_STARTING_SUBSTATE_FINAL,
149
150 /**
151 * Maximum number of substates for the STARTING state machine
152 */
153 SCIC_SDS_PHY_STARTING_MAX_SUBSTATES
154};
155
156struct scic_sds_port;
157struct scic_sds_controller;
158
159#ifdef SCIC_DEBUG_ENABLED
160#define MAX_STATE_TRANSITION_RECORD (256)
161
162/**
163 *
164 *
165 * Debug code to record the state transitions for the phy object
166 */
167struct scic_sds_phy_state_record {
168 struct sci_base_observer base_state_observer;
169 struct sci_base_observer starting_state_observer;
170
171 u16 index;
172
173 u32 state_transition_table[MAX_STATE_TRANSITION_RECORD];
174
175};
176#endif /* SCIC_DEBUG_ENABLED */
177
178/**
179 * This enumeration provides a named phy type for the state machine
180 *
181 *
182 */
183enum SCIC_SDS_PHY_PROTOCOL {
184 /**
185 * This is an unknown phy type since there is either nothing on the other
186 * end or we have not detected the phy type as yet.
187 */
188 SCIC_SDS_PHY_PROTOCOL_UNKNOWN,
189
190 /**
191 * This is a SAS PHY
192 */
193 SCIC_SDS_PHY_PROTOCOL_SAS,
194
195 /**
196 * This is a SATA PHY
197 */
198 SCIC_SDS_PHY_PROTOCOL_SATA,
199
200 SCIC_SDS_MAX_PHY_PROTOCOLS
201};
202
203/**
204 * struct scic_sds_phy - This structure contains or references all of the data
205 * necessary to represent the core phy object and SCU harware protocol
206 * engine.
207 *
208 *
209 */
210struct scic_sds_phy {
211 struct sci_base_phy parent;
212
213 /**
214 * This field specifies the port object that owns/contains this phy.
215 */
216 struct scic_sds_port *owning_port;
217
218 /**
219 * This field indicates whether the phy supports 1.5 Gb/s, 3.0 Gb/s,
220 * or 6.0 Gb/s operation.
221 */
222 enum sci_sas_link_rate max_negotiated_speed;
223
224 /**
225 * This member specifies the protocol being utilized on this phy. This
226 * field contains a legitamite value once the PHY has link trained with
227 * a remote phy.
228 */
229 enum SCIC_SDS_PHY_PROTOCOL protocol;
230
231 /**
232 * This field specifies the index with which this phy is associated (0-3).
233 */
234 u8 phy_index;
235
236 /**
237 * This member indicates if this particular PHY has received a BCN while
238 * it had no port assignement. This BCN will be reported once the phy is
239 * assigned to a port.
240 */
241 bool bcn_received_while_port_unassigned;
242
243 /**
244 * This field indicates if this PHY is currently in the process of
245 * link training (i.e. it has started OOB, but has yet to perform
246 * IAF exchange/Signature FIS reception).
247 */
248 bool is_in_link_training;
249
250 union {
251 struct {
252 struct sci_sas_identify_address_frame identify_address_frame_buffer;
253
254 } sas;
255
256 struct {
257 struct sata_fis_reg_d2h signature_fis_buffer;
258
259 } sata;
260
261 } phy_type;
262
263 /**
264 * This field contains a reference to the timer utilized in detecting
265 * when a signature FIS timeout has occurred. The signature FIS is the
266 * first FIS sent by an attached SATA device after OOB/SN.
267 */
268 void *sata_timeout_timer;
269
270 struct scic_sds_phy_state_handler *state_handlers;
271
272 struct sci_base_state_machine starting_substate_machine;
273
274 #ifdef SCIC_DEBUG_ENABLED
275 struct scic_sds_phy_state_record state_record;
276 #endif /* SCIC_DEBUG_ENABLED */
277
278 /**
279 * This field points to the link layer register set within the SCU.
280 */
281 struct scu_link_layer_registers *link_layer_registers;
282
283};
284
285
286typedef enum sci_status (*SCIC_SDS_PHY_EVENT_HANDLER_T)(struct scic_sds_phy *, u32);
287typedef enum sci_status (*SCIC_SDS_PHY_FRAME_HANDLER_T)(struct scic_sds_phy *, u32);
288typedef enum sci_status (*SCIC_SDS_PHY_POWER_HANDLER_T)(struct scic_sds_phy *);
289
290/**
291 * struct scic_sds_phy_state_handler -
292 *
293 *
294 */
295struct scic_sds_phy_state_handler {
296 /**
297 * This is the struct sci_base_phy object state handlers.
298 */
299 struct sci_base_phy_state_handler parent;
300
301 /**
302 * The state handler for unsolicited frames received from the SCU hardware.
303 */
304 SCIC_SDS_PHY_FRAME_HANDLER_T frame_handler;
305
306 /**
307 * The state handler for events received from the SCU hardware.
308 */
309 SCIC_SDS_PHY_EVENT_HANDLER_T event_handler;
310
311 /**
312 * The state handler for staggered spinup.
313 */
314 SCIC_SDS_PHY_POWER_HANDLER_T consume_power_handler;
315
316};
317
318extern struct scic_sds_phy_state_handler scic_sds_phy_state_handler_table[];
319extern const struct sci_base_state scic_sds_phy_state_table[];
320extern const struct sci_base_state scic_sds_phy_starting_substates[];
321extern struct scic_sds_phy_state_handler
322 scic_sds_phy_starting_substate_handler_table[];
323
324
325/**
326 * scic_sds_phy_get_index() -
327 *
328 * This macro returns the phy index for the specified phy
329 */
330#define scic_sds_phy_get_index(phy) \
331 ((phy)->phy_index)
332
333/**
334 * scic_sds_phy_get_controller() - This macro returns the controller for this
335 * phy
336 *
337 *
338 */
339#define scic_sds_phy_get_controller(phy) \
340 (scic_sds_port_get_controller((phy)->owning_port))
341
342/**
343 * scic_sds_phy_get_base_state_machine() - This macro returns the state machine
344 * for the base phy
345 *
346 *
347 */
348#define scic_sds_phy_get_base_state_machine(phy) \
349 (&(phy)->parent.state_machine)
350
351/**
352 * scic_sds_phy_get_starting_substate_machine() - This macro returns the
353 * starting substate machine for this phy
354 *
355 *
356 */
357#define scic_sds_phy_get_starting_substate_machine(phy) \
358 (&(phy)->starting_substate_machine)
359
360/**
361 * scic_sds_phy_set_state_handlers() - This macro sets the state handlers for
362 * this phy object
363 *
364 *
365 */
366#define scic_sds_phy_set_state_handlers(phy, handlers) \
367 ((phy)->state_handlers = (handlers))
368
369/**
370 * scic_sds_phy_set_base_state_handlers() -
371 *
372 * This macro set the base state handlers for the phy object.
373 */
374#define scic_sds_phy_set_base_state_handlers(phy, state_id) \
375 scic_sds_phy_set_state_handlers(\
376 (phy), \
377 &scic_sds_phy_state_handler_table[(state_id)] \
378 )
379
380/**
381 * scic_sds_phy_is_ready() -
382 *
383 * This macro returns true if the current base state for this phy is
384 * SCI_BASE_PHY_STATE_READY
385 */
386#define scic_sds_phy_is_ready(phy) \
387 (\
388 SCI_BASE_PHY_STATE_READY \
389 == sci_base_state_machine_get_state(\
390 scic_sds_phy_get_base_state_machine(phy) \
391 ) \
392 )
393
394/* --------------------------------------------------------------------------- */
395
396
397
398
399/* --------------------------------------------------------------------------- */
400
401void scic_sds_phy_construct(
402 struct scic_sds_phy *this_phy,
403 struct scic_sds_port *owning_port,
404 u8 phy_index);
405
406struct scic_sds_port *scic_sds_phy_get_port(
407 struct scic_sds_phy *this_phy);
408
409void scic_sds_phy_set_port(
410 struct scic_sds_phy *this_phy,
411 struct scic_sds_port *owning_port);
412
413enum sci_status scic_sds_phy_initialize(
414 struct scic_sds_phy *this_phy,
415 struct scu_link_layer_registers *link_layer_registers);
416
417enum sci_status scic_sds_phy_start(
418 struct scic_sds_phy *this_phy);
419
420enum sci_status scic_sds_phy_stop(
421 struct scic_sds_phy *this_phy);
422
423enum sci_status scic_sds_phy_reset(
424 struct scic_sds_phy *this_phy);
425
426/* --------------------------------------------------------------------------- */
427
428void scic_sds_phy_suspend(
429 struct scic_sds_phy *this_phy);
430
431void scic_sds_phy_resume(
432 struct scic_sds_phy *this_phy);
433
434/* --------------------------------------------------------------------------- */
435
436enum sci_status scic_sds_phy_event_handler(
437 struct scic_sds_phy *this_phy,
438 u32 event_code);
439
440enum sci_status scic_sds_phy_frame_handler(
441 struct scic_sds_phy *this_phy,
442 u32 frame_index);
443
444enum sci_status scic_sds_phy_consume_power_handler(
445 struct scic_sds_phy *this_phy);
446
447void scic_sds_phy_get_sas_address(
448 struct scic_sds_phy *this_phy,
449 struct sci_sas_address *sas_address);
450
451void scic_sds_phy_get_attached_sas_address(
452 struct scic_sds_phy *this_phy,
453 struct sci_sas_address *sas_address);
454
455void scic_sds_phy_get_protocols(
456 struct scic_sds_phy *this_phy,
457 struct sci_sas_identify_address_frame_protocols *protocols);
458
459void scic_sds_phy_get_attached_phy_protocols(
460 struct scic_sds_phy *this_phy,
461 struct sci_sas_identify_address_frame_protocols *protocols);
462
463/*
464 * ****************************************************************************-
465 * * SCIC SDS PHY Handler Methods
466 * ****************************************************************************- */
467
468enum sci_status scic_sds_phy_default_start_handler(
469 struct sci_base_phy *phy);
470
471enum sci_status scic_sds_phy_default_stop_handler(
472 struct sci_base_phy *phy);
473
474enum sci_status scic_sds_phy_default_reset_handler(
475 struct sci_base_phy *phy);
476
477enum sci_status scic_sds_phy_default_destroy_handler(
478 struct sci_base_phy *phy);
479
480enum sci_status scic_sds_phy_default_frame_handler(
481 struct scic_sds_phy *phy,
482 u32 frame_index);
483
484enum sci_status scic_sds_phy_default_event_handler(
485 struct scic_sds_phy *phy,
486 u32 evnet_code);
487
488enum sci_status scic_sds_phy_default_consume_power_handler(
489 struct scic_sds_phy *phy);
490
491#endif /* _SCIC_SDS_PHY_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_phy_registers.h b/drivers/scsi/isci/core/scic_sds_phy_registers.h
new file mode 100644
index 000000000000..7883819035da
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_phy_registers.h
@@ -0,0 +1,187 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_SDS_PHY_REGISTERS_H_
57#define _SCIC_SDS_PHY_REGISTERS_H_
58
59/**
60 * This file contains the macros used by the phy object to read/write to the
61 * SCU link layer registers.
62 *
63 *
64 */
65
66#include "scic_sds_controller.h"
67
68/*
69 * *****************************************************************************
70 * * SCU LINK LAYER REGISTER OPERATIONS
71 * ***************************************************************************** */
72
73/**
74 * scu_link_layer_register_read() -
75 *
76 * THis macro requests the SCU register write for the specified link layer
77 * register.
78 */
79#define scu_link_layer_register_read(phy, reg) \
80 scu_register_read(\
81 scic_sds_phy_get_controller(phy), \
82 (phy)->link_layer_registers->reg \
83 )
84
85/**
86 * scu_link_layer_register_write() -
87 *
88 * This macro requests the SCU register read for the specified link layer
89 * register.
90 */
91#define scu_link_layer_register_write(phy, reg, value) \
92 scu_register_write(\
93 scic_sds_phy_get_controller(phy), \
94 (phy)->link_layer_registers->reg, \
95 (value) \
96 )
97
98/*
99 * *****************************************************************************
100 * * SCU LINK LAYER REGISTERS
101 * ***************************************************************************** */
102
103/* / This macro reads from the SAS Identify Frame PHY Identifier register */
104#define SCU_SAS_TIPID_READ(phy) \
105 scu_link_layer_register_read(phy, identify_frame_phy_id)
106
107/* / This macro writes to the SAS Identify Frame PHY Identifier register */
108#define SCU_SAS_TIPID_WRITE(phy, value) \
109 scu_link_layer_register_write(phy, identify_frame_phy_id, value)
110
111/* / This macro reads from the SAS Identification register */
112#define SCU_SAS_TIID_READ(phy) \
113 scu_link_layer_register_read(phy, transmit_identification)
114
115/* / This macro writes to the SAS Identification register */
116#define SCU_SAS_TIID_WRITE(phy, value) \
117 scu_link_layer_register_write(phy, transmit_identification, value)
118
119/* / This macro reads the SAS Device Name High register */
120#define SCU_SAS_TIDNH_READ(phy) \
121 scu_link_layer_register_read(phy, sas_device_name_high)
122
123/* / This macro writes the SAS Device Name High register */
124#define SCU_SAS_TIDNH_WRITE(phy, value) \
125 scu_link_layer_register_write(phy, sas_device_name_high, value)
126
127/* / This macro reads the SAS Device Name Low register */
128#define SCU_SAS_TIDNL_READ(phy) \
129 scu_link_layer_register_read(phy, sas_device_name_low)
130
131/* / This macro writes the SAS Device Name Low register */
132#define SCU_SAS_TIDNL_WRITE(phy, value) \
133 scu_link_layer_register_write(phy, sas_device_name_low, value)
134
135/* / This macro reads the Source SAS Address High register */
136#define SCU_SAS_TISSAH_READ(phy) \
137 scu_link_layer_register_read(phy, source_sas_address_high)
138
139/* / This macro writes the Source SAS Address High register */
140#define SCU_SAS_TISSAH_WRITE(phy, value) \
141 scu_link_layer_register_write(phy, source_sas_address_high, value)
142
143/* / This macro reads the Source SAS Address Low register */
144#define SCU_SAS_TISSAL_READ(phy) \
145 scu_link_layer_register_read(phy, source_sas_address_low)
146
147/* / This macro writes the Source SAS Address Low register */
148#define SCU_SAS_TISSAL_WRITE(phy, value) \
149 scu_link_layer_register_write(phy, source_sas_address_low, value)
150
151/* / This macro reads the PHY Configuration register */
152#define SCU_SAS_PCFG_READ(phy) \
153 scu_link_layer_register_read(phy, phy_configuration);
154
155/* / This macro writes the PHY Configuration register */
156#define SCU_SAS_PCFG_WRITE(phy, value) \
157 scu_link_layer_register_write(phy, phy_configuration, value)
158
159/* / This macro reads the PHY Enable Spinup register */
160#define SCU_SAS_ENSPINUP_READ(phy) \
161 scu_link_layer_register_read(phy, notify_enable_spinup_control)
162
163/* / This macro writes the PHY Enable Spinup register */
164#define SCU_SAS_ENSPINUP_WRITE(phy, value) \
165 scu_link_layer_register_write(phy, notify_enable_spinup_control, value)
166
167/* / This macro reads the PHY Capacity register */
168#define SCU_SAS_PHYCAP_READ(phy) \
169 scu_link_layer_register_read(phy, phy_capabilities)
170
171/* / This macro writes the PHY Capacity register */
172#define SCU_SAS_PHYCAP_WRITE(phy, value) \
173 scu_link_layer_register_write(phy, phy_capabilities, value)
174
175/* / This macro reads the Recieved PHY Capacity register */
176#define SCU_SAS_RECPHYCAP_READ(phy) \
177 scu_link_layer_register_read(phy, receive_phycap)
178
179/* / This macro reads the link layer control register */
180#define SCU_SAS_LLCTL_READ(phy) \
181 scu_link_layer_register_read(phy, link_layer_control);
182
183/* / This macro writes the link layer control register */
184#define SCU_SAS_LLCTL_WRITE(phy, value) \
185 scu_link_layer_register_write(phy, link_layer_control, value);
186
187#endif /* _SCIC_SDS_PHY_REGISTERS_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_port.c b/drivers/scsi/isci/core/scic_sds_port.c
new file mode 100644
index 000000000000..1af38505840c
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_port.c
@@ -0,0 +1,2757 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include "intel_sas.h"
57#include "sci_base_port.h"
58#include "scic_controller.h"
59#include "scic_phy.h"
60#include "scic_port.h"
61#include "scic_sds_controller.h"
62#include "scic_sds_phy.h"
63#include "scic_sds_phy_registers.h"
64#include "scic_sds_port.h"
65#include "scic_sds_port_registers.h"
66#include "scic_sds_remote_device.h"
67#include "scic_sds_remote_node_context.h"
68#include "scic_sds_request.h"
69#include "scic_user_callback.h"
70#include "sci_environment.h"
71
72
73static void scic_sds_port_invalid_link_up(
74 struct scic_sds_port *this_port,
75 struct scic_sds_phy *phy);
76static void scic_sds_port_timeout_handler(
77 void *port);
78#define SCIC_SDS_PORT_MIN_TIMER_COUNT (SCI_MAX_PORTS)
79#define SCIC_SDS_PORT_MAX_TIMER_COUNT (SCI_MAX_PORTS)
80
81#define SCIC_SDS_PORT_HARD_RESET_TIMEOUT (1000)
82
83void sci_base_port_construct(
84 struct sci_base_port *base_port,
85 const struct sci_base_state *state_table)
86{
87 base_port->parent.private = NULL;
88 sci_base_state_machine_construct(
89 &base_port->state_machine,
90 &base_port->parent,
91 state_table,
92 SCI_BASE_PORT_STATE_STOPPED
93 );
94
95 sci_base_state_machine_start(
96 &base_port->state_machine
97 );
98}
99
100/**
101 *
102 * @this_port: This is the port object to which the phy is being assigned.
103 * @phy_index: This is the phy index that is being assigned to the port.
104 *
105 * This method will return a true value if the specified phy can be assigned to
106 * this port The following is a list of phys for each port that are allowed: -
107 * Port 0 - 3 2 1 0 - Port 1 - 1 - Port 2 - 3 2 - Port 3 - 3 This method
108 * doesn't preclude all configurations. It merely ensures that a phy is part
109 * of the allowable set of phy identifiers for that port. For example, one
110 * could assign phy 3 to port 0 and no other phys. Please refer to
111 * scic_sds_port_is_phy_mask_valid() for information regarding whether the
112 * phy_mask for a port can be supported. bool true if this is a valid phy
113 * assignment for the port false if this is not a valid phy assignment for the
114 * port
115 */
116bool scic_sds_port_is_valid_phy_assignment(
117 struct scic_sds_port *this_port,
118 u32 phy_index)
119{
120 /* Initialize to invalid value. */
121 u32 existing_phy_index = SCI_MAX_PHYS;
122 u32 index;
123
124 if ((this_port->physical_port_index == 1) && (phy_index != 1)) {
125 return false;
126 }
127
128 if (this_port->physical_port_index == 3 && phy_index != 3) {
129 return false;
130 }
131
132 if (
133 (this_port->physical_port_index == 2)
134 && ((phy_index == 0) || (phy_index == 1))
135 ) {
136 return false;
137 }
138
139 for (index = 0; index < SCI_MAX_PHYS; index++) {
140 if ((this_port->phy_table[index] != NULL)
141 && (index != phy_index)) {
142 existing_phy_index = index;
143 }
144 }
145
146 /*
147 * Ensure that all of the phys in the port are capable of
148 * operating at the same maximum link rate. */
149 if (
150 (existing_phy_index < SCI_MAX_PHYS)
151 && (this_port->owning_controller->user_parameters.sds1.phys[
152 phy_index].max_speed_generation !=
153 this_port->owning_controller->user_parameters.sds1.phys[
154 existing_phy_index].max_speed_generation)
155 )
156 return false;
157
158 return true;
159}
160
161/**
162 * This method requests a list (mask) of the phys contained in the supplied SAS
163 * port.
164 * @this_port: a handle corresponding to the SAS port for which to return the
165 * phy mask.
166 *
167 * Return a bit mask indicating which phys are a part of this port. Each bit
168 * corresponds to a phy identifier (e.g. bit 0 = phy id 0).
169 */
170u32 scic_sds_port_get_phys(struct scic_sds_port *this_port)
171{
172 u32 index;
173 u32 mask;
174
175 mask = 0;
176
177 for (index = 0; index < SCI_MAX_PHYS; index++) {
178 if (this_port->phy_table[index] != NULL) {
179 mask |= (1 << index);
180 }
181 }
182
183 return mask;
184}
185
186/**
187 *
188 * @this_port: This is the port object for which to determine if the phy mask
189 * can be supported.
190 *
191 * This method will return a true value if the port's phy mask can be supported
192 * by the SCU. The following is a list of valid PHY mask configurations for
193 * each port: - Port 0 - [[3 2] 1] 0 - Port 1 - [1] - Port 2 - [[3] 2]
194 * - Port 3 - [3] This method returns a boolean indication specifying if the
195 * phy mask can be supported. true if this is a valid phy assignment for the
196 * port false if this is not a valid phy assignment for the port
197 */
198bool scic_sds_port_is_phy_mask_valid(
199 struct scic_sds_port *this_port,
200 u32 phy_mask)
201{
202 if (this_port->physical_port_index == 0) {
203 if (((phy_mask & 0x0F) == 0x0F)
204 || ((phy_mask & 0x03) == 0x03)
205 || ((phy_mask & 0x01) == 0x01)
206 || (phy_mask == 0))
207 return true;
208 } else if (this_port->physical_port_index == 1) {
209 if (((phy_mask & 0x02) == 0x02)
210 || (phy_mask == 0))
211 return true;
212 } else if (this_port->physical_port_index == 2) {
213 if (((phy_mask & 0x0C) == 0x0C)
214 || ((phy_mask & 0x04) == 0x04)
215 || (phy_mask == 0))
216 return true;
217 } else if (this_port->physical_port_index == 3) {
218 if (((phy_mask & 0x08) == 0x08)
219 || (phy_mask == 0))
220 return true;
221 }
222
223 return false;
224}
225
226/**
227 *
228 * @this_port: This parameter specifies the port from which to return a
229 * connected phy.
230 *
231 * This method retrieves a currently active (i.e. connected) phy contained in
232 * the port. Currently, the lowest order phy that is connected is returned.
233 * This method returns a pointer to a SCIS_SDS_PHY object. NULL This value is
234 * returned if there are no currently active (i.e. connected to a remote end
235 * point) phys contained in the port. All other values specify a struct scic_sds_phy
236 * object that is active in the port.
237 */
238static struct scic_sds_phy *scic_sds_port_get_a_connected_phy(
239 struct scic_sds_port *this_port
240 ) {
241 u32 index;
242 struct scic_sds_phy *phy;
243
244 for (index = 0; index < SCI_MAX_PHYS; index++) {
245 /*
246 * Ensure that the phy is both part of the port and currently
247 * connected to the remote end-point. */
248 phy = this_port->phy_table[index];
249 if (
250 (phy != NULL)
251 && scic_sds_port_active_phy(this_port, phy)
252 ) {
253 return phy;
254 }
255 }
256
257 return NULL;
258}
259
260/**
261 * scic_sds_port_set_phy() -
262 * @out]: port The port object to which the phy assignement is being made.
263 * @out]: phy The phy which is being assigned to the port.
264 *
265 * This method attempts to make the assignment of the phy to the port. If
266 * successful the phy is assigned to the ports phy table. bool true if the phy
267 * assignment can be made. false if the phy assignement can not be made. This
268 * is a functional test that only fails if the phy is currently assigned to a
269 * different port.
270 */
271enum sci_status scic_sds_port_set_phy(
272 struct scic_sds_port *port,
273 struct scic_sds_phy *phy)
274{
275 /*
276 * Check to see if we can add this phy to a port
277 * that means that the phy is not part of a port and that the port does
278 * not already have a phy assinged to the phy index. */
279 if (
280 (port->phy_table[phy->phy_index] == SCI_INVALID_HANDLE)
281 && (scic_sds_phy_get_port(phy) == SCI_INVALID_HANDLE)
282 && scic_sds_port_is_valid_phy_assignment(port, phy->phy_index)
283 ) {
284 /*
285 * Phy is being added in the stopped state so we are in MPC mode
286 * make logical port index = physical port index */
287 port->logical_port_index = port->physical_port_index;
288 port->phy_table[phy->phy_index] = phy;
289 scic_sds_phy_set_port(phy, port);
290
291 return SCI_SUCCESS;
292 }
293
294 return SCI_FAILURE;
295}
296
297/**
298 * scic_sds_port_clear_phy() -
299 * @out]: port The port from which the phy is being cleared.
300 * @out]: phy The phy being cleared from the port.
301 *
302 * This method will clear the phy assigned to this port. This method fails if
303 * this phy is not currently assinged to this port. bool true if the phy is
304 * removed from the port. false if this phy is not assined to this port.
305 */
306enum sci_status scic_sds_port_clear_phy(
307 struct scic_sds_port *port,
308 struct scic_sds_phy *phy)
309{
310 /* Make sure that this phy is part of this port */
311 if (
312 (port->phy_table[phy->phy_index] == phy)
313 && (scic_sds_phy_get_port(phy) == port)
314 ) {
315 /* Yep it is assigned to this port so remove it */
316 scic_sds_phy_set_port(
317 phy,
318 &scic_sds_port_get_controller(port)->port_table[SCI_MAX_PORTS]
319 );
320
321 port->phy_table[phy->phy_index] = SCI_INVALID_HANDLE;
322
323 return SCI_SUCCESS;
324 }
325
326 return SCI_FAILURE;
327}
328
329/**
330 * scic_sds_port_add_phy() -
331 * @this_port: This parameter specifies the port in which the phy will be added.
332 * @the_phy: This parameter is the phy which is to be added to the port.
333 *
334 * This method will add a PHY to the selected port. This method returns an
335 * enum sci_status. SCI_SUCCESS the phy has been added to the port. Any other status
336 * is failre to add the phy to the port.
337 */
338enum sci_status scic_sds_port_add_phy(
339 struct scic_sds_port *this_port,
340 struct scic_sds_phy *the_phy)
341{
342 return this_port->state_handlers->parent.add_phy_handler(
343 &this_port->parent, &the_phy->parent);
344}
345
346
347/**
348 * scic_sds_port_remove_phy() -
349 * @this_port: This parameter specifies the port in which the phy will be added.
350 * @the_phy: This parameter is the phy which is to be added to the port.
351 *
352 * This method will remove the PHY from the selected PORT. This method returns
353 * an enum sci_status. SCI_SUCCESS the phy has been removed from the port. Any other
354 * status is failre to add the phy to the port.
355 */
356enum sci_status scic_sds_port_remove_phy(
357 struct scic_sds_port *this_port,
358 struct scic_sds_phy *the_phy)
359{
360 return this_port->state_handlers->parent.remove_phy_handler(
361 &this_port->parent, &the_phy->parent);
362}
363
364/**
365 * This method requests the SAS address for the supplied SAS port from the SCI
366 * implementation.
367 * @this_port: a handle corresponding to the SAS port for which to return the
368 * SAS address.
369 * @sas_address: This parameter specifies a pointer to a SAS address structure
370 * into which the core will copy the SAS address for the port.
371 *
372 */
373void scic_sds_port_get_sas_address(
374 struct scic_sds_port *this_port,
375 struct sci_sas_address *sas_address)
376{
377 u32 index;
378
379 sas_address->high = 0;
380 sas_address->low = 0;
381
382 for (index = 0; index < SCI_MAX_PHYS; index++) {
383 if (this_port->phy_table[index] != NULL) {
384 scic_sds_phy_get_sas_address(this_port->phy_table[index], sas_address);
385 }
386 }
387}
388
389/**
390 * This method will indicate which protocols are supported by this port.
391 * @this_port: a handle corresponding to the SAS port for which to return the
392 * supported protocols.
393 * @protocols: This parameter specifies a pointer to an IAF protocol field
394 * structure into which the core will copy the protocol values for the port.
395 * The values are returned as part of a bit mask in order to allow for
396 * multi-protocol support.
397 *
398 */
399static void scic_sds_port_get_protocols(
400 struct scic_sds_port *this_port,
401 struct sci_sas_identify_address_frame_protocols *protocols)
402{
403 u8 index;
404
405 protocols->u.all = 0;
406
407 for (index = 0; index < SCI_MAX_PHYS; index++) {
408 if (this_port->phy_table[index] != NULL) {
409 scic_sds_phy_get_protocols(this_port->phy_table[index], protocols);
410 }
411 }
412}
413
414/**
415 * This method requests the SAS address for the device directly attached to
416 * this SAS port.
417 * @this_port: a handle corresponding to the SAS port for which to return the
418 * SAS address.
419 * @sas_address: This parameter specifies a pointer to a SAS address structure
420 * into which the core will copy the SAS address for the device directly
421 * attached to the port.
422 *
423 */
424void scic_sds_port_get_attached_sas_address(
425 struct scic_sds_port *this_port,
426 struct sci_sas_address *sas_address)
427{
428 struct sci_sas_identify_address_frame_protocols protocols;
429 struct scic_sds_phy *phy;
430
431 /*
432 * Ensure that the phy is both part of the port and currently
433 * connected to the remote end-point. */
434 phy = scic_sds_port_get_a_connected_phy(this_port);
435 if (phy != NULL) {
436 scic_sds_phy_get_attached_phy_protocols(phy, &protocols);
437
438 if (!protocols.u.bits.stp_target) {
439 scic_sds_phy_get_attached_sas_address(phy, sas_address);
440 } else {
441 scic_sds_phy_get_sas_address(phy, sas_address);
442 sas_address->low += phy->phy_index;
443 }
444 } else {
445 sas_address->high = 0;
446 sas_address->low = 0;
447 }
448}
449
450/**
451 * This method will indicate which protocols are supported by this remote
452 * device.
453 * @this_port: a handle corresponding to the SAS port for which to return the
454 * supported protocols.
455 * @protocols: This parameter specifies a pointer to an IAF protocol field
456 * structure into which the core will copy the protocol values for the port.
457 * The values are returned as part of a bit mask in order to allow for
458 * multi-protocol support.
459 *
460 */
461void scic_sds_port_get_attached_protocols(
462 struct scic_sds_port *this_port,
463 struct sci_sas_identify_address_frame_protocols *protocols)
464{
465 struct scic_sds_phy *phy;
466
467 /*
468 * Ensure that the phy is both part of the port and currently
469 * connected to the remote end-point. */
470 phy = scic_sds_port_get_a_connected_phy(this_port);
471 if (phy != NULL)
472 scic_sds_phy_get_attached_phy_protocols(phy, protocols);
473 else
474 protocols->u.all = 0;
475}
476
477/**
478 * This method returns the amount of memory requred for a port object.
479 *
480 * u32
481 */
482
483/**
484 * This method returns the minimum number of timers required for all port
485 * objects.
486 *
487 * u32
488 */
489
490/**
491 * This method returns the maximum number of timers required for all port
492 * objects.
493 *
494 * u32
495 */
496
497/**
498 *
499 * @this_port:
500 * @port_index:
501 *
502 *
503 */
504void scic_sds_port_construct(
505 struct scic_sds_port *this_port,
506 u8 port_index,
507 struct scic_sds_controller *owning_controller)
508{
509 u32 index;
510
511 sci_base_port_construct(
512 &this_port->parent,
513 scic_sds_port_state_table
514 );
515
516 sci_base_state_machine_construct(
517 scic_sds_port_get_ready_substate_machine(this_port),
518 &this_port->parent.parent,
519 scic_sds_port_ready_substate_table,
520 SCIC_SDS_PORT_READY_SUBSTATE_WAITING
521 );
522
523 this_port->logical_port_index = SCIC_SDS_DUMMY_PORT;
524 this_port->physical_port_index = port_index;
525 this_port->active_phy_mask = 0;
526
527 this_port->owning_controller = owning_controller;
528
529 this_port->started_request_count = 0;
530 this_port->assigned_device_count = 0;
531
532 this_port->timer_handle = SCI_INVALID_HANDLE;
533
534 this_port->transport_layer_registers = NULL;
535 this_port->port_task_scheduler_registers = NULL;
536
537 for (index = 0; index < SCI_MAX_PHYS; index++) {
538 this_port->phy_table[index] = NULL;
539 }
540}
541
542/**
543 * This method performs initialization of the supplied port. Initialization
544 * includes: - state machine initialization - member variable initialization
545 * - configuring the phy_mask
546 * @this_port:
547 * @transport_layer_registers:
548 * @port_task_scheduler_registers:
549 * @port_configuration_regsiter:
550 *
551 * enum sci_status SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION This value is returned
552 * if the phy being added to the port
553 */
554enum sci_status scic_sds_port_initialize(
555 struct scic_sds_port *this_port,
556 void *transport_layer_registers,
557 void *port_task_scheduler_registers,
558 void *port_configuration_regsiter,
559 void *viit_registers)
560{
561 u32 tl_control;
562
563 this_port->transport_layer_registers = transport_layer_registers;
564 this_port->port_task_scheduler_registers = port_task_scheduler_registers;
565 this_port->port_pe_configuration_register = port_configuration_regsiter;
566 this_port->viit_registers = viit_registers;
567
568 scic_sds_port_set_direct_attached_device_id(
569 this_port,
570 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
571 );
572
573 /*
574 * Hardware team recommends that we enable the STP prefetch
575 * for all ports */
576 tl_control = SCU_TLCR_READ(this_port);
577 tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH);
578 SCU_TLCR_WRITE(this_port, tl_control);
579
580 /*
581 * If this is not the dummy port make the assignment of
582 * the timer and start the state machine */
583 if (this_port->physical_port_index != SCI_MAX_PORTS) {
584 /* / @todo should we create the timer at create time? */
585 this_port->timer_handle = scic_cb_timer_create(
586 scic_sds_port_get_controller(this_port),
587 scic_sds_port_timeout_handler,
588 this_port
589 );
590
591 } else {
592 /*
593 * Force the dummy port into a condition where it rejects all requests
594 * as its in an invalid state for any operation.
595 * / @todo should we set a set of specical handlers for the dummy port? */
596 scic_sds_port_set_base_state_handlers(
597 this_port, SCI_BASE_PORT_STATE_STOPPED
598 );
599 }
600
601 return SCI_SUCCESS;
602}
603
604/**
605 *
606 * @this_port: This is the struct scic_sds_port object for which has a phy that has
607 * gone link up.
608 * @the_phy: This is the struct scic_sds_phy object that has gone link up.
609 * @do_notify_user: This parameter specifies whether to inform the user (via
610 * scic_cb_port_link_up()) as to the fact that a new phy as become ready.
611 *
612 * This method is the a general link up handler for the struct scic_sds_port object.
613 * This function will determine if this struct scic_sds_phy can be assigned to this
614 * struct scic_sds_port object. If the struct scic_sds_phy object can is not a valid PHY for
615 * this port then the function will notify the SCIC_USER. A PHY can only be
616 * part of a port if it's attached SAS ADDRESS is the same as all other PHYs in
617 * the same port. none
618 */
619void scic_sds_port_general_link_up_handler(
620 struct scic_sds_port *this_port,
621 struct scic_sds_phy *the_phy,
622 bool do_notify_user)
623{
624 struct sci_sas_address port_sas_address;
625 struct sci_sas_address phy_sas_address;
626
627 scic_sds_port_get_attached_sas_address(this_port, &port_sas_address);
628 scic_sds_phy_get_attached_sas_address(the_phy, &phy_sas_address);
629
630 /*
631 * If the SAS address of the new phy matches the SAS address of
632 * other phys in the port OR this is the first phy in the port,
633 * then activate the phy and allow it to be used for operations
634 * in this port. */
635 if (
636 (
637 (phy_sas_address.high == port_sas_address.high)
638 && (phy_sas_address.low == port_sas_address.low)
639 )
640 || (this_port->active_phy_mask == 0)
641 ) {
642 scic_sds_port_activate_phy(this_port, the_phy, do_notify_user);
643
644 if (this_port->parent.state_machine.current_state_id
645 == SCI_BASE_PORT_STATE_RESETTING) {
646 sci_base_state_machine_change_state(
647 &this_port->parent.state_machine, SCI_BASE_PORT_STATE_READY
648 );
649 }
650 } else {
651 scic_sds_port_invalid_link_up(this_port, the_phy);
652 }
653}
654
655
656enum sci_status scic_port_start(struct scic_sds_port *port)
657{
658 return port->state_handlers->parent.start_handler(&port->parent);
659}
660
661
662enum sci_status scic_port_stop(struct scic_sds_port *port)
663{
664 return port->state_handlers->parent.stop_handler(&port->parent);
665}
666
667
668enum sci_status scic_port_get_properties(
669 struct scic_sds_port *port,
670 struct scic_port_properties *prop)
671{
672 if ((port == SCI_INVALID_HANDLE) ||
673 (port->logical_port_index == SCIC_SDS_DUMMY_PORT))
674 return SCI_FAILURE_INVALID_PORT;
675
676 prop->index = port->logical_port_index;
677 prop->phy_mask = scic_sds_port_get_phys(port);
678 scic_sds_port_get_sas_address(port, &prop->local.sas_address);
679 scic_sds_port_get_protocols(port, &prop->local.protocols);
680 scic_sds_port_get_attached_sas_address(port, &prop->remote.sas_address);
681 scic_sds_port_get_attached_protocols(port, &prop->remote.protocols);
682
683 return SCI_SUCCESS;
684}
685
686
687enum sci_status scic_port_hard_reset(
688 struct scic_sds_port *port,
689 u32 reset_timeout)
690{
691 return port->state_handlers->parent.reset_handler(
692 &port->parent, reset_timeout);
693}
694
695/**
696 *
697 * @this_port: The port for which the direct attached device id is to be
698 * assigned.
699 *
700 * This method assigns the direct attached device ID for this port.
701 */
702void scic_sds_port_set_direct_attached_device_id(
703 struct scic_sds_port *this_port,
704 u32 device_id)
705{
706 u32 tl_control;
707
708 SCU_STPTLDARNI_WRITE(this_port, device_id);
709
710 /*
711 * The read should guarntee that the first write gets posted
712 * before the next write */
713 tl_control = SCU_TLCR_READ(this_port);
714 tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
715 SCU_TLCR_WRITE(this_port, tl_control);
716}
717
718
719/**
720 *
721 * @this_port: This is the port on which the phy should be enabled.
722 * @the_phy: This is the specific phy which to enable.
723 * @do_notify_user: This parameter specifies whether to inform the user (via
724 * scic_cb_port_link_up()) as to the fact that a new phy as become ready.
725 *
726 * This method will activate the phy in the port. Activation includes: - adding
727 * the phy to the port - enabling the Protocol Engine in the silicon. -
728 * notifying the user that the link is up. none
729 */
730void scic_sds_port_activate_phy(
731 struct scic_sds_port *this_port,
732 struct scic_sds_phy *the_phy,
733 bool do_notify_user)
734{
735 struct scic_sds_controller *controller;
736 struct sci_sas_identify_address_frame_protocols protocols;
737
738 controller = scic_sds_port_get_controller(this_port);
739 scic_sds_phy_get_attached_phy_protocols(the_phy, &protocols);
740
741 /* If this is sata port then the phy has already been resumed */
742 if (!protocols.u.bits.stp_target) {
743 scic_sds_phy_resume(the_phy);
744 }
745
746 this_port->active_phy_mask |= 1 << the_phy->phy_index;
747
748 scic_sds_controller_clear_invalid_phy(controller, the_phy);
749
750 if (do_notify_user == true)
751 scic_cb_port_link_up(this_port->owning_controller, this_port, the_phy);
752}
753
754/**
755 *
756 * @this_port: This is the port on which the phy should be deactivated.
757 * @the_phy: This is the specific phy that is no longer active in the port.
758 * @do_notify_user: This parameter specifies whether to inform the user (via
759 * scic_cb_port_link_down()) as to the fact that a new phy as become ready.
760 *
761 * This method will deactivate the supplied phy in the port. none
762 */
763void scic_sds_port_deactivate_phy(
764 struct scic_sds_port *this_port,
765 struct scic_sds_phy *the_phy,
766 bool do_notify_user)
767{
768 this_port->active_phy_mask &= ~(1 << the_phy->phy_index);
769
770 the_phy->max_negotiated_speed = SCI_SAS_NO_LINK_RATE;
771
772 /* Re-assign the phy back to the LP as if it were a narrow port */
773 SCU_PCSPExCR_WRITE(this_port, the_phy->phy_index, the_phy->phy_index);
774
775 if (do_notify_user == true)
776 scic_cb_port_link_down(this_port->owning_controller, this_port, the_phy);
777}
778
779/**
780 *
781 * @this_port: This is the port on which the phy should be disabled.
782 * @the_phy: This is the specific phy which to disabled.
783 *
784 * This method will disable the phy and report that the phy is not valid for
785 * this port object. None
786 */
787static void scic_sds_port_invalid_link_up(
788 struct scic_sds_port *this_port,
789 struct scic_sds_phy *the_phy)
790{
791 struct scic_sds_controller *controller = scic_sds_port_get_controller(this_port);
792
793 /*
794 * Check to see if we have alreay reported this link as bad and if not go
795 * ahead and tell the SCI_USER that we have discovered an invalid link. */
796 if ((controller->invalid_phy_mask & (1 << the_phy->phy_index)) == 0) {
797 scic_sds_controller_set_invalid_phy(controller, the_phy);
798
799 scic_cb_port_invalid_link_up(controller, this_port, the_phy);
800 }
801}
802
803/**
804 * This method returns false if the port only has a single phy object assigned.
805 * If there are no phys or more than one phy then the method will return
806 * true.
807 * @this_port: The port for which the wide port condition is to be checked.
808 *
809 * bool true Is returned if this is a wide ported port. false Is returned if
810 * this is a narrow port.
811 */
812static bool scic_sds_port_is_wide(struct scic_sds_port *this_port)
813{
814 u32 index;
815 u32 phy_count = 0;
816
817 for (index = 0; index < SCI_MAX_PHYS; index++) {
818 if (this_port->phy_table[index] != NULL) {
819 phy_count++;
820 }
821 }
822
823 return phy_count != 1;
824}
825
826/**
827 * This method is called by the PHY object when the link is detected. if the
828 * port wants the PHY to continue on to the link up state then the port
829 * layer must return true. If the port object returns false the phy object
830 * must halt its attempt to go link up.
831 * @this_port: The port associated with the phy object.
832 * @the_phy: The phy object that is trying to go link up.
833 *
834 * true if the phy object can continue to the link up condition. true Is
835 * returned if this phy can continue to the ready state. false Is returned if
836 * can not continue on to the ready state. This notification is in place for
837 * wide ports and direct attached phys. Since there are no wide ported SATA
838 * devices this could become an invalid port configuration.
839 */
840bool scic_sds_port_link_detected(
841 struct scic_sds_port *this_port,
842 struct scic_sds_phy *the_phy)
843{
844 struct sci_sas_identify_address_frame_protocols protocols;
845
846 scic_sds_phy_get_attached_phy_protocols(the_phy, &protocols);
847
848 if (
849 (this_port->logical_port_index != SCIC_SDS_DUMMY_PORT)
850 && (protocols.u.bits.stp_target)
851 && scic_sds_port_is_wide(this_port)
852 ) {
853 scic_sds_port_invalid_link_up(this_port, the_phy);
854
855 return false;
856 }
857
858 return true;
859}
860
861/**
862 * This method is the entry point for the phy to inform the port that it is now
863 * in a ready state
864 * @this_port:
865 *
866 *
867 */
868void scic_sds_port_link_up(
869 struct scic_sds_port *this_port,
870 struct scic_sds_phy *the_phy)
871{
872 the_phy->is_in_link_training = false;
873
874 this_port->state_handlers->link_up_handler(this_port, the_phy);
875}
876
877/**
878 * This method is the entry point for the phy to inform the port that it is no
879 * longer in a ready state
880 * @this_port:
881 *
882 *
883 */
884void scic_sds_port_link_down(
885 struct scic_sds_port *this_port,
886 struct scic_sds_phy *the_phy)
887{
888 this_port->state_handlers->link_down_handler(this_port, the_phy);
889}
890
891/**
892 * This method is called to start an IO request on this port.
893 * @this_port:
894 * @the_device:
895 * @the_io_request:
896 *
897 * enum sci_status
898 */
899enum sci_status scic_sds_port_start_io(
900 struct scic_sds_port *this_port,
901 struct scic_sds_remote_device *the_device,
902 struct scic_sds_request *the_io_request)
903{
904 return this_port->state_handlers->start_io_handler(
905 this_port, the_device, the_io_request);
906}
907
908/**
909 * This method is called to complete an IO request to the port.
910 * @this_port:
911 * @the_device:
912 * @the_io_request:
913 *
914 * enum sci_status
915 */
916enum sci_status scic_sds_port_complete_io(
917 struct scic_sds_port *this_port,
918 struct scic_sds_remote_device *the_device,
919 struct scic_sds_request *the_io_request)
920{
921 return this_port->state_handlers->complete_io_handler(
922 this_port, the_device, the_io_request);
923}
924
925/**
926 * This method is provided to timeout requests for port operations. Mostly its
927 * for the port reset operation.
928 *
929 *
930 */
931static void scic_sds_port_timeout_handler(void *port)
932{
933 struct scic_sds_port *this_port = port;
934 u32 current_state;
935
936 current_state = sci_base_state_machine_get_state(
937 &this_port->parent.state_machine);
938
939 if (current_state == SCI_BASE_PORT_STATE_RESETTING) {
940 /*
941 * if the port is still in the resetting state then the timeout fired
942 * before the reset completed. */
943 sci_base_state_machine_change_state(
944 &this_port->parent.state_machine,
945 SCI_BASE_PORT_STATE_FAILED
946 );
947 } else if (current_state == SCI_BASE_PORT_STATE_STOPPED) {
948 /*
949 * if the port is stopped then the start request failed
950 * In this case stay in the stopped state. */
951 dev_err(sciport_to_dev(this_port),
952 "%s: SCIC Port 0x%p failed to stop before tiemout.\n",
953 __func__,
954 this_port);
955 } else if (current_state == SCI_BASE_PORT_STATE_STOPPING) {
956 /* if the port is still stopping then the stop has not completed */
957 scic_cb_port_stop_complete(
958 scic_sds_port_get_controller(this_port),
959 port,
960 SCI_FAILURE_TIMEOUT
961 );
962 } else {
963 /*
964 * The port is in the ready state and we have a timer reporting a timeout
965 * this should not happen. */
966 dev_err(sciport_to_dev(this_port),
967 "%s: SCIC Port 0x%p is processing a timeout operation "
968 "in state %d.\n",
969 __func__,
970 this_port,
971 current_state);
972 }
973}
974
975/* --------------------------------------------------------------------------- */
976
977#ifdef SCIC_DEBUG_ENABLED
978void scic_sds_port_decrement_request_count(struct scic_sds_port *this_port)
979{
980 if (this_port->started_request_count == 0)
981 dev_warn(sciport_to_dev(this_port),
982 __func__,
983 "%s: SCIC Port object requested to decrement started "
984 "io count past zero.\n");
985 else
986 this_port->started_request_count--;
987}
988#endif
989
990/**
991 * This function updates the hardwares VIIT entry for this port.
992 *
993 *
994 */
995void scic_sds_port_update_viit_entry(struct scic_sds_port *this_port)
996{
997 struct sci_sas_address sas_address;
998
999 scic_sds_port_get_sas_address(this_port, &sas_address);
1000
1001 scu_port_viit_register_write(
1002 this_port, initiator_sas_address_hi, sas_address.high);
1003
1004 scu_port_viit_register_write(
1005 this_port, initiator_sas_address_lo, sas_address.low);
1006
1007 /* This value get cleared just in case its not already cleared */
1008 scu_port_viit_register_write(
1009 this_port, reserved, 0);
1010
1011 /* We are required to update the status register last */
1012 scu_port_viit_register_write(
1013 this_port, status, (
1014 SCU_VIIT_ENTRY_ID_VIIT
1015 | SCU_VIIT_IPPT_INITIATOR
1016 | ((1 << this_port->physical_port_index) << SCU_VIIT_ENTRY_LPVIE_SHIFT)
1017 | SCU_VIIT_STATUS_ALL_VALID
1018 )
1019 );
1020}
1021
1022/**
1023 * This method returns the maximum allowed speed for data transfers on this
1024 * port. This maximum allowed speed evaluates to the maximum speed of the
1025 * slowest phy in the port.
1026 * @this_port: This parameter specifies the port for which to retrieve the
1027 * maximum allowed speed.
1028 *
1029 * This method returns the maximum negotiated speed of the slowest phy in the
1030 * port.
1031 */
1032enum sci_sas_link_rate scic_sds_port_get_max_allowed_speed(
1033 struct scic_sds_port *this_port)
1034{
1035 u16 index = 0;
1036 enum sci_sas_link_rate max_allowed_speed = SCI_SAS_600_GB;
1037 struct scic_sds_phy *phy = NULL;
1038
1039 /*
1040 * Loop through all of the phys in this port and find the phy with the
1041 * lowest maximum link rate. */
1042 for (index = 0; index < SCI_MAX_PHYS; index++) {
1043 phy = this_port->phy_table[index];
1044 if (
1045 (phy != NULL)
1046 && (scic_sds_port_active_phy(this_port, phy) == true)
1047 && (phy->max_negotiated_speed < max_allowed_speed)
1048 )
1049 max_allowed_speed = phy->max_negotiated_speed;
1050 }
1051
1052 return max_allowed_speed;
1053}
1054
1055
1056/**
1057 * This method passes the event to core user.
1058 * @this_port: The port that a BCN happens.
1059 * @this_phy: The phy that receives BCN.
1060 *
1061 */
1062void scic_sds_port_broadcast_change_received(
1063 struct scic_sds_port *this_port,
1064 struct scic_sds_phy *this_phy)
1065{
1066 /* notify the user. */
1067 scic_cb_port_bc_change_primitive_received(
1068 this_port->owning_controller, this_port, this_phy
1069 );
1070}
1071
1072
1073/**
1074 * This API methhod enables the broadcast change notification from underneath
1075 * hardware.
1076 * @this_port: The port that a BCN had been disabled from.
1077 *
1078 */
1079void scic_port_enable_broadcast_change_notification(
1080 struct scic_sds_port *port)
1081{
1082 struct scic_sds_phy *phy;
1083 u32 register_value;
1084 u8 index;
1085
1086 /* Loop through all of the phys to enable BCN. */
1087 for (index = 0; index < SCI_MAX_PHYS; index++) {
1088 phy = port->phy_table[index];
1089 if (phy != NULL) {
1090 register_value = SCU_SAS_LLCTL_READ(phy);
1091
1092 /* clear the bit by writing 1. */
1093 SCU_SAS_LLCTL_WRITE(phy, register_value);
1094 }
1095 }
1096}
1097
1098/*
1099 * ****************************************************************************
1100 * * READY SUBSTATE HANDLERS
1101 * **************************************************************************** */
1102
1103/**
1104 *
1105 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1106 * object.
1107 *
1108 * This method is the general ready state stop handler for the struct scic_sds_port
1109 * object. This function will transition the ready substate machine to its
1110 * final state. enum sci_status SCI_SUCCESS
1111 */
1112static enum sci_status scic_sds_port_ready_substate_stop_handler(
1113 struct sci_base_port *port)
1114{
1115 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1116
1117 sci_base_state_machine_change_state(
1118 &this_port->parent.state_machine,
1119 SCI_BASE_PORT_STATE_STOPPING
1120 );
1121
1122 return SCI_SUCCESS;
1123}
1124
1125/**
1126 *
1127 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1128 * object.
1129 * @device: This is the struct sci_base_remote_device object which is not used in this
1130 * function.
1131 * @io_request: This is the struct sci_base_request object which is not used in this
1132 * function.
1133 *
1134 * This method is the general ready substate complete io handler for the
1135 * struct scic_sds_port object. This function decrments the outstanding request count
1136 * for this port object. enum sci_status SCI_SUCCESS
1137 */
1138static enum sci_status scic_sds_port_ready_substate_complete_io_handler(
1139 struct scic_sds_port *port,
1140 struct scic_sds_remote_device *device,
1141 struct scic_sds_request *io_request)
1142{
1143 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1144
1145 scic_sds_port_decrement_request_count(this_port);
1146
1147 return SCI_SUCCESS;
1148}
1149
1150static enum sci_status scic_sds_port_ready_substate_add_phy_handler(
1151 struct sci_base_port *port,
1152 struct sci_base_phy *phy)
1153{
1154 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1155 struct scic_sds_phy *this_phy = (struct scic_sds_phy *)phy;
1156 enum sci_status status;
1157
1158 status = scic_sds_port_set_phy(this_port, this_phy);
1159
1160 if (status == SCI_SUCCESS) {
1161 scic_sds_port_general_link_up_handler(this_port, this_phy, true);
1162
1163 this_port->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
1164
1165 sci_base_state_machine_change_state(
1166 &this_port->ready_substate_machine,
1167 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1168 );
1169 }
1170
1171 return status;
1172}
1173
1174
1175static enum sci_status scic_sds_port_ready_substate_remove_phy_handler(
1176 struct sci_base_port *port,
1177 struct sci_base_phy *phy)
1178{
1179 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1180 struct scic_sds_phy *this_phy = (struct scic_sds_phy *)phy;
1181 enum sci_status status;
1182
1183 status = scic_sds_port_clear_phy(this_port, this_phy);
1184
1185 if (status == SCI_SUCCESS) {
1186 scic_sds_port_deactivate_phy(this_port, this_phy, true);
1187
1188 this_port->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
1189
1190 sci_base_state_machine_change_state(
1191 &this_port->ready_substate_machine,
1192 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1193 );
1194 }
1195
1196 return status;
1197}
1198
1199/*
1200 * ****************************************************************************
1201 * * READY SUBSTATE WAITING HANDLERS
1202 * **************************************************************************** */
1203
1204/**
1205 *
1206 * @this_port: This is the struct scic_sds_port object that which has a phy that has
1207 * gone link up.
1208 * @the_phy: This is the struct scic_sds_phy object that has gone link up.
1209 *
1210 * This method is the ready waiting substate link up handler for the
1211 * struct scic_sds_port object. This methos will report the link up condition for
1212 * this port and will transition to the ready operational substate. none
1213 */
1214static void scic_sds_port_ready_waiting_substate_link_up_handler(
1215 struct scic_sds_port *this_port,
1216 struct scic_sds_phy *the_phy)
1217{
1218 /*
1219 * Since this is the first phy going link up for the port we can just enable
1220 * it and continue. */
1221 scic_sds_port_activate_phy(this_port, the_phy, true);
1222
1223 sci_base_state_machine_change_state(
1224 &this_port->ready_substate_machine,
1225 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1226 );
1227}
1228
1229/**
1230 *
1231 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1232 * object.
1233 * @device: This is the struct sci_base_remote_device object which is not used in this
1234 * request.
1235 * @io_request: This is the struct sci_base_request object which is not used in this
1236 * function.
1237 *
1238 * This method is the ready waiting substate start io handler for the
1239 * struct scic_sds_port object. The port object can not accept new requests so the
1240 * request is failed. enum sci_status SCI_FAILURE_INVALID_STATE
1241 */
1242static enum sci_status scic_sds_port_ready_waiting_substate_start_io_handler(
1243 struct scic_sds_port *port,
1244 struct scic_sds_remote_device *device,
1245 struct scic_sds_request *io_request)
1246{
1247 return SCI_FAILURE_INVALID_STATE;
1248}
1249
1250/*
1251 * ****************************************************************************
1252 * * READY SUBSTATE OPERATIONAL HANDLERS
1253 * **************************************************************************** */
1254
1255/**
1256 *
1257 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1258 * object.
1259 * @timeout: This is the timeout for the reset request to complete.
1260 *
1261 * This method will casue the port to reset. enum sci_status SCI_SUCCESS
1262 */
1263static enum sci_status scic_sds_port_ready_operational_substate_reset_handler(
1264 struct sci_base_port *port,
1265 u32 timeout)
1266{
1267 enum sci_status status = SCI_FAILURE_INVALID_PHY;
1268 u32 phy_index;
1269 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1270 struct scic_sds_phy *selected_phy = SCI_INVALID_HANDLE;
1271
1272
1273 /* Select a phy on which we can send the hard reset request. */
1274 for (
1275 phy_index = 0;
1276 (phy_index < SCI_MAX_PHYS)
1277 && (selected_phy == SCI_INVALID_HANDLE);
1278 phy_index++
1279 ) {
1280 selected_phy = this_port->phy_table[phy_index];
1281
1282 if (
1283 (selected_phy != SCI_INVALID_HANDLE)
1284 && !scic_sds_port_active_phy(this_port, selected_phy)
1285 ) {
1286 /* We found a phy but it is not ready select different phy */
1287 selected_phy = SCI_INVALID_HANDLE;
1288 }
1289 }
1290
1291 /* If we have a phy then go ahead and start the reset procedure */
1292 if (selected_phy != SCI_INVALID_HANDLE) {
1293 status = scic_sds_phy_reset(selected_phy);
1294
1295 if (status == SCI_SUCCESS) {
1296 scic_cb_timer_start(
1297 scic_sds_port_get_controller(this_port),
1298 this_port->timer_handle,
1299 timeout
1300 );
1301
1302 this_port->not_ready_reason = SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED;
1303
1304 sci_base_state_machine_change_state(
1305 &this_port->parent.state_machine,
1306 SCI_BASE_PORT_STATE_RESETTING
1307 );
1308 }
1309 }
1310
1311 return status;
1312}
1313
1314/**
1315 * scic_sds_port_ready_operational_substate_link_up_handler() -
1316 * @this_port: This is the struct scic_sds_port object that which has a phy that has
1317 * gone link up.
1318 * @the_phy: This is the struct scic_sds_phy object that has gone link up.
1319 *
1320 * This method is the ready operational substate link up handler for the
1321 * struct scic_sds_port object. This function notifies the SCI User that the phy has
1322 * gone link up. none
1323 */
1324static void scic_sds_port_ready_operational_substate_link_up_handler(
1325 struct scic_sds_port *this_port,
1326 struct scic_sds_phy *the_phy)
1327{
1328 scic_sds_port_general_link_up_handler(this_port, the_phy, true);
1329}
1330
1331/**
1332 * scic_sds_port_ready_operational_substate_link_down_handler() -
1333 * @this_port: This is the struct scic_sds_port object that which has a phy that has
1334 * gone link down.
1335 * @the_phy: This is the struct scic_sds_phy object that has gone link down.
1336 *
1337 * This method is the ready operational substate link down handler for the
1338 * struct scic_sds_port object. This function notifies the SCI User that the phy has
1339 * gone link down and if this is the last phy in the port the port will change
1340 * state to the ready waiting substate. none
1341 */
1342static void scic_sds_port_ready_operational_substate_link_down_handler(
1343 struct scic_sds_port *this_port,
1344 struct scic_sds_phy *the_phy)
1345{
1346 scic_sds_port_deactivate_phy(this_port, the_phy, true);
1347
1348 /*
1349 * If there are no active phys left in the port, then transition
1350 * the port to the WAITING state until such time as a phy goes
1351 * link up. */
1352 if (this_port->active_phy_mask == 0) {
1353 sci_base_state_machine_change_state(
1354 scic_sds_port_get_ready_substate_machine(this_port),
1355 SCIC_SDS_PORT_READY_SUBSTATE_WAITING
1356 );
1357 }
1358}
1359
1360/**
1361 *
1362 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1363 * object.
1364 * @device: This is the struct sci_base_remote_device object which is not used in this
1365 * function.
1366 * @io_request: This is the struct sci_base_request object which is not used in this
1367 * function.
1368 *
1369 * This method is the ready operational substate start io handler for the
1370 * struct scic_sds_port object. This function incremetns the outstanding request
1371 * count for this port object. enum sci_status SCI_SUCCESS
1372 */
1373static enum sci_status scic_sds_port_ready_operational_substate_start_io_handler(
1374 struct scic_sds_port *port,
1375 struct scic_sds_remote_device *device,
1376 struct scic_sds_request *io_request)
1377{
1378 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1379
1380 scic_sds_port_increment_request_count(this_port);
1381
1382 return SCI_SUCCESS;
1383}
1384
1385/*
1386 * ****************************************************************************
1387 * * READY SUBSTATE OPERATIONAL HANDLERS
1388 * **************************************************************************** */
1389
1390/**
1391 * scic_sds_port_ready_configuring_substate_add_phy_handler() -
1392 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1393 * object.
1394 *
1395 * This is the default method for a port add phy request. It will report a
1396 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1397 */
1398static enum sci_status scic_sds_port_ready_configuring_substate_add_phy_handler(
1399 struct sci_base_port *port,
1400 struct sci_base_phy *phy)
1401{
1402 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1403 struct scic_sds_phy *this_phy = (struct scic_sds_phy *)phy;
1404 enum sci_status status;
1405
1406 status = scic_sds_port_set_phy(this_port, this_phy);
1407
1408 if (status == SCI_SUCCESS) {
1409 scic_sds_port_general_link_up_handler(this_port, this_phy, true);
1410
1411 /*
1412 * Re-enter the configuring state since this may be the last phy in
1413 * the port. */
1414 sci_base_state_machine_change_state(
1415 &this_port->ready_substate_machine,
1416 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1417 );
1418 }
1419
1420 return status;
1421}
1422
1423/**
1424 * scic_sds_port_ready_configuring_substate_remove_phy_handler() -
1425 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1426 * object.
1427 *
1428 * This is the default method for a port remove phy request. It will report a
1429 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1430 */
1431static enum sci_status scic_sds_port_ready_configuring_substate_remove_phy_handler(
1432 struct sci_base_port *port,
1433 struct sci_base_phy *phy)
1434{
1435 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
1436 struct scic_sds_phy *this_phy = (struct scic_sds_phy *)phy;
1437 enum sci_status status;
1438
1439 status = scic_sds_port_clear_phy(this_port, this_phy);
1440
1441 if (status == SCI_SUCCESS) {
1442 scic_sds_port_deactivate_phy(this_port, this_phy, true);
1443
1444 /*
1445 * Re-enter the configuring state since this may be the last phy in
1446 * the port. */
1447 sci_base_state_machine_change_state(
1448 &this_port->ready_substate_machine,
1449 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1450 );
1451 }
1452
1453 return status;
1454}
1455
1456/**
1457 * scic_sds_port_ready_configuring_substate_complete_io_handler() -
1458 * @port: This is the port that is being requested to complete the io request.
1459 * @device: This is the device on which the io is completing.
1460 *
1461 * This method will decrement the outstanding request count for this port. If
1462 * the request count goes to 0 then the port can be reprogrammed with its new
1463 * phy data.
1464 */
1465static enum sci_status scic_sds_port_ready_configuring_substate_complete_io_handler(
1466 struct scic_sds_port *port,
1467 struct scic_sds_remote_device *device,
1468 struct scic_sds_request *io_request)
1469{
1470 scic_sds_port_decrement_request_count(port);
1471
1472 if (port->started_request_count == 0) {
1473 sci_base_state_machine_change_state(
1474 &port->ready_substate_machine,
1475 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1476 );
1477 }
1478
1479 return SCI_SUCCESS;
1480}
1481
1482/* --------------------------------------------------------------------------- */
1483
1484struct scic_sds_port_state_handler
1485scic_sds_port_ready_substate_handler_table[SCIC_SDS_PORT_READY_MAX_SUBSTATES] =
1486{
1487 /* SCIC_SDS_PORT_READY_SUBSTATE_WAITING */
1488 {
1489 {
1490 scic_sds_port_default_start_handler,
1491 scic_sds_port_ready_substate_stop_handler,
1492 scic_sds_port_default_destruct_handler,
1493 scic_sds_port_default_reset_handler,
1494 scic_sds_port_ready_substate_add_phy_handler,
1495 scic_sds_port_default_remove_phy_handler
1496 },
1497 scic_sds_port_default_frame_handler,
1498 scic_sds_port_default_event_handler,
1499 scic_sds_port_ready_waiting_substate_link_up_handler,
1500 scic_sds_port_default_link_down_handler,
1501 scic_sds_port_ready_waiting_substate_start_io_handler,
1502 scic_sds_port_ready_substate_complete_io_handler,
1503 },
1504 /* SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL */
1505 {
1506 {
1507 scic_sds_port_default_start_handler,
1508 scic_sds_port_ready_substate_stop_handler,
1509 scic_sds_port_default_destruct_handler,
1510 scic_sds_port_ready_operational_substate_reset_handler,
1511 scic_sds_port_ready_substate_add_phy_handler,
1512 scic_sds_port_ready_substate_remove_phy_handler
1513 },
1514 scic_sds_port_default_frame_handler,
1515 scic_sds_port_default_event_handler,
1516 scic_sds_port_ready_operational_substate_link_up_handler,
1517 scic_sds_port_ready_operational_substate_link_down_handler,
1518 scic_sds_port_ready_operational_substate_start_io_handler,
1519 scic_sds_port_ready_substate_complete_io_handler
1520 },
1521 /* SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING */
1522 {
1523 {
1524 scic_sds_port_default_start_handler,
1525 scic_sds_port_ready_substate_stop_handler,
1526 scic_sds_port_default_destruct_handler,
1527 scic_sds_port_default_reset_handler,
1528 scic_sds_port_ready_configuring_substate_add_phy_handler,
1529 scic_sds_port_ready_configuring_substate_remove_phy_handler
1530 },
1531 scic_sds_port_default_frame_handler,
1532 scic_sds_port_default_event_handler,
1533 scic_sds_port_default_link_up_handler,
1534 scic_sds_port_default_link_down_handler,
1535 scic_sds_port_default_start_io_handler,
1536 scic_sds_port_ready_configuring_substate_complete_io_handler
1537 }
1538};
1539
1540
1541/**
1542 * scic_sds_port_set_ready_state_handlers() -
1543 *
1544 * This macro sets the port ready substate handlers.
1545 */
1546#define scic_sds_port_set_ready_state_handlers(port, state_id) \
1547 scic_sds_port_set_state_handlers(\
1548 port, &scic_sds_port_ready_substate_handler_table[(state_id)] \
1549 )
1550
1551/*
1552 * ******************************************************************************
1553 * * PORT STATE PRIVATE METHODS
1554 * ****************************************************************************** */
1555
1556/**
1557 *
1558 * @this_port: This is the struct scic_sds_port object to suspend.
1559 *
1560 * This method will susped the port task scheduler for this port object. none
1561 */
1562static void scic_sds_port_suspend_port_task_scheduler(
1563 struct scic_sds_port *this_port)
1564{
1565 u32 pts_control_value;
1566 u32 tl_control_value;
1567
1568 pts_control_value = scu_port_task_scheduler_read(this_port, control);
1569 tl_control_value = scu_transport_layer_read(this_port, control);
1570
1571 pts_control_value |= SCU_PTSxCR_GEN_BIT(SUSPEND);
1572 tl_control_value |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
1573
1574 scu_port_task_scheduler_write(this_port, control, pts_control_value);
1575 scu_transport_layer_write(this_port, control, tl_control_value);
1576}
1577
1578/**
1579 *
1580 * @this_port: This is the struct scic_sds_port object to resume.
1581 *
1582 * This method will resume the port task scheduler for this port object. none
1583 */
1584static void scic_sds_port_resume_port_task_scheduler(
1585 struct scic_sds_port *this_port)
1586{
1587 u32 pts_control_value;
1588
1589 pts_control_value = scu_port_task_scheduler_read(this_port, control);
1590
1591 pts_control_value &= ~SCU_PTSxCR_GEN_BIT(SUSPEND);
1592
1593 scu_port_task_scheduler_write(this_port, control, pts_control_value);
1594}
1595
1596/*
1597 * ******************************************************************************
1598 * * PORT READY SUBSTATE METHODS
1599 * ****************************************************************************** */
1600
1601/**
1602 *
1603 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
1604 *
1605 * This method will perform the actions required by the struct scic_sds_port on
1606 * entering the SCIC_SDS_PORT_READY_SUBSTATE_WAITING. This function checks the
1607 * port for any ready phys. If there is at least one phy in a ready state then
1608 * the port transitions to the ready operational substate. none
1609 */
1610static void scic_sds_port_ready_substate_waiting_enter(
1611 struct sci_base_object *object)
1612{
1613 struct scic_sds_port *this_port = (struct scic_sds_port *)object;
1614
1615 scic_sds_port_set_ready_state_handlers(
1616 this_port, SCIC_SDS_PORT_READY_SUBSTATE_WAITING
1617 );
1618
1619 scic_sds_port_suspend_port_task_scheduler(this_port);
1620
1621 this_port->not_ready_reason = SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS;
1622
1623 if (this_port->active_phy_mask != 0) {
1624 /* At least one of the phys on the port is ready */
1625 sci_base_state_machine_change_state(
1626 &this_port->ready_substate_machine,
1627 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1628 );
1629 }
1630}
1631
1632/**
1633 *
1634 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
1635 *
1636 * This method will perform the actions required by the struct scic_sds_port on
1637 * entering the SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL. This function sets
1638 * the state handlers for the port object, notifies the SCI User that the port
1639 * is ready, and resumes port operations. none
1640 */
1641static void scic_sds_port_ready_substate_operational_enter(
1642 struct sci_base_object *object)
1643{
1644 u32 index;
1645 struct scic_sds_port *this_port = (struct scic_sds_port *)object;
1646
1647 scic_sds_port_set_ready_state_handlers(
1648 this_port, SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1649 );
1650
1651 scic_cb_port_ready(
1652 scic_sds_port_get_controller(this_port), this_port
1653 );
1654
1655 for (index = 0; index < SCI_MAX_PHYS; index++) {
1656 if (this_port->phy_table[index] != NULL) {
1657 scic_sds_port_write_phy_assignment(
1658 this_port, this_port->phy_table[index]
1659 );
1660 }
1661 }
1662
1663 scic_sds_port_update_viit_entry(this_port);
1664
1665 scic_sds_port_resume_port_task_scheduler(this_port);
1666}
1667
1668/**
1669 *
1670 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
1671 *
1672 * This method will perform the actions required by the struct scic_sds_port on
1673 * exiting the SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL. This function reports
1674 * the port not ready and suspends the port task scheduler. none
1675 */
1676static void scic_sds_port_ready_substate_operational_exit(
1677 struct sci_base_object *object)
1678{
1679 struct scic_sds_port *this_port = (struct scic_sds_port *)object;
1680
1681 scic_cb_port_not_ready(
1682 scic_sds_port_get_controller(this_port),
1683 this_port,
1684 this_port->not_ready_reason
1685 );
1686}
1687
1688/*
1689 * ******************************************************************************
1690 * * PORT READY CONFIGURING METHODS
1691 * ****************************************************************************** */
1692
1693/**
1694 * scic_sds_port_ready_substate_configuring_enter() -
1695 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
1696 *
1697 * This method will perform the actions required by the struct scic_sds_port on
1698 * exiting the SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL. This function reports
1699 * the port not ready and suspends the port task scheduler. none
1700 */
1701static void scic_sds_port_ready_substate_configuring_enter(
1702 struct sci_base_object *object)
1703{
1704 struct scic_sds_port *this_port = (struct scic_sds_port *)object;
1705
1706 scic_sds_port_set_ready_state_handlers(
1707 this_port, SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING
1708 );
1709
1710 if (this_port->active_phy_mask == 0) {
1711 scic_cb_port_not_ready(
1712 scic_sds_port_get_controller(this_port),
1713 this_port,
1714 SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS
1715 );
1716
1717 sci_base_state_machine_change_state(
1718 &this_port->ready_substate_machine,
1719 SCIC_SDS_PORT_READY_SUBSTATE_WAITING
1720 );
1721 } else if (this_port->started_request_count == 0) {
1722 sci_base_state_machine_change_state(
1723 &this_port->ready_substate_machine,
1724 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL
1725 );
1726 }
1727}
1728
1729static void scic_sds_port_ready_substate_configuring_exit(
1730 struct sci_base_object *object)
1731{
1732 struct scic_sds_port *this_port = (struct scic_sds_port *)object;
1733
1734 scic_sds_port_suspend_port_task_scheduler(this_port);
1735}
1736
1737/* --------------------------------------------------------------------------- */
1738
1739const struct sci_base_state scic_sds_port_ready_substate_table[] = {
1740 [SCIC_SDS_PORT_READY_SUBSTATE_WAITING] = {
1741 .enter_state = scic_sds_port_ready_substate_waiting_enter,
1742 },
1743 [SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL] = {
1744 .enter_state = scic_sds_port_ready_substate_operational_enter,
1745 .exit_state = scic_sds_port_ready_substate_operational_exit
1746 },
1747 [SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING] = {
1748 .enter_state = scic_sds_port_ready_substate_configuring_enter,
1749 .exit_state = scic_sds_port_ready_substate_configuring_exit
1750 },
1751};
1752
1753/*
1754 * ***************************************************************************
1755 * * DEFAULT HANDLERS
1756 * *************************************************************************** */
1757
1758/**
1759 *
1760 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1761 * object.
1762 *
1763 * This is the default method for port a start request. It will report a
1764 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1765 */
1766enum sci_status scic_sds_port_default_start_handler(
1767 struct sci_base_port *port)
1768{
1769 struct scic_sds_port *sci_port = (struct scic_sds_port *)port;
1770
1771 dev_warn(sciport_to_dev(sci_port),
1772 "%s: SCIC Port 0x%p requested to start while in invalid "
1773 "state %d\n",
1774 __func__,
1775 port,
1776 sci_base_state_machine_get_state(
1777 scic_sds_port_get_base_state_machine(
1778 (struct scic_sds_port *)port)));
1779
1780 return SCI_FAILURE_INVALID_STATE;
1781}
1782
1783/**
1784 *
1785 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1786 * object.
1787 *
1788 * This is the default method for a port stop request. It will report a
1789 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1790 */
1791static enum sci_status scic_sds_port_default_stop_handler(
1792 struct sci_base_port *port)
1793{
1794 struct scic_sds_port *sci_port = (struct scic_sds_port *)port;
1795
1796 dev_warn(sciport_to_dev(sci_port),
1797 "%s: SCIC Port 0x%p requested to stop while in invalid "
1798 "state %d\n",
1799 __func__,
1800 port,
1801 sci_base_state_machine_get_state(
1802 scic_sds_port_get_base_state_machine(
1803 (struct scic_sds_port *)port)));
1804
1805 return SCI_FAILURE_INVALID_STATE;
1806}
1807
1808/**
1809 *
1810 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1811 * object.
1812 *
1813 * This is the default method for a port destruct request. It will report a
1814 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1815 */
1816enum sci_status scic_sds_port_default_destruct_handler(
1817 struct sci_base_port *port)
1818{
1819 struct scic_sds_port *sci_port = (struct scic_sds_port *)port;
1820
1821 dev_warn(sciport_to_dev(sci_port),
1822 "%s: SCIC Port 0x%p requested to destruct while in invalid "
1823 "state %d\n",
1824 __func__,
1825 port,
1826 sci_base_state_machine_get_state(
1827 scic_sds_port_get_base_state_machine(
1828 (struct scic_sds_port *)port)));
1829
1830 return SCI_FAILURE_INVALID_STATE;
1831}
1832
1833/**
1834 *
1835 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1836 * object.
1837 * @timeout: This is the timeout for the reset request to complete.
1838 *
1839 * This is the default method for a port reset request. It will report a
1840 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1841 */
1842enum sci_status scic_sds_port_default_reset_handler(
1843 struct sci_base_port *port,
1844 u32 timeout)
1845{
1846 struct scic_sds_port *sci_port = (struct scic_sds_port *)port;
1847
1848 dev_warn(sciport_to_dev(sci_port),
1849 "%s: SCIC Port 0x%p requested to reset while in invalid "
1850 "state %d\n",
1851 __func__,
1852 port,
1853 sci_base_state_machine_get_state(
1854 scic_sds_port_get_base_state_machine(
1855 (struct scic_sds_port *)port)));
1856
1857 return SCI_FAILURE_INVALID_STATE;
1858}
1859
1860/**
1861 *
1862 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1863 * object.
1864 *
1865 * This is the default method for a port add phy request. It will report a
1866 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1867 */
1868static enum sci_status scic_sds_port_default_add_phy_handler(
1869 struct sci_base_port *port,
1870 struct sci_base_phy *phy)
1871{
1872 struct scic_sds_port *sci_port = (struct scic_sds_port *)port;
1873
1874 dev_warn(sciport_to_dev(sci_port),
1875 "%s: SCIC Port 0x%p requested to add phy 0x%p while in "
1876 "invalid state %d\n",
1877 __func__,
1878 port,
1879 phy,
1880 sci_base_state_machine_get_state(
1881 scic_sds_port_get_base_state_machine(
1882 (struct scic_sds_port *)port)));
1883
1884 return SCI_FAILURE_INVALID_STATE;
1885}
1886
1887/**
1888 *
1889 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1890 * object.
1891 *
1892 * This is the default method for a port remove phy request. It will report a
1893 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1894 */
1895enum sci_status scic_sds_port_default_remove_phy_handler(
1896 struct sci_base_port *port,
1897 struct sci_base_phy *phy)
1898{
1899 struct scic_sds_port *sci_port = (struct scic_sds_port *)port;
1900
1901 dev_warn(sciport_to_dev(sci_port),
1902 "%s: SCIC Port 0x%p requested to remove phy 0x%p while in "
1903 "invalid state %d\n",
1904 __func__,
1905 port,
1906 phy,
1907 sci_base_state_machine_get_state(
1908 scic_sds_port_get_base_state_machine(
1909 (struct scic_sds_port *)port)));
1910
1911 return SCI_FAILURE_INVALID_STATE;
1912}
1913
1914/**
1915 *
1916 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1917 * object.
1918 *
1919 * This is the default method for a port unsolicited frame request. It will
1920 * report a warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE Is it even
1921 * possible to receive an unsolicited frame directed to a port object? It
1922 * seems possible if we implementing virtual functions but until then?
1923 */
1924enum sci_status scic_sds_port_default_frame_handler(
1925 struct scic_sds_port *port,
1926 u32 frame_index)
1927{
1928 dev_warn(sciport_to_dev(port),
1929 "%s: SCIC Port 0x%p requested to process frame %d while in "
1930 "invalid state %d\n",
1931 __func__,
1932 port,
1933 frame_index,
1934 sci_base_state_machine_get_state(
1935 scic_sds_port_get_base_state_machine(port)));
1936
1937 scic_sds_controller_release_frame(
1938 scic_sds_port_get_controller(port), frame_index
1939 );
1940
1941 return SCI_FAILURE_INVALID_STATE;
1942}
1943
1944/**
1945 *
1946 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1947 * object.
1948 *
1949 * This is the default method for a port event request. It will report a
1950 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1951 */
1952enum sci_status scic_sds_port_default_event_handler(
1953 struct scic_sds_port *port,
1954 u32 event_code)
1955{
1956 dev_warn(sciport_to_dev(port),
1957 "%s: SCIC Port 0x%p requested to process event 0x%x while "
1958 "in invalid state %d\n",
1959 __func__,
1960 port,
1961 event_code,
1962 sci_base_state_machine_get_state(
1963 scic_sds_port_get_base_state_machine(
1964 (struct scic_sds_port *)port)));
1965
1966 return SCI_FAILURE_INVALID_STATE;
1967}
1968
1969/**
1970 *
1971 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1972 * object.
1973 *
1974 * This is the default method for a port link up notification. It will report
1975 * a warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1976 */
1977void scic_sds_port_default_link_up_handler(
1978 struct scic_sds_port *this_port,
1979 struct scic_sds_phy *phy)
1980{
1981 dev_warn(sciport_to_dev(this_port),
1982 "%s: SCIC Port 0x%p received link_up notification from phy "
1983 "0x%p while in invalid state %d\n",
1984 __func__,
1985 this_port,
1986 phy,
1987 sci_base_state_machine_get_state(
1988 scic_sds_port_get_base_state_machine(this_port)));
1989}
1990
1991/**
1992 *
1993 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
1994 * object.
1995 *
1996 * This is the default method for a port link down notification. It will
1997 * report a warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
1998 */
1999void scic_sds_port_default_link_down_handler(
2000 struct scic_sds_port *this_port,
2001 struct scic_sds_phy *phy)
2002{
2003 dev_warn(sciport_to_dev(this_port),
2004 "%s: SCIC Port 0x%p received link down notification from "
2005 "phy 0x%p while in invalid state %d\n",
2006 __func__,
2007 this_port,
2008 phy,
2009 sci_base_state_machine_get_state(
2010 scic_sds_port_get_base_state_machine(this_port)));
2011}
2012
2013/**
2014 *
2015 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2016 * object.
2017 *
2018 * This is the default method for a port start io request. It will report a
2019 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2020 */
2021enum sci_status scic_sds_port_default_start_io_handler(
2022 struct scic_sds_port *this_port,
2023 struct scic_sds_remote_device *device,
2024 struct scic_sds_request *io_request)
2025{
2026 dev_warn(sciport_to_dev(this_port),
2027 "%s: SCIC Port 0x%p requested to start io request 0x%p "
2028 "while in invalid state %d\n",
2029 __func__,
2030 this_port,
2031 io_request,
2032 sci_base_state_machine_get_state(
2033 scic_sds_port_get_base_state_machine(this_port)));
2034
2035 return SCI_FAILURE_INVALID_STATE;
2036}
2037
2038/**
2039 *
2040 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2041 * object.
2042 *
2043 * This is the default method for a port complete io request. It will report a
2044 * warning and exit. enum sci_status SCI_FAILURE_INVALID_STATE
2045 */
2046static enum sci_status scic_sds_port_default_complete_io_handler(
2047 struct scic_sds_port *this_port,
2048 struct scic_sds_remote_device *device,
2049 struct scic_sds_request *io_request)
2050{
2051 dev_warn(sciport_to_dev(this_port),
2052 "%s: SCIC Port 0x%p requested to complete io request 0x%p "
2053 "while in invalid state %d\n",
2054 __func__,
2055 this_port,
2056 io_request,
2057 sci_base_state_machine_get_state(
2058 scic_sds_port_get_base_state_machine(this_port)));
2059
2060 return SCI_FAILURE_INVALID_STATE;
2061}
2062
2063/*
2064 * ****************************************************************************
2065 * * GENERAL STATE HANDLERS
2066 * **************************************************************************** */
2067
2068/**
2069 *
2070 * @port: This is the struct scic_sds_port object on which the io request count will
2071 * be decremented.
2072 * @device: This is the struct scic_sds_remote_device object to which the io request
2073 * is being directed. This parameter is not required to complete this
2074 * operation.
2075 * @io_request: This is the request that is being completed on this port
2076 * object. This parameter is not required to complete this operation.
2077 *
2078 * This is a general complete io request handler for the struct scic_sds_port object.
2079 * enum sci_status SCI_SUCCESS
2080 */
2081static enum sci_status scic_sds_port_general_complete_io_handler(
2082 struct scic_sds_port *port,
2083 struct scic_sds_remote_device *device,
2084 struct scic_sds_request *io_request)
2085{
2086 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
2087
2088 scic_sds_port_decrement_request_count(this_port);
2089
2090 return SCI_SUCCESS;
2091}
2092
2093/*
2094 * ****************************************************************************
2095 * * STOPPED STATE HANDLERS
2096 * **************************************************************************** */
2097
2098/**
2099 *
2100 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2101 * object.
2102 *
2103 * This method takes the struct scic_sds_port from a stopped state and attempts to
2104 * start it. To start a port it must have no assiged devices and it must have
2105 * at least one phy assigned to it. If those conditions are met then the port
2106 * can transition to the ready state. enum sci_status
2107 * SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION This struct scic_sds_port object could
2108 * not be started because the port configuration is not valid. SCI_SUCCESS the
2109 * start request is successful and the struct scic_sds_port object has transitioned to
2110 * the SCI_BASE_PORT_STATE_READY.
2111 */
2112static enum sci_status scic_sds_port_stopped_state_start_handler(
2113 struct sci_base_port *port)
2114{
2115 u32 phy_mask;
2116 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
2117
2118 if (this_port->assigned_device_count > 0) {
2119 /*
2120 * / @todo This is a start failure operation because there are still
2121 * / devices assigned to this port. There must be no devices
2122 * / assigned to a port on a start operation. */
2123 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
2124 }
2125
2126 phy_mask = scic_sds_port_get_phys(this_port);
2127
2128 /*
2129 * There are one or more phys assigned to this port. Make sure
2130 * the port's phy mask is in fact legal and supported by the
2131 * silicon. */
2132 if (scic_sds_port_is_phy_mask_valid(this_port, phy_mask) == true) {
2133 sci_base_state_machine_change_state(
2134 scic_sds_port_get_base_state_machine(this_port),
2135 SCI_BASE_PORT_STATE_READY
2136 );
2137
2138 return SCI_SUCCESS;
2139 }
2140
2141 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
2142}
2143
2144/**
2145 *
2146 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2147 * object.
2148 *
2149 * This method takes the struct scic_sds_port that is in a stopped state and handles a
2150 * stop request. This function takes no action. enum sci_status SCI_SUCCESS the
2151 * stop request is successful as the struct scic_sds_port object is already stopped.
2152 */
2153static enum sci_status scic_sds_port_stopped_state_stop_handler(
2154 struct sci_base_port *port)
2155{
2156 /* We are already stopped so there is nothing to do here */
2157 return SCI_SUCCESS;
2158}
2159
2160/**
2161 *
2162 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2163 * object.
2164 *
2165 * This method takes the struct scic_sds_port that is in a stopped state and handles
2166 * the destruct request. The stopped state is the only state in which the
2167 * struct scic_sds_port can be destroyed. This function causes the port object to
2168 * transition to the SCI_BASE_PORT_STATE_FINAL. enum sci_status SCI_SUCCESS
2169 */
2170static enum sci_status scic_sds_port_stopped_state_destruct_handler(
2171 struct sci_base_port *port)
2172{
2173 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
2174
2175 sci_base_state_machine_stop(&this_port->parent.state_machine);
2176
2177 return SCI_SUCCESS;
2178}
2179
2180/**
2181 *
2182 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2183 * object.
2184 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2185 * object.
2186 *
2187 * This method takes the struct scic_sds_port that is in a stopped state and handles
2188 * the add phy request. In MPC mode the only time a phy can be added to a port
2189 * is in the SCI_BASE_PORT_STATE_STOPPED. enum sci_status
2190 * SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION is returned when the phy can not
2191 * be added to the port. SCI_SUCCESS if the phy is added to the port.
2192 */
2193static enum sci_status scic_sds_port_stopped_state_add_phy_handler(
2194 struct sci_base_port *port,
2195 struct sci_base_phy *phy)
2196{
2197 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
2198 struct scic_sds_phy *this_phy = (struct scic_sds_phy *)phy;
2199 struct sci_sas_address port_sas_address;
2200
2201 /* Read the port assigned SAS Address if there is one */
2202 scic_sds_port_get_sas_address(this_port, &port_sas_address);
2203
2204 if (port_sas_address.high != 0 && port_sas_address.low != 0) {
2205 struct sci_sas_address phy_sas_address;
2206
2207 /*
2208 * Make sure that the PHY SAS Address matches the SAS Address
2209 * for this port. */
2210 scic_sds_phy_get_sas_address(this_phy, &phy_sas_address);
2211
2212 if (
2213 (port_sas_address.high != phy_sas_address.high)
2214 || (port_sas_address.low != phy_sas_address.low)
2215 ) {
2216 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
2217 }
2218 }
2219
2220 return scic_sds_port_set_phy(this_port, this_phy);
2221}
2222
2223
2224/**
2225 *
2226 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2227 * object.
2228 * @phy: This is the struct sci_base_phy object which is cast into a struct scic_sds_phy
2229 * object.
2230 *
2231 * This method takes the struct scic_sds_port that is in a stopped state and handles
2232 * the remove phy request. In MPC mode the only time a phy can be removed from
2233 * a port is in the SCI_BASE_PORT_STATE_STOPPED. enum sci_status
2234 * SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION is returned when the phy can not
2235 * be added to the port. SCI_SUCCESS if the phy is added to the port.
2236 */
2237static enum sci_status scic_sds_port_stopped_state_remove_phy_handler(
2238 struct sci_base_port *port,
2239 struct sci_base_phy *phy)
2240{
2241 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
2242 struct scic_sds_phy *this_phy = (struct scic_sds_phy *)phy;
2243
2244 return scic_sds_port_clear_phy(this_port, this_phy);
2245}
2246
2247/*
2248 * ****************************************************************************
2249 * * READY STATE HANDLERS
2250 * **************************************************************************** */
2251
2252/*
2253 * ****************************************************************************
2254 * * RESETTING STATE HANDLERS
2255 * **************************************************************************** */
2256
2257/*
2258 * ****************************************************************************
2259 * * STOPPING STATE HANDLERS
2260 * **************************************************************************** */
2261
2262/**
2263 *
2264 * @port: This is the struct scic_sds_port object on which the io request count will
2265 * be decremented.
2266 * @device: This is the struct scic_sds_remote_device object to which the io request
2267 * is being directed. This parameter is not required to complete this
2268 * operation.
2269 * @io_request: This is the request that is being completed on this port
2270 * object. This parameter is not required to complete this operation.
2271 *
2272 * This method takes the struct scic_sds_port that is in a stopping state and handles
2273 * the complete io request. Should the request count reach 0 then the port
2274 * object will transition to the stopped state. enum sci_status SCI_SUCCESS
2275 */
2276static enum sci_status scic_sds_port_stopping_state_complete_io_handler(
2277 struct scic_sds_port *port,
2278 struct scic_sds_remote_device *device,
2279 struct scic_sds_request *io_request)
2280{
2281 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
2282
2283 scic_sds_port_decrement_request_count(this_port);
2284
2285 if (this_port->started_request_count == 0) {
2286 sci_base_state_machine_change_state(
2287 scic_sds_port_get_base_state_machine(this_port),
2288 SCI_BASE_PORT_STATE_STOPPED
2289 );
2290 }
2291
2292 return SCI_SUCCESS;
2293}
2294
2295/*
2296 * ****************************************************************************
2297 * * RESETTING STATE HANDLERS
2298 * **************************************************************************** */
2299
2300/**
2301 *
2302 * @port: This is the port object which is being requested to stop.
2303 *
2304 * This method will stop a failed port. This causes a transition to the
2305 * stopping state. enum sci_status SCI_SUCCESS
2306 */
2307static enum sci_status scic_sds_port_reset_state_stop_handler(
2308 struct sci_base_port *port)
2309{
2310 struct scic_sds_port *this_port = (struct scic_sds_port *)port;
2311
2312 sci_base_state_machine_change_state(
2313 &this_port->parent.state_machine,
2314 SCI_BASE_PORT_STATE_STOPPING
2315 );
2316
2317 return SCI_SUCCESS;
2318}
2319
2320/**
2321 *
2322 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2323 * object.
2324 *
2325 * This method will transition a failed port to its ready state. The port
2326 * failed because a hard reset request timed out but at some time later one or
2327 * more phys in the port became ready. enum sci_status SCI_SUCCESS
2328 */
2329static void scic_sds_port_reset_state_link_up_handler(
2330 struct scic_sds_port *this_port,
2331 struct scic_sds_phy *phy)
2332{
2333 /*
2334 * / @todo We should make sure that the phy that has gone link up is the same
2335 * / one on which we sent the reset. It is possible that the phy on
2336 * / which we sent the reset is not the one that has gone link up and we
2337 * / want to make sure that phy being reset comes back. Consider the
2338 * / case where a reset is sent but before the hardware processes the
2339 * / reset it get a link up on the port because of a hot plug event.
2340 * / because of the reset request this phy will go link down almost
2341 * / immediately. */
2342
2343 /*
2344 * In the resetting state we don't notify the user regarding
2345 * link up and link down notifications. */
2346 scic_sds_port_general_link_up_handler(this_port, phy, false);
2347}
2348
2349/**
2350 *
2351 * @port: This is the struct sci_base_port object which is cast into a struct scic_sds_port
2352 * object.
2353 *
2354 * This method process link down notifications that occur during a port reset
2355 * operation. Link downs can occur during the reset operation. enum sci_status
2356 * SCI_SUCCESS
2357 */
2358static void scic_sds_port_reset_state_link_down_handler(
2359 struct scic_sds_port *this_port,
2360 struct scic_sds_phy *phy)
2361{
2362 /*
2363 * In the resetting state we don't notify the user regarding
2364 * link up and link down notifications. */
2365 scic_sds_port_deactivate_phy(this_port, phy, false);
2366}
2367
2368/* --------------------------------------------------------------------------- */
2369
2370struct scic_sds_port_state_handler
2371scic_sds_port_state_handler_table[SCI_BASE_PORT_MAX_STATES] =
2372{
2373 /* SCI_BASE_PORT_STATE_STOPPED */
2374 {
2375 {
2376 scic_sds_port_stopped_state_start_handler,
2377 scic_sds_port_stopped_state_stop_handler,
2378 scic_sds_port_stopped_state_destruct_handler,
2379 scic_sds_port_default_reset_handler,
2380 scic_sds_port_stopped_state_add_phy_handler,
2381 scic_sds_port_stopped_state_remove_phy_handler
2382 },
2383 scic_sds_port_default_frame_handler,
2384 scic_sds_port_default_event_handler,
2385 scic_sds_port_default_link_up_handler,
2386 scic_sds_port_default_link_down_handler,
2387 scic_sds_port_default_start_io_handler,
2388 scic_sds_port_default_complete_io_handler
2389 },
2390 /* SCI_BASE_PORT_STATE_STOPPING */
2391 {
2392 {
2393 scic_sds_port_default_start_handler,
2394 scic_sds_port_default_stop_handler,
2395 scic_sds_port_default_destruct_handler,
2396 scic_sds_port_default_reset_handler,
2397 scic_sds_port_default_add_phy_handler,
2398 scic_sds_port_default_remove_phy_handler
2399 },
2400 scic_sds_port_default_frame_handler,
2401 scic_sds_port_default_event_handler,
2402 scic_sds_port_default_link_up_handler,
2403 scic_sds_port_default_link_down_handler,
2404 scic_sds_port_default_start_io_handler,
2405 scic_sds_port_stopping_state_complete_io_handler
2406 },
2407 /* SCI_BASE_PORT_STATE_READY */
2408 {
2409 {
2410 scic_sds_port_default_start_handler,
2411 scic_sds_port_default_stop_handler,
2412 scic_sds_port_default_destruct_handler,
2413 scic_sds_port_default_reset_handler,
2414 scic_sds_port_default_add_phy_handler,
2415 scic_sds_port_default_remove_phy_handler
2416 },
2417 scic_sds_port_default_frame_handler,
2418 scic_sds_port_default_event_handler,
2419 scic_sds_port_default_link_up_handler,
2420 scic_sds_port_default_link_down_handler,
2421 scic_sds_port_default_start_io_handler,
2422 scic_sds_port_general_complete_io_handler
2423 },
2424 /* SCI_BASE_PORT_STATE_RESETTING */
2425 {
2426 {
2427 scic_sds_port_default_start_handler,
2428 scic_sds_port_reset_state_stop_handler,
2429 scic_sds_port_default_destruct_handler,
2430 scic_sds_port_default_reset_handler,
2431 scic_sds_port_default_add_phy_handler,
2432 scic_sds_port_default_remove_phy_handler
2433 },
2434 scic_sds_port_default_frame_handler,
2435 scic_sds_port_default_event_handler,
2436 scic_sds_port_reset_state_link_up_handler,
2437 scic_sds_port_reset_state_link_down_handler,
2438 scic_sds_port_default_start_io_handler,
2439 scic_sds_port_general_complete_io_handler
2440 },
2441 /* SCI_BASE_PORT_STATE_FAILED */
2442 {
2443 {
2444 scic_sds_port_default_start_handler,
2445 scic_sds_port_default_stop_handler,
2446 scic_sds_port_default_destruct_handler,
2447 scic_sds_port_default_reset_handler,
2448 scic_sds_port_default_add_phy_handler,
2449 scic_sds_port_default_remove_phy_handler
2450 },
2451 scic_sds_port_default_frame_handler,
2452 scic_sds_port_default_event_handler,
2453 scic_sds_port_default_link_up_handler,
2454 scic_sds_port_default_link_down_handler,
2455 scic_sds_port_default_start_io_handler,
2456 scic_sds_port_general_complete_io_handler
2457 }
2458};
2459
2460/*
2461 * ******************************************************************************
2462 * * PORT STATE PRIVATE METHODS
2463 * ****************************************************************************** */
2464
2465/**
2466 *
2467 * @this_port: This is the port object which to suspend.
2468 *
2469 * This method will enable the SCU Port Task Scheduler for this port object but
2470 * will leave the port task scheduler in a suspended state. none
2471 */
2472static void scic_sds_port_enable_port_task_scheduler(
2473 struct scic_sds_port *this_port)
2474{
2475 u32 pts_control_value;
2476
2477 pts_control_value = scu_port_task_scheduler_read(this_port, control);
2478
2479 pts_control_value |= SCU_PTSxCR_GEN_BIT(ENABLE) | SCU_PTSxCR_GEN_BIT(SUSPEND);
2480
2481 scu_port_task_scheduler_write(this_port, control, pts_control_value);
2482}
2483
2484/**
2485 *
2486 * @this_port: This is the port object which to resume.
2487 *
2488 * This method will disable the SCU port task scheduler for this port object.
2489 * none
2490 */
2491static void scic_sds_port_disable_port_task_scheduler(
2492 struct scic_sds_port *this_port)
2493{
2494 u32 pts_control_value;
2495
2496 pts_control_value = scu_port_task_scheduler_read(this_port, control);
2497
2498 pts_control_value &= ~(SCU_PTSxCR_GEN_BIT(ENABLE)
2499 | SCU_PTSxCR_GEN_BIT(SUSPEND));
2500
2501 scu_port_task_scheduler_write(this_port, control, pts_control_value);
2502}
2503
2504/*
2505 * ******************************************************************************
2506 * * PORT STATE METHODS
2507 * ****************************************************************************** */
2508
2509/**
2510 *
2511 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2512 *
2513 * This method will perform the actions required by the struct scic_sds_port on
2514 * entering the SCI_BASE_PORT_STATE_STOPPED. This function sets the stopped
2515 * state handlers for the struct scic_sds_port object and disables the port task
2516 * scheduler in the hardware. none
2517 */
2518static void scic_sds_port_stopped_state_enter(
2519 struct sci_base_object *object)
2520{
2521 struct scic_sds_port *this_port;
2522
2523 this_port = (struct scic_sds_port *)object;
2524
2525 scic_sds_port_set_base_state_handlers(
2526 this_port, SCI_BASE_PORT_STATE_STOPPED
2527 );
2528
2529 if (
2530 SCI_BASE_PORT_STATE_STOPPING
2531 == this_port->parent.state_machine.previous_state_id
2532 ) {
2533 /*
2534 * If we enter this state becasuse of a request to stop
2535 * the port then we want to disable the hardwares port
2536 * task scheduler. */
2537 scic_sds_port_disable_port_task_scheduler(this_port);
2538 }
2539}
2540
2541/**
2542 *
2543 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2544 *
2545 * This method will perform the actions required by the struct scic_sds_port on
2546 * exiting the SCI_BASE_STATE_STOPPED. This function enables the SCU hardware
2547 * port task scheduler. none
2548 */
2549static void scic_sds_port_stopped_state_exit(
2550 struct sci_base_object *object)
2551{
2552 struct scic_sds_port *this_port;
2553
2554 this_port = (struct scic_sds_port *)object;
2555
2556 /* Enable and suspend the port task scheduler */
2557 scic_sds_port_enable_port_task_scheduler(this_port);
2558}
2559
2560/**
2561 *
2562 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2563 *
2564 * This method will perform the actions required by the struct scic_sds_port on
2565 * entering the SCI_BASE_PORT_STATE_READY. This function sets the ready state
2566 * handlers for the struct scic_sds_port object, reports the port object as not ready
2567 * and starts the ready substate machine. none
2568 */
2569static void scic_sds_port_ready_state_enter(
2570 struct sci_base_object *object)
2571{
2572 struct scic_sds_port *this_port;
2573
2574 this_port = (struct scic_sds_port *)object;
2575
2576 /* Put the ready state handlers in place though they will not be there long */
2577 scic_sds_port_set_base_state_handlers(
2578 this_port, SCI_BASE_PORT_STATE_READY
2579 );
2580
2581 if (
2582 SCI_BASE_PORT_STATE_RESETTING
2583 == this_port->parent.state_machine.previous_state_id
2584 ) {
2585 scic_cb_port_hard_reset_complete(
2586 scic_sds_port_get_controller(this_port),
2587 this_port,
2588 SCI_SUCCESS
2589 );
2590 } else {
2591 /* Notify the caller that the port is not yet ready */
2592 scic_cb_port_not_ready(
2593 scic_sds_port_get_controller(this_port),
2594 this_port,
2595 SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS
2596 );
2597 }
2598
2599 /* Start the ready substate machine */
2600 sci_base_state_machine_start(
2601 scic_sds_port_get_ready_substate_machine(this_port)
2602 );
2603}
2604
2605/**
2606 *
2607 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2608 *
2609 * This method will perform the actions required by the struct scic_sds_port on
2610 * exiting the SCI_BASE_STATE_READY. This function does nothing. none
2611 */
2612static void scic_sds_port_ready_state_exit(
2613 struct sci_base_object *object)
2614{
2615 struct scic_sds_port *this_port;
2616
2617 this_port = (struct scic_sds_port *)object;
2618
2619 sci_base_state_machine_stop(&this_port->ready_substate_machine);
2620}
2621
2622/**
2623 *
2624 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2625 *
2626 * This method will perform the actions required by the struct scic_sds_port on
2627 * entering the SCI_BASE_PORT_STATE_RESETTING. This function sets the resetting
2628 * state handlers for the struct scic_sds_port object. none
2629 */
2630static void scic_sds_port_resetting_state_enter(
2631 struct sci_base_object *object)
2632{
2633 struct scic_sds_port *this_port;
2634
2635 this_port = (struct scic_sds_port *)object;
2636
2637 scic_sds_port_set_base_state_handlers(
2638 this_port, SCI_BASE_PORT_STATE_RESETTING
2639 );
2640
2641 scic_sds_port_set_direct_attached_device_id(
2642 this_port,
2643 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
2644 );
2645}
2646
2647/**
2648 *
2649 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2650 *
2651 * This method will perform the actions required by the struct scic_sds_port on
2652 * exiting the SCI_BASE_STATE_RESETTING. This function does nothing. none
2653 */
2654static void scic_sds_port_resetting_state_exit(
2655 struct sci_base_object *object)
2656{
2657 struct scic_sds_port *this_port;
2658
2659 this_port = (struct scic_sds_port *)object;
2660
2661 scic_cb_timer_stop(
2662 scic_sds_port_get_controller(this_port),
2663 this_port->timer_handle
2664 );
2665}
2666
2667/**
2668 *
2669 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2670 *
2671 * This method will perform the actions required by the struct scic_sds_port on
2672 * entering the SCI_BASE_PORT_STATE_STOPPING. This function sets the stopping
2673 * state handlers for the struct scic_sds_port object. none
2674 */
2675static void scic_sds_port_stopping_state_enter(
2676 struct sci_base_object *object)
2677{
2678 struct scic_sds_port *this_port;
2679
2680 this_port = (struct scic_sds_port *)object;
2681
2682 scic_sds_port_set_base_state_handlers(
2683 this_port, SCI_BASE_PORT_STATE_STOPPING
2684 );
2685}
2686
2687/**
2688 *
2689 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2690 *
2691 * This method will perform the actions required by the struct scic_sds_port on
2692 * exiting the SCI_BASE_STATE_STOPPING. This function does nothing. none
2693 */
2694static void scic_sds_port_stopping_state_exit(
2695 struct sci_base_object *object)
2696{
2697 struct scic_sds_port *this_port;
2698
2699 this_port = (struct scic_sds_port *)object;
2700
2701 scic_cb_timer_stop(
2702 scic_sds_port_get_controller(this_port),
2703 this_port->timer_handle
2704 );
2705}
2706
2707/**
2708 *
2709 * @object: This is the struct sci_base_object which is cast to a struct scic_sds_port object.
2710 *
2711 * This method will perform the actions required by the struct scic_sds_port on
2712 * entering the SCI_BASE_PORT_STATE_STOPPING. This function sets the stopping
2713 * state handlers for the struct scic_sds_port object. none
2714 */
2715static void scic_sds_port_failed_state_enter(
2716 struct sci_base_object *object)
2717{
2718 struct scic_sds_port *this_port;
2719
2720 this_port = (struct scic_sds_port *)object;
2721
2722 scic_sds_port_set_base_state_handlers(
2723 this_port,
2724 SCI_BASE_PORT_STATE_FAILED
2725 );
2726
2727 scic_cb_port_hard_reset_complete(
2728 scic_sds_port_get_controller(this_port),
2729 this_port,
2730 SCI_FAILURE_TIMEOUT
2731 );
2732}
2733
2734/* --------------------------------------------------------------------------- */
2735
2736const struct sci_base_state scic_sds_port_state_table[] = {
2737 [SCI_BASE_PORT_STATE_STOPPED] = {
2738 .enter_state = scic_sds_port_stopped_state_enter,
2739 .exit_state = scic_sds_port_stopped_state_exit
2740 },
2741 [SCI_BASE_PORT_STATE_STOPPING] = {
2742 .enter_state = scic_sds_port_stopping_state_enter,
2743 .exit_state = scic_sds_port_stopping_state_exit
2744 },
2745 [SCI_BASE_PORT_STATE_READY] = {
2746 .enter_state = scic_sds_port_ready_state_enter,
2747 .exit_state = scic_sds_port_ready_state_exit
2748 },
2749 [SCI_BASE_PORT_STATE_RESETTING] = {
2750 .enter_state = scic_sds_port_resetting_state_enter,
2751 .exit_state = scic_sds_port_resetting_state_exit
2752 },
2753 [SCI_BASE_PORT_STATE_FAILED] = {
2754 .enter_state = scic_sds_port_failed_state_enter,
2755 }
2756};
2757
diff --git a/drivers/scsi/isci/core/scic_sds_port.h b/drivers/scsi/isci/core/scic_sds_port.h
new file mode 100644
index 000000000000..bbb9de5228ed
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_port.h
@@ -0,0 +1,514 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_SDS_PORT_H_
57#define _SCIC_SDS_PORT_H_
58
59/**
60 * This file contains the structures, constants and prototypes for the
61 * struct scic_sds_port object.
62 *
63 *
64 */
65
66#include "sci_controller_constants.h"
67#include "intel_sas.h"
68#include "sci_base_port.h"
69#include "sci_base_phy.h"
70#include "scu_registers.h"
71
72#define SCIC_SDS_DUMMY_PORT 0xFF
73
74/**
75 * enum SCIC_SDS_PORT_READY_SUBSTATES -
76 *
77 * This enumeration depicts all of the states for the core port ready substate
78 * machine.
79 */
80enum SCIC_SDS_PORT_READY_SUBSTATES {
81 /**
82 * The substate where the port is started and ready but has no active phys.
83 */
84 SCIC_SDS_PORT_READY_SUBSTATE_WAITING,
85
86 /**
87 * The substate where the port is started and ready and there is at least one
88 * phy operational.
89 */
90 SCIC_SDS_PORT_READY_SUBSTATE_OPERATIONAL,
91
92 /**
93 * The substate where the port is started and there was an add/remove phy
94 * event. This state is only used in Automatic Port Configuration Mode (APC)
95 */
96 SCIC_SDS_PORT_READY_SUBSTATE_CONFIGURING,
97
98 SCIC_SDS_PORT_READY_MAX_SUBSTATES
99};
100
101struct scic_sds_controller;
102struct scic_sds_phy;
103struct scic_sds_remote_device;
104struct scic_sds_request;
105
106/**
107 * struct scic_sds_port -
108 *
109 * The core port object provides the the abstraction for an SCU port.
110 */
111struct scic_sds_port {
112 /**
113 * This field is the oommon base port object.
114 */
115 struct sci_base_port parent;
116
117 /**
118 * This field is the port index that is reported to the SCI USER. This allows
119 * the actual hardware physical port to change without the SCI USER getting a
120 * different answer for the get port index.
121 */
122 u8 logical_port_index;
123
124 /**
125 * This field is the port index used to program the SCU hardware.
126 */
127 u8 physical_port_index;
128
129 /**
130 * This field contains the active phy mask for the port. This mask is used in
131 * conjunction with the phy state to determine which phy to select for some
132 * port operations.
133 */
134 u8 active_phy_mask;
135
136 /**
137 * This field contains the count of the io requests started on this port
138 * object. It is used to control controller shutdown.
139 */
140 u32 started_request_count;
141
142 /**
143 * This field contains the number of devices assigned to this port. It is
144 * used to control port start requests.
145 */
146 u32 assigned_device_count;
147
148 /**
149 * This field contains the reason for the port not going ready. It is
150 * assigned in the state handlers and used in the state transition.
151 */
152 u32 not_ready_reason;
153
154 /**
155 * This field is the table of phys assigned to the port.
156 */
157 struct scic_sds_phy *phy_table[SCI_MAX_PHYS];
158
159 /**
160 * This field is a pointer back to the controller that owns this port object.
161 */
162 struct scic_sds_controller *owning_controller;
163
164 /**
165 * This field contains the port start/stop timer handle.
166 */
167 void *timer_handle;
168
169 /**
170 * This field points to the current set of state handlers for this port
171 * object. These state handlers are assigned at each enter state of the state
172 * machine.
173 */
174 struct scic_sds_port_state_handler *state_handlers;
175
176 /**
177 * This field is the ready substate machine for the port.
178 */
179 struct sci_base_state_machine ready_substate_machine;
180
181 /* / Memory mapped hardware register space */
182 /**
183 * This field is the pointer to the transport layer register for the SCU
184 * hardware.
185 */
186 struct scu_transport_layer_registers *transport_layer_registers;
187
188 /**
189 * This field is the pointer to the port task scheduler registers for the SCU
190 * hardware.
191 */
192 struct scu_port_task_scheduler_registers *port_task_scheduler_registers;
193
194 /**
195 * This field is identical for all port objects and points to the port task
196 * scheduler group PE configuration registers. It is used to assign PEs to a
197 * port.
198 */
199 SCU_PORT_PE_CONFIGURATION_REGISTER_T *port_pe_configuration_register;
200
201 /**
202 * This field is the VIIT register space for ths port object.
203 */
204 struct scu_viit_entry *viit_registers;
205
206};
207
208
209typedef enum sci_status (*SCIC_SDS_PORT_EVENT_HANDLER_T)(struct scic_sds_port *, u32);
210
211typedef enum sci_status (*SCIC_SDS_PORT_FRAME_HANDLER_T)(struct scic_sds_port *, u32);
212
213typedef void (*SCIC_SDS_PORT_LINK_HANDLER_T)(struct scic_sds_port *, struct scic_sds_phy *);
214
215typedef enum sci_status (*SCIC_SDS_PORT_IO_REQUEST_HANDLER_T)(
216 struct scic_sds_port *,
217 struct scic_sds_remote_device *,
218 struct scic_sds_request *);
219
220struct scic_sds_port_state_handler {
221 struct sci_base_port_state_handler parent;
222
223 SCIC_SDS_PORT_FRAME_HANDLER_T frame_handler;
224 SCIC_SDS_PORT_EVENT_HANDLER_T event_handler;
225
226 SCIC_SDS_PORT_LINK_HANDLER_T link_up_handler;
227 SCIC_SDS_PORT_LINK_HANDLER_T link_down_handler;
228
229 SCIC_SDS_PORT_IO_REQUEST_HANDLER_T start_io_handler;
230 SCIC_SDS_PORT_IO_REQUEST_HANDLER_T complete_io_handler;
231
232};
233
234extern const struct sci_base_state scic_sds_port_state_table[];
235extern const struct sci_base_state scic_sds_port_ready_substate_table[];
236
237extern struct scic_sds_port_state_handler scic_sds_port_state_handler_table[];
238extern struct scic_sds_port_state_handler scic_sds_port_ready_substate_handler_table[];
239
240/**
241 * scic_sds_port_get_controller() -
242 *
243 * Helper macro to get the owning controller of this port
244 */
245#define scic_sds_port_get_controller(this_port) \
246 ((this_port)->owning_controller)
247
248/**
249 * scic_sds_port_get_base_state_machine() -
250 *
251 * Helper macro to get the base state machine for this port
252 */
253#define scic_sds_port_get_base_state_machine(this_port) \
254 (&(this_port)->parent.state_machine)
255
256/**
257 * scic_sds_port_set_base_state_handlers() -
258 *
259 * This macro will change the state handlers to those of the specified state id
260 */
261#define scic_sds_port_set_base_state_handlers(this_port, state_id) \
262 scic_sds_port_set_state_handlers(\
263 (this_port), &scic_sds_port_state_handler_table[(state_id)])
264
265/**
266 * scic_sds_port_get_ready_substate_machine() -
267 *
268 * Helper macro to get the ready substate machine for this port
269 */
270#define scic_sds_port_get_ready_substate_machine(this_port) \
271 (&(this_port)->ready_substate_machine)
272
273/**
274 * scic_sds_port_set_state_handlers() -
275 *
276 * Helper macro to set the port object state handlers
277 */
278#define scic_sds_port_set_state_handlers(this_port, handlers) \
279 ((this_port)->state_handlers = (handlers))
280
281/**
282 * scic_sds_port_get_index() -
283 *
284 * This macro returns the physical port index for this port object
285 */
286#define scic_sds_port_get_index(this_port) \
287 ((this_port)->physical_port_index)
288
289/**
290 * scic_sds_port_increment_request_count() -
291 *
292 * Helper macro to increment the started request count
293 */
294#define scic_sds_port_increment_request_count(this_port) \
295 ((this_port)->started_request_count++)
296
297#ifdef SCIC_DEBUG_ENABLED
298/**
299 * scic_sds_port_decrement_request_count() - This method decrements the started
300 * io request count. The method will not decrment the started io request
301 * count below 0 and will log a debug message if this is attempted.
302 *
303 *
304 */
305void scic_sds_port_decrement_request_count(
306 struct scic_sds_port *this_port);
307#else
308/**
309 * scic_sds_port_decrement_request_count() -
310 *
311 * Helper macro to decrement the started io request count. The macro will not
312 * decrement the started io request count below 0.
313 */
314#define scic_sds_port_decrement_request_count(this_port) \
315 (\
316 (this_port)->started_request_count = (\
317 ((this_port)->started_request_count == 0) ? \
318 (this_port)->started_request_count : \
319 ((this_port)->started_request_count - 1) \
320 ) \
321 )
322#endif
323
324/**
325 * scic_sds_port_write_phy_assignment() -
326 *
327 * Helper macro to write the phys port assignment
328 */
329#define scic_sds_port_write_phy_assignment(port, phy) \
330 SCU_PCSPExCR_WRITE(\
331 (port), \
332 (phy)->phy_index, \
333 (port)->physical_port_index \
334 )
335
336/**
337 * scic_sds_port_read_phy_assignment() -
338 *
339 * Helper macro to read the phys port assignment
340 */
341#define scic_sds_port_read_phy_assignment(port, phy) \
342 SCU_PCSPExCR_READ(\
343 (port), \
344 (phy)->phy_index \
345 )
346
347#define scic_sds_port_active_phy(port, phy) \
348 (((port)->active_phy_mask & (1 << (phy)->phy_index)) != 0)
349
350/* --------------------------------------------------------------------------- */
351
352
353
354
355/* --------------------------------------------------------------------------- */
356
357/* --------------------------------------------------------------------------- */
358
359void scic_sds_port_construct(
360 struct scic_sds_port *this_port,
361 u8 port_index,
362 struct scic_sds_controller *owning_controller);
363
364enum sci_status scic_sds_port_initialize(
365 struct scic_sds_port *this_port,
366 void *transport_layer_registers,
367 void *port_task_scheduler_registers,
368 void *port_configuration_regsiter,
369 void *viit_registers);
370
371/* --------------------------------------------------------------------------- */
372
373enum sci_status scic_sds_port_add_phy(
374 struct scic_sds_port *this_port,
375 struct scic_sds_phy *the_phy);
376
377enum sci_status scic_sds_port_remove_phy(
378 struct scic_sds_port *this_port,
379 struct scic_sds_phy *the_phy);
380
381void scic_sds_port_set_direct_attached_device_id(
382 struct scic_sds_port *this_port,
383 u32 device_id);
384
385void scic_sds_port_activate_phy(
386 struct scic_sds_port *this_port,
387 struct scic_sds_phy *phy,
388 bool do_notify_user);
389
390void scic_sds_port_deactivate_phy(
391 struct scic_sds_port *this_port,
392 struct scic_sds_phy *phy,
393 bool do_notify_user);
394
395
396
397void scic_sds_port_general_link_up_handler(
398 struct scic_sds_port *this_port,
399 struct scic_sds_phy *the_phy,
400 bool do_notify_user);
401
402bool scic_sds_port_link_detected(
403 struct scic_sds_port *this_port,
404 struct scic_sds_phy *phy);
405
406void scic_sds_port_link_up(
407 struct scic_sds_port *this_port,
408 struct scic_sds_phy *phy);
409
410void scic_sds_port_link_down(
411 struct scic_sds_port *this_port,
412 struct scic_sds_phy *phy);
413
414/* --------------------------------------------------------------------------- */
415
416
417/* --------------------------------------------------------------------------- */
418
419enum sci_status scic_sds_port_start_io(
420 struct scic_sds_port *this_port,
421 struct scic_sds_remote_device *the_device,
422 struct scic_sds_request *the_io_request);
423
424enum sci_status scic_sds_port_complete_io(
425 struct scic_sds_port *this_port,
426 struct scic_sds_remote_device *the_device,
427 struct scic_sds_request *the_io_request);
428
429/* --------------------------------------------------------------------------- */
430
431void scic_sds_port_update_viit_entry(
432 struct scic_sds_port *this_port);
433
434/* --------------------------------------------------------------------------- */
435
436enum sci_status scic_sds_port_default_start_handler(
437 struct sci_base_port *port);
438
439
440enum sci_status scic_sds_port_default_destruct_handler(
441 struct sci_base_port *port);
442
443enum sci_status scic_sds_port_default_reset_handler(
444 struct sci_base_port *port,
445 u32 timeout);
446
447
448enum sci_status scic_sds_port_default_remove_phy_handler(
449 struct sci_base_port *port,
450 struct sci_base_phy *phy);
451
452enum sci_status scic_sds_port_default_frame_handler(
453 struct scic_sds_port *port,
454 u32 frame_index);
455
456enum sci_status scic_sds_port_default_event_handler(
457 struct scic_sds_port *port,
458 u32 event_code);
459
460void scic_sds_port_default_link_up_handler(
461 struct scic_sds_port *this_port,
462 struct scic_sds_phy *phy);
463
464void scic_sds_port_default_link_down_handler(
465 struct scic_sds_port *this_port,
466 struct scic_sds_phy *phy);
467
468enum sci_status scic_sds_port_default_start_io_handler(
469 struct scic_sds_port *port,
470 struct scic_sds_remote_device *device,
471 struct scic_sds_request *io_request);
472
473
474enum sci_sas_link_rate scic_sds_port_get_max_allowed_speed(
475 struct scic_sds_port *this_port);
476
477void scic_sds_port_broadcast_change_received(
478 struct scic_sds_port *this_port,
479 struct scic_sds_phy *this_phy);
480
481bool scic_sds_port_is_valid_phy_assignment(
482 struct scic_sds_port *this_port,
483 u32 phy_index);
484
485bool scic_sds_port_is_phy_mask_valid(
486 struct scic_sds_port *this_port,
487 u32 phy_mask);
488
489u32 scic_sds_port_get_phys(
490 struct scic_sds_port *this_port);
491
492void scic_sds_port_get_sas_address(
493 struct scic_sds_port *this_port,
494 struct sci_sas_address *sas_address);
495
496void scic_sds_port_get_attached_sas_address(
497 struct scic_sds_port *this_port,
498 struct sci_sas_address *sas_address);
499
500void scic_sds_port_get_attached_protocols(
501 struct scic_sds_port *this_port,
502 struct sci_sas_identify_address_frame_protocols *protocols);
503
504enum sci_status scic_sds_port_set_phy(
505 struct scic_sds_port *port,
506 struct scic_sds_phy *phy);
507
508enum sci_status scic_sds_port_clear_phy(
509 struct scic_sds_port *port,
510 struct scic_sds_phy *phy);
511
512
513
514#endif /* _SCIC_SDS_PORT_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c b/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c
new file mode 100644
index 000000000000..37d4469162a7
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_port_configuration_agent.c
@@ -0,0 +1,851 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file contains the implementation for the public and protected methods
58 * for the port configuration agent.
59 *
60 *
61 */
62
63#include "sci_environment.h"
64#include "scic_controller.h"
65#include "scic_sds_controller.h"
66#include "scic_sds_port_configuration_agent.h"
67
68#define SCIC_SDS_MPC_RECONFIGURATION_TIMEOUT (10)
69#define SCIC_SDS_APC_RECONFIGURATION_TIMEOUT (10)
70#define SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION (100)
71
72enum SCIC_SDS_APC_ACTIVITY {
73 SCIC_SDS_APC_SKIP_PHY,
74 SCIC_SDS_APC_ADD_PHY,
75 SCIC_SDS_APC_START_TIMER,
76
77 SCIC_SDS_APC_ACTIVITY_MAX
78};
79
80/*
81 * ******************************************************************************
82 * General port configuration agent routines
83 * ****************************************************************************** */
84
85/**
86 *
87 * @address_one: A SAS Address to be compared.
88 * @address_two: A SAS Address to be compared.
89 *
90 * Compare the two SAS Address and if SAS Address One is greater than SAS
91 * Address Two then return > 0 else if SAS Address One is less than SAS Address
92 * Two return < 0 Otherwise they are the same return 0 A signed value of x > 0
93 * > y where x is returned for Address One > Address Two y is returned for
94 * Address One < Address Two 0 is returned ofr Address One = Address Two
95 */
96static s32 sci_sas_address_compare(
97 struct sci_sas_address address_one,
98 struct sci_sas_address address_two)
99{
100 if (address_one.high > address_two.high) {
101 return 1;
102 } else if (address_one.high < address_two.high) {
103 return -1;
104 } else if (address_one.low > address_two.low) {
105 return 1;
106 } else if (address_one.low < address_two.low) {
107 return -1;
108 }
109
110 /* The two SAS Address must be identical */
111 return 0;
112}
113
114/**
115 *
116 * @controller: The controller object used for the port search.
117 * @phy: The phy object to match.
118 *
119 * This routine will find a matching port for the phy. This means that the
120 * port and phy both have the same broadcast sas address and same received sas
121 * address. The port address or the SCI_INVALID_HANDLE if there is no matching
122 * port. port address if the port can be found to match the phy.
123 * SCI_INVALID_HANDLE if there is no matching port for the phy.
124 */
125static struct scic_sds_port *scic_sds_port_configuration_agent_find_port(
126 struct scic_sds_controller *controller,
127 struct scic_sds_phy *phy)
128{
129 u8 port_index;
130 struct scic_sds_port *port_handle;
131 struct sci_sas_address port_sas_address;
132 struct sci_sas_address port_attached_device_address;
133 struct sci_sas_address phy_sas_address;
134 struct sci_sas_address phy_attached_device_address;
135
136 /*
137 * Since this phy can be a member of a wide port check to see if one or
138 * more phys match the sent and received SAS address as this phy in which
139 * case it should participate in the same port. */
140 scic_sds_phy_get_sas_address(phy, &phy_sas_address);
141 scic_sds_phy_get_attached_sas_address(phy, &phy_attached_device_address);
142
143 for (port_index = 0; port_index < SCI_MAX_PORTS; port_index++) {
144 if (scic_controller_get_port_handle(controller, port_index, &port_handle) == SCI_SUCCESS) {
145 struct scic_sds_port *port = (struct scic_sds_port *)port_handle;
146
147 scic_sds_port_get_sas_address(port, &port_sas_address);
148 scic_sds_port_get_attached_sas_address(port, &port_attached_device_address);
149
150 if (
151 (sci_sas_address_compare(port_sas_address, phy_sas_address) == 0)
152 && (sci_sas_address_compare(port_attached_device_address, phy_attached_device_address) == 0)
153 ) {
154 return port;
155 }
156 }
157 }
158
159 return SCI_INVALID_HANDLE;
160}
161
162/**
163 *
164 * @controller: This is the controller object that contains the port agent
165 * @port_agent: This is the port configruation agent for the controller.
166 *
167 * This routine will validate the port configuration is correct for the SCU
168 * hardware. The SCU hardware allows for port configurations as follows. LP0
169 * -> (PE0), (PE0, PE1), (PE0, PE1, PE2, PE3) LP1 -> (PE1) LP2 -> (PE2), (PE2,
170 * PE3) LP3 -> (PE3) enum sci_status SCI_SUCCESS the port configuration is valid for
171 * this port configuration agent. SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION
172 * the port configuration is not valid for this port configuration agent.
173 */
174static enum sci_status scic_sds_port_configuration_agent_validate_ports(
175 struct scic_sds_controller *controller,
176 struct scic_sds_port_configuration_agent *port_agent)
177{
178 struct sci_sas_address first_address;
179 struct sci_sas_address second_address;
180
181 /*
182 * Sanity check the max ranges for all the phys the max index
183 * is always equal to the port range index */
184 if (
185 (port_agent->phy_valid_port_range[0].max_index != 0)
186 || (port_agent->phy_valid_port_range[1].max_index != 1)
187 || (port_agent->phy_valid_port_range[2].max_index != 2)
188 || (port_agent->phy_valid_port_range[3].max_index != 3)
189 ) {
190 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
191 }
192
193 /*
194 * This is a request to configure a single x4 port or at least attempt
195 * to make all the phys into a single port */
196 if (
197 (port_agent->phy_valid_port_range[0].min_index == 0)
198 && (port_agent->phy_valid_port_range[1].min_index == 0)
199 && (port_agent->phy_valid_port_range[2].min_index == 0)
200 && (port_agent->phy_valid_port_range[3].min_index == 0)
201 ) {
202 return SCI_SUCCESS;
203 }
204
205 /*
206 * This is a degenerate case where phy 1 and phy 2 are assigned
207 * to the same port this is explicitly disallowed by the hardware
208 * unless they are part of the same x4 port and this condition was
209 * already checked above. */
210 if (port_agent->phy_valid_port_range[2].min_index == 1) {
211 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
212 }
213
214 /*
215 * PE0 and PE3 can never have the same SAS Address unless they
216 * are part of the same x4 wide port and we have already checked
217 * for this condition. */
218 scic_sds_phy_get_sas_address(&controller->phy_table[0], &first_address);
219 scic_sds_phy_get_sas_address(&controller->phy_table[3], &second_address);
220
221 if (sci_sas_address_compare(first_address, second_address) == 0) {
222 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
223 }
224
225 /*
226 * PE0 and PE1 are configured into a 2x1 ports make sure that the
227 * SAS Address for PE0 and PE2 are different since they can not be
228 * part of the same port. */
229 if (
230 (port_agent->phy_valid_port_range[0].min_index == 0)
231 && (port_agent->phy_valid_port_range[1].min_index == 1)
232 ) {
233 scic_sds_phy_get_sas_address(&controller->phy_table[0], &first_address);
234 scic_sds_phy_get_sas_address(&controller->phy_table[2], &second_address);
235
236 if (sci_sas_address_compare(first_address, second_address) == 0) {
237 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
238 }
239 }
240
241 /*
242 * PE2 and PE3 are configured into a 2x1 ports make sure that the
243 * SAS Address for PE1 and PE3 are different since they can not be
244 * part of the same port. */
245 if (
246 (port_agent->phy_valid_port_range[2].min_index == 2)
247 && (port_agent->phy_valid_port_range[3].min_index == 3)
248 ) {
249 scic_sds_phy_get_sas_address(&controller->phy_table[1], &first_address);
250 scic_sds_phy_get_sas_address(&controller->phy_table[3], &second_address);
251
252 if (sci_sas_address_compare(first_address, second_address) == 0) {
253 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
254 }
255 }
256
257 return SCI_SUCCESS;
258}
259
260/*
261 * ******************************************************************************
262 * Manual port configuration agent routines
263 * ****************************************************************************** */
264
265/**
266 *
267 *
268 * This routine will verify that all of the phys in the same port are using the
269 * same SAS address.
270 */
271static enum sci_status scic_sds_mpc_agent_validate_phy_configuration(
272 struct scic_sds_controller *controller,
273 struct scic_sds_port_configuration_agent *port_agent)
274{
275 u32 phy_mask;
276 u32 assigned_phy_mask;
277 struct sci_sas_address sas_address;
278 struct sci_sas_address phy_assigned_address;
279 u8 port_index;
280 u8 phy_index;
281
282 assigned_phy_mask = 0;
283 sas_address.high = 0;
284 sas_address.low = 0;
285
286 for (port_index = 0; port_index < SCI_MAX_PORTS; port_index++) {
287 phy_mask = controller->oem_parameters.sds1.ports[port_index].phy_mask;
288
289 if (phy_mask != 0) {
290 /*
291 * Make sure that one or more of the phys were not already assinged to
292 * a different port. */
293 if ((phy_mask & ~assigned_phy_mask) == 0) {
294 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
295 }
296
297 /* Find the starting phy index for this round through the loop */
298 for (phy_index = 0; phy_index < SCI_MAX_PHYS; phy_index++) {
299 if ((1 << phy_index) & phy_mask) {
300 scic_sds_phy_get_sas_address(
301 &controller->phy_table[phy_index], &sas_address
302 );
303
304 /*
305 * The phy_index can be used as the starting point for the
306 * port range since the hardware starts all logical ports
307 * the same as the PE index. */
308 port_agent->phy_valid_port_range[phy_index].min_index = port_index;
309 port_agent->phy_valid_port_range[phy_index].max_index = phy_index;
310
311 if (phy_index != port_index) {
312 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
313 }
314
315 break;
316 }
317 }
318
319 /*
320 * See how many additional phys are being added to this logical port.
321 * Note: We have not moved the current phy_index so we will actually
322 * compare the startting phy with itself.
323 * This is expected and required to add the phy to the port. */
324 while (phy_index < SCI_MAX_PHYS) {
325 if ((1 << phy_index) & phy_mask) {
326 scic_sds_phy_get_sas_address(
327 &controller->phy_table[phy_index], &phy_assigned_address
328 );
329
330 if (sci_sas_address_compare(sas_address, phy_assigned_address) != 0) {
331 /*
332 * The phy mask specified that this phy is part of the same port
333 * as the starting phy and it is not so fail this configuration */
334 return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
335 }
336
337 port_agent->phy_valid_port_range[phy_index].min_index = port_index;
338 port_agent->phy_valid_port_range[phy_index].max_index = phy_index;
339
340 scic_sds_port_add_phy(
341 &controller->port_table[port_index],
342 &controller->phy_table[phy_index]
343 );
344
345 assigned_phy_mask |= (1 << phy_index);
346 }
347
348 phy_index++;
349 }
350 }
351 }
352
353 return scic_sds_port_configuration_agent_validate_ports(controller, port_agent);
354}
355
356/**
357 *
358 *
359 * This timer routine is used to allow the SCI User to rediscover or change
360 * device objects before a new series of link up notifications because a link
361 * down has allowed a better port configuration.
362 */
363static void scic_sds_mpc_agent_timeout_handler(
364 void *object)
365{
366 u8 index;
367 struct scic_sds_controller *controller = (struct scic_sds_controller *)object;
368 struct scic_sds_port_configuration_agent *port_agent = &controller->port_agent;
369 u16 configure_phy_mask;
370
371 port_agent->timer_pending = false;
372
373 /* Find the mask of phys that are reported read but as yet unconfigured into a port */
374 configure_phy_mask = ~port_agent->phy_configured_mask & port_agent->phy_ready_mask;
375
376 for (index = 0; index < SCI_MAX_PHYS; index++) {
377 if (configure_phy_mask & (1 << index)) {
378 port_agent->link_up_handler(
379 controller,
380 port_agent,
381 scic_sds_phy_get_port(&controller->phy_table[index]),
382 &controller->phy_table[index]
383 );
384 }
385 }
386}
387
388/**
389 *
390 * @controller: This is the controller object that receives the link up
391 * notification.
392 * @port: This is the port object associated with the phy. If the is no
393 * associated port this is an SCI_INVALID_HANDLE.
394 * @phy: This is the phy object which has gone ready.
395 *
396 * This method handles the manual port configuration link up notifications.
397 * Since all ports and phys are associate at initialization time we just turn
398 * around and notifiy the port object that there is a link up. If this PHY is
399 * not associated with a port there is no action taken. Is it possible to get a
400 * link up notification from a phy that has no assocoated port?
401 */
402static void scic_sds_mpc_agent_link_up(
403 struct scic_sds_controller *controller,
404 struct scic_sds_port_configuration_agent *port_agent,
405 struct scic_sds_port *port,
406 struct scic_sds_phy *phy)
407{
408 /*
409 * If the port has an invalid handle then the phy was not assigned to
410 * a port. This is because the phy was not given the same SAS Address
411 * as the other PHYs in the port. */
412 if (port != SCI_INVALID_HANDLE) {
413 port_agent->phy_ready_mask |= (1 << scic_sds_phy_get_index(phy));
414
415 scic_sds_port_link_up(port, phy);
416
417 if ((port->active_phy_mask & (1 << scic_sds_phy_get_index(phy))) != 0) {
418 port_agent->phy_configured_mask |= (1 << scic_sds_phy_get_index(phy));
419 }
420 }
421}
422
423/**
424 *
425 * @controller: This is the controller object that receives the link down
426 * notification.
427 * @port: This is the port object associated with the phy. If the is no
428 * associated port this is an SCI_INVALID_HANDLE. The port is an invalid
429 * handle only if the phy was never port of this port. This happens when
430 * the phy is not broadcasting the same SAS address as the other phys in the
431 * assigned port.
432 * @phy: This is the phy object which has gone link down.
433 *
434 * This method handles the manual port configuration link down notifications.
435 * Since all ports and phys are associated at initialization time we just turn
436 * around and notifiy the port object of the link down event. If this PHY is
437 * not associated with a port there is no action taken. Is it possible to get a
438 * link down notification from a phy that has no assocoated port?
439 */
440static void scic_sds_mpc_agent_link_down(
441 struct scic_sds_controller *controller,
442 struct scic_sds_port_configuration_agent *port_agent,
443 struct scic_sds_port *port,
444 struct scic_sds_phy *phy)
445{
446 if (port != SCI_INVALID_HANDLE) {
447 /*
448 * If we can form a new port from the remainder of the phys then we want
449 * to start the timer to allow the SCI User to cleanup old devices and
450 * rediscover the port before rebuilding the port with the phys that
451 * remain in the ready state. */
452 port_agent->phy_ready_mask &= ~(1 << scic_sds_phy_get_index(phy));
453 port_agent->phy_configured_mask &= ~(1 << scic_sds_phy_get_index(phy));
454
455 /*
456 * Check to see if there are more phys waiting to be configured into a port.
457 * If there are allow the SCI User to tear down this port, if necessary, and
458 * then reconstruc the port after the timeout. */
459 if (
460 (port_agent->phy_configured_mask == 0x0000)
461 && (port_agent->phy_ready_mask != 0x0000)
462 && !port_agent->timer_pending
463 ) {
464 port_agent->timer_pending = true;
465
466 scic_cb_timer_start(
467 controller,
468 port_agent->timer,
469 SCIC_SDS_MPC_RECONFIGURATION_TIMEOUT
470 );
471 }
472
473 scic_sds_port_link_down(port, phy);
474 }
475}
476
477/*
478 * ******************************************************************************
479 * Automatic port configuration agent routines
480 * ****************************************************************************** */
481
482/**
483 *
484 *
485 * This routine will verify that the phys are assigned a valid SAS address for
486 * automatic port configuration mode.
487 */
488static enum sci_status scic_sds_apc_agent_validate_phy_configuration(
489 struct scic_sds_controller *controller,
490 struct scic_sds_port_configuration_agent *port_agent)
491{
492 u8 phy_index;
493 u8 port_index;
494 struct sci_sas_address sas_address;
495 struct sci_sas_address phy_assigned_address;
496
497 phy_index = 0;
498
499 while (phy_index < SCI_MAX_PHYS) {
500 port_index = phy_index;
501
502 /* Get the assigned SAS Address for the first PHY on the controller. */
503 scic_sds_phy_get_sas_address(
504 &controller->phy_table[phy_index], &sas_address
505 );
506
507 while (++phy_index < SCI_MAX_PHYS) {
508 scic_sds_phy_get_sas_address(
509 &controller->phy_table[phy_index], &phy_assigned_address
510 );
511
512 /* Verify each of the SAS address are all the same for every PHY */
513 if (sci_sas_address_compare(sas_address, phy_assigned_address) == 0) {
514 port_agent->phy_valid_port_range[phy_index].min_index = port_index;
515 port_agent->phy_valid_port_range[phy_index].max_index = phy_index;
516 } else {
517 port_agent->phy_valid_port_range[phy_index].min_index = phy_index;
518 port_agent->phy_valid_port_range[phy_index].max_index = phy_index;
519 break;
520 }
521 }
522 }
523
524 return scic_sds_port_configuration_agent_validate_ports(controller, port_agent);
525}
526
527/**
528 *
529 * @controller: This is the controller that to which the port agent is assigned.
530 * @port_agent: This is the port agent that is requesting the timer start
531 * operation.
532 * @phy: This is the phy that has caused the timer operation to be scheduled.
533 *
534 * This routine will restart the automatic port configuration timeout timer for
535 * the next time period. This could be caused by either a link down event or a
536 * link up event where we can not yet tell to which port a phy belongs.
537 */
538static void scic_sds_apc_agent_start_timer(
539 struct scic_sds_controller *controller,
540 struct scic_sds_port_configuration_agent *port_agent,
541 struct scic_sds_phy *phy,
542 u32 timeout)
543{
544 if (port_agent->timer_pending) {
545 scic_cb_timer_stop(controller, port_agent->timer);
546 }
547
548 port_agent->timer_pending = true;
549
550 scic_cb_timer_start(controller, port_agent->timer, timeout);
551}
552
553/**
554 *
555 * @controller: This is the controller object that receives the link up
556 * notification.
557 * @phy: This is the phy object which has gone link up.
558 *
559 * This method handles the automatic port configuration for link up
560 * notifications.
561 */
562static void scic_sds_apc_agent_configure_ports(
563 struct scic_sds_controller *controller,
564 struct scic_sds_port_configuration_agent *port_agent,
565 struct scic_sds_phy *phy,
566 bool start_timer)
567{
568 u8 port_index;
569 enum sci_status status;
570 struct scic_sds_port *port;
571 struct scic_sds_port *port_handle;
572 enum SCIC_SDS_APC_ACTIVITY apc_activity = SCIC_SDS_APC_SKIP_PHY;
573
574 port = scic_sds_port_configuration_agent_find_port(controller, phy);
575
576 if (port != SCI_INVALID_HANDLE) {
577 if (scic_sds_port_is_valid_phy_assignment(port, phy->phy_index))
578 apc_activity = SCIC_SDS_APC_ADD_PHY;
579 else
580 apc_activity = SCIC_SDS_APC_SKIP_PHY;
581 } else {
582 /*
583 * There is no matching Port for this PHY so lets search through the
584 * Ports and see if we can add the PHY to its own port or maybe start
585 * the timer and wait to see if a wider port can be made.
586 *
587 * Note the break when we reach the condition of the port id == phy id */
588 for (
589 port_index = port_agent->phy_valid_port_range[phy->phy_index].min_index;
590 port_index <= port_agent->phy_valid_port_range[phy->phy_index].max_index;
591 port_index++
592 ) {
593 scic_controller_get_port_handle(controller, port_index, &port_handle);
594
595 port = (struct scic_sds_port *)port_handle;
596
597 /* First we must make sure that this PHY can be added to this Port. */
598 if (scic_sds_port_is_valid_phy_assignment(port, phy->phy_index)) {
599 /*
600 * Port contains a PHY with a greater PHY ID than the current
601 * PHY that has gone link up. This phy can not be part of any
602 * port so skip it and move on. */
603 if (port->active_phy_mask > (1 << phy->phy_index)) {
604 apc_activity = SCIC_SDS_APC_SKIP_PHY;
605 break;
606 }
607
608 /*
609 * We have reached the end of our Port list and have not found
610 * any reason why we should not either add the PHY to the port
611 * or wait for more phys to become active. */
612 if (port->physical_port_index == phy->phy_index) {
613 /*
614 * The Port either has no active PHYs.
615 * Consider that if the port had any active PHYs we would have
616 * or active PHYs with
617 * a lower PHY Id than this PHY. */
618 if (apc_activity != SCIC_SDS_APC_START_TIMER) {
619 apc_activity = SCIC_SDS_APC_ADD_PHY;
620 }
621
622 break;
623 }
624
625 /*
626 * The current Port has no active PHYs and this PHY could be part
627 * of this Port. Since we dont know as yet setup to start the
628 * timer and see if there is a better configuration. */
629 if (port->active_phy_mask == 0) {
630 apc_activity = SCIC_SDS_APC_START_TIMER;
631 }
632 } else if (port->active_phy_mask != 0) {
633 /*
634 * The Port has an active phy and the current Phy can not
635 * participate in this port so skip the PHY and see if
636 * there is a better configuration. */
637 apc_activity = SCIC_SDS_APC_SKIP_PHY;
638 }
639 }
640 }
641
642 /*
643 * Check to see if the start timer operations should instead map to an
644 * add phy operation. This is caused because we have been waiting to
645 * add a phy to a port but could not becuase the automatic port
646 * configuration engine had a choice of possible ports for the phy.
647 * Since we have gone through a timeout we are going to restrict the
648 * choice to the smallest possible port. */
649 if (
650 (start_timer == false)
651 && (apc_activity == SCIC_SDS_APC_START_TIMER)
652 ) {
653 apc_activity = SCIC_SDS_APC_ADD_PHY;
654 }
655
656 switch (apc_activity) {
657 case SCIC_SDS_APC_ADD_PHY:
658 status = scic_sds_port_add_phy(port, phy);
659
660 if (status == SCI_SUCCESS) {
661 port_agent->phy_configured_mask |= (1 << phy->phy_index);
662 }
663 break;
664
665 case SCIC_SDS_APC_START_TIMER:
666 scic_sds_apc_agent_start_timer(
667 controller, port_agent, phy, SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION
668 );
669 break;
670
671 case SCIC_SDS_APC_SKIP_PHY:
672 default:
673 /* do nothing the PHY can not be made part of a port at this time. */
674 break;
675 }
676}
677
678/**
679 *
680 * @controller: This is the controller object that receives the link up
681 * notification.
682 * @port: This is the port object associated with the phy. If the is no
683 * associated port this is an SCI_INVALID_HANDLE.
684 * @phy: This is the phy object which has gone link up.
685 *
686 * This method handles the automatic port configuration for link up
687 * notifications. Is it possible to get a link down notification from a phy
688 * that has no assocoated port?
689 */
690static void scic_sds_apc_agent_link_up(
691 struct scic_sds_controller *controller,
692 struct scic_sds_port_configuration_agent *port_agent,
693 struct scic_sds_port *port,
694 struct scic_sds_phy *phy)
695{
696 BUG_ON(port != SCI_INVALID_HANDLE);
697
698 port_agent->phy_ready_mask |= (1 << scic_sds_phy_get_index(phy));
699
700 scic_sds_apc_agent_configure_ports(controller, port_agent, phy, true);
701}
702
703/**
704 *
705 * @controller: This is the controller object that receives the link down
706 * notification.
707 * @port: This is the port object associated with the phy. If the is no
708 * associated port this is an SCI_INVALID_HANDLE.
709 * @phy: This is the phy object which has gone link down.
710 *
711 * This method handles the automatic port configuration link down
712 * notifications. not associated with a port there is no action taken. Is it
713 * possible to get a link down notification from a phy that has no assocoated
714 * port?
715 */
716static void scic_sds_apc_agent_link_down(
717 struct scic_sds_controller *controller,
718 struct scic_sds_port_configuration_agent *port_agent,
719 struct scic_sds_port *port,
720 struct scic_sds_phy *phy)
721{
722 port_agent->phy_ready_mask &= ~(1 << scic_sds_phy_get_index(phy));
723
724 if (port != SCI_INVALID_HANDLE) {
725 if (port_agent->phy_configured_mask & (1 << phy->phy_index)) {
726 enum sci_status status;
727
728 status = scic_sds_port_remove_phy(port, phy);
729
730 if (status == SCI_SUCCESS) {
731 port_agent->phy_configured_mask &= ~(1 << phy->phy_index);
732 }
733 }
734 }
735}
736
737/**
738 *
739 *
740 * This routine will try to configure the phys into ports when the timer fires.
741 */
742static void scic_sds_apc_agent_timeout_handler(
743 void *object)
744{
745 u32 index;
746 struct scic_sds_port_configuration_agent *port_agent;
747 struct scic_sds_controller *controller = (struct scic_sds_controller *)object;
748 u16 configure_phy_mask;
749
750 port_agent = scic_sds_controller_get_port_configuration_agent(controller);
751
752 port_agent->timer_pending = false;
753
754 configure_phy_mask = ~port_agent->phy_configured_mask & port_agent->phy_ready_mask;
755
756 if (configure_phy_mask != 0x00) {
757 for (index = 0; index < SCI_MAX_PHYS; index++) {
758 if (configure_phy_mask & (1 << index)) {
759 scic_sds_apc_agent_configure_ports(
760 controller, port_agent, &controller->phy_table[index], false
761 );
762 }
763 }
764 }
765}
766
767/*
768 * ******************************************************************************
769 * Public port configuration agent routines
770 * ****************************************************************************** */
771
772/**
773 *
774 *
775 * This method will construct the port configuration agent for operation. This
776 * call is universal for both manual port configuration and automatic port
777 * configuration modes.
778 */
779void scic_sds_port_configuration_agent_construct(
780 struct scic_sds_port_configuration_agent *port_agent)
781{
782 u32 index;
783
784 port_agent->phy_configured_mask = 0x00;
785 port_agent->phy_ready_mask = 0x00;
786
787 port_agent->link_up_handler = NULL;
788 port_agent->link_down_handler = NULL;
789
790 port_agent->timer_pending = false;
791 port_agent->timer = NULL;
792
793 for (index = 0; index < SCI_MAX_PORTS; index++) {
794 port_agent->phy_valid_port_range[index].min_index = 0;
795 port_agent->phy_valid_port_range[index].max_index = 0;
796 }
797}
798
799/**
800 *
801 * @controller: This is the controller object for which the port agent is being
802 * initialized.
803 *
804 * This method will construct the port configuration agent for this controller.
805 */
806enum sci_status scic_sds_port_configuration_agent_initialize(
807 struct scic_sds_controller *controller,
808 struct scic_sds_port_configuration_agent *port_agent)
809{
810 enum sci_status status = SCI_SUCCESS;
811 enum SCIC_PORT_CONFIGURATION_MODE mode;
812
813 mode = scic_sds_controller_get_port_configuration_mode(controller);
814
815 if (mode == SCIC_PORT_MANUAL_CONFIGURATION_MODE) {
816 status = scic_sds_mpc_agent_validate_phy_configuration(controller, port_agent);
817
818 port_agent->link_up_handler = scic_sds_mpc_agent_link_up;
819 port_agent->link_down_handler = scic_sds_mpc_agent_link_down;
820
821 port_agent->timer = scic_cb_timer_create(
822 controller,
823 scic_sds_mpc_agent_timeout_handler,
824 controller
825 );
826 } else {
827 status = scic_sds_apc_agent_validate_phy_configuration(controller, port_agent);
828
829 port_agent->link_up_handler = scic_sds_apc_agent_link_up;
830 port_agent->link_down_handler = scic_sds_apc_agent_link_down;
831
832 port_agent->timer = scic_cb_timer_create(
833 controller,
834 scic_sds_apc_agent_timeout_handler,
835 controller
836 );
837 }
838
839 /* Make sure we have actually gotten a timer */
840 if ((status == SCI_SUCCESS) && (port_agent->timer == NULL)) {
841 dev_err(scic_to_dev(controller),
842 "%s: Controller 0x%p automatic port configuration "
843 "agent could not get timer.\n",
844 __func__,
845 controller);
846
847 status = SCI_FAILURE;
848 }
849
850 return status;
851}
diff --git a/drivers/scsi/isci/core/scic_sds_port_configuration_agent.h b/drivers/scsi/isci/core/scic_sds_port_configuration_agent.h
new file mode 100644
index 000000000000..4146735ffc32
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_port_configuration_agent.h
@@ -0,0 +1,108 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_SDS_PORT_CONFIGURATION_AGENT_H_
57#define _SCIC_SDS_PORT_CONFIGURATION_AGENT_H_
58
59/**
60 * This file contains the structures, constants and prototypes used for the
61 * core controller automatic port configuration engine.
62 *
63 *
64 */
65
66#include "scic_sds_port.h"
67#include "scic_sds_phy.h"
68
69struct scic_sds_controller;
70struct scic_sds_port_configuration_agent;
71struct scic_sds_port;
72struct scic_sds_phy;
73
74typedef void (*SCIC_SDS_PORT_CONFIGURATION_AGENT_PHY_HANDLER_T)(
75 struct scic_sds_controller *,
76 struct scic_sds_port_configuration_agent *,
77 struct scic_sds_port *,
78 struct scic_sds_phy *
79 );
80
81struct SCIC_SDS_PORT_RANGE {
82 u8 min_index;
83 u8 max_index;
84};
85
86struct scic_sds_port_configuration_agent {
87 u16 phy_configured_mask;
88 u16 phy_ready_mask;
89
90 struct SCIC_SDS_PORT_RANGE phy_valid_port_range[SCI_MAX_PHYS];
91
92 bool timer_pending;
93
94 SCIC_SDS_PORT_CONFIGURATION_AGENT_PHY_HANDLER_T link_up_handler;
95 SCIC_SDS_PORT_CONFIGURATION_AGENT_PHY_HANDLER_T link_down_handler;
96
97 void *timer;
98
99};
100
101void scic_sds_port_configuration_agent_construct(
102 struct scic_sds_port_configuration_agent *port_agent);
103
104enum sci_status scic_sds_port_configuration_agent_initialize(
105 struct scic_sds_controller *controller,
106 struct scic_sds_port_configuration_agent *port_agent);
107
108#endif /* _SCIC_SDS_PORT_CONFIGURATION_AGENT_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_port_registers.h b/drivers/scsi/isci/core/scic_sds_port_registers.h
new file mode 100644
index 000000000000..cf8bc073b952
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_port_registers.h
@@ -0,0 +1,223 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_SDS_PORT_REGISTERS_H_
57#define _SCIC_SDS_PORT_REGISTERS_H_
58
59/**
60 * This file contains a set of macros that assist in reading the SCU hardware
61 * registers.
62 *
63 *
64 */
65
66/**
67 * scu_transport_layer_read() -
68 *
69 * Macro to read the transport layer register associated with this port object.
70 */
71#define scu_transport_layer_read(port, reg) \
72 scu_register_read(\
73 scic_sds_port_get_controller(port), \
74 (port)->transport_layer_registers->reg \
75 )
76
77/**
78 * scu_transport_layer_write() -
79 *
80 * Macro to write the transport layer register associated with this port object.
81 */
82#define scu_transport_layer_write(port, reg, value) \
83 scu_register_write(\
84 scic_sds_port_get_controller(port), \
85 (port)->transport_layer_registers->reg, \
86 (value) \
87 )
88
89/**
90 * scu_port_task_scheduler_read() -
91 *
92 * Macro to read the port task scheduler register associated with this port
93 * object
94 */
95#define scu_port_task_scheduler_read(port, reg) \
96 scu_register_read(\
97 scic_sds_port_get_controller(port), \
98 (port)->port_task_scheduler_registers->reg \
99 )
100
101/**
102 * scu_port_task_scheduler_write() -
103 *
104 * Macro to write the port task scheduler register associated with this port
105 * object
106 */
107#define scu_port_task_scheduler_write(port, reg, value) \
108 scu_register_write(\
109 scic_sds_port_get_controller(port), \
110 (port)->port_task_scheduler_registers->reg, \
111 (value) \
112 )
113
114#define scu_port_viit_register_write(port, reg, value) \
115 scu_register_write(\
116 scic_sds_port_get_controller(port), \
117 (port)->viit_registers->reg, \
118 (value) \
119 )
120
121/*
122 * ****************************************************************************
123 * * Transport Layer registers controlled by the port object
124 * **************************************************************************** */
125
126/**
127 * SCU_TLCR_READ() -
128 *
129 * This macro reads the Transport layer control register
130 */
131#define SCU_TLCR_READ(port) \
132 scu_transport_layer_read(port, control)
133
134/**
135 * SCU_TLCR_WRITE() -
136 *
137 * This macro writes the Transport layer control register
138 */
139#define SCU_TLCR_WRITE(port, value) \
140 scu_transport_layer_write(port, control, value)
141
142/**
143 * SCU_TLADTR_READ() -
144 *
145 * This macro reads the Transport layer address translation register
146 */
147#define SCU_TLADTR_READ(port) \
148 scu_transport_layer_read(port, address_translation)
149
150/**
151 * SCU_TLADTR_WRITE() -
152 *
153 * This macro writes the Transport layer address translation register
154 */
155#define SCU_TLADTR_WRITE(port) \
156 scu_transport_layer_write(port, address_translation, value)
157
158/**
159 * SCU_STPTLDARNI_WRITE() -
160 *
161 * This macro writes the STP Transport Layer Direct Attached RNi register.
162 */
163#define SCU_STPTLDARNI_WRITE(port, index) \
164 scu_transport_layer_write(port, stp_rni, index)
165
166/**
167 * SCU_STPTLDARNI_READ() -
168 *
169 * This macro reads the STP Transport Layer Direct Attached RNi register.
170 */
171#define SCU_STPTLDARNI_READ(port) \
172 scu_transport_layer_read(port, stp_rni)
173
174/*
175 * ****************************************************************************
176 * * Port Task Scheduler registers controlled by the port object
177 * **************************************************************************** */
178
179/**
180 * SCU_PTSxCR_READ() -
181 *
182 * Macro to read the port task scheduler control register
183 */
184#define SCU_PTSxCR_READ(port) \
185 scu_port_task_scheduler_read(port, control)
186
187/**
188 * SCU_PTSxCR_WRITE() -
189 *
190 * Macro to write the port task scheduler control regsister
191 */
192#define SCU_PTSxCR_WRITE(port, value) \
193 scu_port_task_scheduler_write(port, control, value)
194
195/*
196 * ****************************************************************************
197 * * Port PE Configuration registers
198 * **************************************************************************** */
199
200/**
201 * SCU_PCSPExCR_WRITE() -
202 *
203 * Macro to write the PE Port Configuration Register
204 */
205#define SCU_PCSPExCR_WRITE(port, phy_id, value) \
206 scu_register_write(\
207 scic_sds_port_get_controller(port), \
208 (port)->port_pe_configuration_register[phy_id], \
209 (value) \
210 )
211
212/**
213 * SCU_PCSPExCR_READ() -
214 *
215 * Macro to read the PE Port Configuration Regsiter
216 */
217#define SCU_PCSPExCR_READ(port, phy_id) \
218 scu_register_read(\
219 scic_sds_port_get_controller(port), \
220 (port)->port_pe_configuration_register[phy_id] \
221 )
222
223#endif /* _SCIC_SDS_PORT_REGISTERS_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_remote_device.c b/drivers/scsi/isci/core/scic_sds_remote_device.c
new file mode 100644
index 000000000000..21f03bc7d797
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_remote_device.c
@@ -0,0 +1,2252 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file contains the implementation of remote device methods.
58 *
59 *
60 */
61
62#include "intel_sas.h"
63#include "sci_util.h"
64#include "sci_environment.h"
65#include "scic_port.h"
66#include "scic_phy.h"
67#include "scic_remote_device.h"
68#include "scic_sds_port.h"
69#include "scic_sds_phy.h"
70#include "scic_sds_remote_device.h"
71#include "scic_sds_request.h"
72#include "scic_sds_controller.h"
73
74#define SCIC_SDS_REMOTE_DEVICE_RESET_TIMEOUT (1000)
75
76/*
77 * *****************************************************************************
78 * * CORE REMOTE DEVICE PRIVATE METHODS
79 * ***************************************************************************** */
80
81/*
82 * *****************************************************************************
83 * * CORE REMOTE DEVICE PUBLIC METHODS
84 * ***************************************************************************** */
85
86u32 scic_remote_device_get_object_size(void)
87{
88 return sizeof(struct scic_sds_remote_device)
89 + sizeof(struct scic_sds_remote_node_context);
90}
91
92/* --------------------------------------------------------------------------- */
93
94void scic_remote_device_construct(struct scic_sds_port *sci_port,
95 struct scic_sds_remote_device *sci_dev)
96{
97 sci_dev->owning_port = sci_port;
98 sci_dev->started_request_count = 0;
99 sci_dev->rnc = (struct scic_sds_remote_node_context *) &sci_dev[1];
100
101 sci_base_remote_device_construct(
102 &sci_dev->parent,
103 scic_sds_remote_device_state_table
104 );
105
106 scic_sds_remote_node_context_construct(
107 sci_dev,
108 sci_dev->rnc,
109 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
110 );
111
112 sci_object_set_association(sci_dev->rnc, sci_dev);
113}
114
115
116enum sci_status scic_remote_device_da_construct(
117 struct scic_sds_remote_device *sci_dev)
118{
119 enum sci_status status;
120 u16 remote_node_index;
121 struct sci_sas_identify_address_frame_protocols protocols;
122
123 /*
124 * This information is request to determine how many remote node context
125 * entries will be needed to store the remote node.
126 */
127 scic_sds_port_get_attached_protocols(sci_dev->owning_port, &protocols);
128 sci_dev->target_protocols.u.all = protocols.u.all;
129 sci_dev->is_direct_attached = true;
130#if !defined(DISABLE_ATAPI)
131 sci_dev->is_atapi = scic_sds_remote_device_is_atapi(sci_dev);
132#endif
133
134 status = scic_sds_controller_allocate_remote_node_context(
135 sci_dev->owning_port->owning_controller,
136 sci_dev,
137 &remote_node_index);
138
139 if (status == SCI_SUCCESS) {
140 scic_sds_remote_node_context_set_remote_node_index(
141 sci_dev->rnc, remote_node_index);
142
143 scic_sds_port_get_attached_sas_address(
144 sci_dev->owning_port, &sci_dev->device_address);
145
146 if (sci_dev->target_protocols.u.bits.attached_ssp_target) {
147 sci_dev->has_ready_substate_machine = false;
148 } else if (sci_dev->target_protocols.u.bits.attached_stp_target) {
149 sci_dev->has_ready_substate_machine = true;
150
151 sci_base_state_machine_construct(
152 &sci_dev->ready_substate_machine,
153 &sci_dev->parent.parent,
154 scic_sds_stp_remote_device_ready_substate_table,
155 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE);
156 } else if (sci_dev->target_protocols.u.bits.attached_smp_target) {
157 sci_dev->has_ready_substate_machine = true;
158
159 /* add the SMP ready substate machine construction here */
160 sci_base_state_machine_construct(
161 &sci_dev->ready_substate_machine,
162 &sci_dev->parent.parent,
163 scic_sds_smp_remote_device_ready_substate_table,
164 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE);
165 }
166
167 sci_dev->connection_rate = scic_sds_port_get_max_allowed_speed(
168 sci_dev->owning_port);
169
170 /* / @todo Should I assign the port width by reading all of the phys on the port? */
171 sci_dev->device_port_width = 1;
172 }
173
174 return status;
175}
176
177
178static void scic_sds_remote_device_get_info_from_smp_discover_response(
179 struct scic_sds_remote_device *this_device,
180 struct smp_response_discover *discover_response)
181{
182 /* decode discover_response to set sas_address to this_device. */
183 this_device->device_address.high =
184 discover_response->attached_sas_address.high;
185
186 this_device->device_address.low =
187 discover_response->attached_sas_address.low;
188
189 this_device->target_protocols.u.all = discover_response->protocols.u.all;
190}
191
192
193enum sci_status scic_remote_device_ea_construct(
194 struct scic_sds_remote_device *sci_dev,
195 struct smp_response_discover *discover_response)
196{
197 enum sci_status status;
198 struct scic_sds_controller *the_controller;
199
200 the_controller = scic_sds_port_get_controller(sci_dev->owning_port);
201
202 scic_sds_remote_device_get_info_from_smp_discover_response(
203 sci_dev, discover_response);
204
205 status = scic_sds_controller_allocate_remote_node_context(
206 the_controller, sci_dev, &sci_dev->rnc->remote_node_index);
207
208 if (status == SCI_SUCCESS) {
209 if (sci_dev->target_protocols.u.bits.attached_ssp_target) {
210 sci_dev->has_ready_substate_machine = false;
211 } else if (sci_dev->target_protocols.u.bits.attached_smp_target) {
212 sci_dev->has_ready_substate_machine = true;
213
214 /* add the SMP ready substate machine construction here */
215 sci_base_state_machine_construct(
216 &sci_dev->ready_substate_machine,
217 &sci_dev->parent.parent,
218 scic_sds_smp_remote_device_ready_substate_table,
219 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE);
220 } else if (sci_dev->target_protocols.u.bits.attached_stp_target) {
221 sci_dev->has_ready_substate_machine = true;
222
223 sci_base_state_machine_construct(
224 &sci_dev->ready_substate_machine,
225 &sci_dev->parent.parent,
226 scic_sds_stp_remote_device_ready_substate_table,
227 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE);
228 }
229
230 /*
231 * For SAS-2 the physical link rate is actually a logical link
232 * rate that incorporates multiplexing. The SCU doesn't
233 * incorporate multiplexing and for the purposes of the
234 * connection the logical link rate is that same as the
235 * physical. Furthermore, the SAS-2 and SAS-1.1 fields overlay
236 * one another, so this code works for both situations. */
237 sci_dev->connection_rate = min_t(u16,
238 scic_sds_port_get_max_allowed_speed(sci_dev->owning_port),
239 discover_response->u2.sas1_1.negotiated_physical_link_rate
240 );
241
242 /* / @todo Should I assign the port width by reading all of the phys on the port? */
243 sci_dev->device_port_width = 1;
244 }
245
246 return status;
247}
248
249enum sci_status scic_remote_device_destruct(
250 struct scic_sds_remote_device *sci_dev)
251{
252 return sci_dev->state_handlers->parent.destruct_handler(&sci_dev->parent);
253}
254
255
256enum sci_status scic_remote_device_start(
257 struct scic_sds_remote_device *sci_dev,
258 u32 timeout)
259{
260 return sci_dev->state_handlers->parent.start_handler(&sci_dev->parent);
261}
262
263
264enum sci_status scic_remote_device_stop(
265 struct scic_sds_remote_device *sci_dev,
266 u32 timeout)
267{
268 return sci_dev->state_handlers->parent.stop_handler(&sci_dev->parent);
269}
270
271
272enum sci_status scic_remote_device_reset(
273 struct scic_sds_remote_device *sci_dev)
274{
275 return sci_dev->state_handlers->parent.reset_handler(&sci_dev->parent);
276}
277
278
279enum sci_status scic_remote_device_reset_complete(
280 struct scic_sds_remote_device *sci_dev)
281{
282 return sci_dev->state_handlers->parent.reset_complete_handler(&sci_dev->parent);
283}
284
285
286enum sci_sas_link_rate scic_remote_device_get_connection_rate(
287 struct scic_sds_remote_device *sci_dev)
288{
289 return sci_dev->connection_rate;
290}
291
292
293void scic_remote_device_get_protocols(
294 struct scic_sds_remote_device *sci_dev,
295 struct smp_discover_response_protocols *pr)
296{
297 pr->u.all = sci_dev->target_protocols.u.all;
298}
299
300#if !defined(DISABLE_ATAPI)
301bool scic_remote_device_is_atapi(struct scic_sds_remote_device *sci_dev)
302{
303 return sci_dev->is_atapi;
304}
305#endif
306
307
308/*
309 * *****************************************************************************
310 * * SCU DRIVER STANDARD (SDS) REMOTE DEVICE IMPLEMENTATIONS
311 * ***************************************************************************** */
312
313/**
314 *
315 *
316 * Remote device timer requirements
317 */
318#define SCIC_SDS_REMOTE_DEVICE_MINIMUM_TIMER_COUNT (0)
319#define SCIC_SDS_REMOTE_DEVICE_MAXIMUM_TIMER_COUNT (SCI_MAX_REMOTE_DEVICES)
320
321
322/**
323 *
324 * @this_device: The remote device for which the suspend is being requested.
325 *
326 * This method invokes the remote device suspend state handler. enum sci_status
327 */
328enum sci_status scic_sds_remote_device_suspend(
329 struct scic_sds_remote_device *this_device,
330 u32 suspend_type)
331{
332 return this_device->state_handlers->suspend_handler(this_device, suspend_type);
333}
334
335/**
336 *
337 * @this_device: The remote device for which the resume is being requested.
338 *
339 * This method invokes the remote device resume state handler. enum sci_status
340 */
341enum sci_status scic_sds_remote_device_resume(
342 struct scic_sds_remote_device *this_device)
343{
344 return this_device->state_handlers->resume_handler(this_device);
345}
346
347/**
348 *
349 * @this_device: The remote device for which the event handling is being
350 * requested.
351 * @frame_index: This is the frame index that is being processed.
352 *
353 * This method invokes the frame handler for the remote device state machine
354 * enum sci_status
355 */
356enum sci_status scic_sds_remote_device_frame_handler(
357 struct scic_sds_remote_device *this_device,
358 u32 frame_index)
359{
360 return this_device->state_handlers->frame_handler(this_device, frame_index);
361}
362
363/**
364 *
365 * @this_device: The remote device for which the event handling is being
366 * requested.
367 * @event_code: This is the event code that is to be processed.
368 *
369 * This method invokes the remote device event handler. enum sci_status
370 */
371enum sci_status scic_sds_remote_device_event_handler(
372 struct scic_sds_remote_device *this_device,
373 u32 event_code)
374{
375 return this_device->state_handlers->event_handler(this_device, event_code);
376}
377
378/**
379 *
380 * @controller: The controller that is starting the io request.
381 * @this_device: The remote device for which the start io handling is being
382 * requested.
383 * @io_request: The io request that is being started.
384 *
385 * This method invokes the remote device start io handler. enum sci_status
386 */
387enum sci_status scic_sds_remote_device_start_io(
388 struct scic_sds_controller *controller,
389 struct scic_sds_remote_device *this_device,
390 struct scic_sds_request *io_request)
391{
392 return this_device->state_handlers->parent.start_io_handler(
393 &this_device->parent, &io_request->parent);
394}
395
396/**
397 *
398 * @controller: The controller that is completing the io request.
399 * @this_device: The remote device for which the complete io handling is being
400 * requested.
401 * @io_request: The io request that is being completed.
402 *
403 * This method invokes the remote device complete io handler. enum sci_status
404 */
405enum sci_status scic_sds_remote_device_complete_io(
406 struct scic_sds_controller *controller,
407 struct scic_sds_remote_device *this_device,
408 struct scic_sds_request *io_request)
409{
410 return this_device->state_handlers->parent.complete_io_handler(
411 &this_device->parent, &io_request->parent);
412}
413
414/**
415 *
416 * @controller: The controller that is starting the task request.
417 * @this_device: The remote device for which the start task handling is being
418 * requested.
419 * @io_request: The task request that is being started.
420 *
421 * This method invokes the remote device start task handler. enum sci_status
422 */
423enum sci_status scic_sds_remote_device_start_task(
424 struct scic_sds_controller *controller,
425 struct scic_sds_remote_device *this_device,
426 struct scic_sds_request *io_request)
427{
428 return this_device->state_handlers->parent.start_task_handler(
429 &this_device->parent, &io_request->parent);
430}
431
432/**
433 *
434 * @controller: The controller that is completing the task request.
435 * @this_device: The remote device for which the complete task handling is
436 * being requested.
437 * @io_request: The task request that is being completed.
438 *
439 * This method invokes the remote device complete task handler. enum sci_status
440 */
441
442/**
443 *
444 * @this_device:
445 * @request:
446 *
447 * This method takes the request and bulids an appropriate SCU context for the
448 * request and then requests the controller to post the request. none
449 */
450void scic_sds_remote_device_post_request(
451 struct scic_sds_remote_device *this_device,
452 u32 request)
453{
454 u32 context;
455
456 context = scic_sds_remote_device_build_command_context(this_device, request);
457
458 scic_sds_controller_post_request(
459 scic_sds_remote_device_get_controller(this_device),
460 context
461 );
462}
463
464#if !defined(DISABLE_ATAPI)
465/**
466 *
467 * @this_device: The device to be checked.
468 *
469 * This method check the signature fis of a stp device to decide whether a
470 * device is atapi or not. true if a device is atapi device. False if a device
471 * is not atapi.
472 */
473bool scic_sds_remote_device_is_atapi(
474 struct scic_sds_remote_device *this_device)
475{
476 if (!this_device->target_protocols.u.bits.attached_stp_target)
477 return false;
478 else if (this_device->is_direct_attached) {
479 struct scic_sds_phy *phy;
480 struct scic_sata_phy_properties properties;
481 struct sata_fis_reg_d2h *signature_fis;
482 phy = scic_sds_port_get_a_connected_phy(this_device->owning_port);
483 scic_sata_phy_get_properties(phy, &properties);
484
485 /* decode the signature fis. */
486 signature_fis = &(properties.signature_fis);
487
488 if ((signature_fis->sector_count == 0x01)
489 && (signature_fis->lba_low == 0x01)
490 && (signature_fis->lba_mid == 0x14)
491 && (signature_fis->lba_high == 0xEB)
492 && ((signature_fis->device & 0x5F) == 0x00)
493 ) {
494 /* An ATA device supporting the PACKET command set. */
495 return true;
496 } else
497 return false;
498 } else {
499 /* Expander supported ATAPI device is not currently supported. */
500 return false;
501 }
502}
503#endif
504/*
505 * This file is provided under a dual BSD/GPLv2 license. When using or
506 * redistributing this file, you may do so under either license.
507 *
508 * GPL LICENSE SUMMARY
509 *
510 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
511 *
512 * This program is free software; you can redistribute it and/or modify
513 * it under the terms of version 2 of the GNU General Public License as
514 * published by the Free Software Foundation.
515 *
516 * This program is distributed in the hope that it will be useful, but
517 * WITHOUT ANY WARRANTY; without even the implied warranty of
518 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
519 * General Public License for more details.
520 *
521 * You should have received a copy of the GNU General Public License
522 * along with this program; if not, write to the Free Software
523 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
524 * The full GNU General Public License is included in this distribution
525 * in the file called LICENSE.GPL.
526 *
527 * BSD LICENSE
528 *
529 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
530 * All rights reserved.
531 *
532 * Redistribution and use in source and binary forms, with or without
533 * modification, are permitted provided that the following conditions
534 * are met:
535 *
536 * * Redistributions of source code must retain the above copyright
537 * notice, this list of conditions and the following disclaimer.
538 * * Redistributions in binary form must reproduce the above copyright
539 * notice, this list of conditions and the following disclaimer in
540 * the documentation and/or other materials provided with the
541 * distribution.
542 * * Neither the name of Intel Corporation nor the names of its
543 * contributors may be used to endorse or promote products derived
544 * from this software without specific prior written permission.
545 *
546 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
547 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
548 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
549 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
550 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
551 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
552 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
553 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
554 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
555 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
556 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
557 */
558
559/**
560 * This file contains the state handlers for the struct scic_sds_remote_device for the
561 * base state machine.
562 *
563 *
564 */
565
566#include "sci_environment.h"
567#include "scic_user_callback.h"
568#include "scic_controller.h"
569#include "scic_sds_remote_device.h"
570#include "scic_sds_controller.h"
571#include "scic_sds_port.h"
572#include "scic_sds_request.h"
573#include "scic_sds_remote_node_context.h"
574#include "scu_event_codes.h"
575
576/*
577 * *****************************************************************************
578 * * PROTECTED METHODS
579 * ***************************************************************************** */
580
581/**
582 *
583 * @user_parameter: This is cast to a remote device object.
584 *
585 * This method is called once the remote node context is ready to be freed.
586 * The remote device can now report that its stop operation is complete. none
587 */
588static void scic_sds_cb_remote_device_rnc_destruct_complete(
589 void *user_parameter)
590{
591 struct scic_sds_remote_device *this_device;
592
593 this_device = (struct scic_sds_remote_device *)user_parameter;
594
595 BUG_ON(this_device->started_request_count != 0);
596
597 sci_base_state_machine_change_state(
598 scic_sds_remote_device_get_base_state_machine(this_device),
599 SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
600 );
601}
602
603/**
604 *
605 * @user_parameter: This is cast to a remote device object.
606 *
607 * This method is called once the remote node context has transisitioned to a
608 * ready state. This is the indication that the remote device object can also
609 * transition to ready. none
610 */
611static void scic_sds_remote_device_resume_complete_handler(
612 void *user_parameter)
613{
614 struct scic_sds_remote_device *this_device;
615
616 this_device = (struct scic_sds_remote_device *)user_parameter;
617
618 if (
619 sci_base_state_machine_get_state(&this_device->parent.state_machine)
620 != SCI_BASE_REMOTE_DEVICE_STATE_READY
621 ) {
622 sci_base_state_machine_change_state(
623 &this_device->parent.state_machine,
624 SCI_BASE_REMOTE_DEVICE_STATE_READY
625 );
626 }
627}
628
629/**
630 *
631 * @device: This parameter specifies the device for which the request is being
632 * started.
633 * @request: This parameter specifies the request being started.
634 * @status: This parameter specifies the current start operation status.
635 *
636 * This method will perform the STP request start processing common to IO
637 * requests and task requests of all types. none
638 */
639void scic_sds_remote_device_start_request(
640 struct scic_sds_remote_device *this_device,
641 struct scic_sds_request *the_request,
642 enum sci_status status)
643{
644 /* We still have a fault in starting the io complete it on the port */
645 if (status == SCI_SUCCESS)
646 scic_sds_remote_device_increment_request_count(this_device);
647 else{
648 this_device->owning_port->state_handlers->complete_io_handler(
649 this_device->owning_port, this_device, the_request
650 );
651 }
652}
653
654
655/**
656 *
657 * @request: This parameter specifies the request being continued.
658 *
659 * This method will continue to post tc for a STP request. This method usually
660 * serves as a callback when RNC gets resumed during a task management
661 * sequence. none
662 */
663void scic_sds_remote_device_continue_request(
664 struct scic_sds_remote_device *this_device)
665{
666 /* we need to check if this request is still valid to continue. */
667 if (this_device->working_request != NULL) {
668 struct scic_sds_request *this_request = this_device->working_request;
669 struct scic_sds_controller *scic = this_request->owning_controller;
670 u32 state = scic->parent.state_machine.current_state_id;
671 sci_base_controller_request_handler_t continue_io;
672
673 continue_io = scic_sds_controller_state_handler_table[state].base.continue_io;
674 continue_io(&scic->parent, &this_request->target_device->parent,
675 &this_request->parent);
676 }
677}
678
679/**
680 *
681 * @user_parameter: This is cast to a remote device object.
682 *
683 * This method is called once the remote node context has reached a suspended
684 * state. The remote device can now report that its suspend operation is
685 * complete. none
686 */
687
688/**
689 * This method will terminate all of the IO requests in the controllers IO
690 * request table that were targeted for this device.
691 * @this_device: This parameter specifies the remote device for which to
692 * attempt to terminate all requests.
693 *
694 * This method returns an indication as to whether all requests were
695 * successfully terminated. If a single request fails to be terminated, then
696 * this method will return the failure.
697 */
698static enum sci_status scic_sds_remote_device_terminate_requests(
699 struct scic_sds_remote_device *this_device)
700{
701 enum sci_status status = SCI_SUCCESS;
702 enum sci_status terminate_status = SCI_SUCCESS;
703 struct scic_sds_request *the_request;
704 u32 index;
705 u32 request_count = this_device->started_request_count;
706
707 for (index = 0;
708 (index < SCI_MAX_IO_REQUESTS) && (request_count > 0);
709 index++) {
710 the_request = this_device->owning_port->owning_controller->io_request_table[index];
711
712 if ((the_request != NULL) && (the_request->target_device == this_device)) {
713 terminate_status = scic_controller_terminate_request(
714 this_device->owning_port->owning_controller,
715 this_device,
716 the_request
717 );
718
719 if (terminate_status != SCI_SUCCESS)
720 status = terminate_status;
721
722 request_count--;
723 }
724 }
725
726 return status;
727}
728
729/*
730 * *****************************************************************************
731 * * DEFAULT STATE HANDLERS
732 * ***************************************************************************** */
733
734/**
735 *
736 * @device: The struct sci_base_remote_device which is then cast into a
737 * struct scic_sds_remote_device.
738 *
739 * This method is the default start handler. It logs a warning and returns a
740 * failure. enum sci_status SCI_FAILURE_INVALID_STATE
741 */
742enum sci_status scic_sds_remote_device_default_start_handler(
743 struct sci_base_remote_device *device)
744{
745 struct scic_sds_remote_device *sds_device =
746 (struct scic_sds_remote_device *)device;
747
748 dev_warn(scirdev_to_dev(sds_device),
749 "%s: SCIC Remote Device requested to start while in wrong "
750 "state %d\n",
751 __func__,
752 sci_base_state_machine_get_state(
753 scic_sds_remote_device_get_base_state_machine(
754 sds_device)));
755
756 return SCI_FAILURE_INVALID_STATE;
757}
758
759/**
760 *
761 * @device: The struct sci_base_remote_device which is then cast into a
762 * struct scic_sds_remote_device.
763 *
764 * This method is the default stop handler. It logs a warning and returns a
765 * failure. enum sci_status SCI_FAILURE_INVALID_STATE
766 */
767static enum sci_status scic_sds_remote_device_default_stop_handler(
768 struct sci_base_remote_device *device)
769{
770 struct scic_sds_remote_device *sds_device =
771 (struct scic_sds_remote_device *)device;
772
773 dev_warn(scirdev_to_dev(sds_device),
774 "%s: SCIC Remote Device requested to stop while in wrong "
775 "state %d\n",
776 __func__,
777 sci_base_state_machine_get_state(
778 scic_sds_remote_device_get_base_state_machine(
779 sds_device)));
780
781 return SCI_FAILURE_INVALID_STATE;
782}
783
784/**
785 *
786 * @device: The struct sci_base_remote_device which is then cast into a
787 * struct scic_sds_remote_device.
788 *
789 * This method is the default fail handler. It logs a warning and returns a
790 * failure. enum sci_status SCI_FAILURE_INVALID_STATE
791 */
792enum sci_status scic_sds_remote_device_default_fail_handler(
793 struct sci_base_remote_device *device)
794{
795 struct scic_sds_remote_device *sds_device =
796 (struct scic_sds_remote_device *)device;
797
798 dev_warn(scirdev_to_dev(sds_device),
799 "%s: SCIC Remote Device requested to fail while in wrong "
800 "state %d\n",
801 __func__,
802 sci_base_state_machine_get_state(
803 scic_sds_remote_device_get_base_state_machine(
804 sds_device)));
805
806 return SCI_FAILURE_INVALID_STATE;
807}
808
809/**
810 *
811 * @device: The struct sci_base_remote_device which is then cast into a
812 * struct scic_sds_remote_device.
813 *
814 * This method is the default destruct handler. It logs a warning and returns
815 * a failure. enum sci_status SCI_FAILURE_INVALID_STATE
816 */
817enum sci_status scic_sds_remote_device_default_destruct_handler(
818 struct sci_base_remote_device *device)
819{
820 struct scic_sds_remote_device *sds_device =
821 (struct scic_sds_remote_device *)device;
822
823 dev_warn(scirdev_to_dev(sds_device),
824 "%s: SCIC Remote Device requested to destroy while in "
825 "wrong state %d\n",
826 __func__,
827 sci_base_state_machine_get_state(
828 scic_sds_remote_device_get_base_state_machine(
829 sds_device)));
830
831 return SCI_FAILURE_INVALID_STATE;
832}
833
834/**
835 *
836 * @device: The struct sci_base_remote_device which is then cast into a
837 * struct scic_sds_remote_device.
838 *
839 * This method is the default reset handler. It logs a warning and returns a
840 * failure. enum sci_status SCI_FAILURE_INVALID_STATE
841 */
842enum sci_status scic_sds_remote_device_default_reset_handler(
843 struct sci_base_remote_device *device)
844{
845 struct scic_sds_remote_device *sds_device =
846 (struct scic_sds_remote_device *)device;
847
848 dev_warn(scirdev_to_dev(sds_device),
849 "%s: SCIC Remote Device requested to reset while in wrong "
850 "state %d\n",
851 __func__,
852 sci_base_state_machine_get_state(
853 scic_sds_remote_device_get_base_state_machine(
854 sds_device)));
855
856 return SCI_FAILURE_INVALID_STATE;
857}
858
859/**
860 *
861 * @device: The struct sci_base_remote_device which is then cast into a
862 * struct scic_sds_remote_device.
863 *
864 * This method is the default reset complete handler. It logs a warning and
865 * returns a failure. enum sci_status SCI_FAILURE_INVALID_STATE
866 */
867enum sci_status scic_sds_remote_device_default_reset_complete_handler(
868 struct sci_base_remote_device *device)
869{
870 struct scic_sds_remote_device *sds_device =
871 (struct scic_sds_remote_device *)device;
872
873 dev_warn(scirdev_to_dev(sds_device),
874 "%s: SCIC Remote Device requested to complete reset while "
875 "in wrong state %d\n",
876 __func__,
877 sci_base_state_machine_get_state(
878 scic_sds_remote_device_get_base_state_machine(
879 sds_device)));
880
881 return SCI_FAILURE_INVALID_STATE;
882}
883
884/**
885 *
886 * @device: The struct sci_base_remote_device which is then cast into a
887 * struct scic_sds_remote_device.
888 *
889 * This method is the default suspend handler. It logs a warning and returns a
890 * failure. enum sci_status SCI_FAILURE_INVALID_STATE
891 */
892enum sci_status scic_sds_remote_device_default_suspend_handler(
893 struct scic_sds_remote_device *this_device,
894 u32 suspend_type)
895{
896 dev_warn(scirdev_to_dev(this_device),
897 "%s: SCIC Remote Device 0x%p requested to suspend %d while "
898 "in wrong state %d\n",
899 __func__,
900 this_device,
901 suspend_type,
902 sci_base_state_machine_get_state(
903 scic_sds_remote_device_get_base_state_machine(
904 this_device)));
905
906 return SCI_FAILURE_INVALID_STATE;
907}
908
909/**
910 *
911 * @device: The struct sci_base_remote_device which is then cast into a
912 * struct scic_sds_remote_device.
913 *
914 * This method is the default resume handler. It logs a warning and returns a
915 * failure. enum sci_status SCI_FAILURE_INVALID_STATE
916 */
917enum sci_status scic_sds_remote_device_default_resume_handler(
918 struct scic_sds_remote_device *this_device)
919{
920 dev_warn(scirdev_to_dev(this_device),
921 "%s: SCIC Remote Device requested to resume while in "
922 "wrong state %d\n",
923 __func__,
924 sci_base_state_machine_get_state(
925 scic_sds_remote_device_get_base_state_machine(
926 this_device)));
927
928 return SCI_FAILURE_INVALID_STATE;
929}
930
931/**
932 *
933 * @device: The struct sci_base_remote_device which is then cast into a
934 * struct scic_sds_remote_device.
935 * @event_code: The event code that the struct scic_sds_controller wants the device
936 * object to process.
937 *
938 * This method is the default event handler. It will call the RNC state
939 * machine handler for any RNC events otherwise it will log a warning and
940 * returns a failure. enum sci_status SCI_FAILURE_INVALID_STATE
941 */
942static enum sci_status scic_sds_remote_device_core_event_handler(
943 struct scic_sds_remote_device *this_device,
944 u32 event_code,
945 bool is_ready_state)
946{
947 enum sci_status status;
948
949 switch (scu_get_event_type(event_code)) {
950 case SCU_EVENT_TYPE_RNC_OPS_MISC:
951 case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
952 case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
953 status = scic_sds_remote_node_context_event_handler(this_device->rnc, event_code);
954 break;
955 case SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT:
956
957 if (scu_get_event_code(event_code) == SCU_EVENT_IT_NEXUS_TIMEOUT) {
958 status = SCI_SUCCESS;
959
960 /* Suspend the associated RNC */
961 scic_sds_remote_node_context_suspend(this_device->rnc,
962 SCI_SOFTWARE_SUSPENSION,
963 NULL, NULL);
964
965 dev_dbg(scirdev_to_dev(this_device),
966 "%s: device: %p event code: %x: %s\n",
967 __func__, this_device, event_code,
968 (is_ready_state)
969 ? "I_T_Nexus_Timeout event"
970 : "I_T_Nexus_Timeout event in wrong state");
971
972 break;
973 }
974 /* Else, fall through and treat as unhandled... */
975
976 default:
977 dev_dbg(scirdev_to_dev(this_device),
978 "%s: device: %p event code: %x: %s\n",
979 __func__, this_device, event_code,
980 (is_ready_state)
981 ? "unexpected event"
982 : "unexpected event in wrong state");
983 status = SCI_FAILURE_INVALID_STATE;
984 break;
985 }
986
987 return status;
988}
989/**
990 *
991 * @device: The struct sci_base_remote_device which is then cast into a
992 * struct scic_sds_remote_device.
993 * @event_code: The event code that the struct scic_sds_controller wants the device
994 * object to process.
995 *
996 * This method is the default event handler. It will call the RNC state
997 * machine handler for any RNC events otherwise it will log a warning and
998 * returns a failure. enum sci_status SCI_FAILURE_INVALID_STATE
999 */
1000static enum sci_status scic_sds_remote_device_default_event_handler(
1001 struct scic_sds_remote_device *this_device,
1002 u32 event_code)
1003{
1004 return scic_sds_remote_device_core_event_handler(this_device,
1005 event_code,
1006 false);
1007}
1008
1009/**
1010 *
1011 * @device: The struct sci_base_remote_device which is then cast into a
1012 * struct scic_sds_remote_device.
1013 * @frame_index: The frame index for which the struct scic_sds_controller wants this
1014 * device object to process.
1015 *
1016 * This method is the default unsolicited frame handler. It logs a warning,
1017 * releases the frame and returns a failure. enum sci_status
1018 * SCI_FAILURE_INVALID_STATE
1019 */
1020enum sci_status scic_sds_remote_device_default_frame_handler(
1021 struct scic_sds_remote_device *this_device,
1022 u32 frame_index)
1023{
1024 dev_warn(scirdev_to_dev(this_device),
1025 "%s: SCIC Remote Device requested to handle frame %x "
1026 "while in wrong state %d\n",
1027 __func__,
1028 frame_index,
1029 sci_base_state_machine_get_state(
1030 &this_device->parent.state_machine));
1031
1032 /* Return the frame back to the controller */
1033 scic_sds_controller_release_frame(
1034 scic_sds_remote_device_get_controller(this_device), frame_index
1035 );
1036
1037 return SCI_FAILURE_INVALID_STATE;
1038}
1039
1040/**
1041 *
1042 * @device: The struct sci_base_remote_device which is then cast into a
1043 * struct scic_sds_remote_device.
1044 * @request: The struct sci_base_request which is then cast into a SCIC_SDS_IO_REQUEST
1045 * to start.
1046 *
1047 * This method is the default start io handler. It logs a warning and returns
1048 * a failure. enum sci_status SCI_FAILURE_INVALID_STATE
1049 */
1050enum sci_status scic_sds_remote_device_default_start_request_handler(
1051 struct sci_base_remote_device *device,
1052 struct sci_base_request *request)
1053{
1054 struct scic_sds_remote_device *sds_device =
1055 (struct scic_sds_remote_device *)device;
1056
1057 dev_warn(scirdev_to_dev(sds_device),
1058 "%s: SCIC Remote Device requested to start io request %p "
1059 "while in wrong state %d\n",
1060 __func__,
1061 request,
1062 sci_base_state_machine_get_state(
1063 scic_sds_remote_device_get_base_state_machine(
1064 (struct scic_sds_remote_device *)device)));
1065
1066 return SCI_FAILURE_INVALID_STATE;
1067}
1068
1069/**
1070 *
1071 * @device: The struct sci_base_remote_device which is then cast into a
1072 * struct scic_sds_remote_device.
1073 * @request: The struct sci_base_request which is then cast into a SCIC_SDS_IO_REQUEST
1074 * to complete.
1075 *
1076 * This method is the default complete io handler. It logs a warning and
1077 * returns a failure. enum sci_status SCI_FAILURE_INVALID_STATE
1078 */
1079enum sci_status scic_sds_remote_device_default_complete_request_handler(
1080 struct sci_base_remote_device *device,
1081 struct sci_base_request *request)
1082{
1083 struct scic_sds_remote_device *sds_device =
1084 (struct scic_sds_remote_device *)device;
1085
1086 dev_warn(scirdev_to_dev(sds_device),
1087 "%s: SCIC Remote Device requested to complete io_request %p "
1088 "while in wrong state %d\n",
1089 __func__,
1090 request,
1091 sci_base_state_machine_get_state(
1092 scic_sds_remote_device_get_base_state_machine(
1093 sds_device)));
1094
1095 return SCI_FAILURE_INVALID_STATE;
1096}
1097
1098/**
1099 *
1100 * @device: The struct sci_base_remote_device which is then cast into a
1101 * struct scic_sds_remote_device.
1102 * @request: The struct sci_base_request which is then cast into a SCIC_SDS_IO_REQUEST
1103 * to continue.
1104 *
1105 * This method is the default continue io handler. It logs a warning and
1106 * returns a failure. enum sci_status SCI_FAILURE_INVALID_STATE
1107 */
1108enum sci_status scic_sds_remote_device_default_continue_request_handler(
1109 struct sci_base_remote_device *device,
1110 struct sci_base_request *request)
1111{
1112 struct scic_sds_remote_device *sds_device =
1113 (struct scic_sds_remote_device *)device;
1114
1115 dev_warn(scirdev_to_dev(sds_device),
1116 "%s: SCIC Remote Device requested to continue io request %p "
1117 "while in wrong state %d\n",
1118 __func__,
1119 request,
1120 sci_base_state_machine_get_state(
1121 scic_sds_remote_device_get_base_state_machine(
1122 sds_device)));
1123
1124 return SCI_FAILURE_INVALID_STATE;
1125}
1126
1127/**
1128 *
1129 * @device: The struct sci_base_remote_device which is then cast into a
1130 * struct scic_sds_remote_device.
1131 * @request: The struct sci_base_request which is then cast into a SCIC_SDS_IO_REQUEST
1132 * to complete.
1133 *
1134 * This method is the default complete task handler. It logs a warning and
1135 * returns a failure. enum sci_status SCI_FAILURE_INVALID_STATE
1136 */
1137
1138/*
1139 * *****************************************************************************
1140 * * NORMAL STATE HANDLERS
1141 * ***************************************************************************** */
1142
1143/**
1144 *
1145 * @device: The struct sci_base_remote_device which is then cast into a
1146 * struct scic_sds_remote_device.
1147 * @frame_index: The frame index for which the struct scic_sds_controller wants this
1148 * device object to process.
1149 *
1150 * This method is a general ssp frame handler. In most cases the device object
1151 * needs to route the unsolicited frame processing to the io request object.
1152 * This method decodes the tag for the io request object and routes the
1153 * unsolicited frame to that object. enum sci_status SCI_FAILURE_INVALID_STATE
1154 */
1155enum sci_status scic_sds_remote_device_general_frame_handler(
1156 struct scic_sds_remote_device *this_device,
1157 u32 frame_index)
1158{
1159 enum sci_status result;
1160 struct sci_ssp_frame_header *frame_header;
1161 struct scic_sds_request *io_request;
1162
1163 result = scic_sds_unsolicited_frame_control_get_header(
1164 &(scic_sds_remote_device_get_controller(this_device)->uf_control),
1165 frame_index,
1166 (void **)&frame_header
1167 );
1168
1169 if (SCI_SUCCESS == result) {
1170 io_request = scic_sds_controller_get_io_request_from_tag(
1171 scic_sds_remote_device_get_controller(this_device), frame_header->tag);
1172
1173 if ((io_request == SCI_INVALID_HANDLE)
1174 || (io_request->target_device != this_device)) {
1175 /*
1176 * We could not map this tag to a valid IO request
1177 * Just toss the frame and continue */
1178 scic_sds_controller_release_frame(
1179 scic_sds_remote_device_get_controller(this_device), frame_index
1180 );
1181 } else {
1182 /* The IO request is now in charge of releasing the frame */
1183 result = io_request->state_handlers->frame_handler(
1184 io_request, frame_index);
1185 }
1186 }
1187
1188 return result;
1189}
1190
1191/**
1192 *
1193 * @[in]: this_device This is the device object that is receiving the event.
1194 * @[in]: event_code The event code to process.
1195 *
1196 * This is a common method for handling events reported to the remote device
1197 * from the controller object. enum sci_status
1198 */
1199enum sci_status scic_sds_remote_device_general_event_handler(
1200 struct scic_sds_remote_device *this_device,
1201 u32 event_code)
1202{
1203 return scic_sds_remote_device_core_event_handler(this_device,
1204 event_code,
1205 true);
1206}
1207
1208/*
1209 * *****************************************************************************
1210 * * STOPPED STATE HANDLERS
1211 * ***************************************************************************** */
1212
1213/**
1214 *
1215 * @device:
1216 *
1217 * This method takes the struct scic_sds_remote_device from a stopped state and
1218 * attempts to start it. The RNC buffer for the device is constructed and the
1219 * device state machine is transitioned to the
1220 * SCIC_BASE_REMOTE_DEVICE_STATE_STARTING. enum sci_status SCI_SUCCESS if there is
1221 * an RNC buffer available to construct the remote device.
1222 * SCI_FAILURE_INSUFFICIENT_RESOURCES if there is no RNC buffer available in
1223 * which to construct the remote device.
1224 */
1225static enum sci_status scic_sds_remote_device_stopped_state_start_handler(
1226 struct sci_base_remote_device *device)
1227{
1228 enum sci_status status;
1229 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
1230
1231 status = scic_sds_remote_node_context_resume(
1232 this_device->rnc,
1233 scic_sds_remote_device_resume_complete_handler,
1234 this_device
1235 );
1236
1237 if (status == SCI_SUCCESS) {
1238 sci_base_state_machine_change_state(
1239 scic_sds_remote_device_get_base_state_machine(this_device),
1240 SCI_BASE_REMOTE_DEVICE_STATE_STARTING
1241 );
1242 }
1243
1244 return status;
1245}
1246
1247/**
1248 *
1249 * @this_device: The struct sci_base_remote_device which is cast into a
1250 * struct scic_sds_remote_device.
1251 *
1252 * This method will stop a struct scic_sds_remote_device that is already in a stopped
1253 * state. This is not considered an error since the device is already stopped.
1254 * enum sci_status SCI_SUCCESS
1255 */
1256static enum sci_status scic_sds_remote_device_stopped_state_stop_handler(
1257 struct sci_base_remote_device *this_device)
1258{
1259 return SCI_SUCCESS;
1260}
1261
1262/**
1263 *
1264 * @this_device: The struct sci_base_remote_device which is cast into a
1265 * struct scic_sds_remote_device.
1266 *
1267 * This method will destruct a struct scic_sds_remote_device that is in a stopped
1268 * state. This is the only state from which a destruct request will succeed.
1269 * The RNi for this struct scic_sds_remote_device is returned to the free pool and the
1270 * device object transitions to the SCI_BASE_REMOTE_DEVICE_STATE_FINAL.
1271 * enum sci_status SCI_SUCCESS
1272 */
1273static enum sci_status scic_sds_remote_device_stopped_state_destruct_handler(
1274 struct sci_base_remote_device *device)
1275{
1276 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
1277
1278 scic_sds_controller_free_remote_node_context(
1279 scic_sds_remote_device_get_controller(this_device),
1280 this_device,
1281 this_device->rnc->remote_node_index
1282 );
1283
1284 scic_sds_remote_node_context_set_remote_node_index(
1285 this_device->rnc,
1286 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
1287 );
1288
1289 scic_sds_port_set_direct_attached_device_id(
1290 this_device->owning_port,
1291 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
1292 );
1293
1294 sci_base_state_machine_change_state(
1295 scic_sds_remote_device_get_base_state_machine(this_device),
1296 SCI_BASE_REMOTE_DEVICE_STATE_FINAL
1297 );
1298
1299 return SCI_SUCCESS;
1300}
1301
1302/*
1303 * *****************************************************************************
1304 * * STARTING STATE HANDLERS
1305 * ***************************************************************************** */
1306
1307static enum sci_status scic_sds_remote_device_starting_state_stop_handler(
1308 struct sci_base_remote_device *device)
1309{
1310 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
1311
1312 /*
1313 * This device has not yet started so there had better be no IO requests
1314 */
1315 BUG_ON(this_device->started_request_count != 0);
1316
1317 /*
1318 * Destroy the remote node context
1319 */
1320 scic_sds_remote_node_context_destruct(
1321 this_device->rnc,
1322 scic_sds_cb_remote_device_rnc_destruct_complete,
1323 this_device
1324 );
1325
1326 /*
1327 * Transition to the stopping state and wait for the remote node to
1328 * complete being posted and invalidated.
1329 */
1330 sci_base_state_machine_change_state(
1331 scic_sds_remote_device_get_base_state_machine(this_device),
1332 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
1333 );
1334
1335 return SCI_SUCCESS;
1336}
1337
1338/*
1339 * *****************************************************************************
1340 * * INITIALIZING STATE HANDLERS
1341 * ***************************************************************************** */
1342
1343/* There is nothing to do here for SSP devices */
1344
1345/*
1346 * *****************************************************************************
1347 * * READY STATE HANDLERS
1348 * ***************************************************************************** */
1349
1350/**
1351 *
1352 * @this_device: The struct scic_sds_remote_device object to be suspended.
1353 *
1354 * This method is the resume handler for the struct scic_sds_remote_device object. It
1355 * will post an RNC resume to the SCU hardware. enum sci_status SCI_SUCCESS
1356 */
1357
1358/**
1359 *
1360 * @device: The struct sci_base_remote_device object which is cast to a
1361 * struct scic_sds_remote_device object.
1362 *
1363 * This method is the default stop handler for the struct scic_sds_remote_device ready
1364 * substate machine. It will stop the current substate machine and transition
1365 * the base state machine to SCI_BASE_REMOTE_DEVICE_STATE_STOPPING. enum sci_status
1366 * SCI_SUCCESS
1367 */
1368enum sci_status scic_sds_remote_device_ready_state_stop_handler(
1369 struct sci_base_remote_device *device)
1370{
1371 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
1372 enum sci_status status = SCI_SUCCESS;
1373
1374 /* Request the parent state machine to transition to the stopping state */
1375 sci_base_state_machine_change_state(
1376 scic_sds_remote_device_get_base_state_machine(this_device),
1377 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
1378 );
1379
1380 if (this_device->started_request_count == 0) {
1381 scic_sds_remote_node_context_destruct(
1382 this_device->rnc,
1383 scic_sds_cb_remote_device_rnc_destruct_complete,
1384 this_device
1385 );
1386 } else
1387 status = scic_sds_remote_device_terminate_requests(this_device);
1388
1389 return status;
1390}
1391
1392/**
1393 *
1394 * @device: The struct sci_base_remote_device object which is cast to a
1395 * struct scic_sds_remote_device object.
1396 *
1397 * This is the ready state device reset handler enum sci_status
1398 */
1399enum sci_status scic_sds_remote_device_ready_state_reset_handler(
1400 struct sci_base_remote_device *device)
1401{
1402 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
1403
1404 /* Request the parent state machine to transition to the stopping state */
1405 sci_base_state_machine_change_state(
1406 scic_sds_remote_device_get_base_state_machine(this_device),
1407 SCI_BASE_REMOTE_DEVICE_STATE_RESETTING
1408 );
1409
1410 return SCI_SUCCESS;
1411}
1412
1413/**
1414 *
1415 * @device: The struct sci_base_remote_device object which is cast to a
1416 * struct scic_sds_remote_device object.
1417 *
1418 * This is the default fail handler for the struct scic_sds_remote_device ready
1419 * substate machine. It will stop the current ready substate and transition
1420 * the remote device object to the SCI_BASE_REMOTE_DEVICE_STATE_FAILED.
1421 * enum sci_status SCI_SUCCESS
1422 */
1423
1424/**
1425 *
1426 * @device: The struct sci_base_remote_device which is cast to a
1427 * struct scic_sds_remote_device for which the request is to be started.
1428 * @request: The struct sci_base_request which is cast to a SCIC_SDS_IO_REQUEST that
1429 * is to be started.
1430 *
1431 * This method will attempt to start a task request for this device object. The
1432 * remote device object will issue the start request for the task and if
1433 * successful it will start the request for the port object then increment its
1434 * own requet count. enum sci_status SCI_SUCCESS if the task request is started for
1435 * this device object. SCI_FAILURE_INSUFFICIENT_RESOURCES if the io request
1436 * object could not get the resources to start.
1437 */
1438static enum sci_status scic_sds_remote_device_ready_state_start_task_handler(
1439 struct sci_base_remote_device *device,
1440 struct sci_base_request *request)
1441{
1442 enum sci_status result;
1443 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
1444 struct scic_sds_request *task_request = (struct scic_sds_request *)request;
1445
1446 /* See if the port is in a state where we can start the IO request */
1447 result = scic_sds_port_start_io(
1448 scic_sds_remote_device_get_port(this_device), this_device, task_request);
1449
1450 if (result == SCI_SUCCESS) {
1451 result = scic_sds_remote_node_context_start_task(
1452 this_device->rnc, task_request
1453 );
1454
1455 if (result == SCI_SUCCESS) {
1456 result = scic_sds_request_start(task_request);
1457 }
1458
1459 scic_sds_remote_device_start_request(this_device, task_request, result);
1460 }
1461
1462 return result;
1463}
1464
1465/**
1466 *
1467 * @device: The struct sci_base_remote_device which is cast to a
1468 * struct scic_sds_remote_device for which the request is to be started.
1469 * @request: The struct sci_base_request which is cast to a SCIC_SDS_IO_REQUEST that
1470 * is to be started.
1471 *
1472 * This method will attempt to start an io request for this device object. The
1473 * remote device object will issue the start request for the io and if
1474 * successful it will start the request for the port object then increment its
1475 * own requet count. enum sci_status SCI_SUCCESS if the io request is started for
1476 * this device object. SCI_FAILURE_INSUFFICIENT_RESOURCES if the io request
1477 * object could not get the resources to start.
1478 */
1479static enum sci_status scic_sds_remote_device_ready_state_start_io_handler(
1480 struct sci_base_remote_device *device,
1481 struct sci_base_request *request)
1482{
1483 enum sci_status result;
1484 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
1485 struct scic_sds_request *io_request = (struct scic_sds_request *)request;
1486
1487 /* See if the port is in a state where we can start the IO request */
1488 result = scic_sds_port_start_io(
1489 scic_sds_remote_device_get_port(this_device), this_device, io_request);
1490
1491 if (result == SCI_SUCCESS) {
1492 result = scic_sds_remote_node_context_start_io(
1493 this_device->rnc, io_request
1494 );
1495
1496 if (result == SCI_SUCCESS) {
1497 result = scic_sds_request_start(io_request);
1498 }
1499
1500 scic_sds_remote_device_start_request(this_device, io_request, result);
1501 }
1502
1503 return result;
1504}
1505
1506/**
1507 *
1508 * @device: The struct sci_base_remote_device which is cast to a
1509 * struct scic_sds_remote_device for which the request is to be completed.
1510 * @request: The struct sci_base_request which is cast to a SCIC_SDS_IO_REQUEST that
1511 * is to be completed.
1512 *
1513 * This method will complete the request for the remote device object. The
1514 * method will call the completion handler for the request object and if
1515 * successful it will complete the request on the port object then decrement
1516 * its own started_request_count. enum sci_status
1517 */
1518static enum sci_status scic_sds_remote_device_ready_state_complete_request_handler(
1519 struct sci_base_remote_device *device,
1520 struct sci_base_request *request)
1521{
1522 enum sci_status result;
1523 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
1524 struct scic_sds_request *the_request = (struct scic_sds_request *)request;
1525
1526 result = scic_sds_request_complete(the_request);
1527
1528 if (result == SCI_SUCCESS) {
1529 /* See if the port is in a state where we can start the IO request */
1530 result = scic_sds_port_complete_io(
1531 scic_sds_remote_device_get_port(this_device), this_device, the_request);
1532
1533 if (result == SCI_SUCCESS) {
1534 scic_sds_remote_device_decrement_request_count(this_device);
1535 }
1536 }
1537
1538 return result;
1539}
1540
1541/*
1542 * *****************************************************************************
1543 * * STOPPING STATE HANDLERS
1544 * ***************************************************************************** */
1545
1546/**
1547 *
1548 * @this_device: The struct sci_base_remote_device which is cast into a
1549 * struct scic_sds_remote_device.
1550 *
1551 * This method will stop a struct scic_sds_remote_device that is already in the
1552 * SCI_BASE_REMOTE_DEVICE_STATE_STOPPING state. This is not considered an error
1553 * since we allow a stop request on a device that is alreay stopping or
1554 * stopped. enum sci_status SCI_SUCCESS
1555 */
1556static enum sci_status scic_sds_remote_device_stopping_state_stop_handler(
1557 struct sci_base_remote_device *device)
1558{
1559 /*
1560 * All requests should have been terminated, but if there is an
1561 * attempt to stop a device already in the stopping state, then
1562 * try again to terminate. */
1563 return scic_sds_remote_device_terminate_requests(
1564 (struct scic_sds_remote_device *)device);
1565}
1566
1567
1568/**
1569 *
1570 * @device: The device object for which the request is completing.
1571 * @request: The task request that is being completed.
1572 *
1573 * This method completes requests for this struct scic_sds_remote_device while it is
1574 * in the SCI_BASE_REMOTE_DEVICE_STATE_STOPPING state. This method calls the
1575 * complete method for the request object and if that is successful the port
1576 * object is called to complete the task request. Then the device object itself
1577 * completes the task request. If struct scic_sds_remote_device started_request_count
1578 * goes to 0 and the invalidate RNC request has completed the device object can
1579 * transition to the SCI_BASE_REMOTE_DEVICE_STATE_STOPPED. enum sci_status
1580 */
1581static enum sci_status scic_sds_remote_device_stopping_state_complete_request_handler(
1582 struct sci_base_remote_device *device,
1583 struct sci_base_request *request)
1584{
1585 enum sci_status status = SCI_SUCCESS;
1586 struct scic_sds_request *this_request = (struct scic_sds_request *)request;
1587 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
1588
1589 status = scic_sds_request_complete(this_request);
1590 if (status == SCI_SUCCESS) {
1591 status = scic_sds_port_complete_io(
1592 scic_sds_remote_device_get_port(this_device),
1593 this_device,
1594 this_request
1595 );
1596
1597 if (status == SCI_SUCCESS) {
1598 scic_sds_remote_device_decrement_request_count(this_device);
1599
1600 if (scic_sds_remote_device_get_request_count(this_device) == 0) {
1601 scic_sds_remote_node_context_destruct(
1602 this_device->rnc,
1603 scic_sds_cb_remote_device_rnc_destruct_complete,
1604 this_device
1605 );
1606 }
1607 }
1608 }
1609
1610 return status;
1611}
1612
1613/*
1614 * *****************************************************************************
1615 * * RESETTING STATE HANDLERS
1616 * ***************************************************************************** */
1617
1618/**
1619 *
1620 * @device: The struct sci_base_remote_device which is to be cast into a
1621 * struct scic_sds_remote_device object.
1622 *
1623 * This method will complete the reset operation when the device is in the
1624 * resetting state. enum sci_status
1625 */
1626static enum sci_status scic_sds_remote_device_resetting_state_reset_complete_handler(
1627 struct sci_base_remote_device *device)
1628{
1629 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
1630
1631 sci_base_state_machine_change_state(
1632 &this_device->parent.state_machine,
1633 SCI_BASE_REMOTE_DEVICE_STATE_READY
1634 );
1635
1636 return SCI_SUCCESS;
1637}
1638
1639/**
1640 *
1641 * @device: The struct sci_base_remote_device which is to be cast into a
1642 * struct scic_sds_remote_device object.
1643 *
1644 * This method will stop the remote device while in the resetting state.
1645 * enum sci_status
1646 */
1647static enum sci_status scic_sds_remote_device_resetting_state_stop_handler(
1648 struct sci_base_remote_device *device)
1649{
1650 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
1651
1652 sci_base_state_machine_change_state(
1653 &this_device->parent.state_machine,
1654 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
1655 );
1656
1657 return SCI_SUCCESS;
1658}
1659
1660/**
1661 *
1662 * @device: The device object for which the request is completing.
1663 * @request: The task request that is being completed.
1664 *
1665 * This method completes requests for this struct scic_sds_remote_device while it is
1666 * in the SCI_BASE_REMOTE_DEVICE_STATE_RESETTING state. This method calls the
1667 * complete method for the request object and if that is successful the port
1668 * object is called to complete the task request. Then the device object itself
1669 * completes the task request. enum sci_status
1670 */
1671static enum sci_status scic_sds_remote_device_resetting_state_complete_request_handler(
1672 struct sci_base_remote_device *device,
1673 struct sci_base_request *request)
1674{
1675 enum sci_status status = SCI_SUCCESS;
1676 struct scic_sds_request *this_request = (struct scic_sds_request *)request;
1677 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
1678
1679 status = scic_sds_request_complete(this_request);
1680
1681 if (status == SCI_SUCCESS) {
1682 status = scic_sds_port_complete_io(
1683 scic_sds_remote_device_get_port(this_device), this_device, this_request);
1684
1685 if (status == SCI_SUCCESS) {
1686 scic_sds_remote_device_decrement_request_count(this_device);
1687 }
1688 }
1689
1690 return status;
1691}
1692
1693/*
1694 * *****************************************************************************
1695 * * FAILED STATE HANDLERS
1696 * ***************************************************************************** */
1697
1698/**
1699 *
1700 * @device: The struct sci_base_remote_device which is to be cast into a
1701 * struct scic_sds_remote_device object.
1702 *
1703 * This method handles the remove request for a failed struct scic_sds_remote_device
1704 * object. The method will transition the device object to the
1705 * SCIC_BASE_REMOTE_DEVICE_STATE_STOPPING. enum sci_status SCI_SUCCESS
1706 */
1707
1708/* --------------------------------------------------------------------------- */
1709
1710struct scic_sds_remote_device_state_handler
1711scic_sds_remote_device_state_handler_table[SCI_BASE_REMOTE_DEVICE_MAX_STATES] =
1712{
1713 /* SCI_BASE_REMOTE_DEVICE_STATE_INITIAL */
1714 {
1715 {
1716 scic_sds_remote_device_default_start_handler,
1717 scic_sds_remote_device_default_stop_handler,
1718 scic_sds_remote_device_default_fail_handler,
1719 scic_sds_remote_device_default_destruct_handler,
1720 scic_sds_remote_device_default_reset_handler,
1721 scic_sds_remote_device_default_reset_complete_handler,
1722 scic_sds_remote_device_default_start_request_handler,
1723 scic_sds_remote_device_default_complete_request_handler,
1724 scic_sds_remote_device_default_continue_request_handler,
1725 scic_sds_remote_device_default_start_request_handler,
1726 scic_sds_remote_device_default_complete_request_handler
1727 },
1728 scic_sds_remote_device_default_suspend_handler,
1729 scic_sds_remote_device_default_resume_handler,
1730 scic_sds_remote_device_default_event_handler,
1731 scic_sds_remote_device_default_frame_handler
1732 },
1733 /* SCI_BASE_REMOTE_DEVICE_STATE_STOPPED */
1734 {
1735 {
1736 scic_sds_remote_device_stopped_state_start_handler,
1737 scic_sds_remote_device_stopped_state_stop_handler,
1738 scic_sds_remote_device_default_fail_handler,
1739 scic_sds_remote_device_stopped_state_destruct_handler,
1740 scic_sds_remote_device_default_reset_handler,
1741 scic_sds_remote_device_default_reset_complete_handler,
1742 scic_sds_remote_device_default_start_request_handler,
1743 scic_sds_remote_device_default_complete_request_handler,
1744 scic_sds_remote_device_default_continue_request_handler,
1745 scic_sds_remote_device_default_start_request_handler,
1746 scic_sds_remote_device_default_complete_request_handler
1747 },
1748 scic_sds_remote_device_default_suspend_handler,
1749 scic_sds_remote_device_default_resume_handler,
1750 scic_sds_remote_device_default_event_handler,
1751 scic_sds_remote_device_default_frame_handler
1752 },
1753 /* SCI_BASE_REMOTE_DEVICE_STATE_STARTING */
1754 {
1755 {
1756 scic_sds_remote_device_default_start_handler,
1757 scic_sds_remote_device_starting_state_stop_handler,
1758 scic_sds_remote_device_default_fail_handler,
1759 scic_sds_remote_device_default_destruct_handler,
1760 scic_sds_remote_device_default_reset_handler,
1761 scic_sds_remote_device_default_reset_complete_handler,
1762 scic_sds_remote_device_default_start_request_handler,
1763 scic_sds_remote_device_default_complete_request_handler,
1764 scic_sds_remote_device_default_continue_request_handler,
1765 scic_sds_remote_device_default_start_request_handler,
1766 scic_sds_remote_device_default_complete_request_handler
1767 },
1768 scic_sds_remote_device_default_suspend_handler,
1769 scic_sds_remote_device_default_resume_handler,
1770 scic_sds_remote_device_general_event_handler,
1771 scic_sds_remote_device_default_frame_handler
1772 },
1773 /* SCI_BASE_REMOTE_DEVICE_STATE_READY */
1774 {
1775 {
1776 scic_sds_remote_device_default_start_handler,
1777 scic_sds_remote_device_ready_state_stop_handler,
1778 scic_sds_remote_device_default_fail_handler,
1779 scic_sds_remote_device_default_destruct_handler,
1780 scic_sds_remote_device_ready_state_reset_handler,
1781 scic_sds_remote_device_default_reset_complete_handler,
1782 scic_sds_remote_device_ready_state_start_io_handler,
1783 scic_sds_remote_device_ready_state_complete_request_handler,
1784 scic_sds_remote_device_default_continue_request_handler,
1785 scic_sds_remote_device_ready_state_start_task_handler,
1786 scic_sds_remote_device_ready_state_complete_request_handler
1787 },
1788 scic_sds_remote_device_default_suspend_handler,
1789 scic_sds_remote_device_default_resume_handler,
1790 scic_sds_remote_device_general_event_handler,
1791 scic_sds_remote_device_general_frame_handler,
1792 },
1793 /* SCI_BASE_REMOTE_DEVICE_STATE_STOPPING */
1794 {
1795 {
1796 scic_sds_remote_device_default_start_handler,
1797 scic_sds_remote_device_stopping_state_stop_handler,
1798 scic_sds_remote_device_default_fail_handler,
1799 scic_sds_remote_device_default_destruct_handler,
1800 scic_sds_remote_device_default_reset_handler,
1801 scic_sds_remote_device_default_reset_complete_handler,
1802 scic_sds_remote_device_default_start_request_handler,
1803 scic_sds_remote_device_stopping_state_complete_request_handler,
1804 scic_sds_remote_device_default_continue_request_handler,
1805 scic_sds_remote_device_default_start_request_handler,
1806 scic_sds_remote_device_stopping_state_complete_request_handler
1807 },
1808 scic_sds_remote_device_default_suspend_handler,
1809 scic_sds_remote_device_default_resume_handler,
1810 scic_sds_remote_device_general_event_handler,
1811 scic_sds_remote_device_general_frame_handler
1812 },
1813 /* SCI_BASE_REMOTE_DEVICE_STATE_FAILED */
1814 {
1815 {
1816 scic_sds_remote_device_default_start_handler,
1817 scic_sds_remote_device_default_stop_handler,
1818 scic_sds_remote_device_default_fail_handler,
1819 scic_sds_remote_device_default_destruct_handler,
1820 scic_sds_remote_device_default_reset_handler,
1821 scic_sds_remote_device_default_reset_complete_handler,
1822 scic_sds_remote_device_default_start_request_handler,
1823 scic_sds_remote_device_default_complete_request_handler,
1824 scic_sds_remote_device_default_continue_request_handler,
1825 scic_sds_remote_device_default_start_request_handler,
1826 scic_sds_remote_device_default_complete_request_handler
1827 },
1828 scic_sds_remote_device_default_suspend_handler,
1829 scic_sds_remote_device_default_resume_handler,
1830 scic_sds_remote_device_default_event_handler,
1831 scic_sds_remote_device_general_frame_handler
1832 },
1833 /* SCI_BASE_REMOTE_DEVICE_STATE_RESETTING */
1834 {
1835 {
1836 scic_sds_remote_device_default_start_handler,
1837 scic_sds_remote_device_resetting_state_stop_handler,
1838 scic_sds_remote_device_default_fail_handler,
1839 scic_sds_remote_device_default_destruct_handler,
1840 scic_sds_remote_device_default_reset_handler,
1841 scic_sds_remote_device_resetting_state_reset_complete_handler,
1842 scic_sds_remote_device_default_start_request_handler,
1843 scic_sds_remote_device_resetting_state_complete_request_handler,
1844 scic_sds_remote_device_default_continue_request_handler,
1845 scic_sds_remote_device_default_start_request_handler,
1846 scic_sds_remote_device_resetting_state_complete_request_handler
1847 },
1848 scic_sds_remote_device_default_suspend_handler,
1849 scic_sds_remote_device_default_resume_handler,
1850 scic_sds_remote_device_default_event_handler,
1851 scic_sds_remote_device_general_frame_handler
1852 },
1853 /* SCI_BASE_REMOTE_DEVICE_STATE_FINAL */
1854 {
1855 {
1856 scic_sds_remote_device_default_start_handler,
1857 scic_sds_remote_device_default_stop_handler,
1858 scic_sds_remote_device_default_fail_handler,
1859 scic_sds_remote_device_default_destruct_handler,
1860 scic_sds_remote_device_default_reset_handler,
1861 scic_sds_remote_device_default_reset_complete_handler,
1862 scic_sds_remote_device_default_start_request_handler,
1863 scic_sds_remote_device_default_complete_request_handler,
1864 scic_sds_remote_device_default_continue_request_handler,
1865 scic_sds_remote_device_default_start_request_handler,
1866 scic_sds_remote_device_default_complete_request_handler
1867 },
1868 scic_sds_remote_device_default_suspend_handler,
1869 scic_sds_remote_device_default_resume_handler,
1870 scic_sds_remote_device_default_event_handler,
1871 scic_sds_remote_device_default_frame_handler
1872 }
1873};
1874
1875/*
1876 * This file is provided under a dual BSD/GPLv2 license. When using or
1877 * redistributing this file, you may do so under either license.
1878 *
1879 * GPL LICENSE SUMMARY
1880 *
1881 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
1882 *
1883 * This program is free software; you can redistribute it and/or modify
1884 * it under the terms of version 2 of the GNU General Public License as
1885 * published by the Free Software Foundation.
1886 *
1887 * This program is distributed in the hope that it will be useful, but
1888 * WITHOUT ANY WARRANTY; without even the implied warranty of
1889 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1890 * General Public License for more details.
1891 *
1892 * You should have received a copy of the GNU General Public License
1893 * along with this program; if not, write to the Free Software
1894 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
1895 * The full GNU General Public License is included in this distribution
1896 * in the file called LICENSE.GPL.
1897 *
1898 * BSD LICENSE
1899 *
1900 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
1901 * All rights reserved.
1902 *
1903 * Redistribution and use in source and binary forms, with or without
1904 * modification, are permitted provided that the following conditions
1905 * are met:
1906 *
1907 * * Redistributions of source code must retain the above copyright
1908 * notice, this list of conditions and the following disclaimer.
1909 * * Redistributions in binary form must reproduce the above copyright
1910 * notice, this list of conditions and the following disclaimer in
1911 * the documentation and/or other materials provided with the
1912 * distribution.
1913 * * Neither the name of Intel Corporation nor the names of its
1914 * contributors may be used to endorse or promote products derived
1915 * from this software without specific prior written permission.
1916 *
1917 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1918 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1919 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1920 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1921 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1922 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1923 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1924 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1925 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1926 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1927 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1928 */
1929
1930/**
1931 * This file contains the operations that are taken on the enter and exit state
1932 * transitions for the struct sci_base_remote_device state machine.
1933 *
1934 *
1935 */
1936
1937#include "scic_remote_device.h"
1938#include "scic_user_callback.h"
1939#include "scic_sds_controller.h"
1940#include "scic_sds_remote_device.h"
1941#include "scic_sds_request.h"
1942#include "scic_sds_controller.h"
1943#include "scic_sds_port.h"
1944
1945/**
1946 *
1947 * @object: This is the struct sci_base_object that is cast into a
1948 * struct scic_sds_remote_device.
1949 *
1950 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_INITIAL it
1951 * immediatly transitions the remote device object to the stopped state. none
1952 */
1953static void scic_sds_remote_device_initial_state_enter(
1954 struct sci_base_object *object)
1955{
1956 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
1957
1958 SET_STATE_HANDLER(
1959 this_device,
1960 scic_sds_remote_device_state_handler_table,
1961 SCI_BASE_REMOTE_DEVICE_STATE_INITIAL
1962 );
1963
1964 /* Initial state is a transitional state to the stopped state */
1965 sci_base_state_machine_change_state(
1966 scic_sds_remote_device_get_base_state_machine(this_device),
1967 SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
1968 );
1969}
1970
1971/**
1972 *
1973 * @object: This is the struct sci_base_object that is cast into a
1974 * struct scic_sds_remote_device.
1975 *
1976 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_INITIAL it
1977 * sets the stopped state handlers and if this state is entered from the
1978 * SCI_BASE_REMOTE_DEVICE_STATE_STOPPING then the SCI User is informed that the
1979 * device stop is complete. none
1980 */
1981static void scic_sds_remote_device_stopped_state_enter(
1982 struct sci_base_object *object)
1983{
1984 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
1985
1986 SET_STATE_HANDLER(
1987 this_device,
1988 scic_sds_remote_device_state_handler_table,
1989 SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
1990 );
1991
1992 /*
1993 * If we are entering from the stopping state let the SCI User know that
1994 * the stop operation has completed. */
1995 if (this_device->parent.state_machine.previous_state_id
1996 == SCI_BASE_REMOTE_DEVICE_STATE_STOPPING) {
1997 scic_cb_remote_device_stop_complete(
1998 scic_sds_remote_device_get_controller(this_device),
1999 this_device,
2000 SCI_SUCCESS
2001 );
2002 }
2003}
2004
2005/**
2006 *
2007 * @object: This is the struct sci_base_object that is cast into a
2008 * struct scic_sds_remote_device.
2009 *
2010 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_STARTING it
2011 * sets the starting state handlers, sets the device not ready, and posts the
2012 * remote node context to the hardware. none
2013 */
2014static void scic_sds_remote_device_starting_state_enter(
2015 struct sci_base_object *object)
2016{
2017 struct scic_sds_controller *the_controller;
2018 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
2019
2020 the_controller = scic_sds_remote_device_get_controller(this_device);
2021
2022 SET_STATE_HANDLER(
2023 this_device,
2024 scic_sds_remote_device_state_handler_table,
2025 SCI_BASE_REMOTE_DEVICE_STATE_STARTING
2026 );
2027
2028 scic_cb_remote_device_not_ready(
2029 the_controller,
2030 this_device,
2031 SCIC_REMOTE_DEVICE_NOT_READY_START_REQUESTED
2032 );
2033}
2034
2035/**
2036 *
2037 * @object: This is the struct sci_base_object that is cast into a
2038 * struct scic_sds_remote_device.
2039 *
2040 * This is the exit method for the SCI_BASE_REMOTE_DEVICE_STATE_STARTING it
2041 * reports that the device start is complete. none
2042 */
2043static void scic_sds_remote_device_starting_state_exit(
2044 struct sci_base_object *object)
2045{
2046 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
2047
2048 /*
2049 * / @todo Check the device object for the proper return code for this
2050 * / callback */
2051 scic_cb_remote_device_start_complete(
2052 scic_sds_remote_device_get_controller(this_device),
2053 this_device,
2054 SCI_SUCCESS
2055 );
2056}
2057
2058/**
2059 *
2060 * @object: This is the struct sci_base_object that is cast into a
2061 * struct scic_sds_remote_device.
2062 *
2063 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_READY it sets
2064 * the ready state handlers, and starts the ready substate machine. none
2065 */
2066static void scic_sds_remote_device_ready_state_enter(
2067 struct sci_base_object *object)
2068{
2069 struct scic_sds_controller *the_controller;
2070 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
2071
2072 the_controller = scic_sds_remote_device_get_controller(this_device);
2073
2074 SET_STATE_HANDLER(
2075 this_device,
2076 scic_sds_remote_device_state_handler_table,
2077 SCI_BASE_REMOTE_DEVICE_STATE_READY
2078 );
2079
2080 the_controller->remote_device_sequence[this_device->rnc->remote_node_index]++;
2081
2082 if (this_device->has_ready_substate_machine) {
2083 sci_base_state_machine_start(&this_device->ready_substate_machine);
2084 } else {
2085 scic_cb_remote_device_ready(the_controller, this_device);
2086 }
2087}
2088
2089/**
2090 *
2091 * @object: This is the struct sci_base_object that is cast into a
2092 * struct scic_sds_remote_device.
2093 *
2094 * This is the exit method for the SCI_BASE_REMOTE_DEVICE_STATE_READY it does
2095 * nothing. none
2096 */
2097static void scic_sds_remote_device_ready_state_exit(
2098 struct sci_base_object *object)
2099{
2100 struct scic_sds_controller *the_controller;
2101 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
2102
2103 the_controller = scic_sds_remote_device_get_controller(this_device);
2104
2105 if (this_device->has_ready_substate_machine) {
2106 sci_base_state_machine_stop(&this_device->ready_substate_machine);
2107 } else {
2108 scic_cb_remote_device_not_ready(
2109 the_controller,
2110 this_device,
2111 SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED
2112 );
2113 }
2114}
2115
2116/**
2117 *
2118 * @object: This is the struct sci_base_object that is cast into a
2119 * struct scic_sds_remote_device.
2120 *
2121 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_STOPPING it
2122 * sets the stopping state handlers and posts an RNC invalidate request to the
2123 * SCU hardware. none
2124 */
2125static void scic_sds_remote_device_stopping_state_enter(
2126 struct sci_base_object *object)
2127{
2128 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
2129
2130 SET_STATE_HANDLER(
2131 this_device,
2132 scic_sds_remote_device_state_handler_table,
2133 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
2134 );
2135}
2136
2137/**
2138 *
2139 * @object: This is the struct sci_base_object that is cast into a
2140 * struct scic_sds_remote_device.
2141 *
2142 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_FAILED it sets
2143 * the stopping state handlers. none
2144 */
2145static void scic_sds_remote_device_failed_state_enter(
2146 struct sci_base_object *object)
2147{
2148 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
2149
2150 SET_STATE_HANDLER(
2151 this_device,
2152 scic_sds_remote_device_state_handler_table,
2153 SCI_BASE_REMOTE_DEVICE_STATE_FAILED
2154 );
2155}
2156
2157/**
2158 *
2159 * @object: This is the struct sci_base_object that is cast into a
2160 * struct scic_sds_remote_device.
2161 *
2162 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_RESETTING it
2163 * sets the resetting state handlers. none
2164 */
2165static void scic_sds_remote_device_resetting_state_enter(
2166 struct sci_base_object *object)
2167{
2168 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
2169
2170 SET_STATE_HANDLER(
2171 this_device,
2172 scic_sds_remote_device_state_handler_table,
2173 SCI_BASE_REMOTE_DEVICE_STATE_RESETTING
2174 );
2175
2176 scic_sds_remote_node_context_suspend(
2177 this_device->rnc, SCI_SOFTWARE_SUSPENSION, NULL, NULL);
2178}
2179
2180/**
2181 *
2182 * @object: This is the struct sci_base_object that is cast into a
2183 * struct scic_sds_remote_device.
2184 *
2185 * This is the exit method for the SCI_BASE_REMOTE_DEVICE_STATE_RESETTING it
2186 * does nothing. none
2187 */
2188static void scic_sds_remote_device_resetting_state_exit(
2189 struct sci_base_object *object)
2190{
2191 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
2192
2193 scic_sds_port_set_direct_attached_device_id(
2194 scic_sds_remote_device_get_port(this_device),
2195 this_device->rnc->remote_node_index
2196 );
2197
2198 scic_sds_remote_node_context_resume(this_device->rnc, NULL, NULL);
2199}
2200
2201/**
2202 *
2203 * @object: This is the struct sci_base_object that is cast into a
2204 * struct scic_sds_remote_device.
2205 *
2206 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_FINAL it sets
2207 * the final state handlers. none
2208 */
2209static void scic_sds_remote_device_final_state_enter(
2210 struct sci_base_object *object)
2211{
2212 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
2213
2214 SET_STATE_HANDLER(
2215 this_device,
2216 scic_sds_remote_device_state_handler_table,
2217 SCI_BASE_REMOTE_DEVICE_STATE_FINAL
2218 );
2219}
2220
2221/* --------------------------------------------------------------------------- */
2222
2223const struct sci_base_state scic_sds_remote_device_state_table[] = {
2224 [SCI_BASE_REMOTE_DEVICE_STATE_INITIAL] = {
2225 .enter_state = scic_sds_remote_device_initial_state_enter,
2226 },
2227 [SCI_BASE_REMOTE_DEVICE_STATE_STOPPED] = {
2228 .enter_state = scic_sds_remote_device_stopped_state_enter,
2229 },
2230 [SCI_BASE_REMOTE_DEVICE_STATE_STARTING] = {
2231 .enter_state = scic_sds_remote_device_starting_state_enter,
2232 .exit_state = scic_sds_remote_device_starting_state_exit
2233 },
2234 [SCI_BASE_REMOTE_DEVICE_STATE_READY] = {
2235 .enter_state = scic_sds_remote_device_ready_state_enter,
2236 .exit_state = scic_sds_remote_device_ready_state_exit
2237 },
2238 [SCI_BASE_REMOTE_DEVICE_STATE_STOPPING] = {
2239 .enter_state = scic_sds_remote_device_stopping_state_enter,
2240 },
2241 [SCI_BASE_REMOTE_DEVICE_STATE_FAILED] = {
2242 .enter_state = scic_sds_remote_device_failed_state_enter,
2243 },
2244 [SCI_BASE_REMOTE_DEVICE_STATE_RESETTING] = {
2245 .enter_state = scic_sds_remote_device_resetting_state_enter,
2246 .exit_state = scic_sds_remote_device_resetting_state_exit
2247 },
2248 [SCI_BASE_REMOTE_DEVICE_STATE_FINAL] = {
2249 .enter_state = scic_sds_remote_device_final_state_enter,
2250 },
2251};
2252
diff --git a/drivers/scsi/isci/core/scic_sds_remote_device.h b/drivers/scsi/isci/core/scic_sds_remote_device.h
new file mode 100644
index 000000000000..44185a2738ec
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_remote_device.h
@@ -0,0 +1,602 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_SDS_REMOTE_DEVICE_H_
57#define _SCIC_SDS_REMOTE_DEVICE_H_
58
59/**
60 * This file contains the structures, constants, and prototypes for the
61 * struct scic_sds_remote_device object.
62 *
63 *
64 */
65
66#include "intel_sas.h"
67#include "sci_base_remote_device.h"
68#include "sci_base_request.h"
69#include "scu_remote_node_context.h"
70#include "scic_sds_remote_node_context.h"
71
72struct scic_sds_controller;
73struct scic_sds_port;
74struct scic_sds_request;
75struct scic_sds_remote_device_state_handler;
76
77/**
78 * enum SCIC_SDS_SSP_REMOTE_DEVICE_READY_SUBSTATES -
79 *
80 * This is the enumeration of the ready substates for the
81 * struct scic_sds_remote_device.
82 */
83enum SCIC_SDS_SSP_REMOTE_DEVICE_READY_SUBSTATES {
84 /**
85 * This is the initial state for the remote device ready substate.
86 */
87 SCIC_SDS_SSP_REMOTE_DEVICE_READY_SUBSTATE_INITIAL,
88
89 /**
90 * This is the ready operational substate for the remote device. This is the
91 * normal operational state for a remote device.
92 */
93 SCIC_SDS_SSP_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL,
94
95 /**
96 * This is the suspended state for the remote device. This is the state that
97 * the device is placed in when a RNC suspend is received by the SCU hardware.
98 */
99 SCIC_SDS_SSP_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED,
100
101 /**
102 * This is the final state that the device is placed in before a change to the
103 * base state machine.
104 */
105 SCIC_SDS_SSP_REMOTE_DEVICE_READY_SUBSTATE_FINAL,
106
107 SCIC_SDS_SSP_REMOTE_DEVICE_READY_MAX_SUBSTATES
108};
109
110/**
111 * enum SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATES -
112 *
113 * This is the enumeration for the struct scic_sds_remote_device ready substates for
114 * the STP remote device.
115 */
116enum SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATES {
117 /**
118 * This is the idle substate for the stp remote device. When there are no
119 * active IO for the device it is is in this state.
120 */
121 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE,
122
123 /**
124 * This is the command state for for the STP remote device. This state is
125 * entered when the device is processing a non-NCQ command. The device object
126 * will fail any new start IO requests until this command is complete.
127 */
128 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD,
129
130 /**
131 * This is the NCQ state for the STP remote device. This state is entered
132 * when the device is processing an NCQ reuqest. It will remain in this state
133 * so long as there is one or more NCQ requests being processed.
134 */
135 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ,
136
137 /**
138 * This is the NCQ error state for the STP remote device. This state is
139 * entered when an SDB error FIS is received by the device object while in the
140 * NCQ state. The device object will only accept a READ LOG command while in
141 * this state.
142 */
143 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR,
144
145#if !defined(DISABLE_ATAPI)
146 /**
147 * This is the ATAPI error state for the STP ATAPI remote device. This state is
148 * entered when ATAPI device sends error status FIS without data while the device
149 * object is in CMD state. A suspension event is expected in this state. The device
150 * object will resume right away.
151 */
152 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR,
153#endif
154
155 /**
156 * This is the READY substate indicates the device is waiting for the RESET task
157 * coming to be recovered from certain hardware specific error.
158 */
159 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET,
160
161 SCIC_SDS_STP_REMOTE_DEVICE_READY_MAX_SUBSTATES
162};
163
164
165/**
166 * enum SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATES -
167 *
168 * This is the enumeration of the ready substates for the SMP REMOTE DEVICE.
169 */
170
171enum SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATES {
172 /**
173 * This is the ready operational substate for the remote device. This is the
174 * normal operational state for a remote device.
175 */
176 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE,
177
178 /**
179 * This is the suspended state for the remote device. This is the state that
180 * the device is placed in when a RNC suspend is received by the SCU hardware.
181 */
182 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD,
183
184 SCIC_SDS_SMP_REMOTE_DEVICE_READY_MAX_SUBSTATES
185};
186
187
188
189
190/**
191 * struct scic_sds_remote_device - This structure contains the data for an SCU
192 * implementation of the SCU Core device data.
193 *
194 *
195 */
196struct scic_sds_remote_device {
197 /**
198 * This field is the common base for all remote device objects.
199 */
200 struct sci_base_remote_device parent;
201
202 /**
203 * This field is the programmed device port width. This value is written to
204 * the RCN data structure to tell the SCU how many open connections this
205 * device can have.
206 */
207 u32 device_port_width;
208
209 /**
210 * This field is the programmed connection rate for this remote device. It is
211 * used to program the TC with the maximum allowed connection rate.
212 */
213 enum sci_sas_link_rate connection_rate;
214
215 /**
216 * This field contains the allowed target protocols for this remote device.
217 */
218 struct smp_discover_response_protocols target_protocols;
219
220 /**
221 * This field contains the device SAS address.
222 */
223 struct sci_sas_address device_address;
224
225 /**
226 * This filed is assinged the value of true if the device is directly attached
227 * to the port.
228 */
229 bool is_direct_attached;
230
231#if !defined(DISABLE_ATAPI)
232 /**
233 * This filed is assinged the value of true if the device is an ATAPI device.
234 */
235 bool is_atapi;
236#endif
237
238 /**
239 * This filed contains a pointer back to the port to which this device is
240 * assigned.
241 */
242 struct scic_sds_port *owning_port;
243
244 /**
245 * This field contains the SCU silicon remote node context specific
246 * information.
247 */
248 struct scic_sds_remote_node_context *rnc;
249
250 /**
251 * This field contains the stated request count for the remote device. The
252 * device can not reach the SCI_BASE_REMOTE_DEVICE_STATE_STOPPED until all
253 * requests are complete and the rnc_posted value is false.
254 */
255 u32 started_request_count;
256
257 /**
258 * This field contains a pointer to the working request object. It is only
259 * used only for SATA requests since the unsolicited frames we get from the
260 * hardware have no Tag value to look up the io request object.
261 */
262 struct scic_sds_request *working_request;
263
264 /**
265 * This field contains the reason for the remote device going not_ready. It is
266 * assigned in the state handlers and used in the state transition.
267 */
268 u32 not_ready_reason;
269
270 /**
271 * This field is true if this remote device has an initialzied ready substate
272 * machine. SSP devices do not have a ready substate machine and STP devices
273 * have a ready substate machine.
274 */
275 bool has_ready_substate_machine;
276
277 /**
278 * This field contains the state machine for the ready substate machine for
279 * this struct scic_sds_remote_device object.
280 */
281 struct sci_base_state_machine ready_substate_machine;
282
283 /**
284 * This field maintains the set of state handlers for the remote device
285 * object. These are changed each time the remote device enters a new state.
286 */
287 struct scic_sds_remote_device_state_handler *state_handlers;
288};
289
290
291typedef enum sci_status (*SCIC_SDS_REMOTE_DEVICE_HANDLER_T)(
292 struct scic_sds_remote_device *this_device);
293
294typedef enum sci_status (*SCIC_SDS_REMOTE_DEVICE_SUSPEND_HANDLER_T)(
295 struct scic_sds_remote_device *this_device,
296 u32 suspend_type);
297
298typedef enum sci_status (*SCIC_SDS_REMOTE_DEVICE_RESUME_HANDLER_T)(
299 struct scic_sds_remote_device *this_device);
300
301typedef enum sci_status (*SCIC_SDS_REMOTE_DEVICE_FRAME_HANDLER_T)(
302 struct scic_sds_remote_device *this_device,
303 u32 frame_index);
304
305typedef enum sci_status (*SCIC_SDS_REMOTE_DEVICE_EVENT_HANDLER_T)(
306 struct scic_sds_remote_device *this_device,
307 u32 event_code);
308
309typedef void (*SCIC_SDS_REMOTE_DEVICE_READY_NOT_READY_HANDLER_T)(
310 struct scic_sds_remote_device *this_device);
311
312/**
313 * struct scic_sds_remote_device_state_handler - This structure conains the
314 * state handlers that are needed to process requests for the SCU remote
315 * device objects.
316 *
317 *
318 */
319struct scic_sds_remote_device_state_handler {
320 struct sci_base_remote_device_state_handler parent;
321
322 SCIC_SDS_REMOTE_DEVICE_SUSPEND_HANDLER_T suspend_handler;
323 SCIC_SDS_REMOTE_DEVICE_RESUME_HANDLER_T resume_handler;
324
325 SCIC_SDS_REMOTE_DEVICE_EVENT_HANDLER_T event_handler;
326 SCIC_SDS_REMOTE_DEVICE_FRAME_HANDLER_T frame_handler;
327
328};
329
330
331extern const struct sci_base_state scic_sds_remote_device_state_table[];
332extern const struct sci_base_state scic_sds_ssp_remote_device_ready_substate_table[];
333extern const struct sci_base_state scic_sds_stp_remote_device_ready_substate_table[];
334extern const struct sci_base_state scic_sds_smp_remote_device_ready_substate_table[];
335
336extern struct scic_sds_remote_device_state_handler
337 scic_sds_remote_device_state_handler_table[];
338extern struct scic_sds_remote_device_state_handler
339 scic_sds_ssp_remote_device_ready_substate_handler_table[];
340extern struct scic_sds_remote_device_state_handler
341 scic_sds_stp_remote_device_ready_substate_handler_table[];
342extern struct scic_sds_remote_device_state_handler
343 scic_sds_smp_remote_device_ready_substate_handler_table[];
344
345/**
346 * scic_sds_remote_device_increment_request_count() -
347 *
348 * This macro incrments the request count for this device
349 */
350#define scic_sds_remote_device_increment_request_count(this_device) \
351 ((this_device)->started_request_count++)
352
353/**
354 * scic_sds_remote_device_decrement_request_count() -
355 *
356 * This macro decrements the request count for this device. This count will
357 * never decrment past 0.
358 */
359#define scic_sds_remote_device_decrement_request_count(this_device) \
360 ((this_device)->started_request_count > 0 ? \
361 (this_device)->started_request_count-- : 0)
362
363/**
364 * scic_sds_remote_device_get_request_count() -
365 *
366 * This is a helper macro to return the current device request count.
367 */
368#define scic_sds_remote_device_get_request_count(this_device) \
369 ((this_device)->started_request_count)
370
371/**
372 * scic_sds_remote_device_get_port() -
373 *
374 * This macro returns the owning port of this remote device obejct.
375 */
376#define scic_sds_remote_device_get_port(this_device) \
377 ((this_device)->owning_port)
378
379/**
380 * scic_sds_remote_device_get_controller() -
381 *
382 * This macro returns the controller object that contains this device object
383 */
384#define scic_sds_remote_device_get_controller(this_device) \
385 scic_sds_port_get_controller(scic_sds_remote_device_get_port(this_device))
386
387/**
388 * scic_sds_remote_device_set_state_handlers() -
389 *
390 * This macro sets the remote device state handlers pointer and is set on entry
391 * to each device state.
392 */
393#define scic_sds_remote_device_set_state_handlers(this_device, handlers) \
394 ((this_device)->state_handlers = (handlers))
395
396/**
397 * scic_sds_remote_device_get_base_state_machine() -
398 *
399 * This macro returns the base sate machine object for the remote device.
400 */
401#define scic_sds_remote_device_get_base_state_machine(this_device) \
402 (&(this_device)->parent.state_machine)
403
404/**
405 * scic_sds_remote_device_get_ready_substate_machine() -
406 *
407 * This macro returns the remote device ready substate machine
408 */
409#define scic_sds_remote_device_get_ready_substate_machine(this_device) \
410 (&(this_device)->ready_substate_machine)
411
412/**
413 * scic_sds_remote_device_get_port() -
414 *
415 * This macro returns the owning port of this device
416 */
417#define scic_sds_remote_device_get_port(this_device) \
418 ((this_device)->owning_port)
419
420/**
421 * scic_sds_remote_device_get_sequence() -
422 *
423 * This macro returns the remote device sequence value
424 */
425#define scic_sds_remote_device_get_sequence(this_device) \
426 (\
427 scic_sds_remote_device_get_controller(this_device)-> \
428 remote_device_sequence[(this_device)->rnc->remote_node_index] \
429 )
430
431/**
432 * scic_sds_remote_device_get_controller_peg() -
433 *
434 * This macro returns the controllers protocol engine group
435 */
436#define scic_sds_remote_device_get_controller_peg(this_device) \
437 (\
438 scic_sds_controller_get_protocol_engine_group(\
439 scic_sds_port_get_controller(\
440 scic_sds_remote_device_get_port(this_device) \
441 ) \
442 ) \
443 )
444
445/**
446 * scic_sds_remote_device_get_port_index() -
447 *
448 * This macro returns the port index for the devices owning port
449 */
450#define scic_sds_remote_device_get_port_index(this_device) \
451 (scic_sds_port_get_index(scic_sds_remote_device_get_port(this_device)))
452
453/**
454 * scic_sds_remote_device_get_index() -
455 *
456 * This macro returns the remote node index for this device object
457 */
458#define scic_sds_remote_device_get_index(this_device) \
459 ((this_device)->rnc->remote_node_index)
460
461/**
462 * scic_sds_remote_device_build_command_context() -
463 *
464 * This macro builds a remote device context for the SCU post request operation
465 */
466#define scic_sds_remote_device_build_command_context(device, command) \
467 ((command) \
468 | (scic_sds_remote_device_get_controller_peg((device)) << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) \
469 | (scic_sds_remote_device_get_port_index((device)) << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) \
470 | (scic_sds_remote_device_get_index((device))) \
471 )
472
473/**
474 * scic_sds_remote_device_set_working_request() -
475 *
476 * This macro makes the working request assingment for the remote device
477 * object. To clear the working request use this macro with a NULL request
478 * object.
479 */
480#define scic_sds_remote_device_set_working_request(device, request) \
481 ((device)->working_request = (request))
482
483/* --------------------------------------------------------------------------- */
484
485
486
487enum sci_status scic_sds_remote_device_frame_handler(
488 struct scic_sds_remote_device *this_device,
489 u32 frame_index);
490
491enum sci_status scic_sds_remote_device_event_handler(
492 struct scic_sds_remote_device *this_device,
493 u32 event_code);
494
495enum sci_status scic_sds_remote_device_start_io(
496 struct scic_sds_controller *controller,
497 struct scic_sds_remote_device *this_device,
498 struct scic_sds_request *io_request);
499
500enum sci_status scic_sds_remote_device_complete_io(
501 struct scic_sds_controller *controller,
502 struct scic_sds_remote_device *this_device,
503 struct scic_sds_request *io_request);
504
505enum sci_status scic_sds_remote_device_resume(
506 struct scic_sds_remote_device *this_device);
507
508enum sci_status scic_sds_remote_device_suspend(
509 struct scic_sds_remote_device *this_device,
510 u32 suspend_type);
511
512enum sci_status scic_sds_remote_device_start_task(
513 struct scic_sds_controller *controller,
514 struct scic_sds_remote_device *this_device,
515 struct scic_sds_request *io_request);
516
517void scic_sds_remote_device_post_request(
518 struct scic_sds_remote_device *this_device,
519 u32 request);
520
521#if !defined(DISABLE_ATAPI)
522bool scic_sds_remote_device_is_atapi(
523 struct scic_sds_remote_device *this_device);
524#else /* !defined(DISABLE_ATAPI) */
525#define scic_sds_remote_device_is_atapi(this_device) false
526#endif /* !defined(DISABLE_ATAPI) */
527
528/* --------------------------------------------------------------------------- */
529
530/* --------------------------------------------------------------------------- */
531
532void scic_sds_remote_device_start_request(
533 struct scic_sds_remote_device *this_device,
534 struct scic_sds_request *the_request,
535 enum sci_status status);
536
537void scic_sds_remote_device_continue_request(
538 struct scic_sds_remote_device *this_device);
539
540enum sci_status scic_sds_remote_device_default_start_handler(
541 struct sci_base_remote_device *this_device);
542
543
544enum sci_status scic_sds_remote_device_default_fail_handler(
545 struct sci_base_remote_device *this_device);
546
547enum sci_status scic_sds_remote_device_default_destruct_handler(
548 struct sci_base_remote_device *this_device);
549
550enum sci_status scic_sds_remote_device_default_reset_handler(
551 struct sci_base_remote_device *device);
552
553enum sci_status scic_sds_remote_device_default_reset_complete_handler(
554 struct sci_base_remote_device *device);
555
556enum sci_status scic_sds_remote_device_default_start_request_handler(
557 struct sci_base_remote_device *device,
558 struct sci_base_request *request);
559
560enum sci_status scic_sds_remote_device_default_complete_request_handler(
561 struct sci_base_remote_device *device,
562 struct sci_base_request *request);
563
564enum sci_status scic_sds_remote_device_default_continue_request_handler(
565 struct sci_base_remote_device *device,
566 struct sci_base_request *request);
567
568enum sci_status scic_sds_remote_device_default_suspend_handler(
569 struct scic_sds_remote_device *this_device,
570 u32 suspend_type);
571
572enum sci_status scic_sds_remote_device_default_resume_handler(
573 struct scic_sds_remote_device *this_device);
574
575
576enum sci_status scic_sds_remote_device_default_frame_handler(
577 struct scic_sds_remote_device *this_device,
578 u32 frame_index);
579
580/* --------------------------------------------------------------------------- */
581
582enum sci_status scic_sds_remote_device_ready_state_stop_handler(
583 struct sci_base_remote_device *device);
584
585enum sci_status scic_sds_remote_device_ready_state_reset_handler(
586 struct sci_base_remote_device *device);
587
588enum sci_status scic_sds_remote_device_general_frame_handler(
589 struct scic_sds_remote_device *this_device,
590 u32 frame_index);
591
592enum sci_status scic_sds_remote_device_general_event_handler(
593 struct scic_sds_remote_device *this_device,
594 u32 event_code);
595
596enum sci_status scic_sds_ssp_remote_device_ready_suspended_substate_resume_handler(
597 struct scic_sds_remote_device *this_device);
598
599/* --------------------------------------------------------------------------- */
600
601
602#endif /* _SCIC_SDS_REMOTE_DEVICE_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_remote_node_context.c b/drivers/scsi/isci/core/scic_sds_remote_node_context.c
new file mode 100644
index 000000000000..79fe9a8cd1ed
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_remote_node_context.c
@@ -0,0 +1,1244 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include "sci_base_state_machine.h"
57#include "scic_remote_device.h"
58#include "scic_sds_controller.h"
59#include "scic_sds_port.h"
60#include "scic_sds_remote_device.h"
61#include "scic_sds_remote_node_context.h"
62#include "sci_environment.h"
63#include "sci_util.h"
64#include "scu_event_codes.h"
65#include "scu_task_context.h"
66
67void scic_sds_remote_node_context_construct(
68 struct scic_sds_remote_device *device,
69 struct scic_sds_remote_node_context *rnc,
70 u16 remote_node_index)
71{
72 memset(rnc, 0, sizeof(struct scic_sds_remote_node_context));
73
74 rnc->remote_node_index = remote_node_index;
75 rnc->device = device;
76 rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED;
77
78 sci_base_state_machine_construct(
79 &rnc->state_machine,
80 &rnc->parent,
81 scic_sds_remote_node_context_state_table,
82 SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE
83 );
84
85 sci_base_state_machine_start(&rnc->state_machine);
86}
87
88/**
89 *
90 * @this_rnc: The RNC for which the is posted request is being made.
91 *
92 * This method will return true if the RNC is not in the initial state. In all
93 * other states the RNC is considered active and this will return true. The
94 * destroy request of the state machine drives the RNC back to the initial
95 * state. If the state machine changes then this routine will also have to be
96 * changed. bool true if the state machine is not in the initial state false if
97 * the state machine is in the initial state
98 */
99
100/**
101 *
102 * @this_rnc: The state of the remote node context object to check.
103 *
104 * This method will return true if the remote node context is in a READY state
105 * otherwise it will return false bool true if the remote node context is in
106 * the ready state. false if the remote node context is not in the ready state.
107 */
108bool scic_sds_remote_node_context_is_ready(
109 struct scic_sds_remote_node_context *this_rnc)
110{
111 u32 current_state = sci_base_state_machine_get_state(&this_rnc->state_machine);
112
113 if (current_state == SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE) {
114 return true;
115 }
116
117 return false;
118}
119
120/**
121 *
122 * @this_device: The remote device to use to construct the RNC buffer.
123 * @rnc: The buffer into which the remote device data will be copied.
124 *
125 * This method will construct the RNC buffer for this remote device object. none
126 */
127void scic_sds_remote_node_context_construct_buffer(
128 struct scic_sds_remote_node_context *this_rnc)
129{
130 union scu_remote_node_context *rnc;
131 struct scic_sds_controller *the_controller;
132
133 the_controller = scic_sds_remote_device_get_controller(this_rnc->device);
134
135 rnc = scic_sds_controller_get_remote_node_context_buffer(
136 the_controller, this_rnc->remote_node_index);
137
138 memset(
139 rnc,
140 0x00,
141 sizeof(union scu_remote_node_context)
142 * scic_sds_remote_device_node_count(this_rnc->device)
143 );
144
145 rnc->ssp.remote_node_index = this_rnc->remote_node_index;
146 rnc->ssp.remote_node_port_width = this_rnc->device->device_port_width;
147 rnc->ssp.logical_port_index =
148 scic_sds_remote_device_get_port_index(this_rnc->device);
149
150 rnc->ssp.remote_sas_address_hi = SCIC_SWAP_DWORD(this_rnc->device->device_address.high);
151 rnc->ssp.remote_sas_address_lo = SCIC_SWAP_DWORD(this_rnc->device->device_address.low);
152
153 rnc->ssp.nexus_loss_timer_enable = true;
154 rnc->ssp.check_bit = false;
155 rnc->ssp.is_valid = false;
156 rnc->ssp.is_remote_node_context = true;
157 rnc->ssp.function_number = 0;
158
159 rnc->ssp.arbitration_wait_time = 0;
160
161
162 if (
163 this_rnc->device->target_protocols.u.bits.attached_sata_device
164 || this_rnc->device->target_protocols.u.bits.attached_stp_target
165 ) {
166 rnc->ssp.connection_occupancy_timeout =
167 the_controller->user_parameters.sds1.stp_max_occupancy_timeout;
168 rnc->ssp.connection_inactivity_timeout =
169 the_controller->user_parameters.sds1.stp_inactivity_timeout;
170 } else {
171 rnc->ssp.connection_occupancy_timeout =
172 the_controller->user_parameters.sds1.ssp_max_occupancy_timeout;
173 rnc->ssp.connection_inactivity_timeout =
174 the_controller->user_parameters.sds1.ssp_inactivity_timeout;
175 }
176
177 rnc->ssp.initial_arbitration_wait_time = 0;
178
179 /* Open Address Frame Parameters */
180 rnc->ssp.oaf_connection_rate = this_rnc->device->connection_rate;
181 rnc->ssp.oaf_features = 0;
182 rnc->ssp.oaf_source_zone_group = 0;
183 rnc->ssp.oaf_more_compatibility_features = 0;
184}
185
186/**
187 *
188 * @this_rnc:
189 * @the_callback:
190 * @callback_parameter:
191 *
192 * This method will setup the remote node context object so it will transition
193 * to its ready state. If the remote node context is already setup to
194 * transition to its final state then this function does nothing. none
195 */
196static void scic_sds_remote_node_context_setup_to_resume(
197 struct scic_sds_remote_node_context *this_rnc,
198 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback,
199 void *callback_parameter)
200{
201 if (this_rnc->destination_state != SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL) {
202 this_rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY;
203 this_rnc->user_callback = the_callback;
204 this_rnc->user_cookie = callback_parameter;
205 }
206}
207
208/**
209 *
210 * @this_rnc:
211 * @the_callback:
212 * @callback_parameter:
213 *
214 * This method will setup the remote node context object so it will transistion
215 * to its final state. none
216 */
217static void scic_sds_remote_node_context_setup_to_destory(
218 struct scic_sds_remote_node_context *this_rnc,
219 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback,
220 void *callback_parameter)
221{
222 this_rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL;
223 this_rnc->user_callback = the_callback;
224 this_rnc->user_cookie = callback_parameter;
225}
226
227/**
228 *
229 * @this_rnc:
230 * @the_callback:
231 *
232 * This method will continue to resume a remote node context. This is used in
233 * the states where a resume is requested while a resume is in progress.
234 */
235static enum sci_status scic_sds_remote_node_context_continue_to_resume_handler(
236 struct scic_sds_remote_node_context *this_rnc,
237 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback,
238 void *callback_parameter)
239{
240 if (this_rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY) {
241 this_rnc->user_callback = the_callback;
242 this_rnc->user_cookie = callback_parameter;
243
244 return SCI_SUCCESS;
245 }
246
247 return SCI_FAILURE_INVALID_STATE;
248}
249
250/* --------------------------------------------------------------------------- */
251
252static enum sci_status scic_sds_remote_node_context_default_destruct_handler(
253 struct scic_sds_remote_node_context *this_rnc,
254 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback,
255 void *callback_parameter)
256{
257 dev_warn(scirdev_to_dev(this_rnc->device),
258 "%s: SCIC Remote Node Context 0x%p requested to stop while "
259 "in unexpected state %d\n",
260 __func__,
261 this_rnc,
262 sci_base_state_machine_get_state(&this_rnc->state_machine));
263
264 /*
265 * We have decided that the destruct request on the remote node context can not fail
266 * since it is either in the initial/destroyed state or is can be destroyed. */
267 return SCI_SUCCESS;
268}
269
270static enum sci_status scic_sds_remote_node_context_default_suspend_handler(
271 struct scic_sds_remote_node_context *this_rnc,
272 u32 suspend_type,
273 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback,
274 void *callback_parameter)
275{
276 dev_warn(scirdev_to_dev(this_rnc->device),
277 "%s: SCIC Remote Node Context 0x%p requested to suspend "
278 "while in wrong state %d\n",
279 __func__,
280 this_rnc,
281 sci_base_state_machine_get_state(&this_rnc->state_machine));
282
283 return SCI_FAILURE_INVALID_STATE;
284}
285
286static enum sci_status scic_sds_remote_node_context_default_resume_handler(
287 struct scic_sds_remote_node_context *this_rnc,
288 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback,
289 void *callback_parameter)
290{
291 dev_warn(scirdev_to_dev(this_rnc->device),
292 "%s: SCIC Remote Node Context 0x%p requested to resume "
293 "while in wrong state %d\n",
294 __func__,
295 this_rnc,
296 sci_base_state_machine_get_state(&this_rnc->state_machine));
297
298 return SCI_FAILURE_INVALID_STATE;
299}
300
301static enum sci_status scic_sds_remote_node_context_default_start_io_handler(
302 struct scic_sds_remote_node_context *this_rnc,
303 struct scic_sds_request *the_request)
304{
305 dev_warn(scirdev_to_dev(this_rnc->device),
306 "%s: SCIC Remote Node Context 0x%p requested to start io "
307 "0x%p while in wrong state %d\n",
308 __func__,
309 this_rnc,
310 the_request,
311 sci_base_state_machine_get_state(&this_rnc->state_machine));
312
313 return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
314}
315
316static enum sci_status scic_sds_remote_node_context_default_start_task_handler(
317 struct scic_sds_remote_node_context *this_rnc,
318 struct scic_sds_request *the_request)
319{
320 dev_warn(scirdev_to_dev(this_rnc->device),
321 "%s: SCIC Remote Node Context 0x%p requested to start "
322 "task 0x%p while in wrong state %d\n",
323 __func__,
324 this_rnc,
325 the_request,
326 sci_base_state_machine_get_state(&this_rnc->state_machine));
327
328 return SCI_FAILURE;
329}
330
331static enum sci_status scic_sds_remote_node_context_default_event_handler(
332 struct scic_sds_remote_node_context *this_rnc,
333 u32 event_code)
334{
335 dev_warn(scirdev_to_dev(this_rnc->device),
336 "%s: SCIC Remote Node Context 0x%p requested to process "
337 "event 0x%x while in wrong state %d\n",
338 __func__,
339 this_rnc,
340 event_code,
341 sci_base_state_machine_get_state(&this_rnc->state_machine));
342
343 return SCI_FAILURE_INVALID_STATE;
344}
345
346/**
347 *
348 * @this_rnc: The rnc for which the task request is targeted.
349 * @the_request: The request which is going to be started.
350 *
351 * This method determines if the task request can be started by the SCU
352 * hardware. When the RNC is in the ready state any task can be started.
353 * enum sci_status SCI_SUCCESS
354 */
355static enum sci_status scic_sds_remote_node_context_success_start_task_handler(
356 struct scic_sds_remote_node_context *this_rnc,
357 struct scic_sds_request *the_request)
358{
359 return SCI_SUCCESS;
360}
361
362/**
363 *
364 * @this_rnc:
365 * @the_callback:
366 * @callback_parameter:
367 *
368 * This method handles destruct calls from the various state handlers. The
369 * remote node context can be requested to destroy from any state. If there was
370 * a user callback it is always replaced with the request to destroy user
371 * callback. enum sci_status
372 */
373static enum sci_status scic_sds_remote_node_context_general_destruct_handler(
374 struct scic_sds_remote_node_context *this_rnc,
375 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback,
376 void *callback_parameter)
377{
378 scic_sds_remote_node_context_setup_to_destory(
379 this_rnc, the_callback, callback_parameter
380 );
381
382 sci_base_state_machine_change_state(
383 &this_rnc->state_machine,
384 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE
385 );
386
387 return SCI_SUCCESS;
388}
389
390/* --------------------------------------------------------------------------- */
391
392static enum sci_status scic_sds_remote_node_context_initial_state_resume_handler(
393 struct scic_sds_remote_node_context *this_rnc,
394 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback,
395 void *callback_parameter)
396{
397 if (this_rnc->remote_node_index != SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) {
398 scic_sds_remote_node_context_setup_to_resume(
399 this_rnc, the_callback, callback_parameter
400 );
401
402 scic_sds_remote_node_context_construct_buffer(this_rnc);
403
404 sci_base_state_machine_change_state(
405 &this_rnc->state_machine,
406 SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE
407 );
408
409 return SCI_SUCCESS;
410 }
411
412 return SCI_FAILURE_INVALID_STATE;
413}
414
415/* --------------------------------------------------------------------------- */
416
417static enum sci_status scic_sds_remote_node_context_posting_state_event_handler(
418 struct scic_sds_remote_node_context *this_rnc,
419 u32 event_code)
420{
421 enum sci_status status;
422
423 switch (scu_get_event_code(event_code)) {
424 case SCU_EVENT_POST_RNC_COMPLETE:
425 status = SCI_SUCCESS;
426
427 sci_base_state_machine_change_state(
428 &this_rnc->state_machine,
429 SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE
430 );
431 break;
432
433 default:
434 status = SCI_FAILURE;
435 dev_warn(scirdev_to_dev(this_rnc->device),
436 "%s: SCIC Remote Node Context 0x%p requested to "
437 "process unexpected event 0x%x while in posting "
438 "state\n",
439 __func__,
440 this_rnc,
441 event_code);
442 break;
443 }
444
445 return status;
446}
447
448/* --------------------------------------------------------------------------- */
449
450static enum sci_status scic_sds_remote_node_context_invalidating_state_destruct_handler(
451 struct scic_sds_remote_node_context *this_rnc,
452 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback,
453 void *callback_parameter)
454{
455 scic_sds_remote_node_context_setup_to_destory(
456 this_rnc, the_callback, callback_parameter
457 );
458
459 return SCI_SUCCESS;
460}
461
462static enum sci_status scic_sds_remote_node_context_invalidating_state_event_handler(
463 struct scic_sds_remote_node_context *this_rnc,
464 u32 event_code)
465{
466 enum sci_status status;
467
468 if (scu_get_event_code(event_code) == SCU_EVENT_POST_RNC_INVALIDATE_COMPLETE) {
469 status = SCI_SUCCESS;
470
471 if (this_rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL) {
472 sci_base_state_machine_change_state(
473 &this_rnc->state_machine,
474 SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE
475 );
476 } else {
477 sci_base_state_machine_change_state(
478 &this_rnc->state_machine,
479 SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE
480 );
481 }
482 } else {
483 switch (scu_get_event_type(event_code)) {
484 case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
485 case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
486 /*
487 * We really dont care if the hardware is going to suspend
488 * the device since it's being invalidated anyway */
489 dev_dbg(scirdev_to_dev(this_rnc->device),
490 "%s: SCIC Remote Node Context 0x%p was "
491 "suspeneded by hardware while being "
492 "invalidated.\n",
493 __func__,
494 this_rnc);
495 status = SCI_SUCCESS;
496 break;
497
498 default:
499 dev_warn(scirdev_to_dev(this_rnc->device),
500 "%s: SCIC Remote Node Context 0x%p "
501 "requested to process event 0x%x while "
502 "in state %d.\n",
503 __func__,
504 this_rnc,
505 event_code,
506 sci_base_state_machine_get_state(
507 &this_rnc->state_machine));
508 status = SCI_FAILURE;
509 break;
510 }
511 }
512
513 return status;
514}
515
516/* --------------------------------------------------------------------------- */
517
518
519static enum sci_status scic_sds_remote_node_context_resuming_state_event_handler(
520 struct scic_sds_remote_node_context *this_rnc,
521 u32 event_code)
522{
523 enum sci_status status;
524
525 if (scu_get_event_code(event_code) == SCU_EVENT_POST_RCN_RELEASE) {
526 status = SCI_SUCCESS;
527
528 sci_base_state_machine_change_state(
529 &this_rnc->state_machine,
530 SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE
531 );
532 } else {
533 switch (scu_get_event_type(event_code)) {
534 case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
535 case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
536 /*
537 * We really dont care if the hardware is going to suspend
538 * the device since it's being resumed anyway */
539 dev_dbg(scirdev_to_dev(this_rnc->device),
540 "%s: SCIC Remote Node Context 0x%p was "
541 "suspeneded by hardware while being resumed.\n",
542 __func__,
543 this_rnc);
544 status = SCI_SUCCESS;
545 break;
546
547 default:
548 dev_warn(scirdev_to_dev(this_rnc->device),
549 "%s: SCIC Remote Node Context 0x%p requested "
550 "to process event 0x%x while in state %d.\n",
551 __func__,
552 this_rnc,
553 event_code,
554 sci_base_state_machine_get_state(
555 &this_rnc->state_machine));
556 status = SCI_FAILURE;
557 break;
558 }
559 }
560
561 return status;
562}
563
564/* --------------------------------------------------------------------------- */
565
566/**
567 *
568 * @this_rnc: The remote node context object being suspended.
569 * @the_callback: The callback when the suspension is complete.
570 * @callback_parameter: The parameter that is to be passed into the callback.
571 *
572 * This method will handle the suspend requests from the ready state.
573 * SCI_SUCCESS
574 */
575static enum sci_status scic_sds_remote_node_context_ready_state_suspend_handler(
576 struct scic_sds_remote_node_context *this_rnc,
577 u32 suspend_type,
578 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback,
579 void *callback_parameter)
580{
581 this_rnc->user_callback = the_callback;
582 this_rnc->user_cookie = callback_parameter;
583 this_rnc->suspension_code = suspend_type;
584
585 if (suspend_type == SCI_SOFTWARE_SUSPENSION) {
586 scic_sds_remote_device_post_request(
587 this_rnc->device,
588 SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX
589 );
590 }
591
592 sci_base_state_machine_change_state(
593 &this_rnc->state_machine,
594 SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE
595 );
596
597 return SCI_SUCCESS;
598}
599
600/**
601 *
602 * @this_rnc: The rnc for which the io request is targeted.
603 * @the_request: The request which is going to be started.
604 *
605 * This method determines if the io request can be started by the SCU hardware.
606 * When the RNC is in the ready state any io request can be started. enum sci_status
607 * SCI_SUCCESS
608 */
609static enum sci_status scic_sds_remote_node_context_ready_state_start_io_handler(
610 struct scic_sds_remote_node_context *this_rnc,
611 struct scic_sds_request *the_request)
612{
613 return SCI_SUCCESS;
614}
615
616
617static enum sci_status scic_sds_remote_node_context_ready_state_event_handler(
618 struct scic_sds_remote_node_context *this_rnc,
619 u32 event_code)
620{
621 enum sci_status status;
622
623 switch (scu_get_event_type(event_code)) {
624 case SCU_EVENT_TL_RNC_SUSPEND_TX:
625 sci_base_state_machine_change_state(
626 &this_rnc->state_machine,
627 SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE
628 );
629
630 this_rnc->suspension_code = scu_get_event_specifier(event_code);
631 status = SCI_SUCCESS;
632 break;
633
634 case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
635 sci_base_state_machine_change_state(
636 &this_rnc->state_machine,
637 SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE
638 );
639
640 this_rnc->suspension_code = scu_get_event_specifier(event_code);
641 status = SCI_SUCCESS;
642 break;
643
644 default:
645 dev_warn(scirdev_to_dev(this_rnc->device),
646 "%s: SCIC Remote Node Context 0x%p requested to "
647 "process event 0x%x while in state %d.\n",
648 __func__,
649 this_rnc,
650 event_code,
651 sci_base_state_machine_get_state(
652 &this_rnc->state_machine));
653
654 status = SCI_FAILURE;
655 break;
656 }
657
658 return status;
659}
660
661/* --------------------------------------------------------------------------- */
662
663static enum sci_status scic_sds_remote_node_context_tx_suspended_state_resume_handler(
664 struct scic_sds_remote_node_context *this_rnc,
665 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback,
666 void *callback_parameter)
667{
668 enum sci_status status;
669 struct smp_discover_response_protocols protocols;
670
671 scic_sds_remote_node_context_setup_to_resume(
672 this_rnc, the_callback, callback_parameter
673 );
674
675 /* TODO: consider adding a resume action of NONE, INVALIDATE, WRITE_TLCR */
676
677 scic_remote_device_get_protocols(this_rnc->device, &protocols);
678
679 if (
680 (protocols.u.bits.attached_ssp_target == 1)
681 || (protocols.u.bits.attached_smp_target == 1)
682 ) {
683 sci_base_state_machine_change_state(
684 &this_rnc->state_machine,
685 SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE
686 );
687
688 status = SCI_SUCCESS;
689 } else if (protocols.u.bits.attached_stp_target == 1) {
690 if (this_rnc->device->is_direct_attached) {
691 /* @todo Fix this since I am being silly in writing to the STPTLDARNI register. */
692 scic_sds_port_set_direct_attached_device_id(
693 this_rnc->device->owning_port,
694 this_rnc->remote_node_index
695 );
696
697 sci_base_state_machine_change_state(
698 &this_rnc->state_machine,
699 SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE
700 );
701 } else {
702 sci_base_state_machine_change_state(
703 &this_rnc->state_machine,
704 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE
705 );
706 }
707
708 status = SCI_SUCCESS;
709 } else {
710 status = SCI_FAILURE;
711 }
712
713 return status;
714}
715
716/**
717 *
718 * @this_rnc: The remote node context which is to receive the task request.
719 * @the_request: The task request to be transmitted to to the remote target
720 * device.
721 *
722 * This method will report a success or failure attempt to start a new task
723 * request to the hardware. Since all task requests are sent on the high
724 * priority queue they can be sent when the RCN is in a TX suspend state.
725 * enum sci_status SCI_SUCCESS
726 */
727static enum sci_status scic_sds_remote_node_context_suspended_start_task_handler(
728 struct scic_sds_remote_node_context *this_rnc,
729 struct scic_sds_request *the_request)
730{
731 scic_sds_remote_node_context_resume(this_rnc, NULL, NULL);
732
733 return SCI_SUCCESS;
734}
735
736/* --------------------------------------------------------------------------- */
737
738static enum sci_status scic_sds_remote_node_context_tx_rx_suspended_state_resume_handler(
739 struct scic_sds_remote_node_context *this_rnc,
740 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback,
741 void *callback_parameter)
742{
743 scic_sds_remote_node_context_setup_to_resume(
744 this_rnc, the_callback, callback_parameter
745 );
746
747 sci_base_state_machine_change_state(
748 &this_rnc->state_machine,
749 SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE
750 );
751
752 return SCI_FAILURE_INVALID_STATE;
753}
754
755/* --------------------------------------------------------------------------- */
756
757/**
758 *
759 *
760 *
761 */
762static enum sci_status scic_sds_remote_node_context_await_suspension_state_resume_handler(
763 struct scic_sds_remote_node_context *this_rnc,
764 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback,
765 void *callback_parameter)
766{
767 scic_sds_remote_node_context_setup_to_resume(
768 this_rnc, the_callback, callback_parameter
769 );
770
771 return SCI_SUCCESS;
772}
773
774/**
775 *
776 * @this_rnc: The remote node context which is to receive the task request.
777 * @the_request: The task request to be transmitted to to the remote target
778 * device.
779 *
780 * This method will report a success or failure attempt to start a new task
781 * request to the hardware. Since all task requests are sent on the high
782 * priority queue they can be sent when the RCN is in a TX suspend state.
783 * enum sci_status SCI_SUCCESS
784 */
785static enum sci_status scic_sds_remote_node_context_await_suspension_state_start_task_handler(
786 struct scic_sds_remote_node_context *this_rnc,
787 struct scic_sds_request *the_request)
788{
789 return SCI_SUCCESS;
790}
791
792static enum sci_status scic_sds_remote_node_context_await_suspension_state_event_handler(
793 struct scic_sds_remote_node_context *this_rnc,
794 u32 event_code)
795{
796 enum sci_status status;
797
798 switch (scu_get_event_type(event_code)) {
799 case SCU_EVENT_TL_RNC_SUSPEND_TX:
800 sci_base_state_machine_change_state(
801 &this_rnc->state_machine,
802 SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE
803 );
804
805 this_rnc->suspension_code = scu_get_event_specifier(event_code);
806 status = SCI_SUCCESS;
807 break;
808
809 case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
810 sci_base_state_machine_change_state(
811 &this_rnc->state_machine,
812 SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE
813 );
814
815 this_rnc->suspension_code = scu_get_event_specifier(event_code);
816 status = SCI_SUCCESS;
817 break;
818
819 default:
820 dev_warn(scirdev_to_dev(this_rnc->device),
821 "%s: SCIC Remote Node Context 0x%p requested to "
822 "process event 0x%x while in state %d.\n",
823 __func__,
824 this_rnc,
825 event_code,
826 sci_base_state_machine_get_state(
827 &this_rnc->state_machine));
828
829 status = SCI_FAILURE;
830 break;
831 }
832
833 return status;
834}
835
836/* --------------------------------------------------------------------------- */
837
838struct scic_sds_remote_node_context_handlers
839scic_sds_remote_node_context_state_handler_table[
840 SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES] =
841{
842 /* SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE */
843 {
844 scic_sds_remote_node_context_default_destruct_handler,
845 scic_sds_remote_node_context_default_suspend_handler,
846 scic_sds_remote_node_context_initial_state_resume_handler,
847 scic_sds_remote_node_context_default_start_io_handler,
848 scic_sds_remote_node_context_default_start_task_handler,
849 scic_sds_remote_node_context_default_event_handler
850 },
851 /* SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE */
852 {
853 scic_sds_remote_node_context_general_destruct_handler,
854 scic_sds_remote_node_context_default_suspend_handler,
855 scic_sds_remote_node_context_continue_to_resume_handler,
856 scic_sds_remote_node_context_default_start_io_handler,
857 scic_sds_remote_node_context_default_start_task_handler,
858 scic_sds_remote_node_context_posting_state_event_handler
859 },
860 /* SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE */
861 {
862 scic_sds_remote_node_context_invalidating_state_destruct_handler,
863 scic_sds_remote_node_context_default_suspend_handler,
864 scic_sds_remote_node_context_continue_to_resume_handler,
865 scic_sds_remote_node_context_default_start_io_handler,
866 scic_sds_remote_node_context_default_start_task_handler,
867 scic_sds_remote_node_context_invalidating_state_event_handler
868 },
869 /* SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE */
870 {
871 scic_sds_remote_node_context_general_destruct_handler,
872 scic_sds_remote_node_context_default_suspend_handler,
873 scic_sds_remote_node_context_continue_to_resume_handler,
874 scic_sds_remote_node_context_default_start_io_handler,
875 scic_sds_remote_node_context_success_start_task_handler,
876 scic_sds_remote_node_context_resuming_state_event_handler
877 },
878 /* SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE */
879 {
880 scic_sds_remote_node_context_general_destruct_handler,
881 scic_sds_remote_node_context_ready_state_suspend_handler,
882 scic_sds_remote_node_context_default_resume_handler,
883 scic_sds_remote_node_context_ready_state_start_io_handler,
884 scic_sds_remote_node_context_success_start_task_handler,
885 scic_sds_remote_node_context_ready_state_event_handler
886 },
887 /* SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE */
888 {
889 scic_sds_remote_node_context_general_destruct_handler,
890 scic_sds_remote_node_context_default_suspend_handler,
891 scic_sds_remote_node_context_tx_suspended_state_resume_handler,
892 scic_sds_remote_node_context_default_start_io_handler,
893 scic_sds_remote_node_context_suspended_start_task_handler,
894 scic_sds_remote_node_context_default_event_handler
895 },
896 /* SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE */
897 {
898 scic_sds_remote_node_context_general_destruct_handler,
899 scic_sds_remote_node_context_default_suspend_handler,
900 scic_sds_remote_node_context_tx_rx_suspended_state_resume_handler,
901 scic_sds_remote_node_context_default_start_io_handler,
902 scic_sds_remote_node_context_suspended_start_task_handler,
903 scic_sds_remote_node_context_default_event_handler
904 },
905 /* SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE */
906 {
907 scic_sds_remote_node_context_general_destruct_handler,
908 scic_sds_remote_node_context_default_suspend_handler,
909 scic_sds_remote_node_context_await_suspension_state_resume_handler,
910 scic_sds_remote_node_context_default_start_io_handler,
911 scic_sds_remote_node_context_await_suspension_state_start_task_handler,
912 scic_sds_remote_node_context_await_suspension_state_event_handler
913 }
914};
915
916/*
917 * *****************************************************************************
918 * * REMOTE NODE CONTEXT PRIVATE METHODS
919 * ***************************************************************************** */
920
921/**
922 *
923 *
924 * This method just calls the user callback function and then resets the
925 * callback.
926 */
927static void scic_sds_remote_node_context_notify_user(
928 struct scic_sds_remote_node_context *rnc)
929{
930 if (rnc->user_callback != NULL) {
931 (*rnc->user_callback)(rnc->user_cookie);
932
933 rnc->user_callback = NULL;
934 rnc->user_cookie = NULL;
935 }
936}
937
938/**
939 *
940 *
941 * This method will continue the remote node context state machine by
942 * requesting to resume the remote node context state machine from its current
943 * state.
944 */
945static void scic_sds_remote_node_context_continue_state_transitions(
946 struct scic_sds_remote_node_context *rnc)
947{
948 if (rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY) {
949 rnc->state_handlers->resume_handler(
950 rnc, rnc->user_callback, rnc->user_cookie
951 );
952 }
953}
954
955/**
956 *
957 * @this_rnc: The remote node context object that is to be validated.
958 *
959 * This method will mark the rnc buffer as being valid and post the request to
960 * the hardware. none
961 */
962static void scic_sds_remote_node_context_validate_context_buffer(
963 struct scic_sds_remote_node_context *this_rnc)
964{
965 union scu_remote_node_context *rnc_buffer;
966
967 rnc_buffer = scic_sds_controller_get_remote_node_context_buffer(
968 scic_sds_remote_device_get_controller(this_rnc->device),
969 this_rnc->remote_node_index
970 );
971
972 rnc_buffer->ssp.is_valid = true;
973
974 if (
975 !this_rnc->device->is_direct_attached
976 && this_rnc->device->target_protocols.u.bits.attached_stp_target
977 ) {
978 scic_sds_remote_device_post_request(
979 this_rnc->device,
980 SCU_CONTEXT_COMMAND_POST_RNC_96
981 );
982 } else {
983 scic_sds_remote_device_post_request(
984 this_rnc->device,
985 SCU_CONTEXT_COMMAND_POST_RNC_32
986 );
987
988 if (this_rnc->device->is_direct_attached) {
989 scic_sds_port_set_direct_attached_device_id(
990 this_rnc->device->owning_port,
991 this_rnc->remote_node_index
992 );
993 }
994 }
995}
996
997/**
998 *
999 * @this_rnc: The remote node context object that is to be invalidated.
1000 *
1001 * This method will update the RNC buffer and post the invalidate request. none
1002 */
1003static void scic_sds_remote_node_context_invalidate_context_buffer(
1004 struct scic_sds_remote_node_context *this_rnc)
1005{
1006 union scu_remote_node_context *rnc_buffer;
1007
1008 rnc_buffer = scic_sds_controller_get_remote_node_context_buffer(
1009 scic_sds_remote_device_get_controller(this_rnc->device),
1010 this_rnc->remote_node_index
1011 );
1012
1013 rnc_buffer->ssp.is_valid = false;
1014
1015 scic_sds_remote_device_post_request(
1016 this_rnc->device,
1017 SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE
1018 );
1019
1020 if (this_rnc->device->is_direct_attached) {
1021 scic_sds_port_set_direct_attached_device_id(
1022 this_rnc->device->owning_port,
1023 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
1024 );
1025 }
1026}
1027
1028/*
1029 * *****************************************************************************
1030 * * REMOTE NODE CONTEXT STATE ENTER AND EXIT METHODS
1031 * ***************************************************************************** */
1032
1033/**
1034 *
1035 *
1036 *
1037 */
1038static void scic_sds_remote_node_context_initial_state_enter(
1039 struct sci_base_object *object)
1040{
1041 struct scic_sds_remote_node_context *rnc;
1042
1043 rnc = (struct scic_sds_remote_node_context *)object;
1044
1045 SET_STATE_HANDLER(
1046 rnc,
1047 scic_sds_remote_node_context_state_handler_table,
1048 SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE
1049 );
1050
1051 /*
1052 * Check to see if we have gotten back to the initial state because someone
1053 * requested to destroy the remote node context object. */
1054 if (
1055 rnc->state_machine.previous_state_id
1056 == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE
1057 ) {
1058 rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED;
1059
1060 scic_sds_remote_node_context_notify_user(rnc);
1061 }
1062}
1063
1064/**
1065 *
1066 *
1067 *
1068 */
1069static void scic_sds_remote_node_context_posting_state_enter(
1070 struct sci_base_object *object)
1071{
1072 struct scic_sds_remote_node_context *this_rnc;
1073
1074 this_rnc = (struct scic_sds_remote_node_context *)object;
1075
1076 SET_STATE_HANDLER(
1077 this_rnc,
1078 scic_sds_remote_node_context_state_handler_table,
1079 SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE
1080 );
1081
1082 scic_sds_remote_node_context_validate_context_buffer(this_rnc);
1083}
1084
1085/**
1086 *
1087 *
1088 *
1089 */
1090static void scic_sds_remote_node_context_invalidating_state_enter(
1091 struct sci_base_object *object)
1092{
1093 struct scic_sds_remote_node_context *rnc;
1094
1095 rnc = (struct scic_sds_remote_node_context *)object;
1096
1097 SET_STATE_HANDLER(
1098 rnc,
1099 scic_sds_remote_node_context_state_handler_table,
1100 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE
1101 );
1102
1103 scic_sds_remote_node_context_invalidate_context_buffer(rnc);
1104}
1105
1106/**
1107 *
1108 *
1109 *
1110 */
1111static void scic_sds_remote_node_context_resuming_state_enter(
1112 struct sci_base_object *object)
1113{
1114 struct scic_sds_remote_node_context *rnc;
1115
1116 rnc = (struct scic_sds_remote_node_context *)object;
1117
1118 SET_STATE_HANDLER(
1119 rnc,
1120 scic_sds_remote_node_context_state_handler_table,
1121 SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE
1122 );
1123
1124 scic_sds_remote_device_post_request(
1125 rnc->device,
1126 SCU_CONTEXT_COMMAND_POST_RNC_RESUME
1127 );
1128}
1129
1130/**
1131 *
1132 *
1133 *
1134 */
1135static void scic_sds_remote_node_context_ready_state_enter(
1136 struct sci_base_object *object)
1137{
1138 struct scic_sds_remote_node_context *rnc;
1139
1140 rnc = (struct scic_sds_remote_node_context *)object;
1141
1142 SET_STATE_HANDLER(
1143 rnc,
1144 scic_sds_remote_node_context_state_handler_table,
1145 SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE
1146 );
1147
1148 rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED;
1149
1150 if (rnc->user_callback != NULL) {
1151 scic_sds_remote_node_context_notify_user(rnc);
1152 }
1153}
1154
1155/**
1156 *
1157 *
1158 *
1159 */
1160static void scic_sds_remote_node_context_tx_suspended_state_enter(
1161 struct sci_base_object *object)
1162{
1163 struct scic_sds_remote_node_context *rnc;
1164
1165 rnc = (struct scic_sds_remote_node_context *)object;
1166
1167 SET_STATE_HANDLER(
1168 rnc,
1169 scic_sds_remote_node_context_state_handler_table,
1170 SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE
1171 );
1172
1173 scic_sds_remote_node_context_continue_state_transitions(rnc);
1174}
1175
1176/**
1177 *
1178 *
1179 *
1180 */
1181static void scic_sds_remote_node_context_tx_rx_suspended_state_enter(
1182 struct sci_base_object *object)
1183{
1184 struct scic_sds_remote_node_context *rnc;
1185
1186 rnc = (struct scic_sds_remote_node_context *)object;
1187
1188 SET_STATE_HANDLER(
1189 rnc,
1190 scic_sds_remote_node_context_state_handler_table,
1191 SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE
1192 );
1193
1194 scic_sds_remote_node_context_continue_state_transitions(rnc);
1195}
1196
1197/**
1198 *
1199 *
1200 *
1201 */
1202static void scic_sds_remote_node_context_await_suspension_state_enter(
1203 struct sci_base_object *object)
1204{
1205 struct scic_sds_remote_node_context *rnc;
1206
1207 rnc = (struct scic_sds_remote_node_context *)object;
1208
1209 SET_STATE_HANDLER(
1210 rnc,
1211 scic_sds_remote_node_context_state_handler_table,
1212 SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE
1213 );
1214}
1215
1216/* --------------------------------------------------------------------------- */
1217
1218const struct sci_base_state scic_sds_remote_node_context_state_table[] = {
1219 [SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE] = {
1220 .enter_state = scic_sds_remote_node_context_initial_state_enter,
1221 },
1222 [SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE] = {
1223 .enter_state = scic_sds_remote_node_context_posting_state_enter,
1224 },
1225 [SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE] = {
1226 .enter_state = scic_sds_remote_node_context_invalidating_state_enter,
1227 },
1228 [SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE] = {
1229 .enter_state = scic_sds_remote_node_context_resuming_state_enter,
1230 },
1231 [SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE] = {
1232 .enter_state = scic_sds_remote_node_context_ready_state_enter,
1233 },
1234 [SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE] = {
1235 .enter_state = scic_sds_remote_node_context_tx_suspended_state_enter,
1236 },
1237 [SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE] = {
1238 .enter_state = scic_sds_remote_node_context_tx_rx_suspended_state_enter,
1239 },
1240 [SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE] = {
1241 .enter_state = scic_sds_remote_node_context_await_suspension_state_enter,
1242 },
1243};
1244
diff --git a/drivers/scsi/isci/core/scic_sds_remote_node_context.h b/drivers/scsi/isci/core/scic_sds_remote_node_context.h
new file mode 100644
index 000000000000..59eacf8f400c
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_remote_node_context.h
@@ -0,0 +1,342 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_SDS_REMOTE_NODE_CONTEXT_H_
57#define _SCIC_SDS_REMOTE_NODE_CONTEXT_H_
58
59/**
60 * This file contains the structures, constants, and prototypes associated with
61 * the remote node context in the silicon. It exists to model and manage
62 * the remote node context in the silicon.
63 *
64 *
65 */
66
67#include "sci_types.h"
68#include "sci_base_state.h"
69#include "sci_base_state_machine.h"
70
71/* --------------------------------------------------------------------------- */
72
73/**
74 *
75 *
76 * This constant represents an invalid remote device id, it is used to program
77 * the STPDARNI register so the driver knows when it has received a SIGNATURE
78 * FIS from the SCU.
79 */
80#define SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX 0x0FFF
81
82#define SCU_HARDWARE_SUSPENSION (0)
83#define SCI_SOFTWARE_SUSPENSION (1)
84
85struct scic_sds_request;
86struct scic_sds_remote_device;
87struct scic_sds_remote_node_context;
88
89typedef void (*SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK)(void *);
90
91typedef enum sci_status (*SCIC_SDS_REMOTE_NODE_CONTEXT_OPERATION)(
92 struct scic_sds_remote_node_context *this_rnc,
93 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback,
94 void *callback_parameter
95 );
96
97typedef enum sci_status (*SCIC_SDS_REMOTE_NODE_CONTEXT_SUSPEND_OPERATION)(
98 struct scic_sds_remote_node_context *this_rnc,
99 u32 suspension_type,
100 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK the_callback,
101 void *callback_parameter
102 );
103
104typedef enum sci_status (*SCIC_SDS_REMOTE_NODE_CONTEXT_IO_REQUEST)(
105 struct scic_sds_remote_node_context *this_rnc,
106 struct scic_sds_request *the_request
107 );
108
109typedef enum sci_status (*SCIC_SDS_REMOTE_NODE_CONTEXT_EVENT_HANDLER)(
110 struct scic_sds_remote_node_context *this_rnc,
111 u32 event_code
112 );
113
114/* --------------------------------------------------------------------------- */
115
116struct scic_sds_remote_node_context_handlers {
117 /**
118 * This handle is invoked to stop the RNC. The callback is invoked when after
119 * the hardware notification that the RNC has been invalidated.
120 */
121 SCIC_SDS_REMOTE_NODE_CONTEXT_OPERATION destruct_handler;
122
123 /**
124 * This handler is invoked when there is a request to suspend the RNC. The
125 * callback is invoked after the hardware notification that the remote node is
126 * suspended.
127 */
128 SCIC_SDS_REMOTE_NODE_CONTEXT_SUSPEND_OPERATION suspend_handler;
129
130 /**
131 * This handler is invoked when there is a request to resume the RNC. The
132 * callback is invoked when after the RNC has reached the ready state.
133 */
134 SCIC_SDS_REMOTE_NODE_CONTEXT_OPERATION resume_handler;
135
136 /**
137 * This handler is invoked when there is a request to start an io request
138 * operation.
139 */
140 SCIC_SDS_REMOTE_NODE_CONTEXT_IO_REQUEST start_io_handler;
141
142 /**
143 * This handler is invoked when there is a request to start a task request
144 * operation.
145 */
146 SCIC_SDS_REMOTE_NODE_CONTEXT_IO_REQUEST start_task_handler;
147
148 /**
149 * This handler is invoked where there is an RNC event that must be processed.
150 */
151 SCIC_SDS_REMOTE_NODE_CONTEXT_EVENT_HANDLER event_handler;
152
153};
154
155/* --------------------------------------------------------------------------- */
156
157/**
158 *
159 *
160 * This is the enumeration of the remote node context states.
161 */
162enum scis_sds_remote_node_context_states {
163 /**
164 * This state is the initial state for a remote node context. On a resume
165 * request the remote node context will transition to the posting state.
166 */
167 SCIC_SDS_REMOTE_NODE_CONTEXT_INITIAL_STATE,
168
169 /**
170 * This is a transition state that posts the RNi to the hardware. Once the RNC
171 * is posted the remote node context will be made ready.
172 */
173 SCIC_SDS_REMOTE_NODE_CONTEXT_POSTING_STATE,
174
175 /**
176 * This is a transition state that will post an RNC invalidate to the
177 * hardware. Once the invalidate is complete the remote node context will
178 * transition to the posting state.
179 */
180 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALIDATING_STATE,
181
182 /**
183 * This is a transition state that will post an RNC resume to the hardare.
184 * Once the event notification of resume complete is received the remote node
185 * context will transition to the ready state.
186 */
187 SCIC_SDS_REMOTE_NODE_CONTEXT_RESUMING_STATE,
188
189 /**
190 * This is the state that the remote node context must be in to accept io
191 * request operations.
192 */
193 SCIC_SDS_REMOTE_NODE_CONTEXT_READY_STATE,
194
195 /**
196 * This is the state that the remote node context transitions to when it gets
197 * a TX suspend notification from the hardware.
198 */
199 SCIC_SDS_REMOTE_NODE_CONTEXT_TX_SUSPENDED_STATE,
200
201 /**
202 * This is the state that the remote node context transitions to when it gets
203 * a TX RX suspend notification from the hardware.
204 */
205 SCIC_SDS_REMOTE_NODE_CONTEXT_TX_RX_SUSPENDED_STATE,
206
207 /**
208 * This state is a wait state for the remote node context that waits for a
209 * suspend notification from the hardware. This state is entered when either
210 * there is a request to supend the remote node context or when there is a TC
211 * completion where the remote node will be suspended by the hardware.
212 */
213 SCIC_SDS_REMOTE_NODE_CONTEXT_AWAIT_SUSPENSION_STATE,
214
215 SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES
216
217};
218
219/**
220 *
221 *
222 * This enumeration is used to define the end destination state for the remote
223 * node context.
224 */
225enum SCIC_SDS_REMOTE_NODE_CONTEXT_DESTINATION_STATE {
226 SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED,
227 SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY,
228 SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL
229};
230
231/**
232 * struct scic_sds_remote_node_context - This structure contains the data
233 * associated with the remote node context object. The remote node context
234 * (RNC) object models the the remote device information necessary to manage
235 * the silicon RNC.
236 *
237 *
238 */
239struct scic_sds_remote_node_context {
240 /*
241 * parent object
242 */
243 struct sci_base_object parent;
244
245 /**
246 * This pointer simply points to the remote device object containing
247 * this RNC.
248 *
249 * @todo Consider making the device pointer the associated object of the
250 * the parent object.
251 */
252 struct scic_sds_remote_device *device;
253
254 /**
255 * This field indicates the remote node index (RNI) associated with
256 * this RNC.
257 */
258 u16 remote_node_index;
259
260 /**
261 * This field is the recored suspension code or the reason for the remote node
262 * context suspension.
263 */
264 u32 suspension_code;
265
266 /**
267 * This field is true if the remote node context is resuming from its current
268 * state. This can cause an automatic resume on receiving a suspension
269 * notification.
270 */
271 enum SCIC_SDS_REMOTE_NODE_CONTEXT_DESTINATION_STATE destination_state;
272
273 /**
274 * This field contains the callback function that the user requested to be
275 * called when the requested state transition is complete.
276 */
277 SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK user_callback;
278
279 /**
280 * This field contains the parameter that is called when the user requested
281 * state transition is completed.
282 */
283 void *user_cookie;
284
285 /**
286 * This field contains the data for the object's state machine.
287 */
288 struct sci_base_state_machine state_machine;
289
290 struct scic_sds_remote_node_context_handlers *state_handlers;
291};
292
293/* --------------------------------------------------------------------------- */
294
295extern const struct sci_base_state scic_sds_remote_node_context_state_table[];
296
297extern struct scic_sds_remote_node_context_handlers
298 scic_sds_remote_node_context_state_handler_table[
299 SCIC_SDS_REMOTE_NODE_CONTEXT_MAX_STATES];
300
301/* --------------------------------------------------------------------------- */
302
303void scic_sds_remote_node_context_construct(
304 struct scic_sds_remote_device *device,
305 struct scic_sds_remote_node_context *rnc,
306 u16 remote_node_index);
307
308void scic_sds_remote_node_context_construct_buffer(
309 struct scic_sds_remote_node_context *rnc);
310
311
312bool scic_sds_remote_node_context_is_ready(
313 struct scic_sds_remote_node_context *this_rnc);
314
315#define scic_sds_remote_node_context_set_remote_node_index(rnc, rni) \
316 ((rnc)->remote_node_index = (rni))
317
318#define scic_sds_remote_node_context_get_remote_node_index(rcn) \
319 ((rnc)->remote_node_index)
320
321#define scic_sds_remote_node_context_event_handler(rnc, event_code) \
322 ((rnc)->state_handlers->event_handler(rnc, event_code))
323
324#define scic_sds_remote_node_context_resume(rnc, callback, parameter) \
325 ((rnc)->state_handlers->resume_handler(rnc, callback, parameter))
326
327#define scic_sds_remote_node_context_suspend(rnc, suspend_type, callback, parameter) \
328 ((rnc)->state_handlers->suspend_handler(rnc, suspend_type, callback, parameter))
329
330#define scic_sds_remote_node_context_destruct(rnc, callback, parameter) \
331 ((rnc)->state_handlers->destruct_handler(rnc, callback, parameter))
332
333#define scic_sds_remote_node_context_start_io(rnc, request) \
334 ((rnc)->state_handlers->start_io_handler(rnc, request))
335
336#define scic_sds_remote_node_context_start_task(rnc, task) \
337 ((rnc)->state_handlers->start_task_handler(rnc, task))
338
339/* --------------------------------------------------------------------------- */
340
341#endif /* _SCIC_SDS_REMOTE_NODE_CONTEXT_H_ */
342
diff --git a/drivers/scsi/isci/core/scic_sds_remote_node_table.c b/drivers/scsi/isci/core/scic_sds_remote_node_table.c
new file mode 100644
index 000000000000..77919a2cf652
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_remote_node_table.c
@@ -0,0 +1,600 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file contains the implementation of the SCIC_SDS_REMOTE_NODE_TABLE
58 * public, protected, and private methods.
59 *
60 *
61 */
62#include "sci_util.h"
63#include "sci_environment.h"
64#include "scic_sds_remote_node_table.h"
65#include "scic_sds_remote_node_context.h"
66
67/**
68 *
69 * @remote_node_table: This is the remote node index table from which the
70 * selection will be made.
71 * @group_table_index: This is the index to the group table from which to
72 * search for an available selection.
73 *
74 * This routine will find the bit position in absolute bit terms of the next 32
75 * + bit position. If there are available bits in the first u32 then it is
76 * just bit position. u32 This is the absolute bit position for an available
77 * group.
78 */
79static u32 scic_sds_remote_node_table_get_group_index(
80 struct scic_remote_node_table *remote_node_table,
81 u32 group_table_index)
82{
83 u32 dword_index;
84 u32 *group_table;
85 u32 bit_index;
86
87 group_table = remote_node_table->remote_node_groups[group_table_index];
88
89 for (dword_index = 0; dword_index < remote_node_table->group_array_size; dword_index++) {
90 if (group_table[dword_index] != 0) {
91 for (bit_index = 0; bit_index < 32; bit_index++) {
92 if ((group_table[dword_index] & (1 << bit_index)) != 0) {
93 return (dword_index * 32) + bit_index;
94 }
95 }
96 }
97 }
98
99 return SCIC_SDS_REMOTE_NODE_TABLE_INVALID_INDEX;
100}
101
102/**
103 *
104 * @out]: remote_node_table This the remote node table in which to clear the
105 * selector.
106 * @set_index: This is the remote node selector in which the change will be
107 * made.
108 * @group_index: This is the bit index in the table to be modified.
109 *
110 * This method will clear the group index entry in the specified group index
111 * table. none
112 */
113static void scic_sds_remote_node_table_clear_group_index(
114 struct scic_remote_node_table *remote_node_table,
115 u32 group_table_index,
116 u32 group_index)
117{
118 u32 dword_index;
119 u32 bit_index;
120 u32 *group_table;
121
122 BUG_ON(group_table_index >= SCU_STP_REMOTE_NODE_COUNT);
123 BUG_ON(group_index >= (u32)(remote_node_table->group_array_size * 32));
124
125 dword_index = group_index / 32;
126 bit_index = group_index % 32;
127 group_table = remote_node_table->remote_node_groups[group_table_index];
128
129 group_table[dword_index] = group_table[dword_index] & ~(1 << bit_index);
130}
131
132/**
133 *
134 * @out]: remote_node_table This the remote node table in which to set the
135 * selector.
136 * @group_table_index: This is the remote node selector in which the change
137 * will be made.
138 * @group_index: This is the bit position in the table to be modified.
139 *
140 * This method will set the group index bit entry in the specified gropu index
141 * table. none
142 */
143static void scic_sds_remote_node_table_set_group_index(
144 struct scic_remote_node_table *remote_node_table,
145 u32 group_table_index,
146 u32 group_index)
147{
148 u32 dword_index;
149 u32 bit_index;
150 u32 *group_table;
151
152 BUG_ON(group_table_index >= SCU_STP_REMOTE_NODE_COUNT);
153 BUG_ON(group_index >= (u32)(remote_node_table->group_array_size * 32));
154
155 dword_index = group_index / 32;
156 bit_index = group_index % 32;
157 group_table = remote_node_table->remote_node_groups[group_table_index];
158
159 group_table[dword_index] = group_table[dword_index] | (1 << bit_index);
160}
161
162/**
163 *
164 * @out]: remote_node_table This is the remote node table in which to modify
165 * the remote node availability.
166 * @remote_node_index: This is the remote node index that is being returned to
167 * the table.
168 *
169 * This method will set the remote to available in the remote node allocation
170 * table. none
171 */
172static void scic_sds_remote_node_table_set_node_index(
173 struct scic_remote_node_table *remote_node_table,
174 u32 remote_node_index)
175{
176 u32 dword_location;
177 u32 dword_remainder;
178 u32 slot_normalized;
179 u32 slot_position;
180
181 BUG_ON(
182 (remote_node_table->available_nodes_array_size * SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD)
183 <= (remote_node_index / SCU_STP_REMOTE_NODE_COUNT)
184 );
185
186 dword_location = remote_node_index / SCIC_SDS_REMOTE_NODES_PER_DWORD;
187 dword_remainder = remote_node_index % SCIC_SDS_REMOTE_NODES_PER_DWORD;
188 slot_normalized = (dword_remainder / SCU_STP_REMOTE_NODE_COUNT) * sizeof(u32);
189 slot_position = remote_node_index % SCU_STP_REMOTE_NODE_COUNT;
190
191 remote_node_table->available_remote_nodes[dword_location] |=
192 1 << (slot_normalized + slot_position);
193}
194
195/**
196 *
197 * @out]: remote_node_table This is the remote node table from which to clear
198 * the available remote node bit.
199 * @remote_node_index: This is the remote node index which is to be cleared
200 * from the table.
201 *
202 * This method clears the remote node index from the table of available remote
203 * nodes. none
204 */
205static void scic_sds_remote_node_table_clear_node_index(
206 struct scic_remote_node_table *remote_node_table,
207 u32 remote_node_index)
208{
209 u32 dword_location;
210 u32 dword_remainder;
211 u32 slot_position;
212 u32 slot_normalized;
213
214 BUG_ON(
215 (remote_node_table->available_nodes_array_size * SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD)
216 <= (remote_node_index / SCU_STP_REMOTE_NODE_COUNT)
217 );
218
219 dword_location = remote_node_index / SCIC_SDS_REMOTE_NODES_PER_DWORD;
220 dword_remainder = remote_node_index % SCIC_SDS_REMOTE_NODES_PER_DWORD;
221 slot_normalized = (dword_remainder / SCU_STP_REMOTE_NODE_COUNT) * sizeof(u32);
222 slot_position = remote_node_index % SCU_STP_REMOTE_NODE_COUNT;
223
224 remote_node_table->available_remote_nodes[dword_location] &=
225 ~(1 << (slot_normalized + slot_position));
226}
227
228/**
229 *
230 * @out]: remote_node_table The remote node table from which the slot will be
231 * cleared.
232 * @group_index: The index for the slot that is to be cleared.
233 *
234 * This method clears the entire table slot at the specified slot index. none
235 */
236static void scic_sds_remote_node_table_clear_group(
237 struct scic_remote_node_table *remote_node_table,
238 u32 group_index)
239{
240 u32 dword_location;
241 u32 dword_remainder;
242 u32 dword_value;
243
244 BUG_ON(
245 (remote_node_table->available_nodes_array_size * SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD)
246 <= (group_index / SCU_STP_REMOTE_NODE_COUNT)
247 );
248
249 dword_location = group_index / SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
250 dword_remainder = group_index % SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
251
252 dword_value = remote_node_table->available_remote_nodes[dword_location];
253 dword_value &= ~(SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE << (dword_remainder * 4));
254 remote_node_table->available_remote_nodes[dword_location] = dword_value;
255}
256
257/**
258 *
259 * @remote_node_table:
260 *
261 * THis method sets an entire remote node group in the remote node table.
262 */
263static void scic_sds_remote_node_table_set_group(
264 struct scic_remote_node_table *remote_node_table,
265 u32 group_index)
266{
267 u32 dword_location;
268 u32 dword_remainder;
269 u32 dword_value;
270
271 BUG_ON(
272 (remote_node_table->available_nodes_array_size * SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD)
273 <= (group_index / SCU_STP_REMOTE_NODE_COUNT)
274 );
275
276 dword_location = group_index / SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
277 dword_remainder = group_index % SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
278
279 dword_value = remote_node_table->available_remote_nodes[dword_location];
280 dword_value |= (SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE << (dword_remainder * 4));
281 remote_node_table->available_remote_nodes[dword_location] = dword_value;
282}
283
284/**
285 *
286 * @remote_node_table: This is the remote node table that for which the group
287 * value is to be returned.
288 * @group_index: This is the group index to use to find the group value.
289 *
290 * This method will return the group value for the specified group index. The
291 * bit values at the specified remote node group index.
292 */
293static u8 scic_sds_remote_node_table_get_group_value(
294 struct scic_remote_node_table *remote_node_table,
295 u32 group_index)
296{
297 u32 dword_location;
298 u32 dword_remainder;
299 u32 dword_value;
300
301 dword_location = group_index / SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
302 dword_remainder = group_index % SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
303
304 dword_value = remote_node_table->available_remote_nodes[dword_location];
305 dword_value &= (SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE << (dword_remainder * 4));
306 dword_value = dword_value >> (dword_remainder * 4);
307
308 return (u8)dword_value;
309}
310
311/**
312 *
313 * @out]: remote_node_table The remote that which is to be initialized.
314 * @remote_node_entries: The number of entries to put in the table.
315 *
316 * This method will initialize the remote node table for use. none
317 */
318void scic_sds_remote_node_table_initialize(
319 struct scic_remote_node_table *remote_node_table,
320 u32 remote_node_entries)
321{
322 u32 index;
323
324 /*
325 * Initialize the raw data we could improve the speed by only initializing
326 * those entries that we are actually going to be used */
327 memset(
328 remote_node_table->available_remote_nodes,
329 0x00,
330 sizeof(remote_node_table->available_remote_nodes)
331 );
332
333 memset(
334 remote_node_table->remote_node_groups,
335 0x00,
336 sizeof(remote_node_table->remote_node_groups)
337 );
338
339 /* Initialize the available remote node sets */
340 remote_node_table->available_nodes_array_size = (u16)
341 (remote_node_entries / SCIC_SDS_REMOTE_NODES_PER_DWORD)
342 + ((remote_node_entries % SCIC_SDS_REMOTE_NODES_PER_DWORD) != 0);
343
344
345 /* Initialize each full DWORD to a FULL SET of remote nodes */
346 for (index = 0; index < remote_node_entries; index++) {
347 scic_sds_remote_node_table_set_node_index(remote_node_table, index);
348 }
349
350 remote_node_table->group_array_size = (u16)
351 (remote_node_entries / (SCU_STP_REMOTE_NODE_COUNT * 32))
352 + ((remote_node_entries % (SCU_STP_REMOTE_NODE_COUNT * 32)) != 0);
353
354 for (index = 0; index < (remote_node_entries / SCU_STP_REMOTE_NODE_COUNT); index++) {
355 /*
356 * These are all guaranteed to be full slot values so fill them in the
357 * available sets of 3 remote nodes */
358 scic_sds_remote_node_table_set_group_index(remote_node_table, 2, index);
359 }
360
361 /* Now fill in any remainders that we may find */
362 if ((remote_node_entries % SCU_STP_REMOTE_NODE_COUNT) == 2) {
363 scic_sds_remote_node_table_set_group_index(remote_node_table, 1, index);
364 } else if ((remote_node_entries % SCU_STP_REMOTE_NODE_COUNT) == 1) {
365 scic_sds_remote_node_table_set_group_index(remote_node_table, 0, index);
366 }
367}
368
369/**
370 *
371 * @out]: remote_node_table The remote node table from which to allocate a
372 * remote node.
373 * @table_index: The group index that is to be used for the search.
374 *
375 * This method will allocate a single RNi from the remote node table. The
376 * table index will determine from which remote node group table to search.
377 * This search may fail and another group node table can be specified. The
378 * function is designed to allow a serach of the available single remote node
379 * group up to the triple remote node group. If an entry is found in the
380 * specified table the remote node is removed and the remote node groups are
381 * updated. The RNi value or an invalid remote node context if an RNi can not
382 * be found.
383 */
384static u16 scic_sds_remote_node_table_allocate_single_remote_node(
385 struct scic_remote_node_table *remote_node_table,
386 u32 group_table_index)
387{
388 u8 index;
389 u8 group_value;
390 u32 group_index;
391 u16 remote_node_index = SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX;
392
393 group_index = scic_sds_remote_node_table_get_group_index(
394 remote_node_table, group_table_index);
395
396 /* We could not find an available slot in the table selector 0 */
397 if (group_index != SCIC_SDS_REMOTE_NODE_TABLE_INVALID_INDEX) {
398 group_value = scic_sds_remote_node_table_get_group_value(
399 remote_node_table, group_index);
400
401 for (index = 0; index < SCU_STP_REMOTE_NODE_COUNT; index++) {
402 if (((1 << index) & group_value) != 0) {
403 /* We have selected a bit now clear it */
404 remote_node_index = (u16)(group_index * SCU_STP_REMOTE_NODE_COUNT
405 + index);
406
407 scic_sds_remote_node_table_clear_group_index(
408 remote_node_table, group_table_index, group_index
409 );
410
411 scic_sds_remote_node_table_clear_node_index(
412 remote_node_table, remote_node_index
413 );
414
415 if (group_table_index > 0) {
416 scic_sds_remote_node_table_set_group_index(
417 remote_node_table, group_table_index - 1, group_index
418 );
419 }
420
421 break;
422 }
423 }
424 }
425
426 return remote_node_index;
427}
428
429/**
430 *
431 * @remote_node_table: This is the remote node table from which to allocate the
432 * remote node entries.
433 * @group_table_index: THis is the group table index which must equal two (2)
434 * for this operation.
435 *
436 * This method will allocate three consecutive remote node context entries. If
437 * there are no remaining triple entries the function will return a failure.
438 * The remote node index that represents three consecutive remote node entries
439 * or an invalid remote node context if none can be found.
440 */
441static u16 scic_sds_remote_node_table_allocate_triple_remote_node(
442 struct scic_remote_node_table *remote_node_table,
443 u32 group_table_index)
444{
445 u32 group_index;
446 u16 remote_node_index = SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX;
447
448 group_index = scic_sds_remote_node_table_get_group_index(
449 remote_node_table, group_table_index);
450
451 if (group_index != SCIC_SDS_REMOTE_NODE_TABLE_INVALID_INDEX) {
452 remote_node_index = (u16)group_index * SCU_STP_REMOTE_NODE_COUNT;
453
454 scic_sds_remote_node_table_clear_group_index(
455 remote_node_table, group_table_index, group_index
456 );
457
458 scic_sds_remote_node_table_clear_group(
459 remote_node_table, group_index
460 );
461 }
462
463 return remote_node_index;
464}
465
466/**
467 *
468 * @remote_node_table: This is the remote node table from which the remote node
469 * allocation is to take place.
470 * @remote_node_count: This is ther remote node count which is one of
471 * SCU_SSP_REMOTE_NODE_COUNT(1) or SCU_STP_REMOTE_NODE_COUNT(3).
472 *
473 * This method will allocate a remote node that mataches the remote node count
474 * specified by the caller. Valid values for remote node count is
475 * SCU_SSP_REMOTE_NODE_COUNT(1) or SCU_STP_REMOTE_NODE_COUNT(3). u16 This is
476 * the remote node index that is returned or an invalid remote node context.
477 */
478u16 scic_sds_remote_node_table_allocate_remote_node(
479 struct scic_remote_node_table *remote_node_table,
480 u32 remote_node_count)
481{
482 u16 remote_node_index = SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX;
483
484 if (remote_node_count == SCU_SSP_REMOTE_NODE_COUNT) {
485 remote_node_index =
486 scic_sds_remote_node_table_allocate_single_remote_node(
487 remote_node_table, 0);
488
489 if (remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) {
490 remote_node_index =
491 scic_sds_remote_node_table_allocate_single_remote_node(
492 remote_node_table, 1);
493 }
494
495 if (remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) {
496 remote_node_index =
497 scic_sds_remote_node_table_allocate_single_remote_node(
498 remote_node_table, 2);
499 }
500 } else if (remote_node_count == SCU_STP_REMOTE_NODE_COUNT) {
501 remote_node_index =
502 scic_sds_remote_node_table_allocate_triple_remote_node(
503 remote_node_table, 2);
504 }
505
506 return remote_node_index;
507}
508
509/**
510 *
511 * @remote_node_table:
512 *
513 * This method will free a single remote node index back to the remote node
514 * table. This routine will update the remote node groups
515 */
516static void scic_sds_remote_node_table_release_single_remote_node(
517 struct scic_remote_node_table *remote_node_table,
518 u16 remote_node_index)
519{
520 u32 group_index;
521 u8 group_value;
522
523 group_index = remote_node_index / SCU_STP_REMOTE_NODE_COUNT;
524
525 group_value = scic_sds_remote_node_table_get_group_value(remote_node_table, group_index);
526
527 /*
528 * Assert that we are not trying to add an entry to a slot that is already
529 * full. */
530 BUG_ON(group_value == SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE);
531
532 if (group_value == 0x00) {
533 /*
534 * There are no entries in this slot so it must be added to the single
535 * slot table. */
536 scic_sds_remote_node_table_set_group_index(remote_node_table, 0, group_index);
537 } else if ((group_value & (group_value - 1)) == 0) {
538 /*
539 * There is only one entry in this slot so it must be moved from the
540 * single slot table to the dual slot table */
541 scic_sds_remote_node_table_clear_group_index(remote_node_table, 0, group_index);
542 scic_sds_remote_node_table_set_group_index(remote_node_table, 1, group_index);
543 } else {
544 /*
545 * There are two entries in the slot so it must be moved from the dual
546 * slot table to the tripple slot table. */
547 scic_sds_remote_node_table_clear_group_index(remote_node_table, 1, group_index);
548 scic_sds_remote_node_table_set_group_index(remote_node_table, 2, group_index);
549 }
550
551 scic_sds_remote_node_table_set_node_index(remote_node_table, remote_node_index);
552}
553
554/**
555 *
556 * @remote_node_table: This is the remote node table to which the remote node
557 * index is to be freed.
558 *
559 * This method will release a group of three consecutive remote nodes back to
560 * the free remote nodes.
561 */
562static void scic_sds_remote_node_table_release_triple_remote_node(
563 struct scic_remote_node_table *remote_node_table,
564 u16 remote_node_index)
565{
566 u32 group_index;
567
568 group_index = remote_node_index / SCU_STP_REMOTE_NODE_COUNT;
569
570 scic_sds_remote_node_table_set_group_index(
571 remote_node_table, 2, group_index
572 );
573
574 scic_sds_remote_node_table_set_group(remote_node_table, group_index);
575}
576
577/**
578 *
579 * @remote_node_table: The remote node table to which the remote node index is
580 * to be freed.
581 * @remote_node_count: This is the count of consecutive remote nodes that are
582 * to be freed.
583 *
584 * This method will release the remote node index back into the remote node
585 * table free pool.
586 */
587void scic_sds_remote_node_table_release_remote_node_index(
588 struct scic_remote_node_table *remote_node_table,
589 u32 remote_node_count,
590 u16 remote_node_index)
591{
592 if (remote_node_count == SCU_SSP_REMOTE_NODE_COUNT) {
593 scic_sds_remote_node_table_release_single_remote_node(
594 remote_node_table, remote_node_index);
595 } else if (remote_node_count == SCU_STP_REMOTE_NODE_COUNT) {
596 scic_sds_remote_node_table_release_triple_remote_node(
597 remote_node_table, remote_node_index);
598 }
599}
600
diff --git a/drivers/scsi/isci/core/scic_sds_remote_node_table.h b/drivers/scsi/isci/core/scic_sds_remote_node_table.h
new file mode 100644
index 000000000000..6ee5fbab25dd
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_remote_node_table.h
@@ -0,0 +1,196 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_SDS_REMOTE_NODE_TABLE_H_
57#define _SCIC_SDS_REMOTE_NODE_TABLE_H_
58
59/**
60 * This file contains the structures, constants and prototypes used for the
61 * remote node table.
62 *
63 *
64 */
65
66#include "sci_types.h"
67#include "sci_controller_constants.h"
68
69/**
70 *
71 *
72 * Remote node sets are sets of remote node index in the remtoe node table The
73 * SCU hardware requires that STP remote node entries take three consecutive
74 * remote node index so the table is arranged in sets of three. The bits are
75 * used as 0111 0111 to make a byte and the bits define the set of three remote
76 * nodes to use as a sequence.
77 */
78#define SCIC_SDS_REMOTE_NODE_SETS_PER_BYTE 2
79
80/**
81 *
82 *
83 * Since the remote node table is organized as DWORDS take the remote node sets
84 * in bytes and represent them in DWORDs. The lowest ordered bits are the ones
85 * used in case full DWORD is not being used. i.e. 0000 0000 0000 0000 0111
86 * 0111 0111 0111 // if only a single WORD is in use in the DWORD.
87 */
88#define SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD \
89 (sizeof(u32) * SCIC_SDS_REMOTE_NODE_SETS_PER_BYTE)
90/**
91 *
92 *
93 * This is a count of the numeber of remote nodes that can be represented in a
94 * byte
95 */
96#define SCIC_SDS_REMOTE_NODES_PER_BYTE \
97 (SCU_STP_REMOTE_NODE_COUNT * SCIC_SDS_REMOTE_NODE_SETS_PER_BYTE)
98
99/**
100 *
101 *
102 * This is a count of the number of remote nodes that can be represented in a
103 * DWROD
104 */
105#define SCIC_SDS_REMOTE_NODES_PER_DWORD \
106 (sizeof(u32) * SCIC_SDS_REMOTE_NODES_PER_BYTE)
107
108/**
109 *
110 *
111 * This is the number of bits in a remote node group
112 */
113#define SCIC_SDS_REMOTE_NODES_BITS_PER_GROUP 4
114
115#define SCIC_SDS_REMOTE_NODE_TABLE_INVALID_INDEX (0xFFFFFFFF)
116#define SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE (0x07)
117#define SCIC_SDS_REMOTE_NODE_TABLE_EMPTY_SLOT_VALUE (0x00)
118
119/**
120 *
121 *
122 * Expander attached sata remote node count
123 */
124#define SCU_STP_REMOTE_NODE_COUNT 3
125
126/**
127 *
128 *
129 * Expander or direct attached ssp remote node count
130 */
131#define SCU_SSP_REMOTE_NODE_COUNT 1
132
133/**
134 *
135 *
136 * Direct attached STP remote node count
137 */
138#define SCU_SATA_REMOTE_NODE_COUNT 1
139
140/**
141 * struct scic_remote_node_table -
142 *
143 *
144 */
145struct scic_remote_node_table {
146 /**
147 * This field contains the array size in dwords
148 */
149 u16 available_nodes_array_size;
150
151 /**
152 * This field contains the array size of the
153 */
154 u16 group_array_size;
155
156 /**
157 * This field is the array of available remote node entries in bits.
158 * Because of the way STP remote node data is allocated on the SCU hardware
159 * the remote nodes must occupy three consecutive remote node context
160 * entries. For ease of allocation and de-allocation we have broken the
161 * sets of three into a single nibble. When the STP RNi is allocated all
162 * of the bits in the nibble are cleared. This math results in a table size
163 * of MAX_REMOTE_NODES / CONSECUTIVE RNi ENTRIES for STP / 2 entries per byte.
164 */
165 u32 available_remote_nodes[
166 (SCI_MAX_REMOTE_DEVICES / SCIC_SDS_REMOTE_NODES_PER_DWORD)
167 + ((SCI_MAX_REMOTE_DEVICES % SCIC_SDS_REMOTE_NODES_PER_DWORD) != 0)];
168
169 /**
170 * This field is the nibble selector for the above table. There are three
171 * possible selectors each for fast lookup when trying to find one, two or
172 * three remote node entries.
173 */
174 u32 remote_node_groups[
175 SCU_STP_REMOTE_NODE_COUNT][
176 (SCI_MAX_REMOTE_DEVICES / (32 * SCU_STP_REMOTE_NODE_COUNT))
177 + ((SCI_MAX_REMOTE_DEVICES % (32 * SCU_STP_REMOTE_NODE_COUNT)) != 0)];
178
179};
180
181/* --------------------------------------------------------------------------- */
182
183void scic_sds_remote_node_table_initialize(
184 struct scic_remote_node_table *remote_node_table,
185 u32 remote_node_entries);
186
187u16 scic_sds_remote_node_table_allocate_remote_node(
188 struct scic_remote_node_table *remote_node_table,
189 u32 remote_node_count);
190
191void scic_sds_remote_node_table_release_remote_node_index(
192 struct scic_remote_node_table *remote_node_table,
193 u32 remote_node_count,
194 u16 remote_node_index);
195
196#endif /* _SCIC_SDS_REMOTE_NODE_TABLE_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_request.c b/drivers/scsi/isci/core/scic_sds_request.c
new file mode 100644
index 000000000000..c696d246ea5a
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_request.c
@@ -0,0 +1,2179 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56
57#include "intel_sas.h"
58#include "intel_sata.h"
59#include "intel_sat.h"
60#include "sci_base_request.h"
61#include "scic_controller.h"
62#include "scic_io_request.h"
63#include "scic_remote_device.h"
64#include "scic_sds_controller.h"
65#include "scic_sds_controller_registers.h"
66#include "scic_sds_pci.h"
67#include "scic_sds_port.h"
68#include "scic_sds_remote_device.h"
69#include "scic_sds_request.h"
70#include "scic_sds_smp_request.h"
71#include "scic_sds_stp_request.h"
72#include "scic_sds_unsolicited_frame_control.h"
73#include "scic_user_callback.h"
74#include "sci_environment.h"
75#include "sci_types.h"
76#include "sci_util.h"
77#include "scu_completion_codes.h"
78#include "scu_constants.h"
79#include "scu_task_context.h"
80
81#if !defined(DISABLE_ATAPI)
82#include "scic_sds_stp_packet_request.h"
83#endif
84
85/*
86 * ****************************************************************************
87 * * SCIC SDS IO REQUEST CONSTANTS
88 * **************************************************************************** */
89
90/**
91 *
92 *
93 * We have no timer requirements for IO requests right now
94 */
95#define SCIC_SDS_IO_REQUEST_MINIMUM_TIMER_COUNT (0)
96#define SCIC_SDS_IO_REQUEST_MAXIMUM_TIMER_COUNT (0)
97
98/*
99 * ****************************************************************************
100 * * SCIC SDS IO REQUEST MACROS
101 * **************************************************************************** */
102
103/**
104 * scic_sds_request_get_user_request() -
105 *
106 * This is a helper macro to return the os handle for this request object.
107 */
108#define scic_sds_request_get_user_request(request) \
109 ((request)->user_request)
110
111
112/**
113 * scic_ssp_io_request_get_object_size() -
114 *
115 * This macro returns the sizeof memory required to store the an SSP IO
116 * request. This does not include the size of the SGL or SCU Task Context
117 * memory.
118 */
119#define scic_ssp_io_request_get_object_size() \
120 (\
121 sizeof(struct sci_ssp_command_iu) \
122 + sizeof(struct sci_ssp_response_iu) \
123 )
124
125/**
126 * scic_sds_ssp_request_get_command_buffer() -
127 *
128 * This macro returns the address of the ssp command buffer in the io request
129 * memory
130 */
131#define scic_sds_ssp_request_get_command_buffer(memory) \
132 ((struct sci_ssp_command_iu *)(\
133 ((char *)(memory)) + sizeof(struct scic_sds_request) \
134 ))
135
136/**
137 * scic_sds_ssp_request_get_response_buffer() -
138 *
139 * This macro returns the address of the ssp response buffer in the io request
140 * memory
141 */
142#define scic_sds_ssp_request_get_response_buffer(memory) \
143 ((struct sci_ssp_response_iu *)(\
144 ((char *)(scic_sds_ssp_request_get_command_buffer(memory))) \
145 + sizeof(struct sci_ssp_command_iu) \
146 ))
147
148/**
149 * scic_sds_ssp_request_get_task_context_buffer() -
150 *
151 * This macro returns the address of the task context buffer in the io request
152 * memory
153 */
154#define scic_sds_ssp_request_get_task_context_buffer(memory) \
155 ((struct scu_task_context *)(\
156 ((char *)(scic_sds_ssp_request_get_response_buffer(memory))) \
157 + sizeof(struct sci_ssp_response_iu) \
158 ))
159
160/**
161 * scic_sds_ssp_request_get_sgl_element_buffer() -
162 *
163 * This macro returns the address of the sgl elment pairs in the io request
164 * memory buffer
165 */
166#define scic_sds_ssp_request_get_sgl_element_buffer(memory) \
167 ((struct scu_sgl_element_pair *)(\
168 ((char *)(scic_sds_ssp_request_get_task_context_buffer(memory))) \
169 + sizeof(struct scu_task_context) \
170 ))
171
172
173/**
174 * scic_ssp_task_request_get_object_size() -
175 *
176 * This macro returns the sizeof of memory required to store an SSP Task
177 * request. This does not include the size of the SCU Task Context memory.
178 */
179#define scic_ssp_task_request_get_object_size() \
180 (\
181 sizeof(struct sci_ssp_task_iu) \
182 + sizeof(struct sci_ssp_response_iu) \
183 )
184
185/**
186 * scic_sds_ssp_task_request_get_command_buffer() -
187 *
188 * This macro returns the address of the ssp command buffer in the task request
189 * memory. Yes its the same as the above macro except for the name.
190 */
191#define scic_sds_ssp_task_request_get_command_buffer(memory) \
192 ((struct sci_ssp_task_iu *)(\
193 ((char *)(memory)) + sizeof(struct scic_sds_request) \
194 ))
195
196/**
197 * scic_sds_ssp_task_request_get_response_buffer() -
198 *
199 * This macro returns the address of the ssp response buffer in the task
200 * request memory.
201 */
202#define scic_sds_ssp_task_request_get_response_buffer(memory) \
203 ((struct sci_ssp_response_iu *)(\
204 ((char *)(scic_sds_ssp_task_request_get_command_buffer(memory))) \
205 + sizeof(struct sci_ssp_task_iu) \
206 ))
207
208/**
209 * scic_sds_ssp_task_request_get_task_context_buffer() -
210 *
211 * This macro returs the task context buffer for the SSP task request.
212 */
213#define scic_sds_ssp_task_request_get_task_context_buffer(memory) \
214 ((struct scu_task_context *)(\
215 ((char *)(scic_sds_ssp_task_request_get_response_buffer(memory))) \
216 + sizeof(struct sci_ssp_response_iu) \
217 ))
218
219
220
221/*
222 * ****************************************************************************
223 * * SCIC SDS IO REQUEST PRIVATE METHODS
224 * **************************************************************************** */
225
226/**
227 *
228 *
229 * This method returns the size required to store an SSP IO request object. u32
230 */
231static u32 scic_sds_ssp_request_get_object_size(void)
232{
233 return sizeof(struct scic_sds_request)
234 + scic_ssp_io_request_get_object_size()
235 + sizeof(struct scu_task_context)
236 + CACHE_LINE_SIZE
237 + sizeof(struct scu_sgl_element_pair) * SCU_MAX_SGL_ELEMENT_PAIRS;
238}
239
240/**
241 * This method returns the sgl element pair for the specificed sgl_pair index.
242 * @this_request: This parameter specifies the IO request for which to retrieve
243 * the Scatter-Gather List element pair.
244 * @sgl_pair_index: This parameter specifies the index into the SGL element
245 * pair to be retrieved.
246 *
247 * This method returns a pointer to an struct scu_sgl_element_pair.
248 */
249static struct scu_sgl_element_pair *scic_sds_request_get_sgl_element_pair(
250 struct scic_sds_request *this_request,
251 u32 sgl_pair_index
252 ) {
253 struct scu_task_context *task_context;
254
255 task_context = (struct scu_task_context *)this_request->task_context_buffer;
256
257 if (sgl_pair_index == 0) {
258 return &task_context->sgl_pair_ab;
259 } else if (sgl_pair_index == 1) {
260 return &task_context->sgl_pair_cd;
261 }
262
263 return &this_request->sgl_element_pair_buffer[sgl_pair_index - 2];
264}
265
266/**
267 * This function will build the SGL list for an IO request.
268 * @this_request: This parameter specifies the IO request for which to build
269 * the Scatter-Gather List.
270 *
271 */
272void scic_sds_request_build_sgl(
273 struct scic_sds_request *this_request)
274{
275 void *os_sge;
276 void *os_handle;
277 dma_addr_t physical_address;
278 u32 sgl_pair_index = 0;
279 struct scu_sgl_element_pair *scu_sgl_list = NULL;
280 struct scu_sgl_element_pair *previous_pair = NULL;
281
282 os_handle = scic_sds_request_get_user_request(this_request);
283 scic_cb_io_request_get_next_sge(os_handle, NULL, &os_sge);
284
285 while (os_sge != NULL) {
286 scu_sgl_list =
287 scic_sds_request_get_sgl_element_pair(this_request, sgl_pair_index);
288
289 SCU_SGL_COPY(os_handle, scu_sgl_list->A, os_sge);
290
291 scic_cb_io_request_get_next_sge(os_handle, os_sge, &os_sge);
292
293 if (os_sge != NULL) {
294 SCU_SGL_COPY(os_handle, scu_sgl_list->B, os_sge);
295
296 scic_cb_io_request_get_next_sge(os_handle, os_sge, &os_sge);
297 } else {
298 SCU_SGL_ZERO(scu_sgl_list->B);
299 }
300
301 if (previous_pair != NULL) {
302 scic_cb_io_request_get_physical_address(
303 scic_sds_request_get_controller(this_request),
304 this_request,
305 scu_sgl_list,
306 &physical_address
307 );
308
309 previous_pair->next_pair_upper =
310 upper_32_bits(physical_address);
311 previous_pair->next_pair_lower =
312 lower_32_bits(physical_address);
313 }
314
315 previous_pair = scu_sgl_list;
316 sgl_pair_index++;
317 }
318
319 if (scu_sgl_list != NULL) {
320 scu_sgl_list->next_pair_upper = 0;
321 scu_sgl_list->next_pair_lower = 0;
322 }
323}
324
325/**
326 * This method initializes common portions of the io request object. This
327 * includes construction of the struct sci_base_request parent.
328 * @the_controller: This parameter specifies the controller for which the
329 * request is being constructed.
330 * @the_target: This parameter specifies the remote device for which the
331 * request is being constructed.
332 * @io_tag: This parameter specifies the IO tag to be utilized for this
333 * request. This parameter can be set to SCI_CONTROLLER_INVALID_IO_TAG.
334 * @user_io_request_object: This parameter specifies the user request object
335 * for which the request is being constructed.
336 * @this_request: This parameter specifies the request being constructed.
337 *
338 */
339static void scic_sds_general_request_construct(
340 struct scic_sds_controller *the_controller,
341 struct scic_sds_remote_device *the_target,
342 u16 io_tag,
343 void *user_io_request_object,
344 struct scic_sds_request *this_request)
345{
346 sci_base_request_construct(
347 &this_request->parent,
348 scic_sds_request_state_table
349 );
350
351 this_request->io_tag = io_tag;
352 this_request->user_request = user_io_request_object;
353 this_request->owning_controller = the_controller;
354 this_request->target_device = the_target;
355 this_request->has_started_substate_machine = false;
356 this_request->protocol = SCIC_NO_PROTOCOL;
357 this_request->saved_rx_frame_index = SCU_INVALID_FRAME_INDEX;
358 this_request->device_sequence = scic_sds_remote_device_get_sequence(the_target);
359
360 this_request->sci_status = SCI_SUCCESS;
361 this_request->scu_status = 0;
362 this_request->post_context = 0xFFFFFFFF;
363
364 this_request->is_task_management_request = false;
365
366 if (io_tag == SCI_CONTROLLER_INVALID_IO_TAG) {
367 this_request->was_tag_assigned_by_user = false;
368 this_request->task_context_buffer = NULL;
369 } else {
370 this_request->was_tag_assigned_by_user = true;
371
372 this_request->task_context_buffer =
373 scic_sds_controller_get_task_context_buffer(
374 this_request->owning_controller, io_tag);
375 }
376}
377
378/**
379 * This method build the remainder of the IO request object.
380 * @this_request: This parameter specifies the request object being constructed.
381 *
382 * The scic_sds_general_request_construct() must be called before this call is
383 * valid. none
384 */
385static void scic_sds_ssp_io_request_assign_buffers(
386 struct scic_sds_request *this_request)
387{
388 this_request->command_buffer =
389 scic_sds_ssp_request_get_command_buffer(this_request);
390 this_request->response_buffer =
391 scic_sds_ssp_request_get_response_buffer(this_request);
392 this_request->sgl_element_pair_buffer =
393 scic_sds_ssp_request_get_sgl_element_buffer(this_request);
394 this_request->sgl_element_pair_buffer =
395 scic_sds_request_align_sgl_element_buffer(this_request->sgl_element_pair_buffer);
396
397 if (this_request->was_tag_assigned_by_user == false) {
398 this_request->task_context_buffer =
399 scic_sds_ssp_request_get_task_context_buffer(this_request);
400 this_request->task_context_buffer =
401 scic_sds_request_align_task_context_buffer(this_request->task_context_buffer);
402 }
403}
404
405/**
406 * This method constructs the SSP Command IU data for this io request object.
407 * @this_request: This parameter specifies the request object for which the SSP
408 * command information unit is being built.
409 *
410 */
411static void scic_sds_io_request_build_ssp_command_iu(
412 struct scic_sds_request *this_request)
413{
414 struct sci_ssp_command_iu *command_frame;
415 void *os_handle;
416 u32 cdb_length;
417 u32 *cdb_buffer;
418
419 command_frame =
420 (struct sci_ssp_command_iu *)this_request->command_buffer;
421
422 os_handle = scic_sds_request_get_user_request(this_request);
423
424 command_frame->lun_upper = 0;
425 command_frame->lun_lower = scic_cb_ssp_io_request_get_lun(os_handle);
426
427 ((u32 *)command_frame)[2] = 0;
428
429 cdb_length = scic_cb_ssp_io_request_get_cdb_length(os_handle);
430 cdb_buffer = (u32 *)scic_cb_ssp_io_request_get_cdb_address(os_handle);
431
432 if (cdb_length > 16) {
433 command_frame->additional_cdb_length = cdb_length - 16;
434 }
435
436 /* / @todo Is it ok to leave junk at the end of the cdb buffer? */
437 scic_word_copy_with_swap(
438 (u32 *)(&command_frame->cdb),
439 (u32 *)(cdb_buffer),
440 (cdb_length + 3) / sizeof(u32)
441 );
442
443 command_frame->enable_first_burst = 0;
444 command_frame->task_priority =
445 scic_cb_ssp_io_request_get_command_priority(os_handle);
446 command_frame->task_attribute =
447 scic_cb_ssp_io_request_get_task_attribute(os_handle);
448}
449
450
451/**
452 * This method constructs the SSP Task IU data for this io request object.
453 * @this_request:
454 *
455 */
456static void scic_sds_task_request_build_ssp_task_iu(
457 struct scic_sds_request *this_request)
458{
459 struct sci_ssp_task_iu *command_frame;
460 void *os_handle;
461
462 command_frame =
463 (struct sci_ssp_task_iu *)this_request->command_buffer;
464
465 os_handle = scic_sds_request_get_user_request(this_request);
466
467 command_frame->lun_upper = 0;
468 command_frame->lun_lower = scic_cb_ssp_task_request_get_lun(os_handle);
469
470 ((u32 *)command_frame)[2] = 0;
471
472 command_frame->task_function =
473 scic_cb_ssp_task_request_get_function(os_handle);
474 command_frame->task_tag =
475 scic_cb_ssp_task_request_get_io_tag_to_manage(os_handle);
476}
477
478
479/**
480 * This method is will fill in the SCU Task Context for any type of SSP request.
481 * @this_request:
482 * @task_context:
483 *
484 */
485static void scu_ssp_reqeust_construct_task_context(
486 struct scic_sds_request *this_request,
487 struct scu_task_context *task_context)
488{
489 dma_addr_t physical_address;
490 struct scic_sds_controller *owning_controller;
491 struct scic_sds_remote_device *target_device;
492 struct scic_sds_port *target_port;
493
494 owning_controller = scic_sds_request_get_controller(this_request);
495 target_device = scic_sds_request_get_device(this_request);
496 target_port = scic_sds_request_get_port(this_request);
497
498 /* Fill in the TC with the its required data */
499 task_context->abort = 0;
500 task_context->priority = 0;
501 task_context->initiator_request = 1;
502 task_context->connection_rate =
503 scic_remote_device_get_connection_rate(target_device);
504 task_context->protocol_engine_index =
505 scic_sds_controller_get_protocol_engine_group(owning_controller);
506 task_context->logical_port_index =
507 scic_sds_port_get_index(target_port);
508 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
509 task_context->valid = SCU_TASK_CONTEXT_VALID;
510 task_context->context_type = SCU_TASK_CONTEXT_TYPE;
511
512 task_context->remote_node_index =
513 scic_sds_remote_device_get_index(this_request->target_device);
514 task_context->command_code = 0;
515
516 task_context->link_layer_control = 0;
517 task_context->do_not_dma_ssp_good_response = 1;
518 task_context->strict_ordering = 0;
519 task_context->control_frame = 0;
520 task_context->timeout_enable = 0;
521 task_context->block_guard_enable = 0;
522
523 task_context->address_modifier = 0;
524
525 /* task_context->type.ssp.tag = this_request->io_tag; */
526 task_context->task_phase = 0x01;
527
528 if (this_request->was_tag_assigned_by_user) {
529 /* Build the task context now since we have already read the data */
530 this_request->post_context = (
531 SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
532 | (
533 scic_sds_controller_get_protocol_engine_group(owning_controller)
534 << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
535 )
536 | (
537 scic_sds_port_get_index(target_port)
538 << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
539 )
540 | scic_sds_io_tag_get_index(this_request->io_tag)
541 );
542 } else {
543 /* Build the task context now since we have already read the data */
544 this_request->post_context = (
545 SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
546 | (
547 scic_sds_controller_get_protocol_engine_group(owning_controller)
548 << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
549 )
550 | (
551 scic_sds_port_get_index(target_port)
552 << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
553 )
554 /* This is not assigned because we have to wait until we get a TCi */
555 );
556 }
557
558 /* Copy the physical address for the command buffer to the SCU Task Context */
559 scic_cb_io_request_get_physical_address(
560 scic_sds_request_get_controller(this_request),
561 this_request,
562 this_request->command_buffer,
563 &physical_address
564 );
565
566 task_context->command_iu_upper =
567 upper_32_bits(physical_address);
568 task_context->command_iu_lower =
569 lower_32_bits(physical_address);
570
571 /* Copy the physical address for the response buffer to the SCU Task Context */
572 scic_cb_io_request_get_physical_address(
573 scic_sds_request_get_controller(this_request),
574 this_request,
575 this_request->response_buffer,
576 &physical_address
577 );
578
579 task_context->response_iu_upper =
580 upper_32_bits(physical_address);
581 task_context->response_iu_lower =
582 lower_32_bits(physical_address);
583}
584
585/**
586 * This method is will fill in the SCU Task Context for a SSP IO request.
587 * @this_request:
588 *
589 */
590static void scu_ssp_io_request_construct_task_context(
591 struct scic_sds_request *this_request,
592 SCI_IO_REQUEST_DATA_DIRECTION data_direction,
593 u32 transfer_length_bytes)
594{
595 struct scu_task_context *task_context;
596
597 task_context = scic_sds_request_get_task_context(this_request);
598
599 scu_ssp_reqeust_construct_task_context(this_request, task_context);
600
601 task_context->ssp_command_iu_length = sizeof(struct sci_ssp_command_iu) / sizeof(u32);
602 task_context->type.ssp.frame_type = SCI_SAS_COMMAND_FRAME;
603
604 switch (data_direction) {
605 case SCI_IO_REQUEST_DATA_IN:
606 case SCI_IO_REQUEST_NO_DATA:
607 task_context->task_type = SCU_TASK_TYPE_IOREAD;
608 break;
609 case SCI_IO_REQUEST_DATA_OUT:
610 task_context->task_type = SCU_TASK_TYPE_IOWRITE;
611 break;
612 }
613
614 task_context->transfer_length_bytes = transfer_length_bytes;
615
616 if (task_context->transfer_length_bytes > 0) {
617 scic_sds_request_build_sgl(this_request);
618 }
619}
620
621
622/**
623 * This method will fill in the remainder of the io request object for SSP Task
624 * requests.
625 * @this_request:
626 *
627 */
628static void scic_sds_ssp_task_request_assign_buffers(
629 struct scic_sds_request *this_request)
630{
631 /* Assign all of the buffer pointers */
632 this_request->command_buffer =
633 scic_sds_ssp_task_request_get_command_buffer(this_request);
634 this_request->response_buffer =
635 scic_sds_ssp_task_request_get_response_buffer(this_request);
636 this_request->sgl_element_pair_buffer = NULL;
637
638 if (this_request->was_tag_assigned_by_user == false) {
639 this_request->task_context_buffer =
640 scic_sds_ssp_task_request_get_task_context_buffer(this_request);
641 this_request->task_context_buffer =
642 scic_sds_request_align_task_context_buffer(this_request->task_context_buffer);
643 }
644}
645
646/**
647 * This method will fill in the SCU Task Context for a SSP Task request. The
648 * following important settings are utilized: -# priority ==
649 * SCU_TASK_PRIORITY_HIGH. This ensures that the task request is issued
650 * ahead of other task destined for the same Remote Node. -# task_type ==
651 * SCU_TASK_TYPE_IOREAD. This simply indicates that a normal request type
652 * (i.e. non-raw frame) is being utilized to perform task management. -#
653 * control_frame == 1. This ensures that the proper endianess is set so
654 * that the bytes are transmitted in the right order for a task frame.
655 * @this_request: This parameter specifies the task request object being
656 * constructed.
657 *
658 */
659static void scu_ssp_task_request_construct_task_context(
660 struct scic_sds_request *this_request)
661{
662 struct scu_task_context *task_context;
663
664 task_context = scic_sds_request_get_task_context(this_request);
665
666 scu_ssp_reqeust_construct_task_context(this_request, task_context);
667
668 task_context->control_frame = 1;
669 task_context->priority = SCU_TASK_PRIORITY_HIGH;
670 task_context->task_type = SCU_TASK_TYPE_RAW_FRAME;
671 task_context->transfer_length_bytes = 0;
672 task_context->type.ssp.frame_type = SCI_SAS_TASK_FRAME;
673 task_context->ssp_command_iu_length = sizeof(struct sci_ssp_task_iu) / sizeof(u32);
674}
675
676
677/**
678 * This method constructs the SSP Command IU data for this ssp passthrough
679 * comand request object.
680 * @this_request: This parameter specifies the request object for which the SSP
681 * command information unit is being built.
682 *
683 * enum sci_status, returns invalid parameter is cdb > 16
684 */
685
686
687/**
688 * This method constructs the SATA request object.
689 * @this_request:
690 * @sat_protocol:
691 * @transfer_length:
692 * @data_direction:
693 * @copy_rx_frame:
694 *
695 * enum sci_status
696 */
697static enum sci_status scic_io_request_construct_sata(
698 struct scic_sds_request *this_request,
699 u8 sat_protocol,
700 u32 transfer_length,
701 SCI_IO_REQUEST_DATA_DIRECTION data_direction,
702 bool copy_rx_frame)
703{
704 enum sci_status status = SCI_SUCCESS;
705
706 switch (sat_protocol) {
707 case SAT_PROTOCOL_PIO_DATA_IN:
708 case SAT_PROTOCOL_PIO_DATA_OUT:
709 status = scic_sds_stp_pio_request_construct(this_request, sat_protocol, copy_rx_frame);
710 break;
711
712 case SAT_PROTOCOL_UDMA_DATA_IN:
713 case SAT_PROTOCOL_UDMA_DATA_OUT:
714 status = scic_sds_stp_udma_request_construct(this_request, transfer_length, data_direction);
715 break;
716
717 case SAT_PROTOCOL_ATA_HARD_RESET:
718 case SAT_PROTOCOL_SOFT_RESET:
719 status = scic_sds_stp_soft_reset_request_construct(this_request);
720 break;
721
722 case SAT_PROTOCOL_NON_DATA:
723 status = scic_sds_stp_non_data_request_construct(this_request);
724 break;
725
726 case SAT_PROTOCOL_FPDMA:
727 status = scic_sds_stp_ncq_request_construct(this_request, transfer_length, data_direction);
728 break;
729
730#if !defined(DISABLE_ATAPI)
731 case SAT_PROTOCOL_PACKET_NON_DATA:
732 case SAT_PROTOCOL_PACKET_DMA_DATA_IN:
733 case SAT_PROTOCOL_PACKET_DMA_DATA_OUT:
734 case SAT_PROTOCOL_PACKET_PIO_DATA_IN:
735 case SAT_PROTOCOL_PACKET_PIO_DATA_OUT:
736 status = scic_sds_stp_packet_request_construct(this_request);
737 break;
738#endif
739
740 case SAT_PROTOCOL_DMA_QUEUED:
741 case SAT_PROTOCOL_DMA:
742 case SAT_PROTOCOL_DEVICE_DIAGNOSTIC:
743 case SAT_PROTOCOL_DEVICE_RESET:
744 case SAT_PROTOCOL_RETURN_RESPONSE_INFO:
745 default:
746 dev_err(scic_to_dev(this_request->owning_controller),
747 "%s: SCIC IO Request 0x%p received un-handled "
748 "SAT Protocl %d.\n",
749 __func__, this_request, sat_protocol);
750
751 status = SCI_FAILURE;
752 break;
753 }
754
755 return status;
756}
757
758/*
759 * ****************************************************************************
760 * * SCIC Interface Implementation
761 * **************************************************************************** */
762
763
764
765
766/* --------------------------------------------------------------------------- */
767
768u32 scic_io_request_get_object_size(void)
769{
770 u32 ssp_request_size;
771 u32 stp_request_size;
772 u32 smp_request_size;
773
774 ssp_request_size = scic_sds_ssp_request_get_object_size();
775 stp_request_size = scic_sds_stp_request_get_object_size();
776 smp_request_size = scic_sds_smp_request_get_object_size();
777
778 return max(ssp_request_size, max(stp_request_size, smp_request_size));
779}
780
781/* --------------------------------------------------------------------------- */
782
783
784/* --------------------------------------------------------------------------- */
785
786
787/* --------------------------------------------------------------------------- */
788
789
790/* --------------------------------------------------------------------------- */
791
792enum sci_status scic_io_request_construct(
793 struct scic_sds_controller *scic_controller,
794 struct scic_sds_remote_device *scic_remote_device,
795 u16 io_tag,
796 void *user_io_request_object,
797 void *scic_io_request_memory,
798 struct scic_sds_request **new_scic_io_request_handle)
799{
800 enum sci_status status = SCI_SUCCESS;
801 struct scic_sds_request *this_request;
802 struct smp_discover_response_protocols device_protocol;
803
804 this_request = (struct scic_sds_request *)scic_io_request_memory;
805
806 /* Build the common part of the request */
807 scic_sds_general_request_construct(
808 (struct scic_sds_controller *)scic_controller,
809 (struct scic_sds_remote_device *)scic_remote_device,
810 io_tag,
811 user_io_request_object,
812 this_request
813 );
814
815 if (
816 scic_sds_remote_device_get_index((struct scic_sds_remote_device *)scic_remote_device)
817 == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
818 ) {
819 return SCI_FAILURE_INVALID_REMOTE_DEVICE;
820 }
821
822 scic_remote_device_get_protocols(scic_remote_device, &device_protocol);
823
824 if (device_protocol.u.bits.attached_ssp_target) {
825 scic_sds_ssp_io_request_assign_buffers(this_request);
826 } else if (device_protocol.u.bits.attached_stp_target) {
827 scic_sds_stp_request_assign_buffers(this_request);
828 memset(this_request->command_buffer, 0, sizeof(struct sata_fis_reg_h2d));
829 } else if (device_protocol.u.bits.attached_smp_target) {
830 scic_sds_smp_request_assign_buffers(this_request);
831 memset(this_request->command_buffer, 0, sizeof(struct smp_request));
832 } else {
833 status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
834 }
835
836 if (status == SCI_SUCCESS) {
837 memset(
838 this_request->task_context_buffer,
839 0,
840 SCI_FIELD_OFFSET(struct scu_task_context, sgl_pair_ab)
841 );
842 *new_scic_io_request_handle = scic_io_request_memory;
843 }
844
845 return status;
846}
847
848/* --------------------------------------------------------------------------- */
849
850
851enum sci_status scic_task_request_construct(
852 struct scic_sds_controller *controller,
853 struct scic_sds_remote_device *remote_device,
854 u16 io_tag,
855 void *user_io_request_object,
856 void *scic_task_request_memory,
857 struct scic_sds_request **new_scic_task_request_handle)
858{
859 enum sci_status status = SCI_SUCCESS;
860 struct scic_sds_request *this_request = (struct scic_sds_request *)
861 scic_task_request_memory;
862 struct smp_discover_response_protocols device_protocol;
863
864 /* Build the common part of the request */
865 scic_sds_general_request_construct(
866 (struct scic_sds_controller *)controller,
867 (struct scic_sds_remote_device *)remote_device,
868 io_tag,
869 user_io_request_object,
870 this_request
871 );
872
873 scic_remote_device_get_protocols(remote_device, &device_protocol);
874
875 if (device_protocol.u.bits.attached_ssp_target) {
876 scic_sds_ssp_task_request_assign_buffers(this_request);
877
878 this_request->has_started_substate_machine = true;
879
880 /* Construct the started sub-state machine. */
881 sci_base_state_machine_construct(
882 &this_request->started_substate_machine,
883 &this_request->parent.parent,
884 scic_sds_io_request_started_task_mgmt_substate_table,
885 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION
886 );
887 } else if (device_protocol.u.bits.attached_stp_target) {
888 scic_sds_stp_request_assign_buffers(this_request);
889 } else {
890 status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
891 }
892
893 if (status == SCI_SUCCESS) {
894 this_request->is_task_management_request = true;
895 memset(this_request->task_context_buffer, 0x00, sizeof(struct scu_task_context));
896 *new_scic_task_request_handle = scic_task_request_memory;
897 }
898
899 return status;
900}
901
902
903enum sci_status scic_io_request_construct_basic_ssp(
904 struct scic_sds_request *sci_req)
905{
906 void *os_handle;
907
908 sci_req->protocol = SCIC_SSP_PROTOCOL;
909
910 os_handle = scic_sds_request_get_user_request(sci_req);
911
912 scu_ssp_io_request_construct_task_context(
913 sci_req,
914 scic_cb_io_request_get_data_direction(os_handle),
915 scic_cb_io_request_get_transfer_length(os_handle)
916 );
917
918
919 scic_sds_io_request_build_ssp_command_iu(sci_req);
920
921 sci_base_state_machine_change_state(
922 &sci_req->parent.state_machine,
923 SCI_BASE_REQUEST_STATE_CONSTRUCTED
924 );
925
926 return SCI_SUCCESS;
927}
928
929
930enum sci_status scic_task_request_construct_ssp(
931 struct scic_sds_request *sci_req)
932{
933 /* Construct the SSP Task SCU Task Context */
934 scu_ssp_task_request_construct_task_context(sci_req);
935
936 /* Fill in the SSP Task IU */
937 scic_sds_task_request_build_ssp_task_iu(sci_req);
938
939 sci_base_state_machine_change_state(
940 &sci_req->parent.state_machine,
941 SCI_BASE_REQUEST_STATE_CONSTRUCTED
942 );
943
944 return SCI_SUCCESS;
945}
946
947
948enum sci_status scic_io_request_construct_basic_sata(
949 struct scic_sds_request *sci_req)
950{
951 enum sci_status status;
952 struct scic_sds_stp_request *this_stp_request;
953 u8 sat_protocol;
954 u32 transfer_length;
955 SCI_IO_REQUEST_DATA_DIRECTION data_direction;
956 bool copy_rx_frame = false;
957
958 this_stp_request = (struct scic_sds_stp_request *)sci_req;
959
960 sci_req->protocol = SCIC_STP_PROTOCOL;
961
962 transfer_length =
963 scic_cb_io_request_get_transfer_length(sci_req->user_request);
964 data_direction =
965 scic_cb_io_request_get_data_direction(sci_req->user_request);
966
967 sat_protocol = scic_cb_request_get_sat_protocol(sci_req->user_request);
968 copy_rx_frame = scic_cb_io_request_do_copy_rx_frames(this_stp_request->parent.user_request);
969
970 status = scic_io_request_construct_sata(
971 sci_req,
972 sat_protocol,
973 transfer_length,
974 data_direction,
975 copy_rx_frame
976 );
977
978 if (status == SCI_SUCCESS)
979 sci_base_state_machine_change_state(
980 &sci_req->parent.state_machine,
981 SCI_BASE_REQUEST_STATE_CONSTRUCTED
982 );
983
984 return status;
985}
986
987
988enum sci_status scic_task_request_construct_sata(
989 struct scic_sds_request *sci_req)
990{
991 enum sci_status status;
992 u8 sat_protocol = scic_cb_request_get_sat_protocol(sci_req->user_request);
993
994 switch (sat_protocol) {
995 case SAT_PROTOCOL_ATA_HARD_RESET:
996 case SAT_PROTOCOL_SOFT_RESET:
997 status = scic_sds_stp_soft_reset_request_construct(sci_req);
998 break;
999
1000 default:
1001 dev_err(scic_to_dev(sci_req->owning_controller),
1002 "%s: SCIC IO Request 0x%p received un-handled SAT "
1003 "Protocl %d.\n",
1004 __func__,
1005 sci_req,
1006 sat_protocol);
1007
1008 status = SCI_FAILURE;
1009 break;
1010 }
1011
1012 if (status == SCI_SUCCESS)
1013 sci_base_state_machine_change_state(
1014 &sci_req->parent.state_machine,
1015 SCI_BASE_REQUEST_STATE_CONSTRUCTED
1016 );
1017
1018 return status;
1019}
1020
1021
1022u16 scic_io_request_get_io_tag(
1023 struct scic_sds_request *sci_req)
1024{
1025 return sci_req->io_tag;
1026}
1027
1028
1029u32 scic_request_get_controller_status(
1030 struct scic_sds_request *sci_req)
1031{
1032 return sci_req->scu_status;
1033}
1034
1035
1036void *scic_io_request_get_command_iu_address(
1037 struct scic_sds_request *sci_req)
1038{
1039 return sci_req->command_buffer;
1040}
1041
1042
1043void *scic_io_request_get_response_iu_address(
1044 struct scic_sds_request *sci_req)
1045{
1046 return sci_req->response_buffer;
1047}
1048
1049
1050#define SCU_TASK_CONTEXT_SRAM 0x200000
1051u32 scic_io_request_get_number_of_bytes_transferred(
1052 struct scic_sds_request *scic_sds_request)
1053{
1054 u32 ret_val = 0;
1055
1056 if (SMU_AMR_READ(scic_sds_request->owning_controller) == 0) {
1057 /*
1058 * get the bytes of data from the Address == BAR1 + 20002Ch + (256*TCi) where
1059 * BAR1 is the scu_registers
1060 * 0x20002C = 0x200000 + 0x2c
1061 * = start of task context SRAM + offset of (type.ssp.data_offset)
1062 * TCi is the io_tag of struct scic_sds_request */
1063 ret_val = scic_sds_pci_read_scu_dword(
1064 scic_sds_request->owning_controller,
1065 (
1066 (u8 *)scic_sds_request->owning_controller->scu_registers +
1067 (SCU_TASK_CONTEXT_SRAM + SCI_FIELD_OFFSET(struct scu_task_context, type.ssp.data_offset)) +
1068 ((sizeof(struct scu_task_context)) * scic_sds_io_tag_get_index(scic_sds_request->io_tag))
1069 )
1070 );
1071 }
1072
1073 return ret_val;
1074}
1075
1076
1077/*
1078 * ****************************************************************************
1079 * * SCIC SDS Interface Implementation
1080 * **************************************************************************** */
1081
1082/**
1083 *
1084 * @this_request: The SCIC_SDS_IO_REQUEST_T object for which the start
1085 * operation is to be executed.
1086 *
1087 * This method invokes the base state start request handler for the
1088 * SCIC_SDS_IO_REQUEST_T object. enum sci_status
1089 */
1090enum sci_status scic_sds_request_start(
1091 struct scic_sds_request *this_request)
1092{
1093 if (
1094 this_request->device_sequence
1095 == scic_sds_remote_device_get_sequence(this_request->target_device)
1096 ) {
1097 return this_request->state_handlers->parent.start_handler(
1098 &this_request->parent
1099 );
1100 }
1101
1102 return SCI_FAILURE;
1103}
1104
1105/**
1106 *
1107 * @this_request: The SCIC_SDS_IO_REQUEST_T object for which the start
1108 * operation is to be executed.
1109 *
1110 * This method invokes the base state terminate request handber for the
1111 * SCIC_SDS_IO_REQUEST_T object. enum sci_status
1112 */
1113enum sci_status scic_sds_io_request_terminate(
1114 struct scic_sds_request *this_request)
1115{
1116 return this_request->state_handlers->parent.abort_handler(
1117 &this_request->parent);
1118}
1119
1120/**
1121 *
1122 * @this_request: The SCIC_SDS_IO_REQUEST_T object for which the start
1123 * operation is to be executed.
1124 *
1125 * This method invokes the base state request completion handler for the
1126 * SCIC_SDS_IO_REQUEST_T object. enum sci_status
1127 */
1128enum sci_status scic_sds_io_request_complete(
1129 struct scic_sds_request *this_request)
1130{
1131 return this_request->state_handlers->parent.complete_handler(
1132 &this_request->parent);
1133}
1134
1135/**
1136 *
1137 * @this_request: The SCIC_SDS_IO_REQUEST_T object for which the start
1138 * operation is to be executed.
1139 * @event_code: The event code returned by the hardware for the task reqeust.
1140 *
1141 * This method invokes the core state handler for the SCIC_SDS_IO_REQUEST_T
1142 * object. enum sci_status
1143 */
1144enum sci_status scic_sds_io_request_event_handler(
1145 struct scic_sds_request *this_request,
1146 u32 event_code)
1147{
1148 return this_request->state_handlers->event_handler(this_request, event_code);
1149}
1150
1151/**
1152 *
1153 * @this_request: The SCIC_SDS_IO_REQUEST_T object for which the start
1154 * operation is to be executed.
1155 * @frame_index: The frame index returned by the hardware for the reqeust
1156 * object.
1157 *
1158 * This method invokes the core state frame handler for the
1159 * SCIC_SDS_IO_REQUEST_T object. enum sci_status
1160 */
1161enum sci_status scic_sds_io_request_frame_handler(
1162 struct scic_sds_request *this_request,
1163 u32 frame_index)
1164{
1165 return this_request->state_handlers->frame_handler(this_request, frame_index);
1166}
1167
1168/**
1169 *
1170 * @this_request: The SCIC_SDS_IO_REQUEST_T object for which the task start
1171 * operation is to be executed.
1172 *
1173 * This method invokes the core state task complete handler for the
1174 * SCIC_SDS_IO_REQUEST_T object. enum sci_status
1175 */
1176
1177/*
1178 * ****************************************************************************
1179 * * SCIC SDS PROTECTED METHODS
1180 * **************************************************************************** */
1181
1182/**
1183 * This method copies response data for requests returning response data
1184 * instead of sense data.
1185 * @this_request: This parameter specifies the request object for which to copy
1186 * the response data.
1187 *
1188 */
1189void scic_sds_io_request_copy_response(
1190 struct scic_sds_request *this_request)
1191{
1192 void *response_buffer;
1193 u32 user_response_length;
1194 u32 core_response_length;
1195 struct sci_ssp_response_iu *ssp_response;
1196
1197 ssp_response = (struct sci_ssp_response_iu *)this_request->response_buffer;
1198
1199 response_buffer = scic_cb_ssp_task_request_get_response_data_address(
1200 this_request->user_request
1201 );
1202
1203 user_response_length = scic_cb_ssp_task_request_get_response_data_length(
1204 this_request->user_request
1205 );
1206
1207 core_response_length = sci_ssp_get_response_data_length(
1208 ssp_response->response_data_length
1209 );
1210
1211 user_response_length = min(user_response_length, core_response_length);
1212
1213 memcpy(response_buffer, ssp_response->data, user_response_length);
1214}
1215
1216/*
1217 * *****************************************************************************
1218 * * DEFAULT STATE HANDLERS
1219 * ***************************************************************************** */
1220
1221/**
1222 * scic_sds_request_default_start_handler() -
1223 * @request: This is the struct sci_base_request object that is cast to the
1224 * SCIC_SDS_IO_REQUEST_T object for which the start operation is requested.
1225 *
1226 * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T
1227 * object receives a scic_sds_request_start() request. The default action is
1228 * to log a warning and return a failure status. enum sci_status
1229 * SCI_FAILURE_INVALID_STATE
1230 */
1231enum sci_status scic_sds_request_default_start_handler(
1232 struct sci_base_request *request)
1233{
1234 struct scic_sds_request *scic_request =
1235 (struct scic_sds_request *)request;
1236
1237 dev_warn(scic_to_dev(scic_request->owning_controller),
1238 "%s: SCIC IO Request requested to start while in wrong "
1239 "state %d\n",
1240 __func__,
1241 sci_base_state_machine_get_state(
1242 &((struct scic_sds_request *)request)->parent.state_machine));
1243
1244 return SCI_FAILURE_INVALID_STATE;
1245}
1246
1247static enum sci_status scic_sds_request_default_abort_handler(
1248 struct sci_base_request *request)
1249{
1250 struct scic_sds_request *scic_request =
1251 (struct scic_sds_request *)request;
1252
1253 dev_warn(scic_to_dev(scic_request->owning_controller),
1254 "%s: SCIC IO Request requested to abort while in wrong "
1255 "state %d\n",
1256 __func__,
1257 sci_base_state_machine_get_state(
1258 &((struct scic_sds_request *)request)->parent.state_machine));
1259
1260 return SCI_FAILURE_INVALID_STATE;
1261}
1262
1263/**
1264 * scic_sds_request_default_complete_handler() -
1265 * @request: This is the struct sci_base_request object that is cast to the
1266 * SCIC_SDS_IO_REQUEST_T object for which the start operation is requested.
1267 *
1268 * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T
1269 * object receives a scic_sds_request_complete() request. The default action
1270 * is to log a warning and return a failure status. enum sci_status
1271 * SCI_FAILURE_INVALID_STATE
1272 */
1273enum sci_status scic_sds_request_default_complete_handler(
1274 struct sci_base_request *request)
1275{
1276 struct scic_sds_request *scic_request =
1277 (struct scic_sds_request *)request;
1278
1279 dev_warn(scic_to_dev(scic_request->owning_controller),
1280 "%s: SCIC IO Request requested to complete while in wrong "
1281 "state %d\n",
1282 __func__,
1283 sci_base_state_machine_get_state(
1284 &((struct scic_sds_request *)request)->parent.state_machine));
1285
1286 return SCI_FAILURE_INVALID_STATE;
1287}
1288
1289/**
1290 * scic_sds_request_default_destruct_handler() -
1291 * @request: This is the struct sci_base_request object that is cast to the
1292 * SCIC_SDS_IO_REQUEST_T object for which the start operation is requested.
1293 *
1294 * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T
1295 * object receives a scic_sds_request_complete() request. The default action
1296 * is to log a warning and return a failure status. enum sci_status
1297 * SCI_FAILURE_INVALID_STATE
1298 */
1299enum sci_status scic_sds_request_default_destruct_handler(
1300 struct sci_base_request *request)
1301{
1302 struct scic_sds_request *scic_request =
1303 (struct scic_sds_request *)request;
1304
1305 dev_warn(scic_to_dev(scic_request->owning_controller),
1306 "%s: SCIC IO Request requested to destroy while in wrong "
1307 "state %d\n",
1308 __func__,
1309 sci_base_state_machine_get_state(
1310 &((struct scic_sds_request *)request)->parent.state_machine));
1311
1312 return SCI_FAILURE_INVALID_STATE;
1313}
1314
1315/**
1316 * scic_sds_request_default_tc_completion_handler() -
1317 * @request: This is the struct sci_base_request object that is cast to the
1318 * SCIC_SDS_IO_REQUEST_T object for which the start operation is requested.
1319 *
1320 * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T
1321 * object receives a scic_sds_task_request_complete() request. The default
1322 * action is to log a warning and return a failure status. enum sci_status
1323 * SCI_FAILURE_INVALID_STATE
1324 */
1325enum sci_status scic_sds_request_default_tc_completion_handler(
1326 struct scic_sds_request *this_request,
1327 u32 completion_code)
1328{
1329 dev_warn(scic_to_dev(this_request->owning_controller),
1330 "%s: SCIC IO Request given task completion notification %x "
1331 "while in wrong state %d\n",
1332 __func__,
1333 completion_code,
1334 sci_base_state_machine_get_state(
1335 &this_request->parent.state_machine));
1336
1337 return SCI_FAILURE_INVALID_STATE;
1338
1339}
1340
1341/**
1342 * scic_sds_request_default_event_handler() -
1343 * @request: This is the struct sci_base_request object that is cast to the
1344 * SCIC_SDS_IO_REQUEST_T object for which the start operation is requested.
1345 *
1346 * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T
1347 * object receives a scic_sds_request_event_handler() request. The default
1348 * action is to log a warning and return a failure status. enum sci_status
1349 * SCI_FAILURE_INVALID_STATE
1350 */
1351enum sci_status scic_sds_request_default_event_handler(
1352 struct scic_sds_request *this_request,
1353 u32 event_code)
1354{
1355 dev_warn(scic_to_dev(this_request->owning_controller),
1356 "%s: SCIC IO Request given event code notification %x while "
1357 "in wrong state %d\n",
1358 __func__,
1359 event_code,
1360 sci_base_state_machine_get_state(
1361 &this_request->parent.state_machine));
1362
1363 return SCI_FAILURE_INVALID_STATE;
1364}
1365
1366/**
1367 * scic_sds_request_default_frame_handler() -
1368 * @request: This is the struct sci_base_request object that is cast to the
1369 * SCIC_SDS_IO_REQUEST_T object for which the start operation is requested.
1370 *
1371 * This method is the default action to take when an SCIC_SDS_IO_REQUEST_T
1372 * object receives a scic_sds_request_event_handler() request. The default
1373 * action is to log a warning and return a failure status. enum sci_status
1374 * SCI_FAILURE_INVALID_STATE
1375 */
1376enum sci_status scic_sds_request_default_frame_handler(
1377 struct scic_sds_request *this_request,
1378 u32 frame_index)
1379{
1380 dev_warn(scic_to_dev(this_request->owning_controller),
1381 "%s: SCIC IO Request given unexpected frame %x while in "
1382 "state %d\n",
1383 __func__,
1384 frame_index,
1385 sci_base_state_machine_get_state(
1386 &this_request->parent.state_machine));
1387
1388 scic_sds_controller_release_frame(
1389 this_request->owning_controller, frame_index);
1390
1391 return SCI_FAILURE_INVALID_STATE;
1392}
1393
1394/*
1395 * *****************************************************************************
1396 * * CONSTRUCTED STATE HANDLERS
1397 * ***************************************************************************** */
1398
1399/**
1400 * scic_sds_request_constructed_state_start_handler() -
1401 * @request: This is the struct sci_base_request object that is cast to the
1402 * SCIC_SDS_IO_REQUEST_T object for which the start operation is requested.
1403 *
1404 * This method implements the action taken when a constructed
1405 * SCIC_SDS_IO_REQUEST_T object receives a scic_sds_request_start() request.
1406 * This method will, if necessary, allocate a TCi for the io request object and
1407 * then will, if necessary, copy the constructed TC data into the actual TC
1408 * buffer. If everything is successful the post context field is updated with
1409 * the TCi so the controller can post the request to the hardware. enum sci_status
1410 * SCI_SUCCESS SCI_FAILURE_INSUFFICIENT_RESOURCES
1411 */
1412static enum sci_status scic_sds_request_constructed_state_start_handler(
1413 struct sci_base_request *request)
1414{
1415 struct scu_task_context *task_context;
1416 struct scic_sds_request *this_request = (struct scic_sds_request *)request;
1417
1418 if (this_request->io_tag == SCI_CONTROLLER_INVALID_IO_TAG) {
1419 this_request->io_tag =
1420 scic_controller_allocate_io_tag(this_request->owning_controller);
1421 }
1422
1423 /* Record the IO Tag in the request */
1424 if (this_request->io_tag != SCI_CONTROLLER_INVALID_IO_TAG) {
1425 task_context = this_request->task_context_buffer;
1426
1427 task_context->task_index = scic_sds_io_tag_get_index(this_request->io_tag);
1428
1429 switch (task_context->protocol_type) {
1430 case SCU_TASK_CONTEXT_PROTOCOL_SMP:
1431 case SCU_TASK_CONTEXT_PROTOCOL_SSP:
1432 /* SSP/SMP Frame */
1433 task_context->type.ssp.tag = this_request->io_tag;
1434 task_context->type.ssp.target_port_transfer_tag = 0xFFFF;
1435 break;
1436
1437 case SCU_TASK_CONTEXT_PROTOCOL_STP:
1438 /*
1439 * STP/SATA Frame
1440 * task_context->type.stp.ncq_tag = this_request->ncq_tag; */
1441 break;
1442
1443 case SCU_TASK_CONTEXT_PROTOCOL_NONE:
1444 /* / @todo When do we set no protocol type? */
1445 break;
1446
1447 default:
1448 /* This should never happen since we build the IO requests */
1449 break;
1450 }
1451
1452 /*
1453 * Check to see if we need to copy the task context buffer
1454 * or have been building into the task context buffer */
1455 if (this_request->was_tag_assigned_by_user == false) {
1456 scic_sds_controller_copy_task_context(
1457 this_request->owning_controller, this_request
1458 );
1459 }
1460
1461 /* Add to the post_context the io tag value */
1462 this_request->post_context |= scic_sds_io_tag_get_index(this_request->io_tag);
1463
1464 /* Everything is good go ahead and change state */
1465 sci_base_state_machine_change_state(
1466 &this_request->parent.state_machine,
1467 SCI_BASE_REQUEST_STATE_STARTED
1468 );
1469
1470 return SCI_SUCCESS;
1471 }
1472
1473 return SCI_FAILURE_INSUFFICIENT_RESOURCES;
1474}
1475
1476/**
1477 * scic_sds_request_constructed_state_abort_handler() -
1478 * @request: This is the struct sci_base_request object that is cast to the
1479 * SCIC_SDS_IO_REQUEST_T object for which the start operation is requested.
1480 *
1481 * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
1482 * object receives a scic_sds_request_terminate() request. Since the request
1483 * has not yet been posted to the hardware the request transitions to the
1484 * completed state. enum sci_status SCI_SUCCESS
1485 */
1486static enum sci_status scic_sds_request_constructed_state_abort_handler(
1487 struct sci_base_request *request)
1488{
1489 struct scic_sds_request *this_request = (struct scic_sds_request *)request;
1490
1491 /*
1492 * This request has been terminated by the user make sure that the correct
1493 * status code is returned */
1494 scic_sds_request_set_status(
1495 this_request,
1496 SCU_TASK_DONE_TASK_ABORT,
1497 SCI_FAILURE_IO_TERMINATED
1498 );
1499
1500 sci_base_state_machine_change_state(
1501 &this_request->parent.state_machine,
1502 SCI_BASE_REQUEST_STATE_COMPLETED
1503 );
1504
1505 return SCI_SUCCESS;
1506}
1507
1508/*
1509 * *****************************************************************************
1510 * * STARTED STATE HANDLERS
1511 * ***************************************************************************** */
1512
1513/**
1514 * scic_sds_request_started_state_abort_handler() -
1515 * @request: This is the struct sci_base_request object that is cast to the
1516 * SCIC_SDS_IO_REQUEST_T object for which the start operation is requested.
1517 *
1518 * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
1519 * object receives a scic_sds_request_terminate() request. Since the request
1520 * has been posted to the hardware the io request state is changed to the
1521 * aborting state. enum sci_status SCI_SUCCESS
1522 */
1523enum sci_status scic_sds_request_started_state_abort_handler(
1524 struct sci_base_request *request)
1525{
1526 struct scic_sds_request *this_request = (struct scic_sds_request *)request;
1527
1528 if (this_request->has_started_substate_machine) {
1529 sci_base_state_machine_stop(&this_request->started_substate_machine);
1530 }
1531
1532 sci_base_state_machine_change_state(
1533 &this_request->parent.state_machine,
1534 SCI_BASE_REQUEST_STATE_ABORTING
1535 );
1536
1537 return SCI_SUCCESS;
1538}
1539
1540/**
1541 * scic_sds_request_started_state_tc_completion_handler() - This method process
1542 * TC (task context) completions for normal IO request (i.e. Task/Abort
1543 * Completions of type 0). This method will update the
1544 * SCIC_SDS_IO_REQUEST_T::status field.
1545 * @this_request: This parameter specifies the request for which a completion
1546 * occurred.
1547 * @completion_code: This parameter specifies the completion code received from
1548 * the SCU.
1549 *
1550 */
1551enum sci_status scic_sds_request_started_state_tc_completion_handler(
1552 struct scic_sds_request *this_request,
1553 u32 completion_code)
1554{
1555 u8 data_present;
1556 struct sci_ssp_response_iu *response_buffer;
1557
1558 /**
1559 * @todo Any SDMA return code of other than 0 is bad
1560 * decode 0x003C0000 to determine SDMA status
1561 */
1562 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1563 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1564 scic_sds_request_set_status(
1565 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
1566 );
1567 break;
1568
1569 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EARLY_RESP):
1570 {
1571 /*
1572 * There are times when the SCU hardware will return an early response
1573 * because the io request specified more data than is returned by the
1574 * target device (mode pages, inquiry data, etc.). We must check the
1575 * response stats to see if this is truly a failed request or a good
1576 * request that just got completed early. */
1577 struct sci_ssp_response_iu *response = (struct sci_ssp_response_iu *)
1578 this_request->response_buffer;
1579 scic_word_copy_with_swap(
1580 this_request->response_buffer,
1581 this_request->response_buffer,
1582 sizeof(struct sci_ssp_response_iu) / sizeof(u32)
1583 );
1584
1585 if (response->status == 0) {
1586 scic_sds_request_set_status(
1587 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS_IO_DONE_EARLY
1588 );
1589 } else {
1590 scic_sds_request_set_status(
1591 this_request,
1592 SCU_TASK_DONE_CHECK_RESPONSE,
1593 SCI_FAILURE_IO_RESPONSE_VALID
1594 );
1595 }
1596 }
1597 break;
1598
1599 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CHECK_RESPONSE):
1600 scic_word_copy_with_swap(
1601 this_request->response_buffer,
1602 this_request->response_buffer,
1603 sizeof(struct sci_ssp_response_iu) / sizeof(u32)
1604 );
1605
1606 scic_sds_request_set_status(
1607 this_request,
1608 SCU_TASK_DONE_CHECK_RESPONSE,
1609 SCI_FAILURE_IO_RESPONSE_VALID
1610 );
1611 break;
1612
1613 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RESP_LEN_ERR):
1614 /*
1615 * / @todo With TASK_DONE_RESP_LEN_ERR is the response frame guaranteed
1616 * / to be received before this completion status is posted? */
1617 response_buffer =
1618 (struct sci_ssp_response_iu *)this_request->response_buffer;
1619 data_present =
1620 response_buffer->data_present & SCI_SSP_RESPONSE_IU_DATA_PRESENT_MASK;
1621
1622 if ((data_present == 0x01) || (data_present == 0x02)) {
1623 scic_sds_request_set_status(
1624 this_request,
1625 SCU_TASK_DONE_CHECK_RESPONSE,
1626 SCI_FAILURE_IO_RESPONSE_VALID
1627 );
1628 } else {
1629 scic_sds_request_set_status(
1630 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
1631 );
1632 }
1633 break;
1634
1635 /* only stp device gets suspended. */
1636 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_ACK_NAK_TO):
1637 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_PERR):
1638 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_NAK_ERR):
1639 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_DATA_LEN_ERR):
1640 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_ABORT_ERR):
1641 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_XR_WD_LEN):
1642 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR):
1643 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_RESP):
1644 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_SDBFIS):
1645 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR):
1646 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SDB_ERR):
1647 if (this_request->protocol == SCIC_STP_PROTOCOL) {
1648 scic_sds_request_set_status(
1649 this_request,
1650 SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT,
1651 SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED
1652 );
1653 } else {
1654 scic_sds_request_set_status(
1655 this_request,
1656 SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT,
1657 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1658 );
1659 }
1660 break;
1661
1662 /* both stp/ssp device gets suspended */
1663 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LF_ERR):
1664 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_WRONG_DESTINATION):
1665 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1):
1666 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2):
1667 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3):
1668 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_BAD_DESTINATION):
1669 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_ZONE_VIOLATION):
1670 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY):
1671 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED):
1672 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED):
1673 scic_sds_request_set_status(
1674 this_request,
1675 SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT,
1676 SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED
1677 );
1678 break;
1679
1680 /* neither ssp nor stp gets suspended. */
1681 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_NAK_CMD_ERR):
1682 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_XR):
1683 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_XR_IU_LEN_ERR):
1684 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SDMA_ERR):
1685 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_OFFSET_ERR):
1686 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EXCESS_DATA):
1687 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_RESP_TO_ERR):
1688 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_UFI_ERR):
1689 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_FRM_TYPE_ERR):
1690 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_LL_RX_ERR):
1691 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_DATA):
1692 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_OPEN_FAIL):
1693 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_VIIT_ENTRY_NV):
1694 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_IIT_ENTRY_NV):
1695 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RNCNV_OUTBOUND):
1696 default:
1697 scic_sds_request_set_status(
1698 this_request,
1699 SCU_GET_COMPLETION_TL_STATUS(completion_code) >> SCU_COMPLETION_TL_STATUS_SHIFT,
1700 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1701 );
1702 break;
1703 }
1704
1705 /**
1706 * @todo This is probably wrong for ACK/NAK timeout conditions
1707 */
1708
1709 /* In all cases we will treat this as the completion of the IO request. */
1710 sci_base_state_machine_change_state(
1711 &this_request->parent.state_machine,
1712 SCI_BASE_REQUEST_STATE_COMPLETED
1713 );
1714
1715 return SCI_SUCCESS;
1716}
1717
1718/**
1719 * scic_sds_request_started_state_frame_handler() -
1720 * @request: This is the struct sci_base_request object that is cast to the
1721 * SCIC_SDS_IO_REQUEST_T object for which the start operation is requested.
1722 * @frame_index: This is the index of the unsolicited frame to be processed.
1723 *
1724 * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
1725 * object receives a scic_sds_request_frame_handler() request. This method
1726 * first determines the frame type received. If this is a response frame then
1727 * the response data is copied to the io request response buffer for processing
1728 * at completion time. If the frame type is not a response buffer an error is
1729 * logged. enum sci_status SCI_SUCCESS SCI_FAILURE_INVALID_PARAMETER_VALUE
1730 */
1731static enum sci_status scic_sds_request_started_state_frame_handler(
1732 struct scic_sds_request *this_request,
1733 u32 frame_index)
1734{
1735 enum sci_status status;
1736 struct sci_ssp_frame_header *frame_header;
1737
1738 /* / @todo If this is a response frame we must record that we received it */
1739 status = scic_sds_unsolicited_frame_control_get_header(
1740 &(scic_sds_request_get_controller(this_request)->uf_control),
1741 frame_index,
1742 (void **)&frame_header
1743 );
1744
1745 if (frame_header->frame_type == SCI_SAS_RESPONSE_FRAME) {
1746 struct sci_ssp_response_iu *response_buffer;
1747
1748 status = scic_sds_unsolicited_frame_control_get_buffer(
1749 &(scic_sds_request_get_controller(this_request)->uf_control),
1750 frame_index,
1751 (void **)&response_buffer
1752 );
1753
1754 scic_word_copy_with_swap(
1755 this_request->response_buffer,
1756 (u32 *)response_buffer,
1757 sizeof(struct sci_ssp_response_iu)
1758 );
1759
1760 response_buffer = (struct sci_ssp_response_iu *)this_request->response_buffer;
1761
1762 if ((response_buffer->data_present == 0x01) ||
1763 (response_buffer->data_present == 0x02)) {
1764 scic_sds_request_set_status(
1765 this_request,
1766 SCU_TASK_DONE_CHECK_RESPONSE,
1767 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1768 );
1769 } else
1770 scic_sds_request_set_status(
1771 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
1772 );
1773 } else
1774 /* This was not a response frame why did it get forwarded? */
1775 dev_err(scic_to_dev(this_request->owning_controller),
1776 "%s: SCIC IO Request 0x%p received unexpected "
1777 "frame %d type 0x%02x\n",
1778 __func__,
1779 this_request,
1780 frame_index,
1781 frame_header->frame_type);
1782
1783 /*
1784 * In any case we are done with this frame buffer return it to the
1785 * controller */
1786 scic_sds_controller_release_frame(
1787 this_request->owning_controller, frame_index
1788 );
1789
1790 return SCI_SUCCESS;
1791}
1792
1793/*
1794 * *****************************************************************************
1795 * * COMPLETED STATE HANDLERS
1796 * ***************************************************************************** */
1797
1798
1799/**
1800 * scic_sds_request_completed_state_complete_handler() -
1801 * @request: This is the struct sci_base_request object that is cast to the
1802 * SCIC_SDS_IO_REQUEST_T object for which the start operation is requested.
1803 *
1804 * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
1805 * object receives a scic_sds_request_complete() request. This method frees up
1806 * any io request resources that have been allocated and transitions the
1807 * request to its final state. Consider stopping the state machine instead of
1808 * transitioning to the final state? enum sci_status SCI_SUCCESS
1809 */
1810static enum sci_status scic_sds_request_completed_state_complete_handler(
1811 struct sci_base_request *request)
1812{
1813 struct scic_sds_request *this_request = (struct scic_sds_request *)request;
1814
1815 if (this_request->was_tag_assigned_by_user != true) {
1816 scic_controller_free_io_tag(
1817 this_request->owning_controller, this_request->io_tag
1818 );
1819 }
1820
1821 if (this_request->saved_rx_frame_index != SCU_INVALID_FRAME_INDEX) {
1822 scic_sds_controller_release_frame(
1823 this_request->owning_controller, this_request->saved_rx_frame_index);
1824 }
1825
1826 sci_base_state_machine_change_state(
1827 &this_request->parent.state_machine,
1828 SCI_BASE_REQUEST_STATE_FINAL
1829 );
1830
1831 return SCI_SUCCESS;
1832}
1833
1834/*
1835 * *****************************************************************************
1836 * * ABORTING STATE HANDLERS
1837 * ***************************************************************************** */
1838
1839/**
1840 * scic_sds_request_aborting_state_abort_handler() -
1841 * @request: This is the struct sci_base_request object that is cast to the
1842 * SCIC_SDS_IO_REQUEST_T object for which the start operation is requested.
1843 *
1844 * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
1845 * object receives a scic_sds_request_terminate() request. This method is the
1846 * io request aborting state abort handlers. On receipt of a multiple
1847 * terminate requests the io request will transition to the completed state.
1848 * This should not happen in normal operation. enum sci_status SCI_SUCCESS
1849 */
1850static enum sci_status scic_sds_request_aborting_state_abort_handler(
1851 struct sci_base_request *request)
1852{
1853 struct scic_sds_request *this_request = (struct scic_sds_request *)request;
1854
1855 sci_base_state_machine_change_state(
1856 &this_request->parent.state_machine,
1857 SCI_BASE_REQUEST_STATE_COMPLETED
1858 );
1859
1860 return SCI_SUCCESS;
1861}
1862
1863/**
1864 * scic_sds_request_aborting_state_tc_completion_handler() -
1865 * @request: This is the struct sci_base_request object that is cast to the
1866 * SCIC_SDS_IO_REQUEST_T object for which the start operation is requested.
1867 *
1868 * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
1869 * object receives a scic_sds_request_task_completion() request. This method
1870 * decodes the completion type waiting for the abort task complete
1871 * notification. When the abort task complete is received the io request
1872 * transitions to the completed state. enum sci_status SCI_SUCCESS
1873 */
1874static enum sci_status scic_sds_request_aborting_state_tc_completion_handler(
1875 struct scic_sds_request *this_request,
1876 u32 completion_code)
1877{
1878 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1879 case (SCU_TASK_DONE_GOOD << SCU_COMPLETION_TL_STATUS_SHIFT):
1880 case (SCU_TASK_DONE_TASK_ABORT << SCU_COMPLETION_TL_STATUS_SHIFT):
1881 scic_sds_request_set_status(
1882 this_request, SCU_TASK_DONE_TASK_ABORT, SCI_FAILURE_IO_TERMINATED
1883 );
1884
1885 sci_base_state_machine_change_state(
1886 &this_request->parent.state_machine,
1887 SCI_BASE_REQUEST_STATE_COMPLETED
1888 );
1889 break;
1890
1891 default:
1892 /*
1893 * Unless we get some strange error wait for the task abort to complete
1894 * TODO: Should there be a state change for this completion? */
1895 break;
1896 }
1897
1898 return SCI_SUCCESS;
1899}
1900
1901/**
1902 * scic_sds_request_aborting_state_frame_handler() -
1903 * @request: This is the struct sci_base_request object that is cast to the
1904 * SCIC_SDS_IO_REQUEST_T object for which the start operation is requested.
1905 *
1906 * This method implements the action to be taken when an SCIC_SDS_IO_REQUEST_T
1907 * object receives a scic_sds_request_frame_handler() request. This method
1908 * discards the unsolicited frame since we are waiting for the abort task
1909 * completion. enum sci_status SCI_SUCCESS
1910 */
1911static enum sci_status scic_sds_request_aborting_state_frame_handler(
1912 struct scic_sds_request *this_request,
1913 u32 frame_index)
1914{
1915 /* TODO: Is it even possible to get an unsolicited frame in the aborting state? */
1916
1917 scic_sds_controller_release_frame(
1918 this_request->owning_controller, frame_index);
1919
1920 return SCI_SUCCESS;
1921}
1922
1923/* --------------------------------------------------------------------------- */
1924
1925const struct scic_sds_io_request_state_handler scic_sds_request_state_handler_table[] = {
1926 [SCI_BASE_REQUEST_STATE_INITIAL] = {
1927 .parent.start_handler = scic_sds_request_default_start_handler,
1928 .parent.abort_handler = scic_sds_request_default_abort_handler,
1929 .parent.complete_handler = scic_sds_request_default_complete_handler,
1930 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1931 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
1932 .event_handler = scic_sds_request_default_event_handler,
1933 .frame_handler = scic_sds_request_default_frame_handler,
1934 },
1935 [SCI_BASE_REQUEST_STATE_CONSTRUCTED] = {
1936 .parent.start_handler = scic_sds_request_constructed_state_start_handler,
1937 .parent.abort_handler = scic_sds_request_constructed_state_abort_handler,
1938 .parent.complete_handler = scic_sds_request_default_complete_handler,
1939 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1940 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
1941 .event_handler = scic_sds_request_default_event_handler,
1942 .frame_handler = scic_sds_request_default_frame_handler,
1943 },
1944 [SCI_BASE_REQUEST_STATE_STARTED] = {
1945 .parent.start_handler = scic_sds_request_default_start_handler,
1946 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1947 .parent.complete_handler = scic_sds_request_default_complete_handler,
1948 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1949 .tc_completion_handler = scic_sds_request_started_state_tc_completion_handler,
1950 .event_handler = scic_sds_request_default_event_handler,
1951 .frame_handler = scic_sds_request_started_state_frame_handler,
1952 },
1953 [SCI_BASE_REQUEST_STATE_COMPLETED] = {
1954 .parent.start_handler = scic_sds_request_default_start_handler,
1955 .parent.abort_handler = scic_sds_request_default_abort_handler,
1956 .parent.complete_handler = scic_sds_request_completed_state_complete_handler,
1957 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1958 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
1959 .event_handler = scic_sds_request_default_event_handler,
1960 .frame_handler = scic_sds_request_default_frame_handler,
1961 },
1962 [SCI_BASE_REQUEST_STATE_ABORTING] = {
1963 .parent.start_handler = scic_sds_request_default_start_handler,
1964 .parent.abort_handler = scic_sds_request_aborting_state_abort_handler,
1965 .parent.complete_handler = scic_sds_request_default_complete_handler,
1966 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1967 .tc_completion_handler = scic_sds_request_aborting_state_tc_completion_handler,
1968 .event_handler = scic_sds_request_default_event_handler,
1969 .frame_handler = scic_sds_request_aborting_state_frame_handler,
1970 },
1971 [SCI_BASE_REQUEST_STATE_FINAL] = {
1972 .parent.start_handler = scic_sds_request_default_start_handler,
1973 .parent.abort_handler = scic_sds_request_default_abort_handler,
1974 .parent.complete_handler = scic_sds_request_default_complete_handler,
1975 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1976 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
1977 .event_handler = scic_sds_request_default_event_handler,
1978 .frame_handler = scic_sds_request_default_frame_handler,
1979 },
1980};
1981
1982/**
1983 * scic_sds_request_initial_state_enter() -
1984 * @object: This parameter specifies the base object for which the state
1985 * transition is occurring.
1986 *
1987 * This method implements the actions taken when entering the
1988 * SCI_BASE_REQUEST_STATE_INITIAL state. This state is entered when the initial
1989 * base request is constructed. Entry into the initial state sets all handlers
1990 * for the io request object to their default handlers. none
1991 */
1992static void scic_sds_request_initial_state_enter(
1993 struct sci_base_object *object)
1994{
1995 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1996
1997 SET_STATE_HANDLER(
1998 this_request,
1999 scic_sds_request_state_handler_table,
2000 SCI_BASE_REQUEST_STATE_INITIAL
2001 );
2002}
2003
2004/**
2005 * scic_sds_request_constructed_state_enter() -
2006 * @object: The io request object that is to enter the constructed state.
2007 *
2008 * This method implements the actions taken when entering the
2009 * SCI_BASE_REQUEST_STATE_CONSTRUCTED state. The method sets the state handlers
2010 * for the the constructed state. none
2011 */
2012static void scic_sds_request_constructed_state_enter(
2013 struct sci_base_object *object)
2014{
2015 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
2016
2017 SET_STATE_HANDLER(
2018 this_request,
2019 scic_sds_request_state_handler_table,
2020 SCI_BASE_REQUEST_STATE_CONSTRUCTED
2021 );
2022}
2023
2024/**
2025 * scic_sds_request_started_state_enter() -
2026 * @object: This parameter specifies the base object for which the state
2027 * transition is occuring. This is cast into a SCIC_SDS_IO_REQUEST object.
2028 *
2029 * This method implements the actions taken when entering the
2030 * SCI_BASE_REQUEST_STATE_STARTED state. If the io request object type is a
2031 * SCSI Task request we must enter the started substate machine. none
2032 */
2033static void scic_sds_request_started_state_enter(
2034 struct sci_base_object *object)
2035{
2036 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
2037
2038 SET_STATE_HANDLER(
2039 this_request,
2040 scic_sds_request_state_handler_table,
2041 SCI_BASE_REQUEST_STATE_STARTED
2042 );
2043
2044 /*
2045 * Most of the request state machines have a started substate machine so
2046 * start its execution on the entry to the started state. */
2047 if (this_request->has_started_substate_machine == true)
2048 sci_base_state_machine_start(&this_request->started_substate_machine);
2049}
2050
2051/**
2052 * scic_sds_request_started_state_exit() -
2053 * @object: This parameter specifies the base object for which the state
2054 * transition is occuring. This object is cast into a SCIC_SDS_IO_REQUEST
2055 * object.
2056 *
2057 * This method implements the actions taken when exiting the
2058 * SCI_BASE_REQUEST_STATE_STARTED state. For task requests the action will be
2059 * to stop the started substate machine. none
2060 */
2061static void scic_sds_request_started_state_exit(
2062 struct sci_base_object *object)
2063{
2064 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
2065
2066 if (this_request->has_started_substate_machine == true)
2067 sci_base_state_machine_stop(&this_request->started_substate_machine);
2068}
2069
2070/**
2071 * scic_sds_request_completed_state_enter() -
2072 * @object: This parameter specifies the base object for which the state
2073 * transition is occuring. This object is cast into a SCIC_SDS_IO_REQUEST
2074 * object.
2075 *
2076 * This method implements the actions taken when entering the
2077 * SCI_BASE_REQUEST_STATE_COMPLETED state. This state is entered when the
2078 * SCIC_SDS_IO_REQUEST has completed. The method will decode the request
2079 * completion status and convert it to an enum sci_status to return in the
2080 * completion callback function. none
2081 */
2082static void scic_sds_request_completed_state_enter(
2083 struct sci_base_object *object)
2084{
2085 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
2086
2087 SET_STATE_HANDLER(
2088 this_request,
2089 scic_sds_request_state_handler_table,
2090 SCI_BASE_REQUEST_STATE_COMPLETED
2091 );
2092
2093 /* Tell the SCI_USER that the IO request is complete */
2094 if (this_request->is_task_management_request == false) {
2095 scic_cb_io_request_complete(
2096 scic_sds_request_get_controller(this_request),
2097 scic_sds_request_get_device(this_request),
2098 this_request,
2099 this_request->sci_status
2100 );
2101 } else {
2102 scic_cb_task_request_complete(
2103 scic_sds_request_get_controller(this_request),
2104 scic_sds_request_get_device(this_request),
2105 this_request,
2106 this_request->sci_status
2107 );
2108 }
2109}
2110
2111/**
2112 * scic_sds_request_aborting_state_enter() -
2113 * @object: This parameter specifies the base object for which the state
2114 * transition is occuring. This object is cast into a SCIC_SDS_IO_REQUEST
2115 * object.
2116 *
2117 * This method implements the actions taken when entering the
2118 * SCI_BASE_REQUEST_STATE_ABORTING state. none
2119 */
2120static void scic_sds_request_aborting_state_enter(
2121 struct sci_base_object *object)
2122{
2123 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
2124
2125 /* Setting the abort bit in the Task Context is required by the silicon. */
2126 this_request->task_context_buffer->abort = 1;
2127
2128 SET_STATE_HANDLER(
2129 this_request,
2130 scic_sds_request_state_handler_table,
2131 SCI_BASE_REQUEST_STATE_ABORTING
2132 );
2133}
2134
2135/**
2136 * scic_sds_request_final_state_enter() -
2137 * @object: This parameter specifies the base object for which the state
2138 * transition is occuring. This is cast into a SCIC_SDS_IO_REQUEST object.
2139 *
2140 * This method implements the actions taken when entering the
2141 * SCI_BASE_REQUEST_STATE_FINAL state. The only action required is to put the
2142 * state handlers in place. none
2143 */
2144static void scic_sds_request_final_state_enter(
2145 struct sci_base_object *object)
2146{
2147 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
2148
2149 SET_STATE_HANDLER(
2150 this_request,
2151 scic_sds_request_state_handler_table,
2152 SCI_BASE_REQUEST_STATE_FINAL
2153 );
2154}
2155
2156/* --------------------------------------------------------------------------- */
2157
2158const struct sci_base_state scic_sds_request_state_table[] = {
2159 [SCI_BASE_REQUEST_STATE_INITIAL] = {
2160 .enter_state = scic_sds_request_initial_state_enter,
2161 },
2162 [SCI_BASE_REQUEST_STATE_CONSTRUCTED] = {
2163 .enter_state = scic_sds_request_constructed_state_enter,
2164 },
2165 [SCI_BASE_REQUEST_STATE_STARTED] = {
2166 .enter_state = scic_sds_request_started_state_enter,
2167 .exit_state = scic_sds_request_started_state_exit
2168 },
2169 [SCI_BASE_REQUEST_STATE_COMPLETED] = {
2170 .enter_state = scic_sds_request_completed_state_enter,
2171 },
2172 [SCI_BASE_REQUEST_STATE_ABORTING] = {
2173 .enter_state = scic_sds_request_aborting_state_enter,
2174 },
2175 [SCI_BASE_REQUEST_STATE_FINAL] = {
2176 .enter_state = scic_sds_request_final_state_enter,
2177 },
2178};
2179
diff --git a/drivers/scsi/isci/core/scic_sds_request.h b/drivers/scsi/isci/core/scic_sds_request.h
new file mode 100644
index 000000000000..0691a7552a2a
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_request.h
@@ -0,0 +1,484 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_SDS_IO_REQUEST_H_
57#define _SCIC_SDS_IO_REQUEST_H_
58
59/**
60 * This file contains the structures, constants and prototypes for the
61 * SCIC_SDS_IO_REQUEST object.
62 *
63 *
64 */
65
66#include "scic_io_request.h"
67
68#include "sci_base_request.h"
69#include "scu_task_context.h"
70#include "intel_sas.h"
71
72struct scic_sds_controller;
73struct scic_sds_remote_device;
74struct scic_sds_io_request_state_handler;
75
76/**
77 * enum _SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATES - This enumeration
78 * depicts all of the substates for a task management request to be
79 * performed in the STARTED super-state.
80 *
81 *
82 */
83enum scic_sds_raw_request_started_task_mgmt_substates {
84 /**
85 * The AWAIT_TC_COMPLETION sub-state indicates that the started raw
86 * task management request is waiting for the transmission of the
87 * initial frame (i.e. command, task, etc.).
88 */
89 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION,
90
91 /**
92 * This sub-state indicates that the started task management request
93 * is waiting for the reception of an unsolicited frame
94 * (i.e. response IU).
95 */
96 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE,
97};
98
99
100/**
101 * enum _SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATES - This enumeration depicts all
102 * of the substates for a SMP request to be performed in the STARTED
103 * super-state.
104 *
105 *
106 */
107enum scic_sds_smp_request_started_substates {
108 /**
109 * This sub-state indicates that the started task management request
110 * is waiting for the reception of an unsolicited frame
111 * (i.e. response IU).
112 */
113 SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE,
114
115 /**
116 * The AWAIT_TC_COMPLETION sub-state indicates that the started SMP request is
117 * waiting for the transmission of the initial frame (i.e. command, task, etc.).
118 */
119 SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION,
120};
121
122/**
123 * struct SCIC_SDS_IO_REQUEST - This structure contains or references all of
124 * the data necessary to process a task management or normal IO request.
125 *
126 *
127 */
128struct scic_sds_request {
129 /**
130 * This field indictes the parent object of the request.
131 */
132 struct sci_base_request parent;
133
134 void *user_request;
135
136 /**
137 * This field simply points to the controller to which this IO request
138 * is associated.
139 */
140 struct scic_sds_controller *owning_controller;
141
142 /**
143 * This field simply points to the remote device to which this IO request
144 * is associated.
145 */
146 struct scic_sds_remote_device *target_device;
147
148 /**
149 * This field is utilized to determine if the SCI user is managing
150 * the IO tag for this request or if the core is managing it.
151 */
152 bool was_tag_assigned_by_user;
153
154 /**
155 * This field indicates the IO tag for this request. The IO tag is
156 * comprised of the task_index and a sequence count. The sequence count
157 * is utilized to help identify tasks from one life to another.
158 */
159 u16 io_tag;
160
161 /**
162 * This field specifies the protocol being utilized for this
163 * IO request.
164 */
165 SCIC_TRANSPORT_PROTOCOL protocol;
166
167 /**
168 * This field indicates the completion status taken from the SCUs
169 * completion code. It indicates the completion result for the SCU hardware.
170 */
171 u32 scu_status;
172
173 /**
174 * This field indicates the completion status returned to the SCI user. It
175 * indicates the users view of the io request completion.
176 */
177 u32 sci_status;
178
179 /**
180 * This field contains the value to be utilized when posting (e.g. Post_TC,
181 * Post_TC_Abort) this request to the silicon.
182 */
183 u32 post_context;
184
185 void *command_buffer;
186 void *response_buffer;
187 struct scu_task_context *task_context_buffer;
188 struct scu_sgl_element_pair *sgl_element_pair_buffer;
189
190 /**
191 * This field indicates if this request is a task management request or
192 * normal IO request.
193 */
194 bool is_task_management_request;
195
196 /**
197 * This field indicates that this request contains an initialized started
198 * substate machine.
199 */
200 bool has_started_substate_machine;
201
202 /**
203 * This field is a pointer to the stored rx frame data. It is used in STP
204 * internal requests and SMP response frames. If this field is non-NULL the
205 * saved frame must be released on IO request completion.
206 *
207 * @todo In the future do we want to keep a list of RX frame buffers?
208 */
209 u32 saved_rx_frame_index;
210
211 /**
212 * This field specifies the data necessary to manage the sub-state
213 * machine executed while in the SCI_BASE_REQUEST_STATE_STARTED state.
214 */
215 struct sci_base_state_machine started_substate_machine;
216
217 /**
218 * This field specifies the current state handlers in place for this
219 * IO Request object. This field is updated each time the request
220 * changes state.
221 */
222 const struct scic_sds_io_request_state_handler *state_handlers;
223
224 /**
225 * This field in the recorded device sequence for the io request. This is
226 * recorded during the build operation and is compared in the start
227 * operation. If the sequence is different then there was a change of
228 * devices from the build to start operations.
229 */
230 u8 device_sequence;
231
232};
233
234
235typedef enum sci_status
236(*scic_sds_io_request_frame_handler_t)(struct scic_sds_request *req, u32 frame);
237
238typedef enum sci_status
239(*scic_sds_io_request_event_handler_t)(struct scic_sds_request *req, u32 event);
240
241typedef enum sci_status
242(*scic_sds_io_request_task_completion_handler_t)(struct scic_sds_request *req, u32 completion_code);
243
244/**
245 * struct scic_sds_io_request_state_handler - This is the SDS core definition
246 * of the state handlers.
247 *
248 *
249 */
250struct scic_sds_io_request_state_handler {
251 struct sci_base_request_state_handler parent;
252
253 scic_sds_io_request_task_completion_handler_t tc_completion_handler;
254 scic_sds_io_request_event_handler_t event_handler;
255 scic_sds_io_request_frame_handler_t frame_handler;
256
257};
258
259extern const struct sci_base_state scic_sds_request_state_table[];
260extern const struct scic_sds_io_request_state_handler scic_sds_request_state_handler_table[];
261
262extern const struct sci_base_state scic_sds_io_request_started_task_mgmt_substate_table[];
263extern const struct scic_sds_io_request_state_handler scic_sds_ssp_task_request_started_substate_handler_table[];
264
265extern const struct sci_base_state scic_sds_smp_request_started_substate_table[];
266extern const struct scic_sds_io_request_state_handler scic_sds_smp_request_started_substate_handler_table[];
267
268/**
269 *
270 *
271 * This macro returns the maximum number of SGL element paris that we will
272 * support in a single IO request.
273 */
274#define SCU_MAX_SGL_ELEMENT_PAIRS ((SCU_IO_REQUEST_SGE_COUNT + 1) / 2)
275
276/**
277 * scic_sds_request_get_controller() -
278 *
279 * This macro will return the controller for this io request object
280 */
281#define scic_sds_request_get_controller(this_request) \
282 ((this_request)->owning_controller)
283
284/**
285 * scic_sds_request_get_device() -
286 *
287 * This macro will return the device for this io request object
288 */
289#define scic_sds_request_get_device(this_request) \
290 ((this_request)->target_device)
291
292/**
293 * scic_sds_request_get_port() -
294 *
295 * This macro will return the port for this io request object
296 */
297#define scic_sds_request_get_port(this_request) \
298 scic_sds_remote_device_get_port(scic_sds_request_get_device(this_request))
299
300/**
301 * scic_sds_request_get_post_context() -
302 *
303 * This macro returns the constructed post context result for the io request.
304 */
305#define scic_sds_request_get_post_context(this_request) \
306 ((this_request)->post_context)
307
308/**
309 * scic_sds_request_get_task_context() -
310 *
311 * This is a helper macro to return the os handle for this request object.
312 */
313#define scic_sds_request_get_task_context(request) \
314 ((request)->task_context_buffer)
315
316#define CACHE_LINE_SIZE (64)
317#define scic_sds_request_align_task_context_buffer(address) \
318 ((struct scu_task_context *)(\
319 (((unsigned long)(address)) + (CACHE_LINE_SIZE - 1)) \
320 & ~(CACHE_LINE_SIZE - 1) \
321 ))
322
323/**
324 * scic_sds_request_align_sgl_element_buffer() -
325 *
326 * This macro will align the memory address so that it is correct for the SCU
327 * hardware to DMA the SGL element pairs.
328 */
329#define scic_sds_request_align_sgl_element_buffer(address) \
330 ((struct scu_sgl_element_pair *)(\
331 ((char *)(address)) \
332 + (\
333 ((~(unsigned long)(address)) + 1) \
334 & (sizeof(struct scu_sgl_element_pair) - 1) \
335 ) \
336 ))
337
338/**
339 * scic_sds_request_set_status() -
340 *
341 * This macro will set the scu hardware status and sci request completion
342 * status for an io request.
343 */
344#define scic_sds_request_set_status(request, scu_status_code, sci_status_code) \
345 { \
346 (request)->scu_status = (scu_status_code); \
347 (request)->sci_status = (sci_status_code); \
348 }
349
350#define scic_sds_request_complete(a_request) \
351 ((a_request)->state_handlers->parent.complete_handler(&(a_request)->parent))
352
353
354
355
356/**
357 * scic_sds_io_request_tc_completion() -
358 *
359 * This macro invokes the core state task completion handler for the
360 * SCIC_SDS_IO_REQUEST_T object.
361 */
362#define scic_sds_io_request_tc_completion(this_request, completion_code) \
363 { \
364 if (this_request->parent.state_machine.current_state_id \
365 == SCI_BASE_REQUEST_STATE_STARTED \
366 && this_request->has_started_substate_machine \
367 == false) \
368 scic_sds_request_started_state_tc_completion_handler(this_request, completion_code); \
369 else \
370 this_request->state_handlers->tc_completion_handler(this_request, completion_code); \
371 }
372
373/**
374 * SCU_SGL_ZERO() -
375 *
376 * This macro zeros the hardware SGL element data
377 */
378#define SCU_SGL_ZERO(scu_sge) \
379 { \
380 (scu_sge).length = 0; \
381 (scu_sge).address_lower = 0; \
382 (scu_sge).address_upper = 0; \
383 (scu_sge).address_modifier = 0; \
384 }
385
386/**
387 * SCU_SGL_COPY() -
388 *
389 * This macro copys the SGL Element data from the host os to the hardware SGL
390 * elment data
391 */
392#define SCU_SGL_COPY(os_handle, scu_sge, os_sge) \
393 { \
394 (scu_sge).length = \
395 scic_cb_sge_get_length_field(os_handle, os_sge); \
396 (scu_sge).address_upper = \
397 upper_32_bits(scic_cb_sge_get_address_field(os_handle, os_sge)); \
398 (scu_sge).address_lower = \
399 lower_32_bits(scic_cb_sge_get_address_field(os_handle, os_sge)); \
400 (scu_sge).address_modifier = 0; \
401 }
402
403/*
404 * *****************************************************************************
405 * * CORE REQUEST PROTOTYPES
406 * ***************************************************************************** */
407
408void scic_sds_request_build_sgl(
409 struct scic_sds_request *this_request);
410
411
412
413void scic_sds_stp_request_assign_buffers(
414 struct scic_sds_request *this_request);
415
416void scic_sds_smp_request_assign_buffers(
417 struct scic_sds_request *this_request);
418
419/* --------------------------------------------------------------------------- */
420
421enum sci_status scic_sds_request_start(
422 struct scic_sds_request *this_request);
423
424enum sci_status scic_sds_io_request_terminate(
425 struct scic_sds_request *this_request);
426
427enum sci_status scic_sds_io_request_complete(
428 struct scic_sds_request *this_request);
429
430void scic_sds_io_request_copy_response(
431 struct scic_sds_request *this_request);
432
433enum sci_status scic_sds_io_request_event_handler(
434 struct scic_sds_request *this_request,
435 u32 event_code);
436
437enum sci_status scic_sds_io_request_frame_handler(
438 struct scic_sds_request *this_request,
439 u32 frame_index);
440
441
442enum sci_status scic_sds_task_request_terminate(
443 struct scic_sds_request *this_request);
444
445/*
446 * *****************************************************************************
447 * * DEFAULT STATE HANDLERS
448 * ***************************************************************************** */
449
450enum sci_status scic_sds_request_default_start_handler(
451 struct sci_base_request *this_request);
452
453
454enum sci_status scic_sds_request_default_complete_handler(
455 struct sci_base_request *this_request);
456
457enum sci_status scic_sds_request_default_destruct_handler(
458 struct sci_base_request *this_request);
459
460enum sci_status scic_sds_request_default_tc_completion_handler(
461 struct scic_sds_request *this_request,
462 u32 completion_code);
463
464enum sci_status scic_sds_request_default_event_handler(
465 struct scic_sds_request *this_request,
466 u32 event_code);
467
468enum sci_status scic_sds_request_default_frame_handler(
469 struct scic_sds_request *this_request,
470 u32 frame_index);
471
472/*
473 * *****************************************************************************
474 * * STARTED STATE HANDLERS
475 * ***************************************************************************** */
476
477enum sci_status scic_sds_request_started_state_abort_handler(
478 struct sci_base_request *this_request);
479
480enum sci_status scic_sds_request_started_state_tc_completion_handler(
481 struct scic_sds_request *this_request,
482 u32 completion_code);
483
484#endif /* _SCIC_SDS_IO_REQUEST_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_smp_remote_device.c b/drivers/scsi/isci/core/scic_sds_smp_remote_device.c
new file mode 100644
index 000000000000..7cf78d3212cc
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_smp_remote_device.c
@@ -0,0 +1,410 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file contains This file contains the ready substate handlers for a SMP
58 * device.
59 *
60 *
61 */
62
63#include "sci_environment.h"
64#include "scic_user_callback.h"
65#include "scic_sds_remote_device.h"
66#include "scic_sds_controller.h"
67#include "scic_sds_port.h"
68#include "scic_sds_request.h"
69#include "scu_event_codes.h"
70#include "scu_task_context.h"
71
72
73/*
74 * *****************************************************************************
75 * * SMP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS
76 * ***************************************************************************** */
77
78/**
79 *
80 * @[in]: device The device the io is sent to.
81 * @[in]: request The io to start.
82 *
83 * This method will handle the start io operation for a SMP device that is in
84 * the idle state. enum sci_status
85 */
86static enum sci_status scic_sds_smp_remote_device_ready_idle_substate_start_io_handler(
87 struct sci_base_remote_device *device,
88 struct sci_base_request *request)
89{
90 enum sci_status status;
91 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
92 struct scic_sds_request *io_request = (struct scic_sds_request *)request;
93
94 /* Will the port allow the io request to start? */
95 status = this_device->owning_port->state_handlers->start_io_handler(
96 this_device->owning_port,
97 this_device,
98 io_request
99 );
100
101 if (status == SCI_SUCCESS) {
102 status =
103 scic_sds_remote_node_context_start_io(this_device->rnc, io_request);
104
105 if (status == SCI_SUCCESS) {
106 status = scic_sds_request_start(io_request);
107 }
108
109 if (status == SCI_SUCCESS) {
110 this_device->working_request = io_request;
111
112 sci_base_state_machine_change_state(
113 &this_device->ready_substate_machine,
114 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD
115 );
116 }
117
118 scic_sds_remote_device_start_request(this_device, io_request, status);
119 }
120
121 return status;
122}
123
124
125/*
126 * ******************************************************************************
127 * * SMP REMOTE DEVICE READY SUBSTATE CMD HANDLERS
128 * ****************************************************************************** */
129/**
130 *
131 * @device: This is the device object that is receiving the IO.
132 * @request: The io to start.
133 *
134 * This device is already handling a command it can not accept new commands
135 * until this one is complete. enum sci_status
136 */
137static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_start_io_handler(
138 struct sci_base_remote_device *device,
139 struct sci_base_request *request)
140{
141 return SCI_FAILURE_INVALID_STATE;
142}
143
144
145/**
146 * this is the complete_io_handler for smp device at ready cmd substate.
147 * @device: This is the device object that is receiving the IO.
148 * @request: The io to start.
149 *
150 * enum sci_status
151 */
152static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_complete_io_handler(
153 struct sci_base_remote_device *device,
154 struct sci_base_request *request)
155{
156 enum sci_status status;
157 struct scic_sds_remote_device *this_device;
158 struct scic_sds_request *the_request;
159
160 this_device = (struct scic_sds_remote_device *)device;
161 the_request = (struct scic_sds_request *)request;
162
163 status = scic_sds_io_request_complete(the_request);
164
165 if (status == SCI_SUCCESS) {
166 status = scic_sds_port_complete_io(
167 this_device->owning_port, this_device, the_request);
168
169 if (status == SCI_SUCCESS) {
170 scic_sds_remote_device_decrement_request_count(this_device);
171 sci_base_state_machine_change_state(
172 &this_device->ready_substate_machine,
173 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
174 );
175 } else
176 dev_err(scirdev_to_dev(this_device),
177 "%s: SCIC SDS Remote Device 0x%p io request "
178 "0x%p could not be completd on the port 0x%p "
179 "failed with status %d.\n",
180 __func__,
181 this_device,
182 the_request,
183 this_device->owning_port,
184 status);
185 }
186
187 return status;
188}
189
190/**
191 * This is frame handler for smp device ready cmd substate.
192 * @this_device: This is the device object that is receiving the frame.
193 * @frame_index: The index for the frame received.
194 *
195 * enum sci_status
196 */
197static enum sci_status scic_sds_smp_remote_device_ready_cmd_substate_frame_handler(
198 struct scic_sds_remote_device *this_device,
199 u32 frame_index)
200{
201 enum sci_status status;
202
203 /*
204 * / The device does not process any UF received from the hardware while
205 * / in this state. All unsolicited frames are forwarded to the io request
206 * / object. */
207 status = scic_sds_io_request_frame_handler(
208 this_device->working_request,
209 frame_index
210 );
211
212 return status;
213}
214
215/* --------------------------------------------------------------------------- */
216
217struct scic_sds_remote_device_state_handler
218scic_sds_smp_remote_device_ready_substate_handler_table[
219 SCIC_SDS_SMP_REMOTE_DEVICE_READY_MAX_SUBSTATES] =
220{
221 /* SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE */
222 {
223 {
224 scic_sds_remote_device_default_start_handler,
225 scic_sds_remote_device_ready_state_stop_handler,
226 scic_sds_remote_device_default_fail_handler,
227 scic_sds_remote_device_default_destruct_handler,
228 scic_sds_remote_device_default_reset_handler,
229 scic_sds_remote_device_default_reset_complete_handler,
230 scic_sds_smp_remote_device_ready_idle_substate_start_io_handler,
231 scic_sds_remote_device_default_complete_request_handler,
232 scic_sds_remote_device_default_continue_request_handler,
233 scic_sds_remote_device_default_start_request_handler,
234 scic_sds_remote_device_default_complete_request_handler
235 },
236 scic_sds_remote_device_default_suspend_handler,
237 scic_sds_remote_device_default_resume_handler,
238 scic_sds_remote_device_general_event_handler,
239 scic_sds_remote_device_default_frame_handler
240 },
241 /* SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD */
242 {
243 {
244 scic_sds_remote_device_default_start_handler,
245 scic_sds_remote_device_ready_state_stop_handler,
246 scic_sds_remote_device_default_fail_handler,
247 scic_sds_remote_device_default_destruct_handler,
248 scic_sds_remote_device_default_reset_handler,
249 scic_sds_remote_device_default_reset_complete_handler,
250 scic_sds_smp_remote_device_ready_cmd_substate_start_io_handler,
251 scic_sds_smp_remote_device_ready_cmd_substate_complete_io_handler,
252 scic_sds_remote_device_default_continue_request_handler,
253 scic_sds_remote_device_default_start_request_handler,
254 scic_sds_remote_device_default_complete_request_handler
255 },
256 scic_sds_remote_device_default_suspend_handler,
257 scic_sds_remote_device_default_resume_handler,
258 scic_sds_remote_device_general_event_handler,
259 scic_sds_smp_remote_device_ready_cmd_substate_frame_handler
260 }
261};
262/*
263 * This file is provided under a dual BSD/GPLv2 license. When using or
264 * redistributing this file, you may do so under either license.
265 *
266 * GPL LICENSE SUMMARY
267 *
268 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
269 *
270 * This program is free software; you can redistribute it and/or modify
271 * it under the terms of version 2 of the GNU General Public License as
272 * published by the Free Software Foundation.
273 *
274 * This program is distributed in the hope that it will be useful, but
275 * WITHOUT ANY WARRANTY; without even the implied warranty of
276 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
277 * General Public License for more details.
278 *
279 * You should have received a copy of the GNU General Public License
280 * along with this program; if not, write to the Free Software
281 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
282 * The full GNU General Public License is included in this distribution
283 * in the file called LICENSE.GPL.
284 *
285 * BSD LICENSE
286 *
287 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
288 * All rights reserved.
289 *
290 * Redistribution and use in source and binary forms, with or without
291 * modification, are permitted provided that the following conditions
292 * are met:
293 *
294 * * Redistributions of source code must retain the above copyright
295 * notice, this list of conditions and the following disclaimer.
296 * * Redistributions in binary form must reproduce the above copyright
297 * notice, this list of conditions and the following disclaimer in
298 * the documentation and/or other materials provided with the
299 * distribution.
300 * * Neither the name of Intel Corporation nor the names of its
301 * contributors may be used to endorse or promote products derived
302 * from this software without specific prior written permission.
303 *
304 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
305 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
306 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
307 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
308 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
309 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
310 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
311 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
312 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
313 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
314 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
315 */
316
317/**
318 * This file contains the enter and exit functions for the
319 * struct scic_sds_remote_device ready substate machine.
320 *
321 *
322 */
323
324#include "scic_remote_device.h"
325#include "scic_user_callback.h"
326#include "scic_sds_remote_device.h"
327#include "scic_sds_controller.h"
328#include "scic_sds_port.h"
329#include "sci_util.h"
330#include "sci_environment.h"
331
332/**
333 *
334 * @object: This is the struct sci_base_object which is cast into a
335 * struct scic_sds_remote_device.
336 *
337 * This is the SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE enter method.
338 * This method sets the ready cmd substate handlers and reports the device as
339 * ready. none
340 */
341static void scic_sds_smp_remote_device_ready_idle_substate_enter(
342 struct sci_base_object *object)
343{
344 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
345
346 SET_STATE_HANDLER(
347 this_device,
348 scic_sds_smp_remote_device_ready_substate_handler_table,
349 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
350 );
351
352 scic_cb_remote_device_ready(
353 scic_sds_remote_device_get_controller(this_device), this_device);
354}
355
356/**
357 *
358 * @object: This is the struct sci_base_object which is cast into a
359 * struct scic_sds_remote_device.
360 *
361 * This is the SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD enter method. This
362 * method sets the remote device objects ready cmd substate handlers, and
363 * notify core user that the device is not ready. none
364 */
365static void scic_sds_smp_remote_device_ready_cmd_substate_enter(
366 struct sci_base_object *object)
367{
368 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
369
370 BUG_ON(this_device->working_request == NULL);
371
372 SET_STATE_HANDLER(
373 this_device,
374 scic_sds_smp_remote_device_ready_substate_handler_table,
375 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD
376 );
377
378 scic_cb_remote_device_not_ready(
379 scic_sds_remote_device_get_controller(this_device),
380 this_device,
381 SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED
382 );
383}
384
385/**
386 *
387 * @object: This is the struct sci_base_object which is cast into a
388 * struct scic_sds_remote_device.
389 *
390 * This is the SCIC_SDS_SSP_REMOTE_DEVICE_READY_SUBSTATE_CMD exit method. none
391 */
392static void scic_sds_smp_remote_device_ready_cmd_substate_exit(
393 struct sci_base_object *object)
394{
395 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)object;
396
397 this_device->working_request = NULL;
398}
399
400/* --------------------------------------------------------------------------- */
401
402const struct sci_base_state scic_sds_smp_remote_device_ready_substate_table[] = {
403 [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
404 .enter_state = scic_sds_smp_remote_device_ready_idle_substate_enter,
405 },
406 [SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
407 .enter_state = scic_sds_smp_remote_device_ready_cmd_substate_enter,
408 .exit_state = scic_sds_smp_remote_device_ready_cmd_substate_exit,
409 },
410};
diff --git a/drivers/scsi/isci/core/scic_sds_smp_request.c b/drivers/scsi/isci/core/scic_sds_smp_request.c
new file mode 100644
index 000000000000..949d23e7452a
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_smp_request.c
@@ -0,0 +1,669 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include "intel_sas.h"
57#include "sci_base_state_machine.h"
58#include "scic_controller.h"
59#include "scic_remote_device.h"
60#include "scic_sds_controller.h"
61#include "scic_sds_remote_device.h"
62#include "scic_sds_request.h"
63#include "scic_sds_smp_request.h"
64#include "sci_environment.h"
65#include "sci_util.h"
66#include "scu_completion_codes.h"
67#include "scu_task_context.h"
68
69static void scu_smp_request_construct_task_context(
70 struct scic_sds_request *this_request,
71 struct smp_request *smp_request);
72
73/**
74 *
75 *
76 * This method return the memory space required for STP PIO requests. u32
77 */
78u32 scic_sds_smp_request_get_object_size(void)
79{
80 return sizeof(struct scic_sds_request)
81 + sizeof(struct smp_request)
82 + sizeof(struct smp_response)
83 + sizeof(struct scu_task_context);
84}
85
86/**
87 * scic_sds_smp_request_get_command_buffer() -
88 *
89 * This macro returns the address of the smp command buffer in the smp request
90 * memory. No need to cast to SMP request type.
91 */
92#define scic_sds_smp_request_get_command_buffer(memory) \
93 (((char *)(memory)) + sizeof(struct scic_sds_request))
94
95/**
96 * scic_sds_smp_request_get_response_buffer() -
97 *
98 * This macro returns the address of the smp response buffer in the smp request
99 * memory.
100 */
101#define scic_sds_smp_request_get_response_buffer(memory) \
102 (((char *)(scic_sds_smp_request_get_command_buffer(memory))) \
103 + sizeof(struct smp_request))
104
105/**
106 * scic_sds_smp_request_get_task_context_buffer() -
107 *
108 * This macro returs the task context buffer for the SMP request.
109 */
110#define scic_sds_smp_request_get_task_context_buffer(memory) \
111 ((struct scu_task_context *)(\
112 ((char *)(scic_sds_smp_request_get_response_buffer(memory))) \
113 + sizeof(struct smp_response) \
114 ))
115
116
117
118/**
119 * This method build the remainder of the IO request object.
120 * @this_request: This parameter specifies the request object being constructed.
121 *
122 * The scic_sds_general_request_construct() must be called before this call is
123 * valid. none
124 */
125
126void scic_sds_smp_request_assign_buffers(
127 struct scic_sds_request *this_request)
128{
129 /* Assign all of the buffer pointers */
130 this_request->command_buffer =
131 scic_sds_smp_request_get_command_buffer(this_request);
132 this_request->response_buffer =
133 scic_sds_smp_request_get_response_buffer(this_request);
134 this_request->sgl_element_pair_buffer = NULL;
135
136 if (this_request->was_tag_assigned_by_user == false) {
137 this_request->task_context_buffer =
138 scic_sds_smp_request_get_task_context_buffer(this_request);
139 this_request->task_context_buffer =
140 scic_sds_request_align_task_context_buffer(this_request->task_context_buffer);
141 }
142
143}
144/**
145 * This method is called by the SCI user to build an SMP IO request.
146 *
147 * - The user must have previously called scic_io_request_construct() on the
148 * supplied IO request. Indicate if the controller successfully built the IO
149 * request. SCI_SUCCESS This value is returned if the IO request was
150 * successfully built. SCI_FAILURE_UNSUPPORTED_PROTOCOL This value is returned
151 * if the remote_device does not support the SMP protocol.
152 * SCI_FAILURE_INVALID_ASSOCIATION This value is returned if the user did not
153 * properly set the association between the SCIC IO request and the user's IO
154 * request. Please refer to the sci_object_set_association() routine for more
155 * information.
156 */
157enum sci_status scic_io_request_construct_smp(
158 struct scic_sds_request *sci_req)
159{
160 struct smp_request *smp_req = kmalloc(sizeof(*smp_req), GFP_KERNEL);
161
162 if (!smp_req)
163 return SCI_FAILURE_INSUFFICIENT_RESOURCES;
164
165 sci_req->protocol = SCIC_SMP_PROTOCOL;
166 sci_req->has_started_substate_machine = true;
167
168 /* Construct the started sub-state machine. */
169 sci_base_state_machine_construct(
170 &sci_req->started_substate_machine,
171 &sci_req->parent.parent,
172 scic_sds_smp_request_started_substate_table,
173 SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE
174 );
175
176 /* Construct the SMP SCU Task Context */
177 memcpy(smp_req, sci_req->command_buffer, sizeof(*smp_req));
178
179 /*
180 * Look at the SMP requests' header fields; for certain SAS 1.x SMP
181 * functions under SAS 2.0, a zero request length really indicates
182 * a non-zero default length. */
183 if (smp_req->header.request_length == 0) {
184 switch (smp_req->header.function) {
185 case SMP_FUNCTION_DISCOVER:
186 case SMP_FUNCTION_REPORT_PHY_ERROR_LOG:
187 case SMP_FUNCTION_REPORT_PHY_SATA:
188 case SMP_FUNCTION_REPORT_ROUTE_INFORMATION:
189 smp_req->header.request_length = 2;
190 break;
191 case SMP_FUNCTION_CONFIGURE_ROUTE_INFORMATION:
192 case SMP_FUNCTION_PHY_CONTROL:
193 case SMP_FUNCTION_PHY_TEST:
194 smp_req->header.request_length = 9;
195 break;
196 /* Default - zero is a valid default for 2.0. */
197 }
198 }
199
200 scu_smp_request_construct_task_context(sci_req, smp_req);
201
202 sci_base_state_machine_change_state(
203 &sci_req->parent.state_machine,
204 SCI_BASE_REQUEST_STATE_CONSTRUCTED
205 );
206
207 kfree(smp_req);
208
209 return SCI_SUCCESS;
210}
211
212/**
213 * This method is called by the SCI user to build an SMP pass-through IO
214 * request.
215 * @scic_smp_request: This parameter specifies the handle to the io request
216 * object to be built.
217 * @passthru_cb: This parameter specifies the pointer to the callback structure
218 * that contains the function pointers
219 *
220 * - The user must have previously called scic_io_request_construct() on the
221 * supplied IO request. Indicate if the controller successfully built the IO
222 * request.
223 */
224
225/**
226 * This method will fill in the SCU Task Context for a SMP request. The
227 * following important settings are utilized: -# task_type ==
228 * SCU_TASK_TYPE_SMP. This simply indicates that a normal request type
229 * (i.e. non-raw frame) is being utilized to perform task management. -#
230 * control_frame == 1. This ensures that the proper endianess is set so
231 * that the bytes are transmitted in the right order for a smp request frame.
232 * @this_request: This parameter specifies the smp request object being
233 * constructed.
234 *
235 */
236static void scu_smp_request_construct_task_context(
237 struct scic_sds_request *this_request,
238 struct smp_request *smp_request)
239{
240 dma_addr_t physical_address;
241 struct scic_sds_controller *owning_controller;
242 struct scic_sds_remote_device *target_device;
243 struct scic_sds_port *target_port;
244 struct scu_task_context *task_context;
245
246 /* byte swap the smp request. */
247 scic_word_copy_with_swap(
248 this_request->command_buffer,
249 (u32 *)smp_request,
250 sizeof(struct smp_request) / sizeof(u32)
251 );
252
253 task_context = scic_sds_request_get_task_context(this_request);
254
255 owning_controller = scic_sds_request_get_controller(this_request);
256 target_device = scic_sds_request_get_device(this_request);
257 target_port = scic_sds_request_get_port(this_request);
258
259 /*
260 * Fill in the TC with the its required data
261 * 00h */
262 task_context->priority = 0;
263 task_context->initiator_request = 1;
264 task_context->connection_rate =
265 scic_remote_device_get_connection_rate(target_device);
266 task_context->protocol_engine_index =
267 scic_sds_controller_get_protocol_engine_group(owning_controller);
268 task_context->logical_port_index =
269 scic_sds_port_get_index(target_port);
270 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SMP;
271 task_context->abort = 0;
272 task_context->valid = SCU_TASK_CONTEXT_VALID;
273 task_context->context_type = SCU_TASK_CONTEXT_TYPE;
274
275 /* 04h */
276 task_context->remote_node_index = this_request->target_device->rnc->remote_node_index;
277 task_context->command_code = 0;
278 task_context->task_type = SCU_TASK_TYPE_SMP_REQUEST;
279
280 /* 08h */
281 task_context->link_layer_control = 0;
282 task_context->do_not_dma_ssp_good_response = 1;
283 task_context->strict_ordering = 0;
284 task_context->control_frame = 1;
285 task_context->timeout_enable = 0;
286 task_context->block_guard_enable = 0;
287
288 /* 0ch */
289 task_context->address_modifier = 0;
290
291 /* 10h */
292 task_context->ssp_command_iu_length = smp_request->header.request_length;
293
294 /* 14h */
295 task_context->transfer_length_bytes = 0;
296
297 /*
298 * 18h ~ 30h, protocol specific
299 * since commandIU has been build by framework at this point, we just
300 * copy the frist DWord from command IU to this location. */
301 memcpy((void *)(&task_context->type.smp), this_request->command_buffer, sizeof(u32));
302
303 /*
304 * 40h
305 * "For SMP you could program it to zero. We would prefer that way so that
306 * done code will be consistent." - Venki */
307 task_context->task_phase = 0;
308
309 if (this_request->was_tag_assigned_by_user) {
310 /* Build the task context now since we have already read the data */
311 this_request->post_context = (
312 SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
313 | (
314 scic_sds_controller_get_protocol_engine_group(owning_controller)
315 << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
316 )
317 | (
318 scic_sds_port_get_index(target_port)
319 << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
320 )
321 | scic_sds_io_tag_get_index(this_request->io_tag)
322 );
323 } else {
324 /* Build the task context now since we have already read the data */
325 this_request->post_context = (
326 SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
327 | (
328 scic_sds_controller_get_protocol_engine_group(owning_controller)
329 << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
330 )
331 | (
332 scic_sds_port_get_index(target_port)
333 << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
334 )
335 /* This is not assigned because we have to wait until we get a TCi */
336 );
337 }
338
339 /*
340 * Copy the physical address for the command buffer to the SCU Task Context
341 * command buffer should not contain command header. */
342 scic_cb_io_request_get_physical_address(
343 scic_sds_request_get_controller(this_request),
344 this_request,
345 ((char *)(this_request->command_buffer) + sizeof(u32)),
346 &physical_address
347 );
348
349 task_context->command_iu_upper =
350 upper_32_bits(physical_address);
351 task_context->command_iu_lower =
352 lower_32_bits(physical_address);
353
354
355 /* SMP response comes as UF, so no need to set response IU address. */
356 task_context->response_iu_upper = 0;
357 task_context->response_iu_lower = 0;
358}
359
360/**
361 * This method processes an unsolicited frame while the SMP request is waiting
362 * for a response frame. It will copy the response data, release the
363 * unsolicited frame, and transition the request to the
364 * SCI_BASE_REQUEST_STATE_COMPLETED state.
365 * @this_request: This parameter specifies the request for which the
366 * unsolicited frame was received.
367 * @frame_index: This parameter indicates the unsolicited frame index that
368 * should contain the response.
369 *
370 * This method returns an indication of whether the response frame was handled
371 * successfully or not. SCI_SUCCESS Currently this value is always returned and
372 * indicates successful processing of the TC response.
373 */
374static enum sci_status scic_sds_smp_request_await_response_frame_handler(
375 struct scic_sds_request *this_request,
376 u32 frame_index)
377{
378 enum sci_status status;
379 void *frame_header;
380 struct smp_response_header *this_frame_header;
381 u8 *user_smp_buffer = this_request->response_buffer;
382
383 status = scic_sds_unsolicited_frame_control_get_header(
384 &(scic_sds_request_get_controller(this_request)->uf_control),
385 frame_index,
386 &frame_header
387 );
388
389 /* byte swap the header. */
390 scic_word_copy_with_swap(
391 (u32 *)user_smp_buffer,
392 frame_header,
393 sizeof(struct smp_response_header) / sizeof(u32)
394 );
395 this_frame_header = (struct smp_response_header *)user_smp_buffer;
396
397 if (this_frame_header->smp_frame_type == SMP_FRAME_TYPE_RESPONSE) {
398 void *smp_response_buffer;
399
400 status = scic_sds_unsolicited_frame_control_get_buffer(
401 &(scic_sds_request_get_controller(this_request)->uf_control),
402 frame_index,
403 &smp_response_buffer
404 );
405
406 scic_word_copy_with_swap(
407 (u32 *)(user_smp_buffer + sizeof(struct smp_response_header)),
408 smp_response_buffer,
409 sizeof(union smp_response_body) / sizeof(u32)
410 );
411 if (this_frame_header->function == SMP_FUNCTION_DISCOVER) {
412 struct smp_response *this_smp_response;
413
414 this_smp_response = (struct smp_response *)user_smp_buffer;
415
416 /*
417 * Some expanders only report an attached SATA device, and
418 * not an STP target. Since the core depends on the STP
419 * target attribute to correctly build I/O, set the bit now
420 * if necessary. */
421 if (this_smp_response->response.discover.protocols.u.bits.attached_sata_device
422 && !this_smp_response->response.discover.protocols.u.bits.attached_stp_target) {
423 this_smp_response->response.discover.protocols.u.bits.attached_stp_target = 1;
424
425 dev_dbg(scic_to_dev(this_request->owning_controller),
426 "%s: scic_sds_smp_request_await_response_frame_handler(0x%p) Found SATA dev, setting STP bit.\n",
427 __func__, this_request);
428 }
429 }
430
431 /*
432 * Don't need to copy to user space. User instead will refer to
433 * core request's response buffer. */
434
435 /*
436 * copy the smp response to framework smp request's response buffer.
437 * scic_sds_smp_request_copy_response(this_request); */
438
439 scic_sds_request_set_status(
440 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
441 );
442
443 sci_base_state_machine_change_state(
444 &this_request->started_substate_machine,
445 SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION
446 );
447 } else {
448 /* This was not a response frame why did it get forwarded? */
449 dev_err(scic_to_dev(this_request->owning_controller),
450 "%s: SCIC SMP Request 0x%p received unexpected frame "
451 "%d type 0x%02x\n",
452 __func__,
453 this_request,
454 frame_index,
455 this_frame_header->smp_frame_type);
456
457 scic_sds_request_set_status(
458 this_request,
459 SCU_TASK_DONE_SMP_FRM_TYPE_ERR,
460 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
461 );
462
463 sci_base_state_machine_change_state(
464 &this_request->parent.state_machine,
465 SCI_BASE_REQUEST_STATE_COMPLETED
466 );
467 }
468
469 scic_sds_controller_release_frame(
470 this_request->owning_controller, frame_index
471 );
472
473 return SCI_SUCCESS;
474}
475
476
477/**
478 * This method processes an abnormal TC completion while the SMP request is
479 * waiting for a response frame. It decides what happened to the IO based
480 * on TC completion status.
481 * @this_request: This parameter specifies the request for which the TC
482 * completion was received.
483 * @completion_code: This parameter indicates the completion status information
484 * for the TC.
485 *
486 * Indicate if the tc completion handler was successful. SCI_SUCCESS currently
487 * this method always returns success.
488 */
489static enum sci_status scic_sds_smp_request_await_response_tc_completion_handler(
490 struct scic_sds_request *this_request,
491 u32 completion_code)
492{
493 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
494 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
495 /*
496 * In the AWAIT RESPONSE state, any TC completion is unexpected.
497 * but if the TC has success status, we complete the IO anyway. */
498 scic_sds_request_set_status(
499 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
500 );
501
502 sci_base_state_machine_change_state(
503 &this_request->parent.state_machine,
504 SCI_BASE_REQUEST_STATE_COMPLETED
505 );
506 break;
507
508 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_RESP_TO_ERR):
509 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_UFI_ERR):
510 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_FRM_TYPE_ERR):
511 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_LL_RX_ERR):
512 /*
513 * These status has been seen in a specific LSI expander, which sometimes
514 * is not able to send smp response within 2 ms. This causes our hardware
515 * break the connection and set TC completion with one of these SMP_XXX_XX_ERR
516 * status. For these type of error, we ask scic user to retry the request. */
517 scic_sds_request_set_status(
518 this_request, SCU_TASK_DONE_SMP_RESP_TO_ERR, SCI_FAILURE_RETRY_REQUIRED
519 );
520
521 sci_base_state_machine_change_state(
522 &this_request->parent.state_machine,
523 SCI_BASE_REQUEST_STATE_COMPLETED
524 );
525 break;
526
527 default:
528 /*
529 * All other completion status cause the IO to be complete. If a NAK
530 * was received, then it is up to the user to retry the request. */
531 scic_sds_request_set_status(
532 this_request,
533 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
534 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
535 );
536
537 sci_base_state_machine_change_state(
538 &this_request->parent.state_machine,
539 SCI_BASE_REQUEST_STATE_COMPLETED
540 );
541 break;
542 }
543
544 return SCI_SUCCESS;
545}
546
547
548/**
549 * This method processes the completions transport layer (TL) status to
550 * determine if the SMP request was sent successfully. If the SMP request
551 * was sent successfully, then the state for the SMP request transits to
552 * waiting for a response frame.
553 * @this_request: This parameter specifies the request for which the TC
554 * completion was received.
555 * @completion_code: This parameter indicates the completion status information
556 * for the TC.
557 *
558 * Indicate if the tc completion handler was successful. SCI_SUCCESS currently
559 * this method always returns success.
560 */
561static enum sci_status scic_sds_smp_request_await_tc_completion_tc_completion_handler(
562 struct scic_sds_request *this_request,
563 u32 completion_code)
564{
565 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
566 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
567 scic_sds_request_set_status(
568 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
569 );
570
571 sci_base_state_machine_change_state(
572 &this_request->parent.state_machine,
573 SCI_BASE_REQUEST_STATE_COMPLETED
574 );
575 break;
576
577 default:
578 /*
579 * All other completion status cause the IO to be complete. If a NAK
580 * was received, then it is up to the user to retry the request. */
581 scic_sds_request_set_status(
582 this_request,
583 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
584 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
585 );
586
587 sci_base_state_machine_change_state(
588 &this_request->parent.state_machine,
589 SCI_BASE_REQUEST_STATE_COMPLETED
590 );
591 break;
592 }
593
594 return SCI_SUCCESS;
595}
596
597
598const struct scic_sds_io_request_state_handler scic_sds_smp_request_started_substate_handler_table[] = {
599 [SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE] = {
600 .parent.start_handler = scic_sds_request_default_start_handler,
601 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
602 .parent.complete_handler = scic_sds_request_default_complete_handler,
603 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
604 .tc_completion_handler = scic_sds_smp_request_await_response_tc_completion_handler,
605 .event_handler = scic_sds_request_default_event_handler,
606 .frame_handler = scic_sds_smp_request_await_response_frame_handler,
607 },
608 [SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION] = {
609 .parent.start_handler = scic_sds_request_default_start_handler,
610 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
611 .parent.complete_handler = scic_sds_request_default_complete_handler,
612 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
613 .tc_completion_handler = scic_sds_smp_request_await_tc_completion_tc_completion_handler,
614 .event_handler = scic_sds_request_default_event_handler,
615 .frame_handler = scic_sds_request_default_frame_handler,
616 }
617};
618
619/**
620 * This method performs the actions required when entering the
621 * SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_RESPONSE sub-state. This
622 * includes setting the IO request state handlers for this sub-state.
623 * @object: This parameter specifies the request object for which the sub-state
624 * change is occuring.
625 *
626 * none.
627 */
628static void scic_sds_smp_request_started_await_response_substate_enter(
629 struct sci_base_object *object)
630{
631 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
632
633 SET_STATE_HANDLER(
634 this_request,
635 scic_sds_smp_request_started_substate_handler_table,
636 SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE
637 );
638}
639
640/**
641 * This method performs the actions required when entering the
642 * SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION sub-state.
643 * This includes setting the SMP request state handlers for this sub-state.
644 * @object: This parameter specifies the request object for which the sub-state
645 * change is occuring.
646 *
647 * none.
648 */
649static void scic_sds_smp_request_started_await_tc_completion_substate_enter(
650 struct sci_base_object *object)
651{
652 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
653
654 SET_STATE_HANDLER(
655 this_request,
656 scic_sds_smp_request_started_substate_handler_table,
657 SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION
658 );
659}
660
661const struct sci_base_state scic_sds_smp_request_started_substate_table[] = {
662 [SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE] = {
663 .enter_state = scic_sds_smp_request_started_await_response_substate_enter,
664 },
665 [SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION] = {
666 .enter_state = scic_sds_smp_request_started_await_tc_completion_substate_enter,
667 },
668};
669
diff --git a/drivers/scsi/isci/core/scic_sds_smp_request.h b/drivers/scsi/isci/core/scic_sds_smp_request.h
new file mode 100644
index 000000000000..b7c5b83b1989
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_smp_request.h
@@ -0,0 +1,70 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55#ifndef _SCIC_SDS_SMP_REQUEST_T_
56#define _SCIC_SDS_SMP_REQUEST_T_
57
58#include "intel_sas.h"
59#include "sci_types.h"
60#include "scic_sds_request.h"
61
62
63u32 scic_sds_smp_request_get_object_size(void);
64
65
66void scic_sds_smp_request_copy_response(
67 struct scic_sds_request *this_request);
68
69#endif /* _SCIC_SDS_SMP_REQUEST_T_ */
70
diff --git a/drivers/scsi/isci/core/scic_sds_ssp_request.c b/drivers/scsi/isci/core/scic_sds_ssp_request.c
new file mode 100644
index 000000000000..0d6441c5ce00
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_ssp_request.c
@@ -0,0 +1,340 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file contains the task management substate handlers for the
58 * SCIC_SDS_IO_REQUEST object.
59 *
60 *
61 */
62
63#include "intel_sas.h"
64#include "sci_environment.h"
65#include "scic_sds_request.h"
66#include "scic_controller.h"
67#include "scic_sds_controller.h"
68#include "scu_completion_codes.h"
69#include "scu_task_context.h"
70
71/**
72 * This method processes the completions transport layer (TL) status to
73 * determine if the RAW task management frame was sent successfully. If the
74 * raw frame was sent successfully, then the state for the task request
75 * transitions to waiting for a response frame.
76 * @this_request: This parameter specifies the request for which the TC
77 * completion was received.
78 * @completion_code: This parameter indicates the completion status information
79 * for the TC.
80 *
81 * Indicate if the tc completion handler was successful. SCI_SUCCESS currently
82 * this method always returns success.
83 */
84static enum sci_status scic_sds_ssp_task_request_await_tc_completion_tc_completion_handler(
85 struct scic_sds_request *this_request,
86 u32 completion_code)
87{
88 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
89 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
90 scic_sds_request_set_status(
91 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
92 );
93
94 sci_base_state_machine_change_state(
95 &this_request->started_substate_machine,
96 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE
97 );
98 break;
99
100 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_ACK_NAK_TO):
101 /*
102 * Currently, the decision is to simply allow the task request to
103 * timeout if the task IU wasn't received successfully.
104 * There is a potential for receiving multiple task responses if we
105 * decide to send the task IU again. */
106 dev_warn(scic_to_dev(this_request->owning_controller),
107 "%s: TaskRequest:0x%p CompletionCode:%x - "
108 "ACK/NAK timeout\n",
109 __func__,
110 this_request,
111 completion_code);
112
113 sci_base_state_machine_change_state(
114 &this_request->started_substate_machine,
115 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE
116 );
117 break;
118
119 default:
120 /*
121 * All other completion status cause the IO to be complete. If a NAK
122 * was received, then it is up to the user to retry the request. */
123 scic_sds_request_set_status(
124 this_request,
125 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
126 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
127 );
128
129 sci_base_state_machine_change_state(
130 &this_request->parent.state_machine,
131 SCI_BASE_REQUEST_STATE_COMPLETED
132 );
133 break;
134 }
135
136 return SCI_SUCCESS;
137}
138
139/**
140 * This method is responsible for processing a terminate/abort request for this
141 * TC while the request is waiting for the task management response
142 * unsolicited frame.
143 * @this_request: This parameter specifies the request for which the
144 * termination was requested.
145 *
146 * This method returns an indication as to whether the abort request was
147 * successfully handled. need to update to ensure the received UF doesn't cause
148 * damage to subsequent requests (i.e. put the extended tag in a holding
149 * pattern for this particular device).
150 */
151static enum sci_status scic_sds_ssp_task_request_await_tc_response_abort_handler(
152 struct sci_base_request *request)
153{
154 struct scic_sds_request *this_request = (struct scic_sds_request *)request;
155
156 sci_base_state_machine_change_state(
157 &this_request->parent.state_machine,
158 SCI_BASE_REQUEST_STATE_ABORTING
159 );
160
161 sci_base_state_machine_change_state(
162 &this_request->parent.state_machine,
163 SCI_BASE_REQUEST_STATE_COMPLETED
164 );
165
166 return SCI_SUCCESS;
167}
168
169/**
170 * This method processes an unsolicited frame while the task mgmt request is
171 * waiting for a response frame. It will copy the response data, release
172 * the unsolicited frame, and transition the request to the
173 * SCI_BASE_REQUEST_STATE_COMPLETED state.
174 * @this_request: This parameter specifies the request for which the
175 * unsolicited frame was received.
176 * @frame_index: This parameter indicates the unsolicited frame index that
177 * should contain the response.
178 *
179 * This method returns an indication of whether the TC response frame was
180 * handled successfully or not. SCI_SUCCESS Currently this value is always
181 * returned and indicates successful processing of the TC response. Should
182 * probably update to check frame type and make sure it is a response frame.
183 */
184static enum sci_status scic_sds_ssp_task_request_await_tc_response_frame_handler(
185 struct scic_sds_request *this_request,
186 u32 frame_index)
187{
188 scic_sds_io_request_copy_response(this_request);
189
190 sci_base_state_machine_change_state(
191 &this_request->parent.state_machine,
192 SCI_BASE_REQUEST_STATE_COMPLETED
193 );
194
195 scic_sds_controller_release_frame(
196 this_request->owning_controller, frame_index
197 );
198
199 return SCI_SUCCESS;
200}
201
202const struct scic_sds_io_request_state_handler scic_sds_ssp_task_request_started_substate_handler_table[] = {
203 [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION] = {
204 .parent.start_handler = scic_sds_request_default_start_handler,
205 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
206 .parent.complete_handler = scic_sds_request_default_complete_handler,
207 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
208 .tc_completion_handler = scic_sds_ssp_task_request_await_tc_completion_tc_completion_handler,
209 .event_handler = scic_sds_request_default_event_handler,
210 .frame_handler = scic_sds_request_default_frame_handler,
211 },
212 [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE] = {
213 .parent.start_handler = scic_sds_request_default_start_handler,
214 .parent.abort_handler = scic_sds_ssp_task_request_await_tc_response_abort_handler,
215 .parent.complete_handler = scic_sds_request_default_complete_handler,
216 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
217 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
218 .event_handler = scic_sds_request_default_event_handler,
219 .frame_handler = scic_sds_ssp_task_request_await_tc_response_frame_handler,
220 }
221};
222
223/*
224 * This file is provided under a dual BSD/GPLv2 license. When using or
225 * redistributing this file, you may do so under either license.
226 *
227 * GPL LICENSE SUMMARY
228 *
229 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
230 *
231 * This program is free software; you can redistribute it and/or modify
232 * it under the terms of version 2 of the GNU General Public License as
233 * published by the Free Software Foundation.
234 *
235 * This program is distributed in the hope that it will be useful, but
236 * WITHOUT ANY WARRANTY; without even the implied warranty of
237 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
238 * General Public License for more details.
239 *
240 * You should have received a copy of the GNU General Public License
241 * along with this program; if not, write to the Free Software
242 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
243 * The full GNU General Public License is included in this distribution
244 * in the file called LICENSE.GPL.
245 *
246 * BSD LICENSE
247 *
248 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
249 * All rights reserved.
250 *
251 * Redistribution and use in source and binary forms, with or without
252 * modification, are permitted provided that the following conditions
253 * are met:
254 *
255 * * Redistributions of source code must retain the above copyright
256 * notice, this list of conditions and the following disclaimer.
257 * * Redistributions in binary form must reproduce the above copyright
258 * notice, this list of conditions and the following disclaimer in
259 * the documentation and/or other materials provided with the
260 * distribution.
261 * * Neither the name of Intel Corporation nor the names of its
262 * contributors may be used to endorse or promote products derived
263 * from this software without specific prior written permission.
264 *
265 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
266 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
267 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
268 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
269 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
270 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
271 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
272 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
273 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
274 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
275 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276 */
277
278/**
279 * This file contains the enter/exit methods associated with each of the task
280 * management raw request states. For more information on the task
281 * management request state machine please refer to scic_sds_io_request.h
282 *
283 *
284 */
285
286#include "scic_sds_request.h"
287#include "sci_base_state_machine.h"
288
289/**
290 * This method performs the actions required when entering the
291 * SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION
292 * sub-state. This includes setting the IO request state handlers for this
293 * sub-state.
294 * @object: This parameter specifies the request object for which the sub-state
295 * change is occuring.
296 *
297 * none.
298 */
299static void scic_sds_io_request_started_task_mgmt_await_tc_completion_substate_enter(
300 struct sci_base_object *object)
301{
302 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
303
304 SET_STATE_HANDLER(
305 this_request,
306 scic_sds_ssp_task_request_started_substate_handler_table,
307 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION
308 );
309}
310
311/**
312 * This method performs the actions required when entering the
313 * SCIC_SDS_IO_REQUEST_STARTED_SUBSTATE_AWAIT_TC_RESPONSE sub-state. This
314 * includes setting the IO request state handlers for this sub-state.
315 * @object: This parameter specifies the request object for which the sub-state
316 * change is occuring.
317 *
318 * none.
319 */
320static void scic_sds_io_request_started_task_mgmt_await_task_response_substate_enter(
321 struct sci_base_object *object)
322{
323 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
324
325 SET_STATE_HANDLER(
326 this_request,
327 scic_sds_ssp_task_request_started_substate_handler_table,
328 SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE
329 );
330}
331
332const struct sci_base_state scic_sds_io_request_started_task_mgmt_substate_table[] = {
333 [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION] = {
334 .enter_state = scic_sds_io_request_started_task_mgmt_await_tc_completion_substate_enter,
335 },
336 [SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE] = {
337 .enter_state = scic_sds_io_request_started_task_mgmt_await_task_response_substate_enter,
338 },
339};
340
diff --git a/drivers/scsi/isci/core/scic_sds_stp_packet_request.c b/drivers/scsi/isci/core/scic_sds_stp_packet_request.c
new file mode 100644
index 000000000000..f52a8e32b48f
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_stp_packet_request.c
@@ -0,0 +1,838 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55#if !defined(DISABLE_ATAPI)
56
57#include "intel_ata.h"
58#include "intel_sas.h"
59#include "intel_sata.h"
60#include "intel_sat.h"
61#include "sati_translator_sequence.h"
62#include "sci_base_state.h"
63#include "scic_controller.h"
64#include "scic_remote_device.h"
65#include "scic_sds_controller.h"
66#include "scic_sds_remote_device.h"
67#include "scic_sds_request.h"
68#include "scic_sds_stp_packet_request.h"
69#include "scic_user_callback.h"
70#include "sci_util.h"
71#include "scu_completion_codes.h"
72#include "scu_task_context.h"
73
74
75/**
76 * This method will fill in the SCU Task Context for a PACKET fis. And
77 * construct the request STARTED sub-state machine for Packet Protocol IO.
78 * @this_request: This parameter specifies the stp packet request object being
79 * constructed.
80 *
81 */
82enum sci_status scic_sds_stp_packet_request_construct(
83 struct scic_sds_request *this_request)
84{
85 struct sata_fis_reg_h2d *h2d_fis =
86 scic_stp_io_request_get_h2d_reg_address(
87 this_request
88 );
89
90 /*
91 * Work around, we currently only support PACKET DMA protocol, so we
92 * need to make change to Packet Fis features field. */
93 h2d_fis->features = h2d_fis->features | ATA_PACKET_FEATURE_DMA;
94
95 scic_sds_stp_non_ncq_request_construct(this_request);
96
97 /* Build the Packet Fis task context structure */
98 scu_stp_raw_request_construct_task_context(
99 (struct scic_sds_stp_request *)this_request,
100 this_request->task_context_buffer
101 );
102
103 sci_base_state_machine_construct(
104 &this_request->started_substate_machine,
105 &this_request->parent.parent,
106 scic_sds_stp_packet_request_started_substate_table,
107 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
108 );
109
110 return SCI_SUCCESS;
111}
112
113
114/**
115 * This method will fill in the SCU Task Context for a Packet request command
116 * phase in PACKET DMA DATA (IN/OUT) type. The following important settings
117 * are utilized: -# task_type == SCU_TASK_TYPE_PACKET_DMA. This simply
118 * indicates that a normal request type (i.e. non-raw frame) is being
119 * utilized to perform task management. -# control_frame == 1. This ensures
120 * that the proper endianess is set so that the bytes are transmitted in the
121 * right order for a smp request frame.
122 * @this_request: This parameter specifies the smp request object being
123 * constructed.
124 * @task_context: The task_context to be reconstruct for packet request command
125 * phase.
126 *
127 */
128void scu_stp_packet_request_command_phase_construct_task_context(
129 struct scic_sds_request *this_request,
130 struct scu_task_context *task_context)
131{
132 void *atapi_cdb;
133 u32 atapi_cdb_length;
134 struct scic_sds_stp_request *stp_request = (struct scic_sds_stp_request *)this_request;
135
136 /*
137 * reference: SSTL 1.13.4.2
138 * task_type, sata_direction */
139 if (scic_cb_io_request_get_data_direction(this_request->user_request)
140 == SCI_IO_REQUEST_DATA_OUT) {
141 task_context->task_type = SCU_TASK_TYPE_PACKET_DMA_OUT;
142 task_context->sata_direction = 0;
143 } else { /* todo: for NO_DATA command, we need to send out raw frame. */
144 task_context->task_type = SCU_TASK_TYPE_PACKET_DMA_IN;
145 task_context->sata_direction = 1;
146 }
147
148 /* sata header */
149 memset(&(task_context->type.stp), 0, sizeof(struct STP_TASK_CONTEXT));
150 task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA;
151
152 /*
153 * Copy in the command IU with CDB so that the commandIU address doesn't
154 * change. */
155 memset(this_request->command_buffer, 0, sizeof(struct sata_fis_reg_h2d));
156
157 atapi_cdb =
158 scic_cb_stp_packet_io_request_get_cdb_address(this_request->user_request);
159
160 atapi_cdb_length =
161 scic_cb_stp_packet_io_request_get_cdb_length(this_request->user_request);
162
163 memcpy(((u8 *)this_request->command_buffer + sizeof(u32)), atapi_cdb, atapi_cdb_length);
164
165 atapi_cdb_length =
166 max(atapi_cdb_length, stp_request->type.packet.device_preferred_cdb_length);
167
168 task_context->ssp_command_iu_length =
169 ((atapi_cdb_length % 4) == 0) ?
170 (atapi_cdb_length / 4) : ((atapi_cdb_length / 4) + 1);
171
172 /* task phase is set to TX_CMD */
173 task_context->task_phase = 0x1;
174
175 /* retry counter */
176 task_context->stp_retry_count = 0;
177
178 if (scic_cb_request_is_initial_construction(this_request->user_request)) {
179 /* data transfer size. */
180 task_context->transfer_length_bytes =
181 scic_cb_io_request_get_transfer_length(this_request->user_request);
182
183 /* setup sgl */
184 scic_sds_request_build_sgl(this_request);
185 } else {
186 /* data transfer size, need to be 4 bytes aligned. */
187 task_context->transfer_length_bytes = (SCSI_FIXED_SENSE_DATA_BASE_LENGTH + 2);
188
189 scic_sds_stp_packet_internal_request_sense_build_sgl(this_request);
190 }
191}
192
193/**
194 * This method will fill in the SCU Task Context for a DATA fis containing CDB
195 * in Raw Frame type. The TC for previous Packet fis was already there, we
196 * only need to change the H2D fis content.
197 * @this_request: This parameter specifies the smp request object being
198 * constructed.
199 * @task_context: The task_context to be reconstruct for packet request command
200 * phase.
201 *
202 */
203void scu_stp_packet_request_command_phase_reconstruct_raw_frame_task_context(
204 struct scic_sds_request *this_request,
205 struct scu_task_context *task_context)
206{
207 void *atapi_cdb =
208 scic_cb_stp_packet_io_request_get_cdb_address(this_request->user_request);
209
210 u32 atapi_cdb_length =
211 scic_cb_stp_packet_io_request_get_cdb_length(this_request->user_request);
212
213 memset(this_request->command_buffer, 0, sizeof(struct sata_fis_reg_h2d));
214 memcpy(((u8 *)this_request->command_buffer + sizeof(u32)), atapi_cdb, atapi_cdb_length);
215
216 memset(&(task_context->type.stp), 0, sizeof(struct STP_TASK_CONTEXT));
217 task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA;
218
219 /*
220 * Note the data send out has to be 4 bytes aligned. Or else out hardware will
221 * patch non-zero bytes and cause the target device unhappy. */
222 task_context->transfer_length_bytes = 12;
223}
224
225
226/*
227 * *@brief This methods decode the D2H status FIS and retrieve the sense data,
228 * then pass the sense data to user request.
229 *
230 ***@param[in] this_request The request receive D2H status FIS.
231 ***@param[in] status_fis The D2H status fis to be processed.
232 *
233 */
234enum sci_status scic_sds_stp_packet_request_process_status_fis(
235 struct scic_sds_request *this_request,
236 struct sata_fis_reg_d2h *status_fis)
237{
238 enum sci_status status = SCI_SUCCESS;
239
240 /* TODO: Process the error status fis, retrieve sense data. */
241 if (status_fis->status & ATA_STATUS_REG_ERROR_BIT)
242 status = SCI_FAILURE_IO_RESPONSE_VALID;
243
244 return status;
245}
246
247/*
248 * *@brief This methods builds sgl for internal REQUEST SENSE stp packet
249 * command using this request response buffer, only one sge is
250 * needed.
251 *
252 ***@param[in] this_request The request receive request sense data.
253 *
254 */
255void scic_sds_stp_packet_internal_request_sense_build_sgl(
256 struct scic_sds_request *this_request)
257{
258 void *sge;
259 struct scu_sgl_element_pair *scu_sgl_list = NULL;
260 struct scu_task_context *task_context;
261 dma_addr_t physical_address;
262
263 struct sci_ssp_response_iu *rsp_iu =
264 (struct sci_ssp_response_iu *)this_request->response_buffer;
265
266 sge = (void *)&rsp_iu->data[0];
267
268 task_context = (struct scu_task_context *)this_request->task_context_buffer;
269 scu_sgl_list = &task_context->sgl_pair_ab;
270
271 scic_cb_io_request_get_physical_address(
272 scic_sds_request_get_controller(this_request),
273 this_request,
274 ((char *)sge),
275 &physical_address
276 );
277
278 scu_sgl_list->A.address_upper = sci_cb_physical_address_upper(physical_address);
279 scu_sgl_list->A.address_lower = sci_cb_physical_address_lower(physical_address);
280 scu_sgl_list->A.length = task_context->transfer_length_bytes;
281 scu_sgl_list->A.address_modifier = 0;
282
283 SCU_SGL_ZERO(scu_sgl_list->B);
284}
285
286/**
287 * This method processes the completions transport layer (TL) status to
288 * determine if the Packet FIS was sent successfully. If the Packet FIS was
289 * sent successfully, then the state for the Packet request transits to
290 * waiting for a PIO SETUP frame.
291 * @this_request: This parameter specifies the request for which the TC
292 * completion was received.
293 * @completion_code: This parameter indicates the completion status information
294 * for the TC.
295 *
296 * Indicate if the tc completion handler was successful. SCI_SUCCESS currently
297 * this method always returns success.
298 */
299enum sci_status scic_sds_stp_packet_request_packet_phase_await_tc_completion_tc_completion_handler(
300 struct scic_sds_request *this_request,
301 u32 completion_code)
302{
303 enum sci_status status = SCI_SUCCESS;
304
305 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
306 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
307 scic_sds_request_set_status(
308 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
309 );
310
311 sci_base_state_machine_change_state(
312 &this_request->started_substate_machine,
313 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE
314 );
315 break;
316
317 default:
318 /*
319 * All other completion status cause the IO to be complete. If a NAK
320 * was received, then it is up to the user to retry the request. */
321 scic_sds_request_set_status(
322 this_request,
323 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
324 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
325 );
326
327 sci_base_state_machine_change_state(
328 &this_request->parent.state_machine,
329 SCI_BASE_REQUEST_STATE_COMPLETED
330 );
331 break;
332 }
333
334 return status;
335}
336
337
338/**
339 * This method processes an unsolicited frame while the Packet request is
340 * waiting for a PIO SETUP FIS. It will release the unsolicited frame, and
341 * transition the request to the COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
342 * state.
343 * @this_request: This parameter specifies the request for which the
344 * unsolicited frame was received.
345 * @frame_index: This parameter indicates the unsolicited frame index that
346 * should contain the response.
347 *
348 * This method returns an indication of whether the pio setup frame was handled
349 * successfully or not. SCI_SUCCESS Currently this value is always returned and
350 * indicates successful processing of the TC response.
351 */
352enum sci_status scic_sds_stp_packet_request_packet_phase_await_pio_setup_frame_handler(
353 struct scic_sds_request *request,
354 u32 frame_index)
355{
356 enum sci_status status;
357 struct sata_fis_header *frame_header;
358 u32 *frame_buffer;
359 struct scic_sds_stp_request *this_request;
360
361 this_request = (struct scic_sds_stp_request *)request;
362
363 status = scic_sds_unsolicited_frame_control_get_header(
364 &(this_request->parent.owning_controller->uf_control),
365 frame_index,
366 (void **)&frame_header
367 );
368
369 if (status == SCI_SUCCESS) {
370 BUG_ON(frame_header->fis_type != SATA_FIS_TYPE_PIO_SETUP);
371
372 /*
373 * Get from the frame buffer the PIO Setup Data, although we don't need
374 * any info from this pio setup fis. */
375 scic_sds_unsolicited_frame_control_get_buffer(
376 &(this_request->parent.owning_controller->uf_control),
377 frame_index,
378 (void **)&frame_buffer
379 );
380
381 /*
382 * Get the data from the PIO Setup
383 * The SCU Hardware returns first word in the frame_header and the rest
384 * of the data is in the frame buffer so we need to back up one dword */
385 this_request->type.packet.device_preferred_cdb_length =
386 (u16)((struct sata_fis_pio_setup *)(&frame_buffer[-1]))->transfter_count;
387
388 /* Frame has been decoded return it to the controller */
389 scic_sds_controller_release_frame(
390 this_request->parent.owning_controller, frame_index
391 );
392
393 sci_base_state_machine_change_state(
394 &this_request->parent.started_substate_machine,
395 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
396 );
397 } else
398 dev_err(scic_to_dev(request->owning_controller),
399 "%s: SCIC IO Request 0x%p could not get frame header "
400 "for frame index %d, status %x\n",
401 __func__, this_request, frame_index, status);
402
403 return status;
404}
405
406
407/**
408 * This method processes the completions transport layer (TL) status to
409 * determine if the PACKET command data FIS was sent successfully. If
410 * successfully, then the state for the packet request transits to COMPLETE
411 * state. If not successfuly, the request transits to
412 * COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE.
413 * @this_request: This parameter specifies the request for which the TC
414 * completion was received.
415 * @completion_code: This parameter indicates the completion status information
416 * for the TC.
417 *
418 * Indicate if the tc completion handler was successful. SCI_SUCCESS currently
419 * this method always returns success.
420 */
421enum sci_status scic_sds_stp_packet_request_command_phase_await_tc_completion_tc_completion_handler(
422 struct scic_sds_request *this_request,
423 u32 completion_code)
424{
425 enum sci_status status = SCI_SUCCESS;
426 u8 sat_packet_protocol =
427 scic_cb_request_get_sat_protocol(this_request->user_request);
428
429 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
430 case (SCU_TASK_DONE_GOOD << SCU_COMPLETION_TL_STATUS_SHIFT):
431 scic_sds_request_set_status(
432 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
433 );
434
435 if (sat_packet_protocol == SAT_PROTOCOL_PACKET_DMA_DATA_IN
436 || sat_packet_protocol == SAT_PROTOCOL_PACKET_DMA_DATA_OUT
437 )
438 sci_base_state_machine_change_state(
439 &this_request->parent.state_machine,
440 SCI_BASE_REQUEST_STATE_COMPLETED
441 );
442 else
443 sci_base_state_machine_change_state(
444 &this_request->started_substate_machine,
445 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
446 );
447 break;
448
449 case (SCU_TASK_DONE_UNEXP_FIS << SCU_COMPLETION_TL_STATUS_SHIFT):
450 if (scic_io_request_get_number_of_bytes_transferred(this_request) <
451 scic_cb_io_request_get_transfer_length(this_request->user_request)) {
452 scic_sds_request_set_status(
453 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS_IO_DONE_EARLY
454 );
455
456 sci_base_state_machine_change_state(
457 &this_request->parent.state_machine,
458 SCI_BASE_REQUEST_STATE_COMPLETED
459 );
460
461 status = this_request->sci_status;
462 }
463 break;
464
465 case (SCU_TASK_DONE_EXCESS_DATA << SCU_COMPLETION_TL_STATUS_SHIFT):
466 /* In this case, there is no UF coming after. compelte the IO now. */
467 scic_sds_request_set_status(
468 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
469 );
470
471 sci_base_state_machine_change_state(
472 &this_request->parent.state_machine,
473 SCI_BASE_REQUEST_STATE_COMPLETED
474 );
475
476 break;
477
478 default:
479 if (this_request->sci_status != SCI_SUCCESS) { /* The io status was set already. This means an UF for the status
480 * fis was received already.
481 */
482
483 /*
484 * A device suspension event is expected, we need to have the device
485 * coming out of suspension, then complete the IO. */
486 sci_base_state_machine_change_state(
487 &this_request->started_substate_machine,
488 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE
489 );
490
491 /* change the device state to ATAPI_ERROR. */
492 sci_base_state_machine_change_state(
493 &this_request->target_device->ready_substate_machine,
494 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
495 );
496
497 status = this_request->sci_status;
498 } else { /* If receiving any non-sucess TC status, no UF received yet, then an UF for
499 * the status fis is coming after.
500 */
501 scic_sds_request_set_status(
502 this_request,
503 SCU_TASK_DONE_CHECK_RESPONSE,
504 SCI_FAILURE_IO_RESPONSE_VALID
505 );
506
507 sci_base_state_machine_change_state(
508 &this_request->started_substate_machine,
509 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
510 );
511 }
512 break;
513 }
514
515 return status;
516}
517
518
519/**
520 * This method processes an unsolicited frame.
521 * @this_request: This parameter specifies the request for which the
522 * unsolicited frame was received.
523 * @frame_index: This parameter indicates the unsolicited frame index that
524 * should contain the response.
525 *
526 * This method returns an indication of whether the UF frame was handled
527 * successfully or not. SCI_SUCCESS Currently this value is always returned and
528 * indicates successful processing of the TC response.
529 */
530enum sci_status scic_sds_stp_packet_request_command_phase_common_frame_handler(
531 struct scic_sds_request *request,
532 u32 frame_index)
533{
534 enum sci_status status;
535 struct sata_fis_header *frame_header;
536 u32 *frame_buffer;
537 struct scic_sds_stp_request *this_request;
538
539 this_request = (struct scic_sds_stp_request *)request;
540
541 status = scic_sds_unsolicited_frame_control_get_header(
542 &(this_request->parent.owning_controller->uf_control),
543 frame_index,
544 (void **)&frame_header
545 );
546
547 if (status == SCI_SUCCESS) {
548 BUG_ON(frame_header->fis_type != SATA_FIS_TYPE_REGD2H);
549
550 /*
551 * Get from the frame buffer the PIO Setup Data, although we don't need
552 * any info from this pio setup fis. */
553 scic_sds_unsolicited_frame_control_get_buffer(
554 &(this_request->parent.owning_controller->uf_control),
555 frame_index,
556 (void **)&frame_buffer
557 );
558
559 scic_sds_controller_copy_sata_response(
560 &this_request->d2h_reg_fis, (u32 *)frame_header, frame_buffer
561 );
562
563 /* Frame has been decoded return it to the controller */
564 scic_sds_controller_release_frame(
565 this_request->parent.owning_controller, frame_index
566 );
567 }
568
569 return status;
570}
571
572/**
573 * This method processes an unsolicited frame while the packet request is
574 * expecting TC completion. It will process the FIS and construct sense data.
575 * @this_request: This parameter specifies the request for which the
576 * unsolicited frame was received.
577 * @frame_index: This parameter indicates the unsolicited frame index that
578 * should contain the response.
579 *
580 * This method returns an indication of whether the UF frame was handled
581 * successfully or not. SCI_SUCCESS Currently this value is always returned and
582 * indicates successful processing of the TC response.
583 */
584enum sci_status scic_sds_stp_packet_request_command_phase_await_tc_completion_frame_handler(
585 struct scic_sds_request *request,
586 u32 frame_index)
587{
588 struct scic_sds_stp_request *this_request = (struct scic_sds_stp_request *)request;
589
590 enum sci_status status =
591 scic_sds_stp_packet_request_command_phase_common_frame_handler(
592 request, frame_index);
593
594 if (status == SCI_SUCCESS) {
595 /* The command has completed with error status from target device. */
596 status = scic_sds_stp_packet_request_process_status_fis(
597 request, &this_request->d2h_reg_fis);
598
599 if (status != SCI_SUCCESS) {
600 scic_sds_request_set_status(
601 &this_request->parent,
602 SCU_TASK_DONE_CHECK_RESPONSE,
603 status
604 );
605 } else
606 scic_sds_request_set_status(
607 &this_request->parent, SCU_TASK_DONE_GOOD, SCI_SUCCESS
608 );
609 }
610
611 return status;
612}
613
614
615/**
616 * This method processes an unsolicited frame while the packet request is
617 * expecting TC completion. It will process the FIS and construct sense data.
618 * @this_request: This parameter specifies the request for which the
619 * unsolicited frame was received.
620 * @frame_index: This parameter indicates the unsolicited frame index that
621 * should contain the response.
622 *
623 * This method returns an indication of whether the UF frame was handled
624 * successfully or not. SCI_SUCCESS Currently this value is always returned and
625 * indicates successful processing of the TC response.
626 */
627enum sci_status scic_sds_stp_packet_request_command_phase_await_d2h_fis_frame_handler(
628 struct scic_sds_request *request,
629 u32 frame_index)
630{
631 enum sci_status status =
632 scic_sds_stp_packet_request_command_phase_common_frame_handler(
633 request, frame_index);
634
635 struct scic_sds_stp_request *this_request = (struct scic_sds_stp_request *)request;
636
637 if (status == SCI_SUCCESS) {
638 /* The command has completed with error status from target device. */
639 status = scic_sds_stp_packet_request_process_status_fis(
640 request, &this_request->d2h_reg_fis);
641
642 if (status != SCI_SUCCESS) {
643 scic_sds_request_set_status(
644 request,
645 SCU_TASK_DONE_CHECK_RESPONSE,
646 status
647 );
648 } else
649 scic_sds_request_set_status(
650 request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
651 );
652
653 /*
654 * Always complete the NON_DATA command right away, no need to delay completion
655 * even an error status fis came from target device. */
656 sci_base_state_machine_change_state(
657 &request->parent.state_machine,
658 SCI_BASE_REQUEST_STATE_COMPLETED
659 );
660 }
661
662 return status;
663}
664
665enum sci_status scic_sds_stp_packet_request_started_completion_delay_complete_handler(
666 struct sci_base_request *request)
667{
668 struct scic_sds_request *this_request = (struct scic_sds_request *)request;
669
670 sci_base_state_machine_change_state(
671 &this_request->parent.state_machine,
672 SCI_BASE_REQUEST_STATE_COMPLETED
673 );
674
675 return this_request->sci_status;
676}
677
678/* --------------------------------------------------------------------------- */
679
680const struct scic_sds_io_request_state_handler scic_sds_stp_packet_request_started_substate_handler_table[] = {
681 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
682 .parent.start_handler = scic_sds_request_default_start_handler,
683 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
684 .parent.complete_handler = scic_sds_request_default_complete_handler,
685 .parent.destruct_handler = scic_sds_request_default_destruct_handler
686 .tc_completion_handler = scic_sds_stp_packet_request_packet_phase_await_tc_completion_tc_completion_handler,
687 .event_handler = scic_sds_request_default_event_handler,
688 .frame_handler = scic_sds_request_default_frame_handler
689 },
690 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE] = {
691 .parent.start_handler = scic_sds_request_default_start_handler,
692 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
693 .parent.complete_handler = scic_sds_request_default_complete_handler,
694 .parent.destruct_handler = scic_sds_request_default_destruct_handler
695 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
696 .event_handler = scic_sds_request_default_event_handler,
697 .frame_handler = scic_sds_stp_packet_request_packet_phase_await_pio_setup_frame_handler
698 },
699 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
700 .parent.start_handler = scic_sds_request_default_start_handler,
701 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
702 .parent.complete_handler = scic_sds_request_default_complete_handler,
703 .parent.destruct_handler = scic_sds_request_default_destruct_handler
704 .tc_completion_handler = scic_sds_stp_packet_request_command_phase_await_tc_completion_tc_completion_handler,
705 .event_handler = scic_sds_request_default_event_handler,
706 .frame_handler = scic_sds_stp_packet_request_command_phase_await_tc_completion_frame_handler
707 },
708 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE] = {
709 .parent.start_handler = scic_sds_request_default_start_handler,
710 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
711 .parent.complete_handler = scic_sds_request_default_complete_handler,
712 .parent.destruct_handler = scic_sds_request_default_destruct_handler
713 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
714 .event_handler = scic_sds_request_default_event_handler,
715 .frame_handler = scic_sds_stp_packet_request_command_phase_await_d2h_fis_frame_handler
716 },
717 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE] = {
718 .parent.start_handler = scic_sds_request_default_start_handler,
719 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
720 .parent.complete_handler = scic_sds_stp_packet_request_started_completion_delay_complete_handler,
721 .parent.destruct_handler = scic_sds_request_default_destruct_handler
722 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
723 .event_handler = scic_sds_request_default_event_handler,
724 .frame_handler = scic_sds_request_default_frame_handler
725 },
726};
727
728void scic_sds_stp_packet_request_started_packet_phase_await_tc_completion_enter(
729 struct sci_base_object *object)
730{
731 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
732
733 SET_STATE_HANDLER(
734 this_request,
735 scic_sds_stp_packet_request_started_substate_handler_table,
736 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
737 );
738
739 scic_sds_remote_device_set_working_request(
740 this_request->target_device, this_request
741 );
742}
743
744void scic_sds_stp_packet_request_started_packet_phase_await_pio_setup_enter(
745 struct sci_base_object *object)
746{
747 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
748
749 SET_STATE_HANDLER(
750 this_request,
751 scic_sds_stp_packet_request_started_substate_handler_table,
752 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE
753 );
754}
755
756void scic_sds_stp_packet_request_started_command_phase_await_tc_completion_enter(
757 struct sci_base_object *object)
758{
759 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
760 u8 sat_packet_protocol =
761 scic_cb_request_get_sat_protocol(this_request->user_request);
762
763 struct scu_task_context *task_context;
764 enum sci_status status;
765
766 /*
767 * Recycle the TC and reconstruct it for sending out data fis containing
768 * CDB. */
769 task_context = scic_sds_controller_get_task_context_buffer(
770 this_request->owning_controller, this_request->io_tag);
771
772 if (sat_packet_protocol == SAT_PROTOCOL_PACKET_NON_DATA)
773 scu_stp_packet_request_command_phase_reconstruct_raw_frame_task_context(
774 this_request, task_context);
775 else
776 scu_stp_packet_request_command_phase_construct_task_context(
777 this_request, task_context);
778
779 /* send the new TC out. */
780 status = this_request->owning_controller->state_handlers->parent.continue_io_handler(
781 &this_request->owning_controller->parent,
782 &this_request->target_device->parent,
783 &this_request->parent
784 );
785
786 if (status == SCI_SUCCESS)
787 SET_STATE_HANDLER(
788 this_request,
789 scic_sds_stp_packet_request_started_substate_handler_table,
790 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE
791 );
792}
793
794void scic_sds_stp_packet_request_started_command_phase_await_d2h_fis_enter(
795 struct sci_base_object *object)
796{
797 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
798
799 SET_STATE_HANDLER(
800 this_request,
801 scic_sds_stp_packet_request_started_substate_handler_table,
802 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE
803 );
804}
805
806void scic_sds_stp_packet_request_started_completion_delay_enter(
807 struct sci_base_object *object)
808{
809 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
810
811 SET_STATE_HANDLER(
812 this_request,
813 scic_sds_stp_packet_request_started_substate_handler_table,
814 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE
815 );
816}
817
818
819/* --------------------------------------------------------------------------- */
820const struct sci_base_state scic_sds_stp_packet_request_started_substate_table[] = {
821 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
822 .enter_state = scic_sds_stp_packet_request_started_packet_phase_await_tc_completion_enter,
823 },
824 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE] = {
825 .enter_state = scic_sds_stp_packet_request_started_packet_phase_await_pio_setup_enter,
826 },
827 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE] = {
828 .enter_state = scic_sds_stp_packet_request_started_command_phase_await_tc_completion_enter,
829 },
830 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE] = {
831 .enter_state = scic_sds_stp_packet_request_started_command_phase_await_d2h_fis_enter,
832 },
833 [SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE] = {
834 .enter_state scic_sds_stp_packet_request_started_completion_delay_enter,
835 }
836};
837
838#endif /* !defined(DISABLE_ATAPI) */
diff --git a/drivers/scsi/isci/core/scic_sds_stp_packet_request.h b/drivers/scsi/isci/core/scic_sds_stp_packet_request.h
new file mode 100644
index 000000000000..fc18b3f6a13f
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_stp_packet_request.h
@@ -0,0 +1,154 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55#ifndef _SCIC_SDS_STP_PACKET_REQUEST_H_
56#define _SCIC_SDS_STP_PACKET_REQUEST_H_
57
58#include "intel_sas.h"
59#include "sci_types.h"
60#include "scic_sds_stp_request.h"
61
62/**
63 * This file contains the structures and constants for PACKET protocol requests.
64 *
65 *
66 */
67
68
69/**
70 *
71 *
72 * This is the enumeration of the SATA PIO DATA IN started substate machine.
73 */
74enum _SCIC_SDS_STP_PACKET_REQUEST_STARTED_SUBSTATES {
75 /**
76 * While in this state the IO request object is waiting for the TC completion
77 * notification for the H2D Register FIS
78 */
79 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_TC_COMPLETION_SUBSTATE,
80
81 /**
82 * While in this state the IO request object is waiting for either a PIO Setup.
83 */
84 SCIC_SDS_STP_PACKET_REQUEST_STARTED_PACKET_PHASE_AWAIT_PIO_SETUP_SUBSTATE,
85
86 /**
87 * While in this state the IO request object is waiting for TC completion for
88 * the Packet DMA DATA fis or Raw Frame.
89 */
90 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_TC_COMPLETION_SUBSTATE,
91
92 /**
93 * The non-data IO transit to this state in this state after receiving TC
94 * completion. While in this state IO request object is waiting for D2H status
95 * frame as UF.
96 */
97 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMMAND_PHASE_AWAIT_D2H_FIS_SUBSTATE,
98
99 /**
100 * The IO transit to this state in this state if the previous TC completion status
101 * is not success and the atapi device is suspended due to target device failed the IO.
102 * While in this state IO request object is waiting for device coming out of the
103 * suspension state then complete the IO.
104 */
105 SCIC_SDS_STP_PACKET_REQUEST_STARTED_COMPLETION_DELAY_SUBSTATE,
106};
107
108
109
110#if !defined(DISABLE_ATAPI)
111extern const struct sci_base_state scic_sds_stp_packet_request_started_substate_table[];
112extern const struct scic_sds_io_request_state_handler scic_sds_stp_packet_request_started_substate_handler_table[];
113#endif /* !defined(DISABLE_ATAPI) */
114
115#if !defined(DISABLE_ATAPI)
116enum sci_status scic_sds_stp_packet_request_construct(
117 struct scic_sds_request *this_request);
118#else /* !defined(DISABLE_ATAPI) */
119#define scic_sds_stp_packet_request_construct(request) SCI_FAILURE
120#endif /* !defined(DISABLE_ATAPI) */
121
122#if !defined(DISABLE_ATAPI)
123void scu_stp_packet_request_command_phase_construct_task_context(
124 struct scic_sds_request *this_request,
125 struct scu_task_context *task_context);
126#else /* !defined(DISABLE_ATAPI) */
127#define scu_stp_packet_request_command_phase_construct_task_context(reqeust, tc)
128#endif /* !defined(DISABLE_ATAPI) */
129
130#if !defined(DISABLE_ATAPI)
131void scu_stp_packet_request_command_phase_reconstruct_raw_frame_task_context(
132 struct scic_sds_request *this_request,
133 struct scu_task_context *task_context);
134#else /* !defined(DISABLE_ATAPI) */
135#define scu_stp_packet_request_command_phase_reconstruct_raw_frame_task_context(reqeust, tc)
136#endif /* !defined(DISABLE_ATAPI) */
137
138#if !defined(DISABLE_ATAPI)
139enum sci_status scic_sds_stp_packet_request_process_status_fis(
140 struct scic_sds_request *this_request,
141 struct sata_fis_reg_d2h *status_fis);
142#else /* !defined(DISABLE_ATAPI) */
143#define scic_sds_stp_packet_request_process_status_fis(reqeust, fis) SCI_FAILURE
144#endif /* !defined(DISABLE_ATAPI) */
145
146#if !defined(DISABLE_ATAPI)
147void scic_sds_stp_packet_internal_request_sense_build_sgl(
148 struct scic_sds_request *this_request);
149#else /* !defined(DISABLE_ATAPI) */
150#define scic_sds_stp_packet_internal_request_sense_build_sgl(request)
151#endif /* !defined(DISABLE_ATAPI) */
152
153#endif /* _SCIC_SDS_STP_PACKET_REQUEST_H_ */
154
diff --git a/drivers/scsi/isci/core/scic_sds_stp_pio_request.h b/drivers/scsi/isci/core/scic_sds_stp_pio_request.h
new file mode 100644
index 000000000000..64bf40a6e1d2
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_stp_pio_request.h
@@ -0,0 +1,116 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_SDS_SATA_PIO_REQUEST_H_
57#define _SCIC_SDS_SATA_PIO_REQUEST_H_
58
59#include "sci_base_state.h"
60#include "scic_sds_request.h"
61#include "scu_task_context.h"
62
63/**
64 * This file contains the structures and constants for SATA PIO requests.
65 *
66 *
67 */
68
69
70/**
71 *
72 *
73 * This is the enumeration of the SATA PIO DATA IN started substate machine.
74 */
75enum _SCIC_SDS_STP_REQUEST_STARTED_PIO_SUBSTATES {
76 /**
77 * While in this state the IO request object is waiting for the TC completion
78 * notification for the H2D Register FIS
79 */
80 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE,
81
82 /**
83 * While in this state the IO request object is waiting for either a PIO Setup
84 * FIS or a D2H register FIS. The type of frame received is based on the
85 * result of the prior frame and line conditions.
86 */
87 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE,
88
89 /**
90 * While in this state the IO request object is waiting for a DATA frame from
91 * the device.
92 */
93 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE,
94
95 /**
96 * While in this state the IO request object is waiting to transmit the next data
97 * frame to the device.
98 */
99 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE,
100};
101
102
103/* --------------------------------------------------------------------------- */
104
105extern const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_pio_substate_handler_table[];
106
107extern const struct sci_base_state scic_sds_stp_request_started_pio_substate_table[];
108
109/* --------------------------------------------------------------------------- */
110
111struct scic_sds_stp_request;
112
113struct scu_sgl_element *scic_sds_stp_request_pio_get_next_sgl(
114 struct scic_sds_stp_request *this_request);
115
116#endif /* _SCIC_SDS_SATA_PIO_REQUEST_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_stp_remote_device.c b/drivers/scsi/isci/core/scic_sds_stp_remote_device.c
new file mode 100644
index 000000000000..abe8f331a15c
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_stp_remote_device.c
@@ -0,0 +1,975 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file contains the ready substate handlers for an STP device.
58 *
59 *
60 */
61
62#include "intel_sat.h"
63#include "intel_ata.h"
64#include "intel_sata.h"
65#include "sci_environment.h"
66#include "scic_remote_device.h"
67#include "scic_user_callback.h"
68#include "scic_sds_controller.h"
69#include "scic_sds_port.h"
70#include "scic_sds_remote_device.h"
71#include "scic_sds_request.h"
72#include "scu_event_codes.h"
73
74/**
75 * This method will perform the STP request completion processing common to IO
76 * requests and task requests of all types
77 * @device: This parameter specifies the device for which the request is being
78 * completed.
79 * @request: This parameter specifies the request being completed.
80 *
81 * This method returns an indication as to whether the request processing
82 * completed successfully.
83 */
84static enum sci_status scic_sds_stp_remote_device_complete_request(
85 struct sci_base_remote_device *device,
86 struct sci_base_request *request)
87{
88 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
89 struct scic_sds_request *the_request = (struct scic_sds_request *)request;
90 enum sci_status status;
91
92 status = scic_sds_io_request_complete(the_request);
93
94 if (status == SCI_SUCCESS) {
95 status = scic_sds_port_complete_io(
96 this_device->owning_port, this_device, the_request
97 );
98
99 if (status == SCI_SUCCESS) {
100 scic_sds_remote_device_decrement_request_count(this_device);
101 if (the_request->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
102 /*
103 * This request causes hardware error, device needs to be Lun Reset.
104 * So here we force the state machine to IDLE state so the rest IOs
105 * can reach RNC state handler, these IOs will be completed by RNC with
106 * status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE". */
107 sci_base_state_machine_change_state(
108 &this_device->ready_substate_machine,
109 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
110 );
111 } else if (scic_sds_remote_device_get_request_count(this_device) == 0) {
112 sci_base_state_machine_change_state(
113 &this_device->ready_substate_machine,
114 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
115 );
116 }
117 }
118 }
119
120 if (status != SCI_SUCCESS)
121 dev_err(scirdev_to_dev(this_device),
122 "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
123 "could not complete\n",
124 __func__,
125 this_device->owning_port,
126 this_device,
127 the_request,
128 status);
129
130 return status;
131}
132
133/*
134 * *****************************************************************************
135 * * STP REMOTE DEVICE READY COMMON SUBSTATE HANDLERS
136 * ***************************************************************************** */
137
138/**
139 * This is the READY NCQ substate handler to start task management request. In
140 * this routine, we suspend and resume the RNC.
141 * @device: The target device a task management request towards to.
142 * @request: The task request.
143 *
144 * enum sci_status Always return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS status to
145 * let controller_start_task_handler know that the controller can't post TC for
146 * task request yet, instead, when RNC gets resumed, a controller_continue_task
147 * callback will be called.
148 */
149static enum sci_status scic_sds_stp_remote_device_ready_substate_start_request_handler(
150 struct sci_base_remote_device *device,
151 struct sci_base_request *request)
152{
153 enum sci_status status;
154 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
155 struct scic_sds_request *this_request = (struct scic_sds_request *)request;
156
157 /* Will the port allow the io request to start? */
158 status = this_device->owning_port->state_handlers->start_io_handler(
159 this_device->owning_port,
160 this_device,
161 this_request
162 );
163
164 if (SCI_SUCCESS == status) {
165 status =
166 scic_sds_remote_node_context_start_task(this_device->rnc, this_request);
167
168 if (SCI_SUCCESS == status) {
169 status = this_request->state_handlers->parent.start_handler(request);
170 }
171
172 if (status == SCI_SUCCESS) {
173 /*
174 * / @note If the remote device state is not IDLE this will replace
175 * / the request that probably resulted in the task management
176 * / request. */
177 this_device->working_request = this_request;
178
179 sci_base_state_machine_change_state(
180 &this_device->ready_substate_machine,
181 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
182 );
183
184 /*
185 * The remote node context must cleanup the TCi to NCQ mapping table.
186 * The only way to do this correctly is to either write to the TLCR
187 * register or to invalidate and repost the RNC. In either case the
188 * remote node context state machine will take the correct action when
189 * the remote node context is suspended and later resumed. */
190 scic_sds_remote_node_context_suspend(
191 this_device->rnc, SCI_SOFTWARE_SUSPENSION, NULL, NULL);
192
193 scic_sds_remote_node_context_resume(
194 this_device->rnc,
195 (SCICS_SDS_REMOTE_NODE_CONTEXT_CALLBACK)
196 scic_sds_remote_device_continue_request,
197 this_device);
198 }
199
200 scic_sds_remote_device_start_request(this_device, this_request, status);
201
202 /*
203 * We need to let the controller start request handler know that it can't
204 * post TC yet. We will provide a callback function to post TC when RNC gets
205 * resumed. */
206 return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS;
207 }
208
209 return status;
210}
211
212/*
213 * *****************************************************************************
214 * * STP REMOTE DEVICE READY IDLE SUBSTATE HANDLERS
215 * ***************************************************************************** */
216
217/**
218 * This method will handle the start io operation for a sata device that is in
219 * the command idle state. - Evalute the type of IO request to be started -
220 * If its an NCQ request change to NCQ substate - If its any other command
221 * change to the CMD substate
222 * @device:
223 * @request:
224 *
225 * If this is a softreset we may want to have a different substate. enum sci_status
226 */
227static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_start_io_handler(
228 struct sci_base_remote_device *device,
229 struct sci_base_request *request)
230{
231 enum sci_status status;
232 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
233 struct scic_sds_request *io_request = (struct scic_sds_request *)request;
234
235
236 /* Will the port allow the io request to start? */
237 status = this_device->owning_port->state_handlers->start_io_handler(
238 this_device->owning_port,
239 this_device,
240 io_request
241 );
242
243 if (status == SCI_SUCCESS) {
244 status =
245 scic_sds_remote_node_context_start_io(this_device->rnc, io_request);
246
247 if (status == SCI_SUCCESS) {
248 status = io_request->state_handlers->parent.start_handler(request);
249 }
250
251 if (status == SCI_SUCCESS) {
252 if (
253 scic_cb_request_get_sat_protocol(io_request->user_request)
254 == SAT_PROTOCOL_FPDMA
255 ) {
256 sci_base_state_machine_change_state(
257 &this_device->ready_substate_machine,
258 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
259 );
260 } else {
261 this_device->working_request = io_request;
262
263 sci_base_state_machine_change_state(
264 &this_device->ready_substate_machine,
265 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
266 );
267 }
268 }
269
270 scic_sds_remote_device_start_request(this_device, io_request, status);
271 }
272
273 return status;
274}
275
276
277/**
278 *
279 * @[in]: device The device received event.
280 * @[in]: event_code The event code.
281 *
282 * This method will handle the event for a sata device that is in the idle
283 * state. We pick up suspension events to handle specifically to this state. We
284 * resume the RNC right away. enum sci_status
285 */
286static enum sci_status scic_sds_stp_remote_device_ready_idle_substate_event_handler(
287 struct scic_sds_remote_device *this_device,
288 u32 event_code)
289{
290 enum sci_status status;
291
292 status = scic_sds_remote_device_general_event_handler(this_device, event_code);
293
294 if (status == SCI_SUCCESS) {
295 if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
296 || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) {
297 status = scic_sds_remote_node_context_resume(
298 this_device->rnc, NULL, NULL);
299 }
300 }
301
302 return status;
303}
304
305
306/*
307 * *****************************************************************************
308 * * STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
309 * ***************************************************************************** */
310
311static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler(
312 struct sci_base_remote_device *device,
313 struct sci_base_request *request)
314{
315 enum sci_status status;
316 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
317 struct scic_sds_request *io_request = (struct scic_sds_request *)request;
318
319 if (
320 scic_cb_request_get_sat_protocol(io_request->user_request)
321 == SAT_PROTOCOL_FPDMA
322 ) {
323 status = this_device->owning_port->state_handlers->start_io_handler(
324 this_device->owning_port,
325 this_device,
326 io_request
327 );
328
329 if (status == SCI_SUCCESS) {
330 status = scic_sds_remote_node_context_start_io(this_device->rnc, io_request);
331
332 if (status == SCI_SUCCESS) {
333 status = io_request->state_handlers->parent.start_handler(request);
334 }
335
336 scic_sds_remote_device_start_request(this_device, io_request, status);
337 }
338 } else {
339 status = SCI_FAILURE_INVALID_STATE;
340 }
341
342 return status;
343}
344
345
346/**
347 * This method will handle events received while the STP device is in the ready
348 * command substate.
349 * @this_device: This is the device object that is receiving the event.
350 * @event_code: The event code to process.
351 *
352 * enum sci_status
353 */
354
355static enum sci_status scic_sds_stp_remote_device_ready_ncq_substate_frame_handler(
356 struct scic_sds_remote_device *this_device,
357 u32 frame_index)
358{
359 enum sci_status status;
360 struct sata_fis_header *frame_header;
361
362 status = scic_sds_unsolicited_frame_control_get_header(
363 &(scic_sds_remote_device_get_controller(this_device)->uf_control),
364 frame_index,
365 (void **)&frame_header
366 );
367
368 if (status == SCI_SUCCESS) {
369 if (
370 (frame_header->fis_type == SATA_FIS_TYPE_SETDEVBITS)
371 && (frame_header->status & ATA_STATUS_REG_ERROR_BIT)
372 ) {
373 this_device->not_ready_reason =
374 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
375
376 sci_base_state_machine_change_state(
377 &this_device->ready_substate_machine,
378 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
379 );
380 } else {
381 status = SCI_FAILURE;
382 }
383
384 scic_sds_controller_release_frame(
385 scic_sds_remote_device_get_controller(this_device), frame_index
386 );
387 }
388
389 return status;
390}
391
392/*
393 * *****************************************************************************
394 * * STP REMOTE DEVICE READY CMD SUBSTATE HANDLERS
395 * ***************************************************************************** */
396
397/**
398 * This device is already handling a command it can not accept new commands
399 * until this one is complete.
400 * @device:
401 * @request:
402 *
403 * enum sci_status
404 */
405static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler(
406 struct sci_base_remote_device *device,
407 struct sci_base_request *request)
408{
409 return SCI_FAILURE_INVALID_STATE;
410}
411
412static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler(
413 struct scic_sds_remote_device *this_device,
414 u32 suspend_type)
415{
416 enum sci_status status;
417
418 status = scic_sds_remote_node_context_suspend(
419 this_device->rnc, suspend_type, NULL, NULL
420 );
421
422 return status;
423}
424
425static enum sci_status scic_sds_stp_remote_device_ready_cmd_substate_frame_handler(
426 struct scic_sds_remote_device *this_device,
427 u32 frame_index)
428{
429 enum sci_status status;
430
431 /*
432 * / The device doe not process any UF received from the hardware while
433 * / in this state. All unsolicited frames are forwarded to the io request
434 * / object. */
435 status = scic_sds_io_request_frame_handler(
436 this_device->working_request,
437 frame_index
438 );
439
440 return status;
441}
442
443
444/*
445 * *****************************************************************************
446 * * STP REMOTE DEVICE READY NCQ SUBSTATE HANDLERS
447 * ***************************************************************************** */
448
449/*
450 * *****************************************************************************
451 * * STP REMOTE DEVICE READY NCQ ERROR SUBSTATE HANDLERS
452 * ***************************************************************************** */
453
454/*
455 * *****************************************************************************
456 * * STP REMOTE DEVICE READY AWAIT RESET SUBSTATE HANDLERS
457 * ***************************************************************************** */
458static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler(
459 struct sci_base_remote_device *device,
460 struct sci_base_request *request)
461{
462 return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
463}
464
465
466
467/**
468 * This method will perform the STP request (both io or task) completion
469 * processing for await reset state.
470 * @device: This parameter specifies the device for which the request is being
471 * completed.
472 * @request: This parameter specifies the request being completed.
473 *
474 * This method returns an indication as to whether the request processing
475 * completed successfully.
476 */
477static enum sci_status scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler(
478 struct sci_base_remote_device *device,
479 struct sci_base_request *request)
480{
481 struct scic_sds_remote_device *this_device = (struct scic_sds_remote_device *)device;
482 struct scic_sds_request *the_request = (struct scic_sds_request *)request;
483 enum sci_status status;
484
485 status = scic_sds_io_request_complete(the_request);
486
487 if (status == SCI_SUCCESS) {
488 status = scic_sds_port_complete_io(
489 this_device->owning_port, this_device, the_request
490 );
491
492 if (status == SCI_SUCCESS)
493 scic_sds_remote_device_decrement_request_count(this_device);
494 }
495
496 if (status != SCI_SUCCESS)
497 dev_err(scirdev_to_dev(this_device),
498 "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
499 "could not complete\n",
500 __func__,
501 this_device->owning_port,
502 this_device,
503 the_request,
504 status);
505
506 return status;
507}
508
509#if !defined(DISABLE_ATAPI)
510/*
511 * *****************************************************************************
512 * * STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE HANDLERS
513 * ***************************************************************************** */
514
515/**
516 *
517 * @[in]: device The device received event.
518 * @[in]: event_code The event code.
519 *
520 * This method will handle the event for a ATAPI device that is in the ATAPI
521 * ERROR state. We pick up suspension events to handle specifically to this
522 * state. We resume the RNC right away. We then complete the outstanding IO to
523 * this device. enum sci_status
524 */
525enum sci_status scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler(
526 struct scic_sds_remote_device *this_device,
527 u32 event_code)
528{
529 enum sci_status status;
530
531 status = scic_sds_remote_device_general_event_handler(this_device, event_code);
532
533 if (status == SCI_SUCCESS) {
534 if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX
535 || scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) {
536 status = scic_sds_remote_node_context_resume(
537 this_device->rnc,
538 this_device->working_request->state_handlers->parent.complete_handler,
539 (void *)this_device->working_request
540 );
541 }
542 }
543
544 return status;
545}
546#endif /* !defined(DISABLE_ATAPI) */
547
548/* --------------------------------------------------------------------------- */
549
550struct scic_sds_remote_device_state_handler
551scic_sds_stp_remote_device_ready_substate_handler_table[
552 SCIC_SDS_STP_REMOTE_DEVICE_READY_MAX_SUBSTATES] =
553{
554 /* SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE */
555 {
556 {
557 scic_sds_remote_device_default_start_handler,
558 scic_sds_remote_device_ready_state_stop_handler,
559 scic_sds_remote_device_default_fail_handler,
560 scic_sds_remote_device_default_destruct_handler,
561 scic_sds_remote_device_ready_state_reset_handler,
562 scic_sds_remote_device_default_reset_complete_handler,
563 scic_sds_stp_remote_device_ready_idle_substate_start_io_handler,
564 scic_sds_remote_device_default_complete_request_handler,
565 scic_sds_remote_device_default_continue_request_handler,
566 scic_sds_stp_remote_device_ready_substate_start_request_handler,
567 scic_sds_remote_device_default_complete_request_handler
568 },
569 scic_sds_remote_device_default_suspend_handler,
570 scic_sds_remote_device_default_resume_handler,
571 scic_sds_stp_remote_device_ready_idle_substate_event_handler,
572 scic_sds_remote_device_default_frame_handler
573 },
574 /* SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD */
575 {
576 {
577 scic_sds_remote_device_default_start_handler,
578 scic_sds_remote_device_ready_state_stop_handler,
579 scic_sds_remote_device_default_fail_handler,
580 scic_sds_remote_device_default_destruct_handler,
581 scic_sds_remote_device_ready_state_reset_handler,
582 scic_sds_remote_device_default_reset_complete_handler,
583 scic_sds_stp_remote_device_ready_cmd_substate_start_io_handler,
584 scic_sds_stp_remote_device_complete_request,
585 scic_sds_remote_device_default_continue_request_handler,
586 scic_sds_stp_remote_device_ready_substate_start_request_handler,
587 scic_sds_stp_remote_device_complete_request,
588 },
589 scic_sds_stp_remote_device_ready_cmd_substate_suspend_handler,
590 scic_sds_remote_device_default_resume_handler,
591 scic_sds_remote_device_general_event_handler,
592 scic_sds_stp_remote_device_ready_cmd_substate_frame_handler
593 },
594 /* SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ */
595 {
596 {
597 scic_sds_remote_device_default_start_handler,
598 scic_sds_remote_device_ready_state_stop_handler,
599 scic_sds_remote_device_default_fail_handler,
600 scic_sds_remote_device_default_destruct_handler,
601 scic_sds_remote_device_ready_state_reset_handler,
602 scic_sds_remote_device_default_reset_complete_handler,
603 scic_sds_stp_remote_device_ready_ncq_substate_start_io_handler,
604 scic_sds_stp_remote_device_complete_request,
605 scic_sds_remote_device_default_continue_request_handler,
606 scic_sds_stp_remote_device_ready_substate_start_request_handler,
607 scic_sds_stp_remote_device_complete_request
608 },
609 scic_sds_remote_device_default_suspend_handler,
610 scic_sds_remote_device_default_resume_handler,
611 scic_sds_remote_device_general_event_handler,
612 scic_sds_stp_remote_device_ready_ncq_substate_frame_handler
613 },
614 /* SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR */
615 {
616 {
617 scic_sds_remote_device_default_start_handler,
618 scic_sds_remote_device_ready_state_stop_handler,
619 scic_sds_remote_device_default_fail_handler,
620 scic_sds_remote_device_default_destruct_handler,
621 scic_sds_remote_device_ready_state_reset_handler,
622 scic_sds_remote_device_default_reset_complete_handler,
623 scic_sds_remote_device_default_start_request_handler,
624 scic_sds_stp_remote_device_complete_request,
625 scic_sds_remote_device_default_continue_request_handler,
626 scic_sds_stp_remote_device_ready_substate_start_request_handler,
627 scic_sds_stp_remote_device_complete_request
628 },
629 scic_sds_remote_device_default_suspend_handler,
630 scic_sds_remote_device_default_resume_handler,
631 scic_sds_remote_device_general_event_handler,
632 scic_sds_remote_device_general_frame_handler
633 },
634#if !defined(DISABLE_ATAPI)
635 /* SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR */
636 {
637 {
638 scic_sds_remote_device_default_start_handler,
639 scic_sds_remote_device_ready_state_stop_handler,
640 scic_sds_remote_device_default_fail_handler,
641 scic_sds_remote_device_default_destruct_handler,
642 scic_sds_remote_device_ready_state_reset_handler,
643 scic_sds_remote_device_default_reset_complete_handler,
644 scic_sds_remote_device_default_start_request_handler,
645 scic_sds_stp_remote_device_complete_request,
646 scic_sds_remote_device_default_continue_request_handler,
647 scic_sds_stp_remote_device_ready_substate_start_request_handler,
648 scic_sds_stp_remote_device_complete_request
649 },
650 scic_sds_remote_device_default_suspend_handler,
651 scic_sds_remote_device_default_resume_handler,
652 scic_sds_stp_remote_device_ready_atapi_error_substate_event_handler,
653 scic_sds_remote_device_general_frame_handler
654 },
655#endif
656 /* SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET */
657 {
658 {
659 scic_sds_remote_device_default_start_handler,
660 scic_sds_remote_device_ready_state_stop_handler,
661 scic_sds_remote_device_default_fail_handler,
662 scic_sds_remote_device_default_destruct_handler,
663 scic_sds_remote_device_ready_state_reset_handler,
664 scic_sds_remote_device_default_reset_complete_handler,
665 scic_sds_stp_remote_device_ready_await_reset_substate_start_io_handler,
666 scic_sds_stp_remote_device_ready_await_reset_substate_complete_request_handler,
667 scic_sds_remote_device_default_continue_request_handler,
668 scic_sds_stp_remote_device_ready_substate_start_request_handler,
669 scic_sds_stp_remote_device_complete_request
670 },
671 scic_sds_remote_device_default_suspend_handler,
672 scic_sds_remote_device_default_resume_handler,
673 scic_sds_remote_device_general_event_handler,
674 scic_sds_remote_device_general_frame_handler
675 }
676};
677
678/*
679 * This file is provided under a dual BSD/GPLv2 license. When using or
680 * redistributing this file, you may do so under either license.
681 *
682 * GPL LICENSE SUMMARY
683 *
684 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
685 *
686 * This program is free software; you can redistribute it and/or modify
687 * it under the terms of version 2 of the GNU General Public License as
688 * published by the Free Software Foundation.
689 *
690 * This program is distributed in the hope that it will be useful, but
691 * WITHOUT ANY WARRANTY; without even the implied warranty of
692 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
693 * General Public License for more details.
694 *
695 * You should have received a copy of the GNU General Public License
696 * along with this program; if not, write to the Free Software
697 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
698 * The full GNU General Public License is included in this distribution
699 * in the file called LICENSE.GPL.
700 *
701 * BSD LICENSE
702 *
703 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
704 * All rights reserved.
705 *
706 * Redistribution and use in source and binary forms, with or without
707 * modification, are permitted provided that the following conditions
708 * are met:
709 *
710 * * Redistributions of source code must retain the above copyright
711 * notice, this list of conditions and the following disclaimer.
712 * * Redistributions in binary form must reproduce the above copyright
713 * notice, this list of conditions and the following disclaimer in
714 * the documentation and/or other materials provided with the
715 * distribution.
716 * * Neither the name of Intel Corporation nor the names of its
717 * contributors may be used to endorse or promote products derived
718 * from this software without specific prior written permission.
719 *
720 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
721 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
722 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
723 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
724 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
725 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
726 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
727 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
728 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
729 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
730 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
731 */
732
733#include "sci_base_state.h"
734#include "scic_remote_device.h"
735#include "scic_user_callback.h"
736#include "scic_sds_controller.h"
737#include "scic_sds_port.h"
738#include "scic_sds_remote_device.h"
739#include "sci_util.h"
740#include "sci_environment.h"
741
742/*
743 * *****************************************************************************
744 * * STP REMOTE DEVICE READY SUBSTATE PRIVATE METHODS
745 * ***************************************************************************** */
746
747static void scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
748 void *user_cookie)
749{
750 struct scic_sds_remote_device *this_device;
751
752 this_device = (struct scic_sds_remote_device *)user_cookie;
753
754 /*
755 * For NCQ operation we do not issue a
756 * scic_cb_remote_device_not_ready(). As a result, avoid sending
757 * the ready notification. */
758 if (this_device->ready_substate_machine.previous_state_id
759 != SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ) {
760 scic_cb_remote_device_ready(
761 scic_sds_remote_device_get_controller(this_device), this_device
762 );
763 }
764}
765
766/*
767 * *****************************************************************************
768 * * STP REMOTE DEVICE READY IDLE SUBSTATE
769 * ***************************************************************************** */
770
771/**
772 *
773 * @device: This is the SCI base object which is cast into a
774 * struct scic_sds_remote_device object.
775 *
776 */
777static void scic_sds_stp_remote_device_ready_idle_substate_enter(
778 struct sci_base_object *device)
779{
780 struct scic_sds_remote_device *this_device;
781
782 this_device = (struct scic_sds_remote_device *)device;
783
784 SET_STATE_HANDLER(
785 this_device,
786 scic_sds_stp_remote_device_ready_substate_handler_table,
787 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE
788 );
789
790 this_device->working_request = NULL;
791
792 if (scic_sds_remote_node_context_is_ready(this_device->rnc)) {
793 /*
794 * Since the RNC is ready, it's alright to finish completion
795 * processing (e.g. signal the remote device is ready). */
796 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler(
797 this_device
798 );
799 } else {
800 scic_sds_remote_node_context_resume(
801 this_device->rnc,
802 scic_sds_stp_remote_device_ready_idle_substate_resume_complete_handler,
803 this_device
804 );
805 }
806}
807
808/*
809 * *****************************************************************************
810 * * STP REMOTE DEVICE READY CMD SUBSTATE
811 * ***************************************************************************** */
812
813/**
814 *
815 * @device: This is the SCI base object which is cast into a
816 * struct scic_sds_remote_device object.
817 *
818 */
819static void scic_sds_stp_remote_device_ready_cmd_substate_enter(
820 struct sci_base_object *device)
821{
822 struct scic_sds_remote_device *this_device;
823
824 this_device = (struct scic_sds_remote_device *)device;
825
826 BUG_ON(this_device->working_request == NULL);
827
828 SET_STATE_HANDLER(
829 this_device,
830 scic_sds_stp_remote_device_ready_substate_handler_table,
831 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD
832 );
833
834 scic_cb_remote_device_not_ready(
835 scic_sds_remote_device_get_controller(this_device),
836 this_device,
837 SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED
838 );
839}
840
841/*
842 * *****************************************************************************
843 * * STP REMOTE DEVICE READY NCQ SUBSTATE
844 * ***************************************************************************** */
845
846/**
847 *
848 * @device: This is the SCI base object which is cast into a
849 * struct scic_sds_remote_device object.
850 *
851 */
852static void scic_sds_stp_remote_device_ready_ncq_substate_enter(
853 struct sci_base_object *device)
854{
855 struct scic_sds_remote_device *this_device;
856
857 this_device = (struct scic_sds_remote_device *)device;
858
859 SET_STATE_HANDLER(
860 this_device,
861 scic_sds_stp_remote_device_ready_substate_handler_table,
862 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ
863 );
864}
865
866/*
867 * *****************************************************************************
868 * * STP REMOTE DEVICE READY NCQ ERROR SUBSTATE
869 * ***************************************************************************** */
870
871/**
872 *
873 * @device: This is the SCI base object which is cast into a
874 * struct scic_sds_remote_device object.
875 *
876 */
877static void scic_sds_stp_remote_device_ready_ncq_error_substate_enter(
878 struct sci_base_object *device)
879{
880 struct scic_sds_remote_device *this_device;
881
882 this_device = (struct scic_sds_remote_device *)device;
883
884 SET_STATE_HANDLER(
885 this_device,
886 scic_sds_stp_remote_device_ready_substate_handler_table,
887 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
888 );
889
890 if (this_device->not_ready_reason ==
891 SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED) {
892 scic_cb_remote_device_not_ready(
893 scic_sds_remote_device_get_controller(this_device),
894 this_device,
895 this_device->not_ready_reason
896 );
897 }
898}
899
900/*
901 * *****************************************************************************
902 * * STP REMOTE DEVICE READY AWAIT RESET SUBSTATE
903 * ***************************************************************************** */
904
905/**
906 * The enter routine to READY AWAIT RESET substate.
907 * @device: This is the SCI base object which is cast into a
908 * struct scic_sds_remote_device object.
909 *
910 */
911static void scic_sds_stp_remote_device_ready_await_reset_substate_enter(
912 struct sci_base_object *device)
913{
914 struct scic_sds_remote_device *this_device;
915
916 this_device = (struct scic_sds_remote_device *)device;
917
918 SET_STATE_HANDLER(
919 this_device,
920 scic_sds_stp_remote_device_ready_substate_handler_table,
921 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET
922 );
923}
924
925#if !defined(DISABLE_ATAPI)
926/*
927 * *****************************************************************************
928 * * STP REMOTE DEVICE READY ATAPI ERROR SUBSTATE
929 * ***************************************************************************** */
930
931/**
932 * The enter routine to READY ATAPI ERROR substate.
933 * @device: This is the SCI base object which is cast into a
934 * struct scic_sds_remote_device object.
935 *
936 */
937void scic_sds_stp_remote_device_ready_atapi_error_substate_enter(
938 struct sci_base_object *device)
939{
940 struct scic_sds_remote_device *this_device;
941
942 this_device = (struct scic_sds_remote_device *)device;
943
944 SET_STATE_HANDLER(
945 this_device,
946 scic_sds_stp_remote_device_ready_substate_handler_table,
947 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR
948 );
949}
950#endif /* !defined(DISABLE_ATAPI) */
951
952/* --------------------------------------------------------------------------- */
953
954const struct sci_base_state scic_sds_stp_remote_device_ready_substate_table[] = {
955 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE] = {
956 .enter_state = scic_sds_stp_remote_device_ready_idle_substate_enter,
957 },
958 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_CMD] = {
959 .enter_state = scic_sds_stp_remote_device_ready_cmd_substate_enter,
960 },
961 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ] = {
962 .enter_state = scic_sds_stp_remote_device_ready_ncq_substate_enter,
963 },
964 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR] = {
965 .enter_state = scic_sds_stp_remote_device_ready_ncq_error_substate_enter,
966 },
967#if !defined(DISABLE_ATAPI)
968 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_ATAPI_ERROR] = {
969 .enter_state = scic_sds_stp_remote_device_ready_atapi_error_substate_enter,
970 },
971#endif
972 [SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_AWAIT_RESET] = {
973 .enter_state = scic_sds_stp_remote_device_ready_await_reset_substate_enter,
974 },
975};
diff --git a/drivers/scsi/isci/core/scic_sds_stp_request.c b/drivers/scsi/isci/core/scic_sds_stp_request.c
new file mode 100644
index 000000000000..c14f6f10edb1
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_stp_request.c
@@ -0,0 +1,2004 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56
57#include "intel_ata.h"
58#include "intel_sata.h"
59#include "intel_sat.h"
60#include "sci_base_state.h"
61#include "sci_base_state_machine.h"
62#include "scic_io_request.h"
63#include "scic_remote_device.h"
64#include "scic_sds_controller.h"
65#include "scic_sds_remote_device.h"
66#include "scic_sds_request.h"
67#include "scic_sds_stp_pio_request.h"
68#include "scic_sds_stp_request.h"
69#include "scic_sds_unsolicited_frame_control.h"
70#include "scic_user_callback.h"
71#include "sci_environment.h"
72#include "sci_types.h"
73#include "sci_util.h"
74#include "scu_completion_codes.h"
75#include "scu_event_codes.h"
76#include "scu_task_context.h"
77
78/**
79 * scic_sds_stp_request_get_h2d_reg_buffer() -
80 *
81 * This macro returns the address of the stp h2d reg fis buffer in the io
82 * request memory
83 */
84#define scic_sds_stp_request_get_h2d_reg_buffer(memory) \
85 ((struct sata_fis_reg_h2d *)(\
86 ((char *)(memory)) + sizeof(struct scic_sds_stp_request) \
87 ))
88
89/**
90 * scic_sds_stp_request_get_response_buffer() -
91 *
92 * This macro returns the address of the ssp response iu buffer in the io
93 * request memory
94 */
95#define scic_sds_stp_request_get_response_buffer(memory) \
96 ((struct sata_fis_reg_d2h *)(\
97 ((char *)(scic_sds_stp_request_get_h2d_reg_buffer(memory))) \
98 + sizeof(struct sata_fis_reg_h2d) \
99 ))
100
101/**
102 * scic_sds_stp_request_get_task_context_buffer() -
103 *
104 * This macro returns the address of the task context buffer in the io request
105 * memory
106 */
107#define scic_sds_stp_request_get_task_context_buffer(memory) \
108 ((struct scu_task_context *)(\
109 ((char *)(scic_sds_stp_request_get_response_buffer(memory))) \
110 + sizeof(struct sci_ssp_response_iu) \
111 ))
112
113/**
114 * scic_sds_stp_request_get_sgl_element_buffer() -
115 *
116 * This macro returns the address of the sgl elment pairs in the io request
117 * memory buffer
118 */
119#define scic_sds_stp_request_get_sgl_element_buffer(memory) \
120 ((struct scu_sgl_element_pair *)(\
121 ((char *)(scic_sds_stp_request_get_task_context_buffer(memory))) \
122 + sizeof(struct scu_task_context) \
123 ))
124
125/**
126 *
127 *
128 * This method return the memory space required for STP PIO requests. u32
129 */
130u32 scic_sds_stp_request_get_object_size(void)
131{
132 return sizeof(struct scic_sds_stp_request)
133 + sizeof(struct sata_fis_reg_h2d)
134 + sizeof(struct sata_fis_reg_d2h)
135 + sizeof(struct scu_task_context)
136 + sizeof(struct scu_sgl_element_pair) * SCU_MAX_SGL_ELEMENT_PAIRS;
137}
138
139/**
140 *
141 *
142 *
143 */
144void scic_sds_stp_request_assign_buffers(
145 struct scic_sds_request *request)
146{
147 struct scic_sds_stp_request *this_request = (struct scic_sds_stp_request *)request;
148
149 this_request->parent.command_buffer =
150 scic_sds_stp_request_get_h2d_reg_buffer(this_request);
151 this_request->parent.response_buffer =
152 scic_sds_stp_request_get_response_buffer(this_request);
153 this_request->parent.sgl_element_pair_buffer =
154 scic_sds_stp_request_get_sgl_element_buffer(this_request);
155 this_request->parent.sgl_element_pair_buffer =
156 scic_sds_request_align_sgl_element_buffer(this_request->parent.sgl_element_pair_buffer);
157
158 if (this_request->parent.was_tag_assigned_by_user == false) {
159 this_request->parent.task_context_buffer =
160 scic_sds_stp_request_get_task_context_buffer(this_request);
161 this_request->parent.task_context_buffer =
162 scic_sds_request_align_task_context_buffer(this_request->parent.task_context_buffer);
163 }
164}
165
166/**
167 * This method is will fill in the SCU Task Context for any type of SATA
168 * request. This is called from the various SATA constructors.
169 * @this_request: The general IO request object which is to be used in
170 * constructing the SCU task context.
171 * @task_context: The buffer pointer for the SCU task context which is being
172 * constructed.
173 *
174 * The general io request construction is complete. The buffer assignment for
175 * the command buffer is complete. none Revisit task context construction to
176 * determine what is common for SSP/SMP/STP task context structures.
177 */
178static void scu_sata_reqeust_construct_task_context(
179 struct scic_sds_request *this_request,
180 struct scu_task_context *task_context)
181{
182 dma_addr_t physical_address;
183 struct scic_sds_controller *owning_controller;
184 struct scic_sds_remote_device *target_device;
185 struct scic_sds_port *target_port;
186
187 owning_controller = scic_sds_request_get_controller(this_request);
188 target_device = scic_sds_request_get_device(this_request);
189 target_port = scic_sds_request_get_port(this_request);
190
191 /* Fill in the TC with the its required data */
192 task_context->abort = 0;
193 task_context->priority = SCU_TASK_PRIORITY_NORMAL;
194 task_context->initiator_request = 1;
195 task_context->connection_rate =
196 scic_remote_device_get_connection_rate(target_device);
197 task_context->protocol_engine_index =
198 scic_sds_controller_get_protocol_engine_group(owning_controller);
199 task_context->logical_port_index =
200 scic_sds_port_get_index(target_port);
201 task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_STP;
202 task_context->valid = SCU_TASK_CONTEXT_VALID;
203 task_context->context_type = SCU_TASK_CONTEXT_TYPE;
204
205 task_context->remote_node_index =
206 scic_sds_remote_device_get_index(this_request->target_device);
207 task_context->command_code = 0;
208
209 task_context->link_layer_control = 0;
210 task_context->do_not_dma_ssp_good_response = 1;
211 task_context->strict_ordering = 0;
212 task_context->control_frame = 0;
213 task_context->timeout_enable = 0;
214 task_context->block_guard_enable = 0;
215
216 task_context->address_modifier = 0;
217 task_context->task_phase = 0x01;
218
219 task_context->ssp_command_iu_length =
220 (sizeof(struct sata_fis_reg_h2d) - sizeof(u32)) / sizeof(u32);
221
222 /* Set the first word of the H2D REG FIS */
223 task_context->type.words[0] = *(u32 *)this_request->command_buffer;
224
225 if (this_request->was_tag_assigned_by_user) {
226 /* Build the task context now since we have already read the data */
227 this_request->post_context = (
228 SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
229 | (
230 scic_sds_controller_get_protocol_engine_group(owning_controller)
231 << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
232 )
233 | (
234 scic_sds_port_get_index(target_port)
235 << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
236 )
237 | scic_sds_io_tag_get_index(this_request->io_tag)
238 );
239 } else {
240 /* Build the task context now since we have already read the data */
241 this_request->post_context = (
242 SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
243 | (
244 scic_sds_controller_get_protocol_engine_group(owning_controller)
245 << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
246 )
247 | (
248 scic_sds_port_get_index(target_port)
249 << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
250 )
251 /* This is not assigned because we have to wait until we get a TCi */
252 );
253 }
254
255 /*
256 * Copy the physical address for the command buffer to the SCU Task Context
257 * We must offset the command buffer by 4 bytes because the first 4 bytes are
258 * transfered in the body of the TC */
259 scic_cb_io_request_get_physical_address(
260 scic_sds_request_get_controller(this_request),
261 this_request,
262 ((char *)this_request->command_buffer) + sizeof(u32),
263 &physical_address
264 );
265
266 task_context->command_iu_upper =
267 upper_32_bits(physical_address);
268 task_context->command_iu_lower =
269 lower_32_bits(physical_address);
270
271 /* SATA Requests do not have a response buffer */
272 task_context->response_iu_upper = 0;
273 task_context->response_iu_lower = 0;
274}
275
276/**
277 *
278 * @this_request:
279 *
280 * This method will perform any general sata request construction. What part of
281 * SATA IO request construction is general? none
282 */
283void scic_sds_stp_non_ncq_request_construct(
284 struct scic_sds_request *this_request)
285{
286 this_request->has_started_substate_machine = true;
287}
288
289/**
290 *
291 * @this_request: This parameter specifies the request to be constructed as an
292 * optimized request.
293 * @optimized_task_type: This parameter specifies whether the request is to be
294 * an UDMA request or a NCQ request. - A value of 0 indicates UDMA. - A
295 * value of 1 indicates NCQ.
296 *
297 * This method will perform request construction common to all types of STP
298 * requests that are optimized by the silicon (i.e. UDMA, NCQ). This method
299 * returns an indication as to whether the construction was successful.
300 */
301static void scic_sds_stp_optimized_request_construct(
302 struct scic_sds_request *this_request,
303 u8 optimized_task_type,
304 u32 transfer_length,
305 SCI_IO_REQUEST_DATA_DIRECTION data_direction)
306{
307 struct scu_task_context *task_context = this_request->task_context_buffer;
308
309 /* Build the STP task context structure */
310 scu_sata_reqeust_construct_task_context(this_request, task_context);
311
312 /* Copy over the SGL elements */
313 scic_sds_request_build_sgl(this_request);
314
315 /* Copy over the number of bytes to be transfered */
316 task_context->transfer_length_bytes = transfer_length;
317
318 if (data_direction == SCI_IO_REQUEST_DATA_OUT) {
319 /*
320 * The difference between the DMA IN and DMA OUT request task type
321 * values are consistent with the difference between FPDMA READ
322 * and FPDMA WRITE values. Add the supplied task type parameter
323 * to this difference to set the task type properly for this
324 * DATA OUT (WRITE) case. */
325 task_context->task_type = optimized_task_type + (SCU_TASK_TYPE_DMA_OUT
326 - SCU_TASK_TYPE_DMA_IN);
327 } else {
328 /*
329 * For the DATA IN (READ) case, simply save the supplied
330 * optimized task type. */
331 task_context->task_type = optimized_task_type;
332 }
333}
334
335/**
336 *
337 * @this_request: This parameter specifies the request to be constructed.
338 *
339 * This method will construct the STP UDMA request and its associated TC data.
340 * This method returns an indication as to whether the construction was
341 * successful. SCI_SUCCESS Currently this method always returns this value.
342 */
343enum sci_status scic_sds_stp_udma_request_construct(
344 struct scic_sds_request *this_request,
345 u32 transfer_length,
346 SCI_IO_REQUEST_DATA_DIRECTION data_direction)
347{
348 scic_sds_stp_non_ncq_request_construct(this_request);
349
350 scic_sds_stp_optimized_request_construct(
351 this_request,
352 SCU_TASK_TYPE_DMA_IN,
353 transfer_length,
354 data_direction
355 );
356
357 sci_base_state_machine_construct(
358 &this_request->started_substate_machine,
359 &this_request->parent.parent,
360 scic_sds_stp_request_started_udma_substate_table,
361 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE
362 );
363
364 return SCI_SUCCESS;
365}
366
367/**
368 *
369 * @this_request: This parameter specifies the request to be constructed.
370 *
371 * This method will construct the STP UDMA request and its associated TC data.
372 * This method returns an indication as to whether the construction was
373 * successful. SCI_SUCCESS Currently this method always returns this value.
374 */
375enum sci_status scic_sds_stp_ncq_request_construct(
376 struct scic_sds_request *this_request,
377 u32 transfer_length,
378 SCI_IO_REQUEST_DATA_DIRECTION data_direction)
379{
380 scic_sds_stp_optimized_request_construct(
381 this_request,
382 SCU_TASK_TYPE_FPDMAQ_READ,
383 transfer_length,
384 data_direction
385 );
386 return SCI_SUCCESS;
387}
388
389/**
390 *
391 * @this_request: This parameter specifies the STP request object for which to
392 * construct a RAW command frame task context.
393 * @task_context: This parameter specifies the SCU specific task context buffer
394 * to construct.
395 *
396 * This method performs the operations common to all SATA/STP requests
397 * utilizing the raw frame method. none
398 */
399void scu_stp_raw_request_construct_task_context(
400 struct scic_sds_stp_request *this_request,
401 struct scu_task_context *task_context)
402{
403 scu_sata_reqeust_construct_task_context(&this_request->parent, task_context);
404
405 task_context->control_frame = 0;
406 task_context->priority = SCU_TASK_PRIORITY_NORMAL;
407 task_context->task_type = SCU_TASK_TYPE_SATA_RAW_FRAME;
408 task_context->type.stp.fis_type = SATA_FIS_TYPE_REGH2D;
409 task_context->transfer_length_bytes = sizeof(struct sata_fis_reg_h2d) - sizeof(u32);
410}
411
412/**
413 *
414 * @this_request: This parameter specifies the core request object to
415 * construction into an STP/SATA non-data request.
416 *
417 * This method will construct the STP Non-data request and its associated TC
418 * data. A non-data request essentially behaves like a 0 length read request
419 * in the SCU. This method currently always returns SCI_SUCCESS
420 */
421enum sci_status scic_sds_stp_non_data_request_construct(
422 struct scic_sds_request *this_request)
423{
424 scic_sds_stp_non_ncq_request_construct(this_request);
425
426 /* Build the STP task context structure */
427 scu_stp_raw_request_construct_task_context(
428 (struct scic_sds_stp_request *)this_request,
429 this_request->task_context_buffer
430 );
431
432 sci_base_state_machine_construct(
433 &this_request->started_substate_machine,
434 &this_request->parent.parent,
435 scic_sds_stp_request_started_non_data_substate_table,
436 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE
437 );
438
439 return SCI_SUCCESS;
440}
441
442
443enum sci_status scic_sds_stp_soft_reset_request_construct(
444 struct scic_sds_request *this_request)
445{
446 scic_sds_stp_non_ncq_request_construct(this_request);
447
448 /* Build the STP task context structure */
449 scu_stp_raw_request_construct_task_context(
450 (struct scic_sds_stp_request *)this_request,
451 this_request->task_context_buffer
452 );
453
454 sci_base_state_machine_construct(
455 &this_request->started_substate_machine,
456 &this_request->parent.parent,
457 scic_sds_stp_request_started_soft_reset_substate_table,
458 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE
459 );
460
461 return SCI_SUCCESS;
462}
463
464
465void scic_stp_io_request_set_ncq_tag(
466 struct scic_sds_request *req,
467 u16 ncq_tag)
468{
469 /**
470 * @note This could be made to return an error to the user if the user
471 * attempts to set the NCQ tag in the wrong state.
472 */
473 req->task_context_buffer->type.stp.ncq_tag = ncq_tag;
474}
475
476
477void *scic_stp_io_request_get_h2d_reg_address(
478 struct scic_sds_request *req)
479{
480 return req->command_buffer;
481}
482
483
484void *scic_stp_io_request_get_d2h_reg_address(
485 struct scic_sds_request *req)
486{
487 return &((struct scic_sds_stp_request *)req)->d2h_reg_fis;
488}
489
490/**
491 *
492 * @this_request:
493 *
494 * Get the next SGL element from the request. - Check on which SGL element pair
495 * we are working - if working on SLG pair element A - advance to element B -
496 * else - check to see if there are more SGL element pairs for this IO request
497 * - if there are more SGL element pairs - advance to the next pair and return
498 * element A struct scu_sgl_element*
499 */
500struct scu_sgl_element *scic_sds_stp_request_pio_get_next_sgl(
501 struct scic_sds_stp_request *this_request
502 ) {
503 struct scu_sgl_element *current_sgl;
504
505 if (this_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) {
506 if (
507 (this_request->type.pio.request_current.sgl_pair->B.address_lower == 0)
508 && (this_request->type.pio.request_current.sgl_pair->B.address_upper == 0)
509 ) {
510 current_sgl = NULL;
511 } else {
512 this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_B;
513 current_sgl = &(this_request->type.pio.request_current.sgl_pair->B);
514 }
515 } else {
516 if (
517 (this_request->type.pio.request_current.sgl_pair->next_pair_lower == 0)
518 && (this_request->type.pio.request_current.sgl_pair->next_pair_upper == 0)
519 ) {
520 current_sgl = NULL;
521 } else {
522 dma_addr_t physical_address;
523
524 sci_cb_make_physical_address(
525 physical_address,
526 this_request->type.pio.request_current.sgl_pair->next_pair_upper,
527 this_request->type.pio.request_current.sgl_pair->next_pair_lower
528 );
529
530 this_request->type.pio.request_current.sgl_pair =
531 (struct scu_sgl_element_pair *)scic_cb_get_virtual_address(
532 this_request->parent.owning_controller,
533 physical_address
534 );
535
536 this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_A;
537
538 current_sgl = &(this_request->type.pio.request_current.sgl_pair->A);
539 }
540 }
541
542 return current_sgl;
543}
544
545/**
546 *
547 * @scic_io_request: The core request object which is cast to a SATA PIO
548 * request object.
549 *
550 * This method will construct the SATA PIO request. This method returns an
551 * indication as to whether the construction was successful. SCI_SUCCESS
552 * Currently this method always returns this value.
553 */
554enum sci_status scic_sds_stp_pio_request_construct(
555 struct scic_sds_request *scic_io_request,
556 u8 sat_protocol,
557 bool copy_rx_frame)
558{
559 struct scic_sds_stp_request *this_request;
560
561 this_request = (struct scic_sds_stp_request *)scic_io_request;
562
563 scic_sds_stp_non_ncq_request_construct(&this_request->parent);
564
565 scu_stp_raw_request_construct_task_context(
566 this_request, this_request->parent.task_context_buffer
567 );
568
569 this_request->type.pio.current_transfer_bytes = 0;
570 this_request->type.pio.ending_error = 0;
571 this_request->type.pio.ending_status = 0;
572
573 this_request->type.pio.request_current.sgl_offset = 0;
574 this_request->type.pio.request_current.sgl_set = SCU_SGL_ELEMENT_PAIR_A;
575 this_request->type.pio.sat_protocol = sat_protocol;
576
577 if (copy_rx_frame) {
578 scic_sds_request_build_sgl(&this_request->parent);
579 /*
580 * Since the IO request copy of the TC contains the same data as
581 * the actual TC this pointer is vaild for either. */
582 this_request->type.pio.request_current.sgl_pair =
583 &this_request->parent.task_context_buffer->sgl_pair_ab;
584 } else {
585 /* The user does not want the data copied to the SGL buffer location */
586 this_request->type.pio.request_current.sgl_pair = NULL;
587 }
588
589 sci_base_state_machine_construct(
590 &this_request->parent.started_substate_machine,
591 &this_request->parent.parent.parent,
592 scic_sds_stp_request_started_pio_substate_table,
593 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE
594 );
595
596 return SCI_SUCCESS;
597}
598
599/**
600 *
601 * @this_request:
602 * @completion_code:
603 *
604 * This method processes a TC completion. The expected TC completion is for
605 * the transmission of the H2D register FIS containing the SATA/STP non-data
606 * request. This method always successfully processes the TC completion.
607 * SCI_SUCCESS This value is always returned.
608 */
609static enum sci_status scic_sds_stp_request_non_data_await_h2d_tc_completion_handler(
610 struct scic_sds_request *this_request,
611 u32 completion_code)
612{
613 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
614 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
615 scic_sds_request_set_status(
616 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
617 );
618
619 sci_base_state_machine_change_state(
620 &this_request->started_substate_machine,
621 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE
622 );
623 break;
624
625 default:
626 /*
627 * All other completion status cause the IO to be complete. If a NAK
628 * was received, then it is up to the user to retry the request. */
629 scic_sds_request_set_status(
630 this_request,
631 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
632 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
633 );
634
635 sci_base_state_machine_change_state(
636 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
637 );
638 break;
639 }
640
641 return SCI_SUCCESS;
642}
643
644/**
645 *
646 * @request: This parameter specifies the request for which a frame has been
647 * received.
648 * @frame_index: This parameter specifies the index of the frame that has been
649 * received.
650 *
651 * This method processes frames received from the target while waiting for a
652 * device to host register FIS. If a non-register FIS is received during this
653 * time, it is treated as a protocol violation from an IO perspective. Indicate
654 * if the received frame was processed successfully.
655 */
656static enum sci_status scic_sds_stp_request_non_data_await_d2h_frame_handler(
657 struct scic_sds_request *request,
658 u32 frame_index)
659{
660 enum sci_status status;
661 struct sata_fis_header *frame_header;
662 u32 *frame_buffer;
663 struct scic_sds_stp_request *this_request = (struct scic_sds_stp_request *)request;
664
665 status = scic_sds_unsolicited_frame_control_get_header(
666 &(this_request->parent.owning_controller->uf_control),
667 frame_index,
668 (void **)&frame_header
669 );
670
671 if (status == SCI_SUCCESS) {
672 switch (frame_header->fis_type) {
673 case SATA_FIS_TYPE_REGD2H:
674 scic_sds_unsolicited_frame_control_get_buffer(
675 &(this_request->parent.owning_controller->uf_control),
676 frame_index,
677 (void **)&frame_buffer
678 );
679
680 scic_sds_controller_copy_sata_response(
681 &this_request->d2h_reg_fis, (u32 *)frame_header, frame_buffer
682 );
683
684 /* The command has completed with error */
685 scic_sds_request_set_status(
686 &this_request->parent,
687 SCU_TASK_DONE_CHECK_RESPONSE,
688 SCI_FAILURE_IO_RESPONSE_VALID
689 );
690 break;
691
692 default:
693 dev_warn(scic_to_dev(request->owning_controller),
694 "%s: IO Request:0x%p Frame Id:%d protocol "
695 "violation occurred\n",
696 __func__, this_request, frame_index);
697
698 scic_sds_request_set_status(
699 &this_request->parent,
700 SCU_TASK_DONE_UNEXP_FIS,
701 SCI_FAILURE_PROTOCOL_VIOLATION
702 );
703 break;
704 }
705
706 sci_base_state_machine_change_state(
707 &this_request->parent.parent.state_machine,
708 SCI_BASE_REQUEST_STATE_COMPLETED
709 );
710
711 /* Frame has been decoded return it to the controller */
712 scic_sds_controller_release_frame(
713 this_request->parent.owning_controller, frame_index
714 );
715 } else
716 dev_err(scic_to_dev(request->owning_controller),
717 "%s: SCIC IO Request 0x%p could not get frame header "
718 "for frame index %d, status %x\n",
719 __func__, this_request, frame_index, status);
720
721 return status;
722}
723
724/* --------------------------------------------------------------------------- */
725
726const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_non_data_substate_handler_table[] = {
727 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE] = {
728 .parent.start_handler = scic_sds_request_default_start_handler,
729 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
730 .parent.complete_handler = scic_sds_request_default_complete_handler,
731 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
732 .tc_completion_handler = scic_sds_stp_request_non_data_await_h2d_tc_completion_handler,
733 .event_handler = scic_sds_request_default_event_handler,
734 .frame_handler = scic_sds_request_default_frame_handler,
735 },
736 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE] = {
737 .parent.start_handler = scic_sds_request_default_start_handler,
738 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
739 .parent.complete_handler = scic_sds_request_default_complete_handler,
740 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
741 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
742 .event_handler = scic_sds_request_default_event_handler,
743 .frame_handler = scic_sds_stp_request_non_data_await_d2h_frame_handler,
744 }
745};
746
747static void scic_sds_stp_request_started_non_data_await_h2d_completion_enter(
748 struct sci_base_object *object)
749{
750 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
751
752 SET_STATE_HANDLER(
753 this_request,
754 scic_sds_stp_request_started_non_data_substate_handler_table,
755 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE
756 );
757
758 scic_sds_remote_device_set_working_request(
759 this_request->target_device, this_request
760 );
761}
762
763static void scic_sds_stp_request_started_non_data_await_d2h_enter(
764 struct sci_base_object *object)
765{
766 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
767
768 SET_STATE_HANDLER(
769 this_request,
770 scic_sds_stp_request_started_non_data_substate_handler_table,
771 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE
772 );
773}
774
775/* --------------------------------------------------------------------------- */
776
777const struct sci_base_state scic_sds_stp_request_started_non_data_substate_table[] = {
778 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE] = {
779 .enter_state = scic_sds_stp_request_started_non_data_await_h2d_completion_enter,
780 },
781 [SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE] = {
782 .enter_state = scic_sds_stp_request_started_non_data_await_d2h_enter,
783 },
784};
785
786#define SCU_MAX_FRAME_BUFFER_SIZE 0x400 /* 1K is the maximum SCU frame data payload */
787
788/**
789 *
790 * @this_request:
791 * @length:
792 *
793 * This function will transmit DATA_FIS from (current sgl + offset) for input
794 * parameter length. current sgl and offset is alreay stored in the IO request
795 * enum sci_status
796 */
797
798static enum sci_status scic_sds_stp_request_pio_data_out_trasmit_data_frame(
799 struct scic_sds_request *this_request,
800 u32 length)
801{
802 struct scic_sds_stp_request *this_sds_stp_request = (struct scic_sds_stp_request *)this_request;
803 sci_base_controller_request_handler_t continue_io;
804 struct scu_sgl_element *current_sgl;
805 struct scic_sds_controller *scic;
806 u32 state;
807
808 /*
809 * Recycle the TC and reconstruct it for sending out DATA FIS containing
810 * for the data from current_sgl+offset for the input length */
811 struct scu_task_context *task_context = scic_sds_controller_get_task_context_buffer(
812 this_request->owning_controller,
813 this_request->io_tag
814 );
815
816 if (this_sds_stp_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A)
817 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->A);
818 else
819 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->B);
820
821 /* update the TC */
822 task_context->command_iu_upper = current_sgl->address_upper;
823 task_context->command_iu_lower = current_sgl->address_lower;
824 task_context->transfer_length_bytes = length;
825 task_context->type.stp.fis_type = SATA_FIS_TYPE_DATA;
826
827 /* send the new TC out. */
828 scic = this_request->owning_controller;
829 state = scic->parent.state_machine.current_state_id;
830 continue_io = scic_sds_controller_state_handler_table[state].base.continue_io;
831 return continue_io(&scic->parent, &this_request->target_device->parent,
832 &this_request->parent);
833}
834
835/**
836 *
837 * @this_request:
838 *
839 * enum sci_status
840 */
841static enum sci_status scic_sds_stp_request_pio_data_out_transmit_data(
842 struct scic_sds_request *this_sds_request)
843{
844
845 struct scu_sgl_element *current_sgl;
846 u32 sgl_offset;
847 u32 remaining_bytes_in_current_sgl = 0;
848 enum sci_status status = SCI_SUCCESS;
849
850 struct scic_sds_stp_request *this_sds_stp_request = (struct scic_sds_stp_request *)this_sds_request;
851
852 sgl_offset = this_sds_stp_request->type.pio.request_current.sgl_offset;
853
854 if (this_sds_stp_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) {
855 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->A);
856 remaining_bytes_in_current_sgl = this_sds_stp_request->type.pio.request_current.sgl_pair->A.length - sgl_offset;
857 } else {
858 current_sgl = &(this_sds_stp_request->type.pio.request_current.sgl_pair->B);
859 remaining_bytes_in_current_sgl = this_sds_stp_request->type.pio.request_current.sgl_pair->B.length - sgl_offset;
860 }
861
862
863 if (this_sds_stp_request->type.pio.pio_transfer_bytes > 0) {
864 if (this_sds_stp_request->type.pio.pio_transfer_bytes >= remaining_bytes_in_current_sgl) {
865 /* recycle the TC and send the H2D Data FIS from (current sgl + sgl_offset) and length = remaining_bytes_in_current_sgl */
866 status = scic_sds_stp_request_pio_data_out_trasmit_data_frame(this_sds_request, remaining_bytes_in_current_sgl);
867 if (status == SCI_SUCCESS) {
868 this_sds_stp_request->type.pio.pio_transfer_bytes -= remaining_bytes_in_current_sgl;
869
870 /* update the current sgl, sgl_offset and save for future */
871 current_sgl = scic_sds_stp_request_pio_get_next_sgl(this_sds_stp_request);
872 sgl_offset = 0;
873 }
874 } else if (this_sds_stp_request->type.pio.pio_transfer_bytes < remaining_bytes_in_current_sgl) {
875 /* recycle the TC and send the H2D Data FIS from (current sgl + sgl_offset) and length = type.pio.pio_transfer_bytes */
876 scic_sds_stp_request_pio_data_out_trasmit_data_frame(this_sds_request, this_sds_stp_request->type.pio.pio_transfer_bytes);
877
878 if (status == SCI_SUCCESS) {
879 /* Sgl offset will be adjusted and saved for future */
880 sgl_offset += this_sds_stp_request->type.pio.pio_transfer_bytes;
881 current_sgl->address_lower += this_sds_stp_request->type.pio.pio_transfer_bytes;
882 this_sds_stp_request->type.pio.pio_transfer_bytes = 0;
883 }
884 }
885 }
886
887 if (status == SCI_SUCCESS) {
888 this_sds_stp_request->type.pio.request_current.sgl_offset = sgl_offset;
889 }
890
891 return status;
892}
893
894/**
895 *
896 * @this_request: The request that is used for the SGL processing.
897 * @data_buffer: The buffer of data to be copied.
898 * @length: The length of the data transfer.
899 *
900 * Copy the data from the buffer for the length specified to the IO reqeust SGL
901 * specified data region. enum sci_status
902 */
903static enum sci_status scic_sds_stp_request_pio_data_in_copy_data_buffer(
904 struct scic_sds_stp_request *this_request,
905 u8 *data_buffer,
906 u32 length)
907{
908 enum sci_status status;
909 struct scu_sgl_element *current_sgl;
910 u32 sgl_offset;
911 u32 data_offset;
912 u8 *source_address;
913 u8 *destination_address;
914 u32 copy_length;
915
916 /* Initial setup to get the current working SGL and the offset within the buffer */
917 current_sgl =
918 (this_request->type.pio.request_current.sgl_set == SCU_SGL_ELEMENT_PAIR_A) ?
919 &(this_request->type.pio.request_current.sgl_pair->A) :
920 &(this_request->type.pio.request_current.sgl_pair->B);
921
922 sgl_offset = this_request->type.pio.request_current.sgl_offset;
923
924 source_address = data_buffer;
925 data_offset = 0;
926
927 status = SCI_SUCCESS;
928
929 /* While we are still doing Ok and there is more data to transfer */
930 while (
931 (length > 0)
932 && (status == SCI_SUCCESS)
933 ) {
934 if (current_sgl->length == sgl_offset) {
935 /* This SGL has been exauhasted so we need to get the next SGL */
936 current_sgl = scic_sds_stp_request_pio_get_next_sgl(this_request);
937
938 if (current_sgl == NULL)
939 status = SCI_FAILURE;
940 else
941 sgl_offset = 0;
942 } else {
943 dma_addr_t physical_address;
944
945 sci_cb_make_physical_address(
946 physical_address,
947 current_sgl->address_upper,
948 current_sgl->address_lower
949 );
950
951 destination_address = (u8 *)scic_cb_get_virtual_address(
952 this_request->parent.owning_controller,
953 physical_address
954 );
955
956 source_address += data_offset;
957 destination_address += sgl_offset;
958
959 copy_length = min(length, current_sgl->length - sgl_offset);
960
961 memcpy(destination_address, source_address, copy_length);
962
963 length -= copy_length;
964 sgl_offset += copy_length;
965 data_offset += copy_length;
966 }
967 }
968
969 this_request->type.pio.request_current.sgl_offset = sgl_offset;
970
971 return status;
972}
973
974/**
975 *
976 * @this_request: The PIO DATA IN request that is to receive the data.
977 * @data_buffer: The buffer to copy from.
978 *
979 * Copy the data buffer to the io request data region. enum sci_status
980 */
981static enum sci_status scic_sds_stp_request_pio_data_in_copy_data(
982 struct scic_sds_stp_request *this_request,
983 u8 *data_buffer)
984{
985 enum sci_status status;
986
987 /*
988 * If there is less than 1K remaining in the transfer request
989 * copy just the data for the transfer */
990 if (this_request->type.pio.pio_transfer_bytes < SCU_MAX_FRAME_BUFFER_SIZE) {
991 status = scic_sds_stp_request_pio_data_in_copy_data_buffer(
992 this_request, data_buffer, this_request->type.pio.pio_transfer_bytes);
993
994 if (status == SCI_SUCCESS)
995 this_request->type.pio.pio_transfer_bytes = 0;
996 } else {
997 /* We are transfering the whole frame so copy */
998 status = scic_sds_stp_request_pio_data_in_copy_data_buffer(
999 this_request, data_buffer, SCU_MAX_FRAME_BUFFER_SIZE);
1000
1001 if (status == SCI_SUCCESS)
1002 this_request->type.pio.pio_transfer_bytes -= SCU_MAX_FRAME_BUFFER_SIZE;
1003 }
1004
1005 return status;
1006}
1007
1008/**
1009 *
1010 * @this_request:
1011 * @completion_code:
1012 *
1013 * enum sci_status
1014 */
1015static enum sci_status scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler(
1016 struct scic_sds_request *this_request,
1017 u32 completion_code)
1018{
1019 enum sci_status status = SCI_SUCCESS;
1020
1021 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1022 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1023 scic_sds_request_set_status(
1024 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
1025 );
1026
1027 sci_base_state_machine_change_state(
1028 &this_request->started_substate_machine,
1029 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1030 );
1031 break;
1032
1033 default:
1034 /*
1035 * All other completion status cause the IO to be complete. If a NAK
1036 * was received, then it is up to the user to retry the request. */
1037 scic_sds_request_set_status(
1038 this_request,
1039 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1040 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1041 );
1042
1043 sci_base_state_machine_change_state(
1044 &this_request->parent.state_machine,
1045 SCI_BASE_REQUEST_STATE_COMPLETED
1046 );
1047 break;
1048 }
1049
1050 return status;
1051}
1052
1053/**
1054 *
1055 * @this_request:
1056 * @frame_index:
1057 *
1058 * enum sci_status
1059 */
1060static enum sci_status scic_sds_stp_request_pio_await_frame_frame_handler(
1061 struct scic_sds_request *request,
1062 u32 frame_index)
1063{
1064 enum sci_status status;
1065 struct sata_fis_header *frame_header;
1066 u32 *frame_buffer;
1067 struct scic_sds_stp_request *this_request;
1068
1069 this_request = (struct scic_sds_stp_request *)request;
1070
1071 status = scic_sds_unsolicited_frame_control_get_header(
1072 &(this_request->parent.owning_controller->uf_control),
1073 frame_index,
1074 (void **)&frame_header
1075 );
1076
1077 if (status == SCI_SUCCESS) {
1078 switch (frame_header->fis_type) {
1079 case SATA_FIS_TYPE_PIO_SETUP:
1080 /* Get from the frame buffer the PIO Setup Data */
1081 scic_sds_unsolicited_frame_control_get_buffer(
1082 &(this_request->parent.owning_controller->uf_control),
1083 frame_index,
1084 (void **)&frame_buffer
1085 );
1086
1087 /*
1088 * Get the data from the PIO Setup
1089 * The SCU Hardware returns first word in the frame_header and the rest
1090 * of the data is in the frame buffer so we need to back up one dword */
1091 this_request->type.pio.pio_transfer_bytes =
1092 (u16)((struct sata_fis_pio_setup *)(&frame_buffer[-1]))->transfter_count;
1093 this_request->type.pio.ending_status =
1094 (u8)((struct sata_fis_pio_setup *)(&frame_buffer[-1]))->ending_status;
1095
1096 scic_sds_controller_copy_sata_response(
1097 &this_request->d2h_reg_fis, (u32 *)frame_header, frame_buffer
1098 );
1099
1100 this_request->d2h_reg_fis.status =
1101 this_request->type.pio.ending_status;
1102
1103 /* The next state is dependent on whether the request was PIO Data-in or Data out */
1104 if (this_request->type.pio.sat_protocol == SAT_PROTOCOL_PIO_DATA_IN) {
1105 sci_base_state_machine_change_state(
1106 &this_request->parent.started_substate_machine,
1107 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE
1108 );
1109 } else if (this_request->type.pio.sat_protocol == SAT_PROTOCOL_PIO_DATA_OUT) {
1110 /* Transmit data */
1111 status = scic_sds_stp_request_pio_data_out_transmit_data(request);
1112 if (status == SCI_SUCCESS) {
1113 sci_base_state_machine_change_state(
1114 &this_request->parent.started_substate_machine,
1115 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE
1116 );
1117 }
1118 }
1119 break;
1120
1121 case SATA_FIS_TYPE_SETDEVBITS:
1122 sci_base_state_machine_change_state(
1123 &this_request->parent.started_substate_machine,
1124 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1125 );
1126 break;
1127
1128 case SATA_FIS_TYPE_REGD2H:
1129 if ((frame_header->status & ATA_STATUS_REG_BSY_BIT) == 0) {
1130 scic_sds_unsolicited_frame_control_get_buffer(
1131 &(this_request->parent.owning_controller->uf_control),
1132 frame_index,
1133 (void **)&frame_buffer
1134 );
1135
1136 scic_sds_controller_copy_sata_response(
1137 &this_request->d2h_reg_fis, (u32 *)frame_header, frame_buffer);
1138
1139 scic_sds_request_set_status(
1140 &this_request->parent,
1141 SCU_TASK_DONE_CHECK_RESPONSE,
1142 SCI_FAILURE_IO_RESPONSE_VALID
1143 );
1144
1145 sci_base_state_machine_change_state(
1146 &this_request->parent.parent.state_machine,
1147 SCI_BASE_REQUEST_STATE_COMPLETED
1148 );
1149 } else {
1150 /*
1151 * Now why is the drive sending a D2H Register FIS when it is still busy?
1152 * Do nothing since we are still in the right state. */
1153 dev_dbg(scic_to_dev(request->owning_controller),
1154 "%s: SCIC PIO Request 0x%p received "
1155 "D2H Register FIS with BSY status "
1156 "0x%x\n",
1157 __func__,
1158 this_request,
1159 frame_header->status);
1160 }
1161 break;
1162
1163 default:
1164 break;
1165 }
1166
1167 /* Frame is decoded return it to the controller */
1168 scic_sds_controller_release_frame(
1169 this_request->parent.owning_controller,
1170 frame_index
1171 );
1172 } else
1173 dev_err(scic_to_dev(request->owning_controller),
1174 "%s: SCIC IO Request 0x%p could not get frame header "
1175 "for frame index %d, status %x\n",
1176 __func__, this_request, frame_index, status);
1177
1178 return status;
1179}
1180
1181/**
1182 *
1183 * @this_request:
1184 * @frame_index:
1185 *
1186 * enum sci_status
1187 */
1188static enum sci_status scic_sds_stp_request_pio_data_in_await_data_frame_handler(
1189 struct scic_sds_request *request,
1190 u32 frame_index)
1191{
1192 enum sci_status status;
1193 struct sata_fis_header *frame_header;
1194 struct sata_fis_data *frame_buffer;
1195 struct scic_sds_stp_request *this_request;
1196
1197 this_request = (struct scic_sds_stp_request *)request;
1198
1199 status = scic_sds_unsolicited_frame_control_get_header(
1200 &(this_request->parent.owning_controller->uf_control),
1201 frame_index,
1202 (void **)&frame_header
1203 );
1204
1205 if (status == SCI_SUCCESS) {
1206 if (frame_header->fis_type == SATA_FIS_TYPE_DATA) {
1207 if (this_request->type.pio.request_current.sgl_pair == NULL) {
1208 this_request->parent.saved_rx_frame_index = frame_index;
1209 this_request->type.pio.pio_transfer_bytes = 0;
1210 } else {
1211 status = scic_sds_unsolicited_frame_control_get_buffer(
1212 &(this_request->parent.owning_controller->uf_control),
1213 frame_index,
1214 (void **)&frame_buffer
1215 );
1216
1217 status = scic_sds_stp_request_pio_data_in_copy_data(this_request, (u8 *)frame_buffer);
1218
1219 /* Frame is decoded return it to the controller */
1220 scic_sds_controller_release_frame(
1221 this_request->parent.owning_controller,
1222 frame_index
1223 );
1224 }
1225
1226 /*
1227 * Check for the end of the transfer, are there more bytes remaining
1228 * for this data transfer */
1229 if (
1230 (status == SCI_SUCCESS)
1231 && (this_request->type.pio.pio_transfer_bytes == 0)
1232 ) {
1233 if ((this_request->type.pio.ending_status & ATA_STATUS_REG_BSY_BIT) == 0) {
1234 scic_sds_request_set_status(
1235 &this_request->parent,
1236 SCU_TASK_DONE_CHECK_RESPONSE,
1237 SCI_FAILURE_IO_RESPONSE_VALID
1238 );
1239
1240 sci_base_state_machine_change_state(
1241 &this_request->parent.parent.state_machine,
1242 SCI_BASE_REQUEST_STATE_COMPLETED
1243 );
1244 } else {
1245 sci_base_state_machine_change_state(
1246 &this_request->parent.started_substate_machine,
1247 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1248 );
1249 }
1250 }
1251 } else {
1252 dev_err(scic_to_dev(request->owning_controller),
1253 "%s: SCIC PIO Request 0x%p received frame %d "
1254 "with fis type 0x%02x when expecting a data "
1255 "fis.\n",
1256 __func__,
1257 this_request,
1258 frame_index,
1259 frame_header->fis_type);
1260
1261 scic_sds_request_set_status(
1262 &this_request->parent,
1263 SCU_TASK_DONE_GOOD,
1264 SCI_FAILURE_IO_REQUIRES_SCSI_ABORT
1265 );
1266
1267 sci_base_state_machine_change_state(
1268 &this_request->parent.parent.state_machine,
1269 SCI_BASE_REQUEST_STATE_COMPLETED
1270 );
1271
1272 /* Frame is decoded return it to the controller */
1273 scic_sds_controller_release_frame(
1274 this_request->parent.owning_controller,
1275 frame_index
1276 );
1277 }
1278 } else
1279 dev_err(scic_to_dev(request->owning_controller),
1280 "%s: SCIC IO Request 0x%p could not get frame header "
1281 "for frame index %d, status %x\n",
1282 __func__, this_request, frame_index, status);
1283
1284 return status;
1285}
1286
1287
1288/**
1289 *
1290 * @this_request:
1291 * @completion_code:
1292 *
1293 * enum sci_status
1294 */
1295static enum sci_status scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler(
1296
1297 struct scic_sds_request *this_request,
1298 u32 completion_code)
1299{
1300 enum sci_status status = SCI_SUCCESS;
1301 bool all_frames_transferred = false;
1302
1303 struct scic_sds_stp_request *this_scic_sds_stp_request = (struct scic_sds_stp_request *)this_request;
1304
1305 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1306 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1307 /* Transmit data */
1308 if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes != 0) {
1309 status = scic_sds_stp_request_pio_data_out_transmit_data(this_request);
1310 if (status == SCI_SUCCESS) {
1311 if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes == 0)
1312 all_frames_transferred = true;
1313 }
1314 } else if (this_scic_sds_stp_request->type.pio.pio_transfer_bytes == 0) {
1315 /*
1316 * this will happen if the all data is written at the
1317 * first time after the pio setup fis is received
1318 */
1319 all_frames_transferred = true;
1320 }
1321
1322 /* all data transferred. */
1323 if (all_frames_transferred) {
1324 /*
1325 * Change the state to SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_FRAME_SUBSTATE
1326 * and wait for PIO_SETUP fis / or D2H REg fis. */
1327 sci_base_state_machine_change_state(
1328 &this_request->started_substate_machine,
1329 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1330 );
1331 }
1332 break;
1333
1334 default:
1335 /*
1336 * All other completion status cause the IO to be complete. If a NAK
1337 * was received, then it is up to the user to retry the request. */
1338 scic_sds_request_set_status(
1339 this_request,
1340 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1341 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1342 );
1343
1344 sci_base_state_machine_change_state(
1345 &this_request->parent.state_machine,
1346 SCI_BASE_REQUEST_STATE_COMPLETED
1347 );
1348 break;
1349 }
1350
1351 return status;
1352}
1353
1354/**
1355 *
1356 * @request: This is the request which is receiving the event.
1357 * @event_code: This is the event code that the request on which the request is
1358 * expected to take action.
1359 *
1360 * This method will handle any link layer events while waiting for the data
1361 * frame. enum sci_status SCI_SUCCESS SCI_FAILURE
1362 */
1363static enum sci_status scic_sds_stp_request_pio_data_in_await_data_event_handler(
1364 struct scic_sds_request *request,
1365 u32 event_code)
1366{
1367 enum sci_status status;
1368
1369 switch (scu_get_event_specifier(event_code)) {
1370 case SCU_TASK_DONE_CRC_ERR << SCU_EVENT_SPECIFIC_CODE_SHIFT:
1371 /*
1372 * We are waiting for data and the SCU has R_ERR the data frame.
1373 * Go back to waiting for the D2H Register FIS */
1374 sci_base_state_machine_change_state(
1375 &request->started_substate_machine,
1376 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1377 );
1378
1379 status = SCI_SUCCESS;
1380 break;
1381
1382 default:
1383 dev_err(scic_to_dev(request->owning_controller),
1384 "%s: SCIC PIO Request 0x%p received unexpected "
1385 "event 0x%08x\n",
1386 __func__, request, event_code);
1387
1388 /* / @todo Should we fail the PIO request when we get an unexpected event? */
1389 status = SCI_FAILURE;
1390 break;
1391 }
1392
1393 return status;
1394}
1395
1396/* --------------------------------------------------------------------------- */
1397
1398const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_pio_substate_handler_table[] = {
1399 [SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE] = {
1400 .parent.start_handler = scic_sds_request_default_start_handler,
1401 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1402 .parent.complete_handler = scic_sds_request_default_complete_handler,
1403 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1404 .tc_completion_handler = scic_sds_stp_request_pio_await_h2d_completion_tc_completion_handler,
1405 .event_handler = scic_sds_request_default_event_handler,
1406 .frame_handler = scic_sds_request_default_frame_handler
1407 },
1408 [SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE] = {
1409 .parent.start_handler = scic_sds_request_default_start_handler,
1410 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1411 .parent.complete_handler = scic_sds_request_default_complete_handler,
1412 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1413 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
1414 .event_handler = scic_sds_request_default_event_handler,
1415 .frame_handler = scic_sds_stp_request_pio_await_frame_frame_handler
1416 },
1417 [SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE] = {
1418 .parent.start_handler = scic_sds_request_default_start_handler,
1419 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1420 .parent.complete_handler = scic_sds_request_default_complete_handler,
1421 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1422 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
1423 .event_handler = scic_sds_stp_request_pio_data_in_await_data_event_handler,
1424 .frame_handler = scic_sds_stp_request_pio_data_in_await_data_frame_handler
1425 },
1426 [SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE] = {
1427 .parent.start_handler = scic_sds_request_default_start_handler,
1428 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1429 .parent.complete_handler = scic_sds_request_default_complete_handler,
1430 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1431 .tc_completion_handler = scic_sds_stp_request_pio_data_out_await_data_transmit_completion_tc_completion_handler,
1432 .event_handler = scic_sds_request_default_event_handler,
1433 .frame_handler = scic_sds_request_default_frame_handler,
1434 }
1435};
1436
1437static void scic_sds_stp_request_started_pio_await_h2d_completion_enter(
1438 struct sci_base_object *object)
1439{
1440 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1441
1442 SET_STATE_HANDLER(
1443 this_request,
1444 scic_sds_stp_request_started_pio_substate_handler_table,
1445 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE
1446 );
1447
1448 scic_sds_remote_device_set_working_request(
1449 this_request->target_device, this_request);
1450}
1451
1452static void scic_sds_stp_request_started_pio_await_frame_enter(
1453 struct sci_base_object *object)
1454{
1455 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1456
1457 SET_STATE_HANDLER(
1458 this_request,
1459 scic_sds_stp_request_started_pio_substate_handler_table,
1460 SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE
1461 );
1462}
1463
1464static void scic_sds_stp_request_started_pio_data_in_await_data_enter(
1465 struct sci_base_object *object)
1466{
1467 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1468
1469 SET_STATE_HANDLER(
1470 this_request,
1471 scic_sds_stp_request_started_pio_substate_handler_table,
1472 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE
1473 );
1474}
1475
1476static void scic_sds_stp_request_started_pio_data_out_transmit_data_enter(
1477 struct sci_base_object *object)
1478{
1479 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1480
1481 SET_STATE_HANDLER(
1482 this_request,
1483 scic_sds_stp_request_started_pio_substate_handler_table,
1484 SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE
1485 );
1486}
1487
1488/* --------------------------------------------------------------------------- */
1489
1490const struct sci_base_state scic_sds_stp_request_started_pio_substate_table[] = {
1491 [SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_H2D_COMPLETION_SUBSTATE] = {
1492 .enter_state = scic_sds_stp_request_started_pio_await_h2d_completion_enter,
1493 },
1494 [SCIC_SDS_STP_REQUEST_STARTED_PIO_AWAIT_FRAME_SUBSTATE] = {
1495 .enter_state = scic_sds_stp_request_started_pio_await_frame_enter,
1496 },
1497 [SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_IN_AWAIT_DATA_SUBSTATE] = {
1498 .enter_state = scic_sds_stp_request_started_pio_data_in_await_data_enter,
1499 },
1500 [SCIC_SDS_STP_REQUEST_STARTED_PIO_DATA_OUT_TRANSMIT_DATA_SUBSTATE] = {
1501 .enter_state = scic_sds_stp_request_started_pio_data_out_transmit_data_enter,
1502 }
1503};
1504
1505static void scic_sds_stp_request_udma_complete_request(
1506 struct scic_sds_request *this_request,
1507 u32 scu_status,
1508 enum sci_status sci_status)
1509{
1510 scic_sds_request_set_status(
1511 this_request, scu_status, sci_status
1512 );
1513
1514 sci_base_state_machine_change_state(
1515 &this_request->parent.state_machine,
1516 SCI_BASE_REQUEST_STATE_COMPLETED
1517 );
1518}
1519
1520/**
1521 *
1522 * @this_request:
1523 * @frame_index:
1524 *
1525 * enum sci_status
1526 */
1527static enum sci_status scic_sds_stp_request_udma_general_frame_handler(
1528 struct scic_sds_request *this_request,
1529 u32 frame_index)
1530{
1531 enum sci_status status;
1532 struct sata_fis_header *frame_header;
1533 u32 *frame_buffer;
1534
1535 status = scic_sds_unsolicited_frame_control_get_header(
1536 &this_request->owning_controller->uf_control,
1537 frame_index,
1538 (void **)&frame_header
1539 );
1540
1541 if (
1542 (status == SCI_SUCCESS)
1543 && (frame_header->fis_type == SATA_FIS_TYPE_REGD2H)
1544 ) {
1545 scic_sds_unsolicited_frame_control_get_buffer(
1546 &this_request->owning_controller->uf_control,
1547 frame_index,
1548 (void **)&frame_buffer
1549 );
1550
1551 scic_sds_controller_copy_sata_response(
1552 &((struct scic_sds_stp_request *)this_request)->d2h_reg_fis,
1553 (u32 *)frame_header,
1554 frame_buffer
1555 );
1556 }
1557
1558 scic_sds_controller_release_frame(
1559 this_request->owning_controller, frame_index);
1560
1561 return status;
1562}
1563
1564/**
1565 * This method process TC completions while in the state where we are waiting
1566 * for TC completions.
1567 * @this_request:
1568 * @completion_code:
1569 *
1570 * enum sci_status
1571 */
1572static enum sci_status scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler(
1573 struct scic_sds_request *request,
1574 u32 completion_code)
1575{
1576 enum sci_status status = SCI_SUCCESS;
1577 struct scic_sds_stp_request *this_request = (struct scic_sds_stp_request *)request;
1578
1579 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1580 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1581 scic_sds_stp_request_udma_complete_request(
1582 &this_request->parent, SCU_TASK_DONE_GOOD, SCI_SUCCESS
1583 );
1584 break;
1585
1586 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_FIS):
1587 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR):
1588 /*
1589 * We must check ther response buffer to see if the D2H Register FIS was
1590 * received before we got the TC completion. */
1591 if (this_request->d2h_reg_fis.fis_type == SATA_FIS_TYPE_REGD2H) {
1592 scic_sds_remote_device_suspend(
1593 this_request->parent.target_device,
1594 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code))
1595 );
1596
1597 scic_sds_stp_request_udma_complete_request(
1598 &this_request->parent,
1599 SCU_TASK_DONE_CHECK_RESPONSE,
1600 SCI_FAILURE_IO_RESPONSE_VALID
1601 );
1602 } else {
1603 /*
1604 * If we have an error completion status for the TC then we can expect a
1605 * D2H register FIS from the device so we must change state to wait for it */
1606 sci_base_state_machine_change_state(
1607 &this_request->parent.started_substate_machine,
1608 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE
1609 );
1610 }
1611 break;
1612
1613 /*
1614 * / @todo Check to see if any of these completion status need to wait for
1615 * / the device to host register fis. */
1616 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_INV_FIS_LEN):
1617 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR):
1618 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_R_ERR):
1619 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CRC_ERR):
1620 scic_sds_remote_device_suspend(
1621 this_request->parent.target_device,
1622 SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code))
1623 );
1624 /* Fall through to the default case */
1625 default:
1626 /* All other completion status cause the IO to be complete. */
1627 scic_sds_stp_request_udma_complete_request(
1628 &this_request->parent,
1629 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1630 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1631 );
1632 break;
1633 }
1634
1635 return status;
1636}
1637
1638static enum sci_status scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler(
1639 struct scic_sds_request *this_request,
1640 u32 frame_index)
1641{
1642 enum sci_status status;
1643
1644 /* Use the general frame handler to copy the resposne data */
1645 status = scic_sds_stp_request_udma_general_frame_handler(this_request, frame_index);
1646
1647 if (status == SCI_SUCCESS) {
1648 scic_sds_stp_request_udma_complete_request(
1649 this_request,
1650 SCU_TASK_DONE_CHECK_RESPONSE,
1651 SCI_FAILURE_IO_RESPONSE_VALID
1652 );
1653 }
1654
1655 return status;
1656}
1657
1658/* --------------------------------------------------------------------------- */
1659
1660const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_udma_substate_handler_table[] = {
1661 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE] = {
1662 .parent.start_handler = scic_sds_request_default_start_handler,
1663 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1664 .parent.complete_handler = scic_sds_request_default_complete_handler,
1665 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1666 .tc_completion_handler = scic_sds_stp_request_udma_await_tc_completion_tc_completion_handler,
1667 .event_handler = scic_sds_request_default_event_handler,
1668 .frame_handler = scic_sds_stp_request_udma_general_frame_handler,
1669 },
1670 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE] = {
1671 .parent.start_handler = scic_sds_request_default_start_handler,
1672 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1673 .parent.complete_handler = scic_sds_request_default_complete_handler,
1674 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1675 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
1676 .event_handler = scic_sds_request_default_event_handler,
1677 .frame_handler = scic_sds_stp_request_udma_await_d2h_reg_fis_frame_handler,
1678 },
1679};
1680
1681static void scic_sds_stp_request_started_udma_await_tc_completion_enter(
1682 struct sci_base_object *object)
1683{
1684 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1685
1686 SET_STATE_HANDLER(
1687 this_request,
1688 scic_sds_stp_request_started_udma_substate_handler_table,
1689 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE
1690 );
1691}
1692
1693/**
1694 *
1695 *
1696 * This state is entered when there is an TC completion failure. The hardware
1697 * received an unexpected condition while processing the IO request and now
1698 * will UF the D2H register FIS to complete the IO.
1699 */
1700static void scic_sds_stp_request_started_udma_await_d2h_reg_fis_enter(
1701 struct sci_base_object *object)
1702{
1703 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1704
1705 SET_STATE_HANDLER(
1706 this_request,
1707 scic_sds_stp_request_started_udma_substate_handler_table,
1708 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE
1709 );
1710}
1711
1712/* --------------------------------------------------------------------------- */
1713
1714const struct sci_base_state scic_sds_stp_request_started_udma_substate_table[] = {
1715 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE] = {
1716 .enter_state = scic_sds_stp_request_started_udma_await_tc_completion_enter,
1717 },
1718 [SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE] = {
1719 .enter_state = scic_sds_stp_request_started_udma_await_d2h_reg_fis_enter,
1720 },
1721};
1722
1723/**
1724 *
1725 * @this_request:
1726 * @completion_code:
1727 *
1728 * This method processes a TC completion. The expected TC completion is for
1729 * the transmission of the H2D register FIS containing the SATA/STP non-data
1730 * request. This method always successfully processes the TC completion.
1731 * SCI_SUCCESS This value is always returned.
1732 */
1733static enum sci_status scic_sds_stp_request_soft_reset_await_h2d_asserted_tc_completion_handler(
1734 struct scic_sds_request *this_request,
1735 u32 completion_code)
1736{
1737 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1738 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1739 scic_sds_request_set_status(
1740 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
1741 );
1742
1743 sci_base_state_machine_change_state(
1744 &this_request->started_substate_machine,
1745 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE
1746 );
1747 break;
1748
1749 default:
1750 /*
1751 * All other completion status cause the IO to be complete. If a NAK
1752 * was received, then it is up to the user to retry the request. */
1753 scic_sds_request_set_status(
1754 this_request,
1755 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1756 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1757 );
1758
1759 sci_base_state_machine_change_state(
1760 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
1761 );
1762 break;
1763 }
1764
1765 return SCI_SUCCESS;
1766}
1767
1768/**
1769 *
1770 * @this_request:
1771 * @completion_code:
1772 *
1773 * This method processes a TC completion. The expected TC completion is for
1774 * the transmission of the H2D register FIS containing the SATA/STP non-data
1775 * request. This method always successfully processes the TC completion.
1776 * SCI_SUCCESS This value is always returned.
1777 */
1778static enum sci_status scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler(
1779 struct scic_sds_request *this_request,
1780 u32 completion_code)
1781{
1782 switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
1783 case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
1784 scic_sds_request_set_status(
1785 this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
1786 );
1787
1788 sci_base_state_machine_change_state(
1789 &this_request->started_substate_machine,
1790 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE
1791 );
1792 break;
1793
1794 default:
1795 /*
1796 * All other completion status cause the IO to be complete. If a NAK
1797 * was received, then it is up to the user to retry the request. */
1798 scic_sds_request_set_status(
1799 this_request,
1800 SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
1801 SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
1802 );
1803
1804 sci_base_state_machine_change_state(
1805 &this_request->parent.state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
1806 );
1807 break;
1808 }
1809
1810 return SCI_SUCCESS;
1811}
1812
1813/**
1814 *
1815 * @request: This parameter specifies the request for which a frame has been
1816 * received.
1817 * @frame_index: This parameter specifies the index of the frame that has been
1818 * received.
1819 *
1820 * This method processes frames received from the target while waiting for a
1821 * device to host register FIS. If a non-register FIS is received during this
1822 * time, it is treated as a protocol violation from an IO perspective. Indicate
1823 * if the received frame was processed successfully.
1824 */
1825static enum sci_status scic_sds_stp_request_soft_reset_await_d2h_frame_handler(
1826 struct scic_sds_request *request,
1827 u32 frame_index)
1828{
1829 enum sci_status status;
1830 struct sata_fis_header *frame_header;
1831 u32 *frame_buffer;
1832 struct scic_sds_stp_request *this_request = (struct scic_sds_stp_request *)request;
1833
1834 status = scic_sds_unsolicited_frame_control_get_header(
1835 &(this_request->parent.owning_controller->uf_control),
1836 frame_index,
1837 (void **)&frame_header
1838 );
1839
1840 if (status == SCI_SUCCESS) {
1841 switch (frame_header->fis_type) {
1842 case SATA_FIS_TYPE_REGD2H:
1843 scic_sds_unsolicited_frame_control_get_buffer(
1844 &(this_request->parent.owning_controller->uf_control),
1845 frame_index,
1846 (void **)&frame_buffer
1847 );
1848
1849 scic_sds_controller_copy_sata_response(
1850 &this_request->d2h_reg_fis, (u32 *)frame_header, frame_buffer
1851 );
1852
1853 /* The command has completed with error */
1854 scic_sds_request_set_status(
1855 &this_request->parent,
1856 SCU_TASK_DONE_CHECK_RESPONSE,
1857 SCI_FAILURE_IO_RESPONSE_VALID
1858 );
1859 break;
1860
1861 default:
1862 dev_warn(scic_to_dev(request->owning_controller),
1863 "%s: IO Request:0x%p Frame Id:%d protocol "
1864 "violation occurred\n",
1865 __func__,
1866 this_request,
1867 frame_index);
1868
1869 scic_sds_request_set_status(
1870 &this_request->parent,
1871 SCU_TASK_DONE_UNEXP_FIS,
1872 SCI_FAILURE_PROTOCOL_VIOLATION
1873 );
1874 break;
1875 }
1876
1877 sci_base_state_machine_change_state(
1878 &this_request->parent.parent.state_machine,
1879 SCI_BASE_REQUEST_STATE_COMPLETED
1880 );
1881
1882 /* Frame has been decoded return it to the controller */
1883 scic_sds_controller_release_frame(
1884 this_request->parent.owning_controller, frame_index
1885 );
1886 } else
1887 dev_err(scic_to_dev(request->owning_controller),
1888 "%s: SCIC IO Request 0x%p could not get frame header "
1889 "for frame index %d, status %x\n",
1890 __func__, this_request, frame_index, status);
1891
1892 return status;
1893}
1894
1895/* --------------------------------------------------------------------------- */
1896
1897const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_soft_reset_substate_handler_table[] = {
1898 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE] = {
1899 .parent.start_handler = scic_sds_request_default_start_handler,
1900 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1901 .parent.complete_handler = scic_sds_request_default_complete_handler,
1902 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1903 .tc_completion_handler = scic_sds_stp_request_soft_reset_await_h2d_asserted_tc_completion_handler,
1904 .event_handler = scic_sds_request_default_event_handler,
1905 .frame_handler = scic_sds_request_default_frame_handler,
1906 },
1907 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE] = {
1908 .parent.start_handler = scic_sds_request_default_start_handler,
1909 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1910 .parent.complete_handler = scic_sds_request_default_complete_handler,
1911 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1912 .tc_completion_handler = scic_sds_stp_request_soft_reset_await_h2d_diagnostic_tc_completion_handler,
1913 .event_handler = scic_sds_request_default_event_handler,
1914 .frame_handler = scic_sds_request_default_frame_handler,
1915 },
1916 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE] = {
1917 .parent.start_handler = scic_sds_request_default_start_handler,
1918 .parent.abort_handler = scic_sds_request_started_state_abort_handler,
1919 .parent.complete_handler = scic_sds_request_default_complete_handler,
1920 .parent.destruct_handler = scic_sds_request_default_destruct_handler,
1921 .tc_completion_handler = scic_sds_request_default_tc_completion_handler,
1922 .event_handler = scic_sds_request_default_event_handler,
1923 .frame_handler = scic_sds_stp_request_soft_reset_await_d2h_frame_handler,
1924 },
1925};
1926
1927static void scic_sds_stp_request_started_soft_reset_await_h2d_asserted_completion_enter(
1928 struct sci_base_object *object)
1929{
1930 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1931
1932 SET_STATE_HANDLER(
1933 this_request,
1934 scic_sds_stp_request_started_soft_reset_substate_handler_table,
1935 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE
1936 );
1937
1938 scic_sds_remote_device_set_working_request(
1939 this_request->target_device, this_request
1940 );
1941}
1942
1943static void scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter(
1944 struct sci_base_object *object)
1945{
1946 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1947 sci_base_controller_request_handler_t continue_io;
1948 struct scu_task_context *task_context;
1949 struct sata_fis_reg_h2d *h2d_fis;
1950 struct scic_sds_controller *scic;
1951 enum sci_status status;
1952 u32 state;
1953
1954 /* Clear the SRST bit */
1955 h2d_fis = scic_stp_io_request_get_h2d_reg_address(this_request);
1956 h2d_fis->control = 0;
1957
1958 /* Clear the TC control bit */
1959 task_context = scic_sds_controller_get_task_context_buffer(
1960 this_request->owning_controller, this_request->io_tag);
1961 task_context->control_frame = 0;
1962
1963 scic = this_request->owning_controller;
1964 state = scic->parent.state_machine.current_state_id;
1965 continue_io = scic_sds_controller_state_handler_table[state].base.continue_io;
1966
1967 status = continue_io(&scic->parent, &this_request->target_device->parent,
1968 &this_request->parent);
1969
1970 if (status == SCI_SUCCESS) {
1971 SET_STATE_HANDLER(
1972 this_request,
1973 scic_sds_stp_request_started_soft_reset_substate_handler_table,
1974 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE
1975 );
1976 }
1977}
1978
1979static void scic_sds_stp_request_started_soft_reset_await_d2h_response_enter(
1980 struct sci_base_object *object)
1981{
1982 struct scic_sds_request *this_request = (struct scic_sds_request *)object;
1983
1984 SET_STATE_HANDLER(
1985 this_request,
1986 scic_sds_stp_request_started_soft_reset_substate_handler_table,
1987 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE
1988 );
1989}
1990
1991/* --------------------------------------------------------------------------- */
1992
1993const struct sci_base_state scic_sds_stp_request_started_soft_reset_substate_table[] = {
1994 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE] = {
1995 .enter_state = scic_sds_stp_request_started_soft_reset_await_h2d_asserted_completion_enter,
1996 },
1997 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE] = {
1998 .enter_state = scic_sds_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter,
1999 },
2000 [SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE] = {
2001 .enter_state = scic_sds_stp_request_started_soft_reset_await_d2h_response_enter,
2002 },
2003};
2004
diff --git a/drivers/scsi/isci/core/scic_sds_stp_request.h b/drivers/scsi/isci/core/scic_sds_stp_request.h
new file mode 100644
index 000000000000..5578d2baf7ca
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_stp_request.h
@@ -0,0 +1,221 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_SDS_STP_REQUEST_T_
57#define _SCIC_SDS_STP_REQUEST_T_
58
59#include "intel_sata.h"
60#include "sci_types.h"
61#include "scic_sds_request.h"
62
63/**
64 * This structure represents the additional information that is required to
65 * handle SATA PIO requests.
66 *
67 *
68 */
69struct scic_sds_stp_request {
70 struct scic_sds_request parent;
71
72 struct sata_fis_reg_d2h d2h_reg_fis;
73
74 union {
75 u32 ncq;
76
77 u32 udma;
78
79 struct {
80 /**
81 * Total transfer for the entire PIO request recorded at request constuction
82 * time.
83 *
84 * @todo Should we just decrement this value for each byte of data transitted
85 * or received to elemenate the current_transfer_bytes field?
86 */
87 u32 total_transfer_bytes;
88
89 /**
90 * Total number of bytes received/transmitted in data frames since the start
91 * of the IO request. At the end of the IO request this should equal the
92 * total_transfer_bytes.
93 */
94 u32 current_transfer_bytes;
95
96 /**
97 * The number of bytes requested in the in the PIO setup.
98 */
99 u32 pio_transfer_bytes;
100
101 /**
102 * PIO Setup ending status value to tell us if we need to wait for another FIS
103 * or if the transfer is complete. On the receipt of a D2H FIS this will be
104 * the status field of that FIS.
105 */
106 u8 ending_status;
107
108 /**
109 * On receipt of a D2H FIS this will be the ending error field if the
110 * ending_status has the SATA_STATUS_ERR bit set.
111 */
112 u8 ending_error;
113
114 /**
115 * Protocol Type. This is filled in by core during IO Request construction type.
116 */
117 u8 sat_protocol;
118
119 struct {
120 struct scu_sgl_element_pair *sgl_pair;
121 u8 sgl_set;
122 u32 sgl_offset;
123 } request_current;
124 } pio;
125
126 struct {
127 /**
128 * The number of bytes requested in the PIO setup before CDB data frame.
129 */
130 u32 device_preferred_cdb_length;
131 } packet;
132 } type;
133
134};
135
136/**
137 * enum SCIC_SDS_STP_REQUEST_STARTED_UDMA_SUBSTATES - This enumeration depicts
138 * the various sub-states associated with a SATA/STP UDMA protocol operation.
139 *
140 *
141 */
142enum SCIC_SDS_STP_REQUEST_STARTED_UDMA_SUBSTATES {
143 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_TC_COMPLETION_SUBSTATE,
144 SCIC_SDS_STP_REQUEST_STARTED_UDMA_AWAIT_D2H_REG_FIS_SUBSTATE,
145};
146
147/**
148 * enum SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_SUBSTATES - This enumeration
149 * depicts the various sub-states associated with a SATA/STP non-data
150 * protocol operation.
151 *
152 *
153 */
154enum SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_SUBSTATES {
155 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_H2D_COMPLETION_SUBSTATE,
156 SCIC_SDS_STP_REQUEST_STARTED_NON_DATA_AWAIT_D2H_SUBSTATE,
157};
158
159/**
160 * enum SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_SUBSTATES - THis enumeration
161 * depicts the various sub-states associated with a SATA/STP soft reset
162 * operation.
163 *
164 *
165 */
166enum SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_SUBSTATES {
167 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_ASSERTED_COMPLETION_SUBSTATE,
168 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_H2D_DIAGNOSTIC_COMPLETION_SUBSTATE,
169 SCIC_SDS_STP_REQUEST_STARTED_SOFT_RESET_AWAIT_D2H_RESPONSE_FRAME_SUBSTATE,
170};
171
172extern const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_udma_substate_handler_table[];
173
174extern const struct sci_base_state scic_sds_stp_request_started_udma_substate_table[];
175
176extern const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_non_data_substate_handler_table[];
177
178extern const struct sci_base_state scic_sds_stp_request_started_non_data_substate_table[];
179
180extern const struct scic_sds_io_request_state_handler scic_sds_stp_request_started_soft_reset_substate_handler_table[];
181
182extern const struct sci_base_state scic_sds_stp_request_started_soft_reset_substate_table[];
183
184/* --------------------------------------------------------------------------- */
185
186u32 scic_sds_stp_request_get_object_size(void);
187
188
189void scic_sds_stp_non_ncq_request_construct(
190 struct scic_sds_request *this_request);
191
192enum sci_status scic_sds_stp_pio_request_construct(
193 struct scic_sds_request *scic_io_request,
194 u8 sat_protocol,
195 bool copy_rx_frame);
196
197enum sci_status scic_sds_stp_pio_request_construct_pass_through(
198 struct scic_sds_request *scic_io_request,
199 struct scic_stp_passthru_request_callbacks *passthru_cb);
200
201enum sci_status scic_sds_stp_udma_request_construct(
202 struct scic_sds_request *this_request,
203 u32 transfer_length,
204 SCI_IO_REQUEST_DATA_DIRECTION data_direction);
205
206enum sci_status scic_sds_stp_non_data_request_construct(
207 struct scic_sds_request *this_request);
208
209enum sci_status scic_sds_stp_soft_reset_request_construct(
210 struct scic_sds_request *this_request);
211
212enum sci_status scic_sds_stp_ncq_request_construct(
213 struct scic_sds_request *this_request,
214 u32 transfer_length,
215 SCI_IO_REQUEST_DATA_DIRECTION data_direction);
216
217void scu_stp_raw_request_construct_task_context(
218 struct scic_sds_stp_request *this_request,
219 struct scu_task_context *task_context);
220
221#endif /* _SCIC_SDS_STP_REQUEST_T_ */
diff --git a/drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.c b/drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.c
new file mode 100644
index 000000000000..7ca2f1709f6d
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.c
@@ -0,0 +1,379 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file contains the implementation of the
58 * struct scic_sds_unsolicited_frame_control object and it's public, protected, and
59 * private methods.
60 *
61 *
62 */
63
64#include "scic_sds_unsolicited_frame_control.h"
65#include "scu_registers.h"
66#include "scic_sds_controller.h"
67#include "scic_user_callback.h"
68#include "sci_util.h"
69#include "sci_environment.h"
70
71/**
72 * The UF buffer address table size must be programmed to a power of 2. Find
73 * the first power of 2 that is equal to or greater then the number of
74 * unsolicited frame buffers to be utilized.
75 * @uf_control: This parameter specifies the UF control object for which to
76 * update the address table count.
77 *
78 */
79void scic_sds_unsolicited_frame_control_set_address_table_count(
80 struct scic_sds_unsolicited_frame_control *uf_control)
81{
82 uf_control->address_table.count = SCU_MIN_UF_TABLE_ENTRIES;
83 while (
84 (uf_control->address_table.count < uf_control->buffers.count)
85 && (uf_control->address_table.count < SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES)
86 ) {
87 uf_control->address_table.count <<= 1;
88 }
89}
90
91/**
92 * This method will program the unsolicited frames (UFs) into the UF address
93 * table and construct the UF frame structure being modeled in the core. It
94 * will handle the case where some of the UFs are not being used and thus
95 * should have entries programmed to zero in the address table.
96 * @uf_control: This parameter specifies the unsolicted frame control object
97 * for which to construct the unsolicited frames objects.
98 * @uf_buffer_phys_address: This parameter specifies the physical address for
99 * the first unsolicited frame buffer.
100 * @uf_buffer_virt_address: This parameter specifies the virtual address for
101 * the first unsolicited frame buffer.
102 * @unused_uf_header_entries: This parameter specifies the number of unused UF
103 * headers. This value can be non-zero when there are a non-power of 2
104 * number of unsolicited frames being supported.
105 * @used_uf_header_entries: This parameter specifies the number of actually
106 * utilized UF headers.
107 *
108 */
109static void scic_sds_unsolicited_frame_control_construct_frames(
110 struct scic_sds_unsolicited_frame_control *uf_control,
111 dma_addr_t uf_buffer_phys_address,
112 unsigned long uf_buffer_virt_address,
113 u32 unused_uf_header_entries,
114 u32 used_uf_header_entries)
115{
116 u32 index;
117 struct scic_sds_unsolicited_frame *uf;
118
119 /*
120 * Program the unused buffers into the UF address table and the
121 * controller's array of UFs. */
122 for (index = 0; index < unused_uf_header_entries; index++) {
123 uf = &uf_control->buffers.array[index];
124
125 sci_cb_make_physical_address(
126 uf_control->address_table.array[index], 0, 0
127 );
128 uf->buffer = NULL;
129 uf->header = &uf_control->headers.array[index];
130 uf->state = UNSOLICITED_FRAME_EMPTY;
131 }
132
133 /*
134 * Program the actual used UF buffers into the UF address table and
135 * the controller's array of UFs. */
136 for (index = unused_uf_header_entries;
137 index < unused_uf_header_entries + used_uf_header_entries;
138 index++) {
139 uf = &uf_control->buffers.array[index];
140
141 uf_control->address_table.array[index] = uf_buffer_phys_address;
142
143 uf->buffer = (void *)uf_buffer_virt_address;
144 uf->header = &uf_control->headers.array[index];
145 uf->state = UNSOLICITED_FRAME_EMPTY;
146
147 /*
148 * Increment the address of the physical and virtual memory pointers
149 * Everything is aligned on 1k boundary with an increment of 1k */
150 uf_buffer_virt_address += SCU_UNSOLICITED_FRAME_BUFFER_SIZE;
151 sci_physical_address_add(
152 uf_buffer_phys_address, SCU_UNSOLICITED_FRAME_BUFFER_SIZE
153 );
154 }
155}
156
157/**
158 * This method constructs the various members of the unsolicted frame control
159 * object (buffers, headers, address, table, etc).
160 * @uf_control: This parameter specifies the unsolicited frame control object
161 * to construct.
162 * @mde: This parameter specifies the memory descriptor from which to derive
163 * all of the address information needed to get the unsolicited frame
164 * functionality working.
165 * @controller: This parameter specifies the controller object associated with
166 * the uf_control being constructed.
167 *
168 */
169void scic_sds_unsolicited_frame_control_construct(
170 struct scic_sds_unsolicited_frame_control *uf_control,
171 struct sci_physical_memory_descriptor *mde,
172 struct scic_sds_controller *controller)
173{
174 u32 unused_uf_header_entries;
175 u32 used_uf_header_entries;
176 u32 used_uf_buffer_bytes;
177 u32 unused_uf_header_bytes;
178 u32 used_uf_header_bytes;
179 dma_addr_t uf_buffer_phys_address;
180
181 /*
182 * Prepare all of the memory sizes for the UF headers, UF address
183 * table, and UF buffers themselves. */
184 used_uf_buffer_bytes = uf_control->buffers.count
185 * SCU_UNSOLICITED_FRAME_BUFFER_SIZE;
186 unused_uf_header_entries = uf_control->address_table.count
187 - uf_control->buffers.count;
188 used_uf_header_entries = uf_control->buffers.count;
189 unused_uf_header_bytes = unused_uf_header_entries
190 * sizeof(struct scu_unsolicited_frame_header);
191 used_uf_header_bytes = used_uf_header_entries
192 * sizeof(struct scu_unsolicited_frame_header);
193
194 /*
195 * The Unsolicited Frame buffers are set at the start of the UF
196 * memory descriptor entry. The headers and address table will be
197 * placed after the buffers. */
198 uf_buffer_phys_address = mde->physical_address;
199
200 /*
201 * Program the location of the UF header table into the SCU.
202 * Notes:
203 * - The address must align on a 64-byte boundary. Guaranteed to be
204 * on 64-byte boundary already 1KB boundary for unsolicited frames.
205 * - Program unused header entries to overlap with the last
206 * unsolicited frame. The silicon will never DMA to these unused
207 * headers, since we program the UF address table pointers to
208 * NULL. */
209 uf_control->headers.physical_address = uf_buffer_phys_address;
210 sci_physical_address_add(
211 uf_control->headers.physical_address, used_uf_buffer_bytes);
212 sci_physical_address_subtract(
213 uf_control->headers.physical_address, unused_uf_header_bytes);
214 uf_control->headers.array
215 = (struct scu_unsolicited_frame_header *)
216 scic_cb_get_virtual_address(
217 controller, uf_control->headers.physical_address
218 );
219
220 /*
221 * Program the location of the UF address table into the SCU.
222 * Notes:
223 * - The address must align on a 64-bit boundary. Guaranteed to be on 64
224 * byte boundary already due to above programming headers being on a
225 * 64-bit boundary and headers are on a 64-bytes in size. */
226 uf_control->address_table.physical_address = uf_buffer_phys_address;
227 sci_physical_address_add(
228 uf_control->address_table.physical_address, used_uf_buffer_bytes);
229 sci_physical_address_add(
230 uf_control->address_table.physical_address, used_uf_header_bytes);
231 uf_control->address_table.array
232 = (dma_addr_t *)
233 scic_cb_get_virtual_address(
234 controller, uf_control->address_table.physical_address
235 );
236
237 uf_control->get = 0;
238
239 /*
240 * UF buffer requirements are:
241 * - The last entry in the UF queue is not NULL.
242 * - There is a power of 2 number of entries (NULL or not-NULL)
243 * programmed into the queue.
244 * - Aligned on a 1KB boundary. */
245
246 /*
247 * If the user provided less then the maximum amount of memory,
248 * then be sure that we programm the first entries in the UF
249 * address table to NULL. */
250 scic_sds_unsolicited_frame_control_construct_frames(
251 uf_control,
252 uf_buffer_phys_address,
253 (unsigned long)mde->virtual_address,
254 unused_uf_header_entries,
255 used_uf_header_entries
256 );
257}
258
259/**
260 * This method returns the frame header for the specified frame index.
261 * @uf_control:
262 * @frame_index:
263 * @frame_header:
264 *
265 * enum sci_status
266 */
267enum sci_status scic_sds_unsolicited_frame_control_get_header(
268 struct scic_sds_unsolicited_frame_control *uf_control,
269 u32 frame_index,
270 void **frame_header)
271{
272 if (frame_index < uf_control->address_table.count) {
273 /*
274 * Skip the first word in the frame since this is a controll word used
275 * by the hardware. */
276 *frame_header = &uf_control->buffers.array[frame_index].header->data;
277
278 return SCI_SUCCESS;
279 }
280
281 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
282}
283
284/**
285 * This method returns the frame buffer for the specified frame index.
286 * @uf_control:
287 * @frame_index:
288 * @frame_buffer:
289 *
290 * enum sci_status
291 */
292enum sci_status scic_sds_unsolicited_frame_control_get_buffer(
293 struct scic_sds_unsolicited_frame_control *uf_control,
294 u32 frame_index,
295 void **frame_buffer)
296{
297 if (frame_index < uf_control->address_table.count) {
298 *frame_buffer = uf_control->buffers.array[frame_index].buffer;
299
300 return SCI_SUCCESS;
301 }
302
303 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
304}
305
306/**
307 * This method releases the frame once this is done the frame is available for
308 * re-use by the hardware. The data contained in the frame header and frame
309 * buffer is no longer valid.
310 * @uf_control: This parameter specifies the UF control object
311 * @frame_index: This parameter specifies the frame index to attempt to release.
312 *
313 * This method returns an indication to the caller as to whether the
314 * unsolicited frame get pointer should be updated. true This value indicates
315 * the unsolicited frame get pointer should be updated (i.e. write
316 * SCU_UFQGP_WRITE). false This value indicates the get pointer should not be
317 * updated.
318 */
319bool scic_sds_unsolicited_frame_control_release_frame(
320 struct scic_sds_unsolicited_frame_control *uf_control,
321 u32 frame_index)
322{
323 u32 frame_get;
324 u32 frame_cycle;
325
326 frame_get = uf_control->get & (uf_control->address_table.count - 1);
327 frame_cycle = uf_control->get & uf_control->address_table.count;
328
329 /*
330 * In the event there are NULL entries in the UF table, we need to
331 * advance the get pointer in order to find out if this frame should
332 * be released (i.e. update the get pointer). */
333 while (((lower_32_bits(uf_control->address_table.array[frame_get])
334 == 0) &&
335 (upper_32_bits(uf_control->address_table.array[frame_get])
336 == 0)) &&
337 (frame_get < uf_control->address_table.count))
338 frame_get++;
339
340 /*
341 * The table has a NULL entry as it's last element. This is
342 * illegal. */
343 BUG_ON(frame_get >= uf_control->address_table.count);
344
345 if (frame_index < uf_control->address_table.count) {
346 uf_control->buffers.array[frame_index].state = UNSOLICITED_FRAME_RELEASED;
347
348 /*
349 * The frame index is equal to the current get pointer so we
350 * can now free up all of the frame entries that */
351 if (frame_get == frame_index) {
352 while (
353 uf_control->buffers.array[frame_get].state
354 == UNSOLICITED_FRAME_RELEASED
355 ) {
356 uf_control->buffers.array[frame_get].state = UNSOLICITED_FRAME_EMPTY;
357
358 INCREMENT_QUEUE_GET(
359 frame_get,
360 frame_cycle,
361 uf_control->address_table.count - 1,
362 uf_control->address_table.count
363 );
364 }
365
366 uf_control->get =
367 (SCU_UFQGP_GEN_BIT(ENABLE_BIT) | frame_cycle | frame_get);
368
369 return true;
370 } else {
371 /*
372 * Frames remain in use until we advance the get pointer
373 * so there is nothing we can do here */
374 }
375 }
376
377 return false;
378}
379
diff --git a/drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.h b/drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.h
new file mode 100644
index 000000000000..49db83faac37
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.h
@@ -0,0 +1,286 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file contains all of the unsolicited frame related management for the
58 * address table, the headers, and actual payload buffers.
59 *
60 *
61 */
62
63#ifndef _SCIC_SDS_UNSOLICITED_FRAME_CONTROL_H_
64#define _SCIC_SDS_UNSOLICITED_FRAME_CONTROL_H_
65
66#include "scu_unsolicited_frame.h"
67#include "sci_memory_descriptor_list.h"
68#include "scu_constants.h"
69#include "sci_status.h"
70
71/**
72 * enum UNSOLICITED_FRAME_STATE -
73 *
74 * This enumeration represents the current unsolicited frame state. The
75 * controller object can not updtate the hardware unsolicited frame put pointer
76 * unless it has already processed the priror unsolicited frames.
77 */
78enum UNSOLICITED_FRAME_STATE {
79 /**
80 * This state is when the frame is empty and not in use. It is
81 * different from the released state in that the hardware could DMA
82 * data to this frame buffer.
83 */
84 UNSOLICITED_FRAME_EMPTY,
85
86 /**
87 * This state is set when the frame buffer is in use by by some
88 * object in the system.
89 */
90 UNSOLICITED_FRAME_IN_USE,
91
92 /**
93 * This state is set when the frame is returned to the free pool
94 * but one or more frames prior to this one are still in use.
95 * Once all of the frame before this one are freed it will go to
96 * the empty state.
97 */
98 UNSOLICITED_FRAME_RELEASED,
99
100 UNSOLICITED_FRAME_MAX_STATES
101};
102
103/**
104 * struct scic_sds_unsolicited_frame -
105 *
106 * This is the unsolicited frame data structure it acts as the container for
107 * the current frame state, frame header and frame buffer.
108 */
109struct scic_sds_unsolicited_frame {
110 /**
111 * This field contains the current frame state
112 */
113 enum UNSOLICITED_FRAME_STATE state;
114
115 /**
116 * This field points to the frame header data.
117 */
118 struct scu_unsolicited_frame_header *header;
119
120 /**
121 * This field points to the frame buffer data.
122 */
123 void *buffer;
124
125};
126
127/**
128 * struct scic_sds_uf_header_array -
129 *
130 * This structure contains all of the unsolicited frame header information.
131 */
132struct scic_sds_uf_header_array {
133 /**
134 * This field is represents a virtual pointer to the start
135 * address of the UF address table. The table contains
136 * 64-bit pointers as required by the hardware.
137 */
138 struct scu_unsolicited_frame_header *array;
139
140 /**
141 * This field specifies the physical address location for the UF
142 * buffer array.
143 */
144 dma_addr_t physical_address;
145
146};
147
148/*
149 * Determine the size of the unsolicited frame array including
150 * unused buffers. */
151#if SCU_UNSOLICITED_FRAME_COUNT <= SCU_MIN_UF_TABLE_ENTRIES
152#define SCU_UNSOLICITED_FRAME_CONTROL_ARRAY_SIZE SCU_MIN_UF_TABLE_ENTRIES
153#else
154#define SCU_UNSOLICITED_FRAME_CONTROL_ARRAY_SIZE SCU_MAX_UNSOLICITED_FRAMES
155#endif /* SCU_UNSOLICITED_FRAME_COUNT <= SCU_MIN_UF_TABLE_ENTRIES */
156
157/**
158 * struct scic_sds_uf_buffer_array -
159 *
160 * This structure contains all of the unsolicited frame buffer (actual payload)
161 * information.
162 */
163struct scic_sds_uf_buffer_array {
164 /**
165 * This field is the minimum number of unsolicited frames supported by the
166 * hardware and the number of unsolicited frames requested by the software.
167 */
168 u32 count;
169
170 /**
171 * This field is the SCIC_UNSOLICITED_FRAME data its used to manage
172 * the data for the unsolicited frame requests. It also represents
173 * the virtual address location that corresponds to the
174 * physical_address field.
175 */
176 struct scic_sds_unsolicited_frame array[SCU_UNSOLICITED_FRAME_CONTROL_ARRAY_SIZE];
177
178 /**
179 * This field specifies the physical address location for the UF
180 * buffer array.
181 */
182 dma_addr_t physical_address;
183
184};
185
186/**
187 * struct scic_sds_uf_address_table_array -
188 *
189 * This object maintains all of the unsolicited frame address table specific
190 * data. The address table is a collection of 64-bit pointers that point to
191 * 1KB buffers into which the silicon will DMA unsolicited frames.
192 */
193struct scic_sds_uf_address_table_array {
194 /**
195 * This field specifies the actual programmed size of the
196 * unsolicited frame buffer address table. The size of the table
197 * can be larger than the actual number of UF buffers, but it must
198 * be a power of 2 and the last entry in the table is not allowed
199 * to be NULL.
200 */
201 u32 count;
202
203 /**
204 * This field represents a virtual pointer that refers to the
205 * starting address of the UF address table.
206 * 64-bit pointers are required by the hardware.
207 */
208 dma_addr_t *array;
209
210 /**
211 * This field specifies the physical address location for the UF
212 * address table.
213 */
214 dma_addr_t physical_address;
215
216};
217
218/**
219 * struct scic_sds_unsolicited_frame_control -
220 *
221 * This object contains all of the data necessary to handle unsolicited frames.
222 */
223struct scic_sds_unsolicited_frame_control {
224 /**
225 * This field is the software copy of the unsolicited frame queue
226 * get pointer. The controller object writes this value to the
227 * hardware to let the hardware put more unsolicited frame entries.
228 */
229 u32 get;
230
231 /**
232 * This field contains all of the unsolicited frame header
233 * specific fields.
234 */
235 struct scic_sds_uf_header_array headers;
236
237 /**
238 * This field contains all of the unsolicited frame buffer
239 * specific fields.
240 */
241 struct scic_sds_uf_buffer_array buffers;
242
243 /**
244 * This field contains all of the unsolicited frame address table
245 * specific fields.
246 */
247 struct scic_sds_uf_address_table_array address_table;
248
249};
250
251void scic_sds_unsolicited_frame_control_set_address_table_count(
252 struct scic_sds_unsolicited_frame_control *uf_control);
253
254struct scic_sds_controller;
255void scic_sds_unsolicited_frame_control_construct(
256 struct scic_sds_unsolicited_frame_control *uf_control,
257 struct sci_physical_memory_descriptor *mde,
258 struct scic_sds_controller *this_controller);
259
260enum sci_status scic_sds_unsolicited_frame_control_get_header(
261 struct scic_sds_unsolicited_frame_control *uf_control,
262 u32 frame_index,
263 void **frame_header);
264
265enum sci_status scic_sds_unsolicited_frame_control_get_buffer(
266 struct scic_sds_unsolicited_frame_control *uf_control,
267 u32 frame_index,
268 void **frame_buffer);
269
270bool scic_sds_unsolicited_frame_control_release_frame(
271 struct scic_sds_unsolicited_frame_control *uf_control,
272 u32 frame_index);
273
274/**
275 * scic_sds_unsolicited_frame_control_get_mde_size() -
276 *
277 * This macro simply calculates the size of the memory descriptor entry that
278 * relates to unsolicited frames and the surrounding silicon memory required to
279 * utilize it.
280 */
281#define scic_sds_unsolicited_frame_control_get_mde_size(uf_control) \
282 (((uf_control).buffers.count * SCU_UNSOLICITED_FRAME_BUFFER_SIZE) \
283 + ((uf_control).address_table.count * sizeof(dma_addr_t)) \
284 + ((uf_control).buffers.count * sizeof(struct scu_unsolicited_frame_header)))
285
286#endif /* _SCIC_SDS_UNSOLICITED_FRAME_CONTROL_H_ */
diff --git a/drivers/scsi/isci/core/scic_task_request.h b/drivers/scsi/isci/core/scic_task_request.h
new file mode 100644
index 000000000000..ef76cb6bdbea
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_task_request.h
@@ -0,0 +1,148 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_TASK_REQUEST_H_
57#define _SCIC_TASK_REQUEST_H_
58
59/**
60 * This file contains the structures and interface methods that can be
61 * referenced and used by the SCI user for to utilize task management
62 * requests.
63 *
64 *
65 */
66
67
68#include "sci_types.h"
69#include "sci_status.h"
70
71struct scic_sds_request;
72struct scic_sds_remote_device;
73struct scic_sds_controller;
74
75
76/**
77 * scic_task_request_construct() - This method is called by the SCI user to
78 * construct all SCI Core task management requests, regardless of protocol.
79 * Memory initialization and functionality common to all task request types
80 * is performed in this method.
81 * @scic_controller: the handle to the core controller object for which to
82 * build the task managmement request.
83 * @scic_remote_device: the handle to the core remote device object for which
84 * to build the task management request. passed, then a copy of the request
85 * is built internally. The request will be copied into the actual
86 * controller request memory when the task is allocated internally during
87 * the scic_controller_start_task() method.
88 * @io_tag: This parameter specifies the IO tag to be associated with this
89 * request. If SCI_CONTROLLER_INVALID_IO_TAG is passed, then a copy of the
90 * request is built internally. The request will be copied into the actual
91 * controller request memory when the IO tag is allocated internally during
92 * the scic_controller_start_io() method.
93 * @user_task_request_object: This parameter specifies the user task request to
94 * be utilized during construction. This task pointer will become the
95 * associated object for the core task request object.
96 * @scic_task_request_memory: This parameter specifies the memory location to
97 * be utilized when building the core request.
98 * @new_scic_task_request_handle: This parameter specifies a pointer to the
99 * handle the core will expect in further interactions with the core task
100 * request object.
101 *
102 * The SCI core implementation will create an association between the user task
103 * request object and the core task request object. Indicate if the controller
104 * successfully built the task request. SCI_SUCCESS This value is returned if
105 * the task request was successfully built.
106 */
107enum sci_status scic_task_request_construct(
108 struct scic_sds_controller *scic_controller,
109 struct scic_sds_remote_device *scic_remote_device,
110 u16 io_tag,
111 void *user_task_request_object,
112 void *scic_task_request_memory,
113 struct scic_sds_request **new_scic_task_request_handle);
114
115/**
116 * scic_task_request_construct_ssp() - This method is called by the SCI user to
117 * construct all SCI Core SSP task management requests. Memory
118 * initialization and functionality common to all task request types is
119 * performed in this method.
120 * @scic_task_request: This parameter specifies the handle to the core task
121 * request object for which to construct a SATA specific task management
122 * request.
123 *
124 * Indicate if the controller successfully built the task request. SCI_SUCCESS
125 * This value is returned if the task request was successfully built.
126 */
127enum sci_status scic_task_request_construct_ssp(
128 struct scic_sds_request *scic_task_request);
129
130/**
131 * scic_task_request_construct_sata() - This method is called by the SCI user
132 * to construct all SCI Core SATA task management requests. Memory
133 * initialization and functionality common to all task request types is
134 * performed in this method.
135 * @scic_task_request_handle: This parameter specifies the handle to the core
136 * task request object for which to construct a SATA specific task
137 * management request.
138 *
139 * Indicate if the controller successfully built the task request. SCI_SUCCESS
140 * This value is returned if the task request was successfully built.
141 */
142enum sci_status scic_task_request_construct_sata(
143 struct scic_sds_request *scic_task_request_handle);
144
145
146
147#endif /* _SCIC_TASK_REQUEST_H_ */
148
diff --git a/drivers/scsi/isci/core/scic_user_callback.h b/drivers/scsi/isci/core/scic_user_callback.h
new file mode 100644
index 000000000000..6eca5a96649e
--- /dev/null
+++ b/drivers/scsi/isci/core/scic_user_callback.h
@@ -0,0 +1,740 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCIC_USER_CALLBACK_H_
57#define _SCIC_USER_CALLBACK_H_
58
59/**
60 * This file contains all of the interface methods/macros that must be
61 * implemented by an SCI Core user.
62 *
63 *
64 */
65
66
67#include "sci_types.h"
68#include "sci_status.h"
69
70struct scic_sds_request;
71struct scic_sds_phy;
72struct scic_sds_port;
73struct scic_sds_remote_device;
74struct scic_sds_controller;
75
76/**
77 * scic_cb_timer_create() - This callback method asks the user to create a
78 * timer and provide a handle for this timer for use in further timer
79 * interactions.
80 * @controller: This parameter specifies the controller with which this timer
81 * is to be associated.
82 * @timer_callback: This parameter specifies the callback method to be invoked
83 * whenever the timer expires.
84 * @cookie: This parameter specifies a piece of information that the user must
85 * retain. This cookie is to be supplied by the user anytime a timeout
86 * occurs for the created timer.
87 *
88 * The "timer_callback" method should be executed in a mutually exlusive manner
89 * from the controller completion handler handler (refer to
90 * scic_controller_get_handler_methods()). This method returns a handle to a
91 * timer object created by the user. The handle will be utilized for all
92 * further interactions relating to this timer.
93 */
94void *scic_cb_timer_create(
95 struct scic_sds_controller *controller,
96 void (*timer_callback)(void *),
97 void *cookie);
98
99
100/**
101 * scic_cb_timer_start() - This callback method asks the user to start the
102 * supplied timer.
103 * @controller: This parameter specifies the controller with which this timer
104 * is to associated.
105 * @timer: This parameter specifies the timer to be started.
106 * @milliseconds: This parameter specifies the number of milliseconds for which
107 * to stall. The operating system driver is allowed to round this value up
108 * where necessary.
109 *
110 * All timers in the system started by the SCI Core are one shot timers.
111 * Therefore, the SCI user should make sure that it removes the timer from it's
112 * list when a timer actually fires. Additionally, SCI Core user's should be
113 * able to handle calls from the SCI Core to stop a timer that may already be
114 * stopped. none
115 */
116void scic_cb_timer_start(
117 struct scic_sds_controller *controller,
118 void *timer,
119 u32 milliseconds);
120
121/**
122 * scic_cb_timer_stop() - This callback method asks the user to stop the
123 * supplied timer.
124 * @controller: This parameter specifies the controller with which this timer
125 * is to associated.
126 * @timer: This parameter specifies the timer to be stopped.
127 *
128 */
129void scic_cb_timer_stop(
130 struct scic_sds_controller *controller,
131 void *timer);
132
133/**
134 * scic_cb_stall_execution() - This method is called when the core requires the
135 * OS driver to stall execution. This method is utilized during
136 * initialization or non-performance paths only.
137 * @microseconds: This parameter specifies the number of microseconds for which
138 * to stall. The operating system driver is allowed to round this value up
139 * where necessary.
140 *
141 * none.
142 */
143void scic_cb_stall_execution(
144 u32 microseconds);
145
146/**
147 * scic_cb_controller_start_complete() - This user callback will inform the
148 * user that the controller has finished the start process.
149 * @controller: This parameter specifies the controller that was started.
150 * @completion_status: This parameter specifies the results of the start
151 * operation. SCI_SUCCESS indicates successful completion.
152 *
153 */
154void scic_cb_controller_start_complete(
155 struct scic_sds_controller *controller,
156 enum sci_status completion_status);
157
158/**
159 * scic_cb_controller_stop_complete() - This user callback will inform the user
160 * that the controller has finished the stop process.
161 * @controller: This parameter specifies the controller that was stopped.
162 * @completion_status: This parameter specifies the results of the stop
163 * operation. SCI_SUCCESS indicates successful completion.
164 *
165 */
166void scic_cb_controller_stop_complete(
167 struct scic_sds_controller *controller,
168 enum sci_status completion_status);
169
170/**
171 * scic_cb_io_request_complete() - This user callback will inform the user that
172 * an IO request has completed.
173 * @controller: This parameter specifies the controller on which the IO is
174 * completing.
175 * @remote_device: This parameter specifies the remote device on which this IO
176 * request is completing.
177 * @io_request: This parameter specifies the IO request that has completed.
178 * @completion_status: This parameter specifies the results of the IO request
179 * operation. SCI_SUCCESS indicates successful completion.
180 *
181 */
182void scic_cb_io_request_complete(
183 struct scic_sds_controller *controller,
184 struct scic_sds_remote_device *remote_device,
185 struct scic_sds_request *io_request,
186 enum sci_io_status completion_status);
187
188/**
189 * scic_cb_task_request_complete() - This user callback will inform the user
190 * that a task management request completed.
191 * @controller: This parameter specifies the controller on which the task
192 * management request is completing.
193 * @remote_device: This parameter specifies the remote device on which this
194 * task management request is completing.
195 * @task_request: This parameter specifies the task management request that has
196 * completed.
197 * @completion_status: This parameter specifies the results of the IO request
198 * operation. SCI_SUCCESS indicates successful completion.
199 *
200 */
201void scic_cb_task_request_complete(
202 struct scic_sds_controller *controller,
203 struct scic_sds_remote_device *remote_device,
204 struct scic_sds_request *task_request,
205 enum sci_task_status completion_status);
206
207#ifndef SCI_GET_PHYSICAL_ADDRESS_OPTIMIZATION_ENABLED
208/**
209 * scic_cb_io_request_get_physical_address() - This callback method asks the
210 * user to provide the physical address for the supplied virtual address
211 * when building an io request object.
212 * @controller: This parameter is the core controller object handle.
213 * @io_request: This parameter is the io request object handle for which the
214 * physical address is being requested.
215 * @virtual_address: This paramter is the virtual address which is to be
216 * returned as a physical address.
217 * @physical_address: The physical address for the supplied virtual address.
218 *
219 * None.
220 */
221void scic_cb_io_request_get_physical_address(
222 struct scic_sds_controller *controller,
223 struct scic_sds_request *io_request,
224 void *virtual_address,
225 dma_addr_t *physical_address);
226#endif /* SCI_GET_PHYSICAL_ADDRESS_OPTIMIZATION_ENABLED */
227
228/**
229 * scic_cb_io_request_get_transfer_length() - This callback method asks the
230 * user to provide the number of bytes to be transfered as part of this
231 * request.
232 * @scic_user_io_request: This parameter points to the user's IO request
233 * object. It is a cookie that allows the user to provide the necessary
234 * information for this callback.
235 *
236 * This method returns the number of payload data bytes to be transfered for
237 * this IO request.
238 */
239u32 scic_cb_io_request_get_transfer_length(
240 void *scic_user_io_request);
241
242/**
243 * scic_cb_io_request_get_data_direction() - This callback method asks the user
244 * to provide the data direction for this request.
245 * @scic_user_io_request: This parameter points to the user's IO request
246 * object. It is a cookie that allows the user to provide the necessary
247 * information for this callback.
248 *
249 * This method returns the value of SCI_IO_REQUEST_DATA_OUT or
250 * SCI_IO_REQUEST_DATA_IN, or SCI_IO_REQUEST_NO_DATA.
251 */
252SCI_IO_REQUEST_DATA_DIRECTION scic_cb_io_request_get_data_direction(
253 void *scic_user_io_request);
254
255#ifndef SCI_SGL_OPTIMIZATION_ENABLED
256/**
257 * scic_cb_io_request_get_next_sge() - This callback method asks the user to
258 * provide the address to where the next Scatter-Gather Element is located.
259 * Details regarding usage: - Regarding the first SGE: the user should
260 * initialize an index, or a pointer, prior to construction of the request
261 * that will reference the very first scatter-gather element. This is
262 * important since this method is called for every scatter-gather element,
263 * including the first element. - Regarding the last SGE: the user should
264 * return NULL from this method when this method is called and the SGL has
265 * exhausted all elements.
266 * @scic_user_io_request: This parameter points to the user's IO request
267 * object. It is a cookie that allows the user to provide the necessary
268 * information for this callback.
269 * @current_sge_address: This parameter specifies the address for the current
270 * SGE (i.e. the one that has just processed).
271 * @next_sge: An address specifying the location for the next scatter gather
272 * element to be processed.
273 *
274 * None
275 */
276void scic_cb_io_request_get_next_sge(
277 void *scic_user_io_request,
278 void *current_sge_address,
279 void **next_sge);
280#endif /* SCI_SGL_OPTIMIZATION_ENABLED */
281
282/**
283 * scic_cb_sge_get_address_field() - This callback method asks the user to
284 * provide the contents of the "address" field in the Scatter-Gather Element.
285 * @scic_user_io_request: This parameter points to the user's IO request
286 * object. It is a cookie that allows the user to provide the necessary
287 * information for this callback.
288 * @sge_address: This parameter specifies the address for the SGE from which to
289 * retrieve the address field.
290 *
291 * A physical address specifying the contents of the SGE's address field.
292 */
293dma_addr_t scic_cb_sge_get_address_field(
294 void *scic_user_io_request,
295 void *sge_address);
296
297/**
298 * scic_cb_sge_get_length_field() - This callback method asks the user to
299 * provide the contents of the "length" field in the Scatter-Gather Element.
300 * @scic_user_io_request: This parameter points to the user's IO request
301 * object. It is a cookie that allows the user to provide the necessary
302 * information for this callback.
303 * @sge_address: This parameter specifies the address for the SGE from which to
304 * retrieve the address field.
305 *
306 * This method returns the length field specified inside the SGE referenced by
307 * the sge_address parameter.
308 */
309u32 scic_cb_sge_get_length_field(
310 void *scic_user_io_request,
311 void *sge_address);
312
313/**
314 * scic_cb_ssp_io_request_get_cdb_address() - This callback method asks the
315 * user to provide the address for the command descriptor block (CDB)
316 * associated with this IO request.
317 * @scic_user_io_request: This parameter points to the user's IO request
318 * object. It is a cookie that allows the user to provide the necessary
319 * information for this callback.
320 *
321 * This method returns the virtual address of the CDB.
322 */
323void *scic_cb_ssp_io_request_get_cdb_address(
324 void *scic_user_io_request);
325
326/**
327 * scic_cb_ssp_io_request_get_cdb_length() - This callback method asks the user
328 * to provide the length of the command descriptor block (CDB) associated
329 * with this IO request.
330 * @scic_user_io_request: This parameter points to the user's IO request
331 * object. It is a cookie that allows the user to provide the necessary
332 * information for this callback.
333 *
334 * This method returns the length of the CDB.
335 */
336u32 scic_cb_ssp_io_request_get_cdb_length(
337 void *scic_user_io_request);
338
339/**
340 * scic_cb_ssp_io_request_get_lun() - This callback method asks the user to
341 * provide the Logical Unit (LUN) associated with this IO request.
342 * @scic_user_io_request: This parameter points to the user's IO request
343 * object. It is a cookie that allows the user to provide the necessary
344 * information for this callback.
345 *
346 * The contents of the value returned from this callback are defined by the
347 * protocol standard (e.g. T10 SAS specification). Please refer to the
348 * transport command information unit description in the associated standard.
349 * This method returns the LUN associated with this request. This should be u64?
350 */
351u32 scic_cb_ssp_io_request_get_lun(
352 void *scic_user_io_request);
353
354/**
355 * scic_cb_ssp_io_request_get_task_attribute() - This callback method asks the
356 * user to provide the task attribute associated with this IO request.
357 * @scic_user_io_request: This parameter points to the user's IO request
358 * object. It is a cookie that allows the user to provide the necessary
359 * information for this callback.
360 *
361 * The contents of the value returned from this callback are defined by the
362 * protocol standard (e.g. T10 SAS specification). Please refer to the
363 * transport command information unit description in the associated standard.
364 * This method returns the task attribute associated with this IO request.
365 */
366u32 scic_cb_ssp_io_request_get_task_attribute(
367 void *scic_user_io_request);
368
369/**
370 * scic_cb_ssp_io_request_get_command_priority() - This callback method asks
371 * the user to provide the command priority associated with this IO request.
372 * @scic_user_io_request: This parameter points to the user's IO request
373 * object. It is a cookie that allows the user to provide the necessary
374 * information for this callback.
375 *
376 * The contents of the value returned from this callback are defined by the
377 * protocol standard (e.g. T10 SAS specification). Please refer to the
378 * transport command information unit description in the associated standard.
379 * This method returns the command priority associated with this IO request.
380 */
381u32 scic_cb_ssp_io_request_get_command_priority(
382 void *scic_user_io_request);
383
384/**
385 * scic_cb_io_request_do_copy_rx_frames() - This callback method asks the user
386 * if the received RX frame data is to be copied to the SGL or should be
387 * stored by the SCI core to be retrieved later with the
388 * scic_io_request_get_rx_frame().
389 * @scic_user_io_request: This parameter points to the user's IO request
390 * object. It is a cookie that allows the user to provide the necessary
391 * information for this callback.
392 *
393 * This method returns true if the SCI core should copy the received frame data
394 * to the SGL location or false if the SCI user wants to retrieve the frame
395 * data at a later time.
396 */
397bool scic_cb_io_request_do_copy_rx_frames(
398 void *scic_user_io_request);
399
400/**
401 * scic_cb_request_get_sat_protocol() - This callback method asks the user to
402 * return the SAT protocol definition for this IO request. This method is
403 * only called by the SCI core if the request type constructed is SATA.
404 * @scic_user_io_request: This parameter points to the user's IO request
405 * object. It is a cookie that allows the user to provide the necessary
406 * information for this callback.
407 *
408 * This method returns one of the sat.h defined protocols for the given io
409 * request.
410 */
411u8 scic_cb_request_get_sat_protocol(
412 void *scic_user_io_request);
413
414
415/**
416 * scic_cb_ssp_task_request_get_lun() - This method returns the Logical Unit to
417 * be utilized for this task management request.
418 * @scic_user_task_request: This parameter points to the user's task request
419 * object. It is a cookie that allows the user to provide the necessary
420 * information for this callback.
421 *
422 * The contents of the value returned from this callback are defined by the
423 * protocol standard (e.g. T10 SAS specification). Please refer to the
424 * transport task information unit description in the associated standard. This
425 * method returns the LUN associated with this request. This should be u64?
426 */
427u32 scic_cb_ssp_task_request_get_lun(
428 void *scic_user_task_request);
429
430/**
431 * scic_cb_ssp_task_request_get_function() - This method returns the task
432 * management function to be utilized for this task request.
433 * @scic_user_task_request: This parameter points to the user's task request
434 * object. It is a cookie that allows the user to provide the necessary
435 * information for this callback.
436 *
437 * The contents of the value returned from this callback are defined by the
438 * protocol standard (e.g. T10 SAS specification). Please refer to the
439 * transport task information unit description in the associated standard. This
440 * method returns an unsigned byte representing the task management function to
441 * be performed.
442 */
443u8 scic_cb_ssp_task_request_get_function(
444 void *scic_user_task_request);
445
446/**
447 * scic_cb_ssp_task_request_get_io_tag_to_manage() - This method returns the
448 * task management IO tag to be managed. Depending upon the task management
449 * function the value returned from this method may be ignored.
450 * @scic_user_task_request: This parameter points to the user's task request
451 * object. It is a cookie that allows the user to provide the necessary
452 * information for this callback.
453 *
454 * This method returns an unsigned 16-bit word depicting the IO tag to be
455 * managed.
456 */
457u16 scic_cb_ssp_task_request_get_io_tag_to_manage(
458 void *scic_user_task_request);
459
460/**
461 * scic_cb_ssp_task_request_get_response_data_address() - This callback method
462 * asks the user to provide the virtual address of the response data buffer
463 * for the supplied IO request.
464 * @scic_user_task_request: This parameter points to the user's task request
465 * object. It is a cookie that allows the user to provide the necessary
466 * information for this callback.
467 *
468 * This method returns the virtual address for the response data buffer
469 * associated with this IO request.
470 */
471void *scic_cb_ssp_task_request_get_response_data_address(
472 void *scic_user_task_request);
473
474/**
475 * scic_cb_ssp_task_request_get_response_data_length() - This callback method
476 * asks the user to provide the length of the response data buffer for the
477 * supplied IO request.
478 * @scic_user_task_request: This parameter points to the user's task request
479 * object. It is a cookie that allows the user to provide the necessary
480 * information for this callback.
481 *
482 * This method returns the length of the response buffer data associated with
483 * this IO request.
484 */
485u32 scic_cb_ssp_task_request_get_response_data_length(
486 void *scic_user_task_request);
487
488/**
489 * scic_cb_pci_get_bar() - In this method the user must return the base address
490 * register (BAR) value for the supplied base address register number.
491 * @controller: The controller for which to retrieve the bar number.
492 * @bar_number: This parameter depicts the BAR index/number to be read.
493 *
494 * Return a pointer value indicating the contents of the BAR. NULL indicates an
495 * invalid BAR index/number was specified. All other values indicate a valid
496 * VIRTUAL address from the BAR.
497 */
498void *scic_cb_pci_get_bar(
499 struct scic_sds_controller *controller,
500 u16 bar_number);
501
502/**
503 * scic_cb_get_virtual_address() - This callback method asks the user to
504 * provide the virtual address for the supplied physical address.
505 * @controller: This parameter is the core controller object handle.
506 * @physical_address: This parameter is the physical address which is to be
507 * returned as a virtual address.
508 *
509 * The method returns the virtual address for the supplied physical address.
510 */
511void *scic_cb_get_virtual_address(
512 struct scic_sds_controller *controller,
513 dma_addr_t physical_address);
514
515/**
516 * scic_cb_port_stop_complete() - This method informs the user when a stop
517 * operation on the port has completed.
518 * @controller: This parameter represents the controller which contains the
519 * port.
520 * @port: This parameter specifies the SCI port object for which the callback
521 * is being invoked.
522 * @completion_status: This parameter specifies the status for the operation
523 * being completed.
524 *
525 */
526void scic_cb_port_stop_complete(
527 struct scic_sds_controller *controller,
528 struct scic_sds_port *port,
529 enum sci_status completion_status);
530
531/**
532 * scic_cb_port_hard_reset_complete() - This method informs the user when a
533 * hard reset on the port has completed. This hard reset could have been
534 * initiated by the user or by the remote port.
535 * @controller: This parameter represents the controller which contains the
536 * port.
537 * @port: This parameter specifies the SCI port object for which the callback
538 * is being invoked.
539 * @completion_status: This parameter specifies the status for the operation
540 * being completed.
541 *
542 */
543void scic_cb_port_hard_reset_complete(
544 struct scic_sds_controller *controller,
545 struct scic_sds_port *port,
546 enum sci_status completion_status);
547
548/**
549 * scic_cb_port_ready() - This method informs the user that the port is now in
550 * a ready state and can be utilized to issue IOs.
551 * @controller: This parameter represents the controller which contains the
552 * port.
553 * @port: This parameter specifies the SCI port object for which the callback
554 * is being invoked.
555 *
556 */
557void scic_cb_port_ready(
558 struct scic_sds_controller *controller,
559 struct scic_sds_port *port);
560
561/**
562 * scic_cb_port_not_ready() - This method informs the user that the port is now
563 * not in a ready (i.e. busy) state and can't be utilized to issue IOs.
564 * @controller: This parameter represents the controller which contains the
565 * port.
566 * @port: This parameter specifies the SCI port object for which the callback
567 * is being invoked.
568 * @reason_code: This parameter specifies the reason for the port not ready
569 * callback.
570 *
571 */
572void scic_cb_port_not_ready(
573 struct scic_sds_controller *controller,
574 struct scic_sds_port *port,
575 u32 reason_code);
576
577/**
578 * scic_cb_port_invalid_link_up() - This method informs the SCI Core user that
579 * a phy/link became ready, but the phy is not allowed in the port. In some
580 * situations the underlying hardware only allows for certain phy to port
581 * mappings. If these mappings are violated, then this API is invoked.
582 * @controller: This parameter represents the controller which contains the
583 * port.
584 * @port: This parameter specifies the SCI port object for which the callback
585 * is being invoked.
586 * @phy: This parameter specifies the phy that came ready, but the phy can't be
587 * a valid member of the port.
588 *
589 */
590void scic_cb_port_invalid_link_up(
591 struct scic_sds_controller *controller,
592 struct scic_sds_port *port,
593 struct scic_sds_phy *phy);
594
595/**
596 * scic_cb_port_bc_change_primitive_received() - This callback method informs
597 * the user that a broadcast change primitive was received.
598 * @controller: This parameter represents the controller which contains the
599 * port.
600 * @port: This parameter specifies the SCI port object for which the callback
601 * is being invoked. For instances where the phy on which the primitive was
602 * received is not part of a port, this parameter will be
603 * SCI_INVALID_HANDLE_T.
604 * @phy: This parameter specifies the phy on which the primitive was received.
605 *
606 */
607void scic_cb_port_bc_change_primitive_received(
608 struct scic_sds_controller *controller,
609 struct scic_sds_port *port,
610 struct scic_sds_phy *phy);
611
612
613
614
615/**
616 * scic_cb_port_link_up() - This callback method informs the user that a phy
617 * has become operational and is capable of communicating with the remote
618 * end point.
619 * @controller: This parameter represents the controller associated with the
620 * phy.
621 * @port: This parameter specifies the port object for which the user callback
622 * is being invoked. There may be conditions where this parameter can be
623 * SCI_INVALID_HANDLE
624 * @phy: This parameter specifies the phy object for which the user callback is
625 * being invoked.
626 *
627 */
628void scic_cb_port_link_up(
629 struct scic_sds_controller *controller,
630 struct scic_sds_port *port,
631 struct scic_sds_phy *phy);
632
633/**
634 * scic_cb_port_link_down() - This callback method informs the user that a phy
635 * is no longer operational and is not capable of communicating with the
636 * remote end point.
637 * @controller: This parameter represents the controller associated with the
638 * phy.
639 * @port: This parameter specifies the port object for which the user callback
640 * is being invoked. There may be conditions where this parameter can be
641 * SCI_INVALID_HANDLE
642 * @phy: This parameter specifies the phy object for which the user callback is
643 * being invoked.
644 *
645 */
646void scic_cb_port_link_down(
647 struct scic_sds_controller *controller,
648 struct scic_sds_port *port,
649 struct scic_sds_phy *phy);
650
651/**
652 * scic_cb_remote_device_start_complete() - This user callback method will
653 * inform the user that a start operation has completed.
654 * @controller: This parameter specifies the core controller associated with
655 * the completion callback.
656 * @remote_device: This parameter specifies the remote device associated with
657 * the completion callback.
658 * @completion_status: This parameter specifies the completion status for the
659 * operation.
660 *
661 */
662void scic_cb_remote_device_start_complete(
663 struct scic_sds_controller *controller,
664 struct scic_sds_remote_device *remote_device,
665 enum sci_status completion_status);
666
667/**
668 * scic_cb_remote_device_stop_complete() - This user callback method will
669 * inform the user that a stop operation has completed.
670 * @controller: This parameter specifies the core controller associated with
671 * the completion callback.
672 * @remote_device: This parameter specifies the remote device associated with
673 * the completion callback.
674 * @completion_status: This parameter specifies the completion status for the
675 * operation.
676 *
677 */
678void scic_cb_remote_device_stop_complete(
679 struct scic_sds_controller *controller,
680 struct scic_sds_remote_device *remote_device,
681 enum sci_status completion_status);
682
683/**
684 * scic_cb_remote_device_ready() - This user callback method will inform the
685 * user that a remote device is now capable of handling IO requests.
686 * @controller: This parameter specifies the core controller associated with
687 * the completion callback.
688 * @remote_device: This parameter specifies the remote device associated with
689 * the callback.
690 *
691 */
692void scic_cb_remote_device_ready(
693 struct scic_sds_controller *controller,
694 struct scic_sds_remote_device *remote_device);
695
696/**
697 * scic_cb_remote_device_not_ready() - This user callback method will inform
698 * the user that a remote device is no longer capable of handling IO
699 * requests (until a ready callback is invoked).
700 * @controller: This parameter specifies the core controller associated with
701 * the completion callback.
702 * @remote_device: This parameter specifies the remote device associated with
703 * the callback.
704 * @reason_code: This paramete specifies the reason the remote device is not
705 * ready.
706 *
707 */
708void scic_cb_remote_device_not_ready(
709 struct scic_sds_controller *controller,
710 struct scic_sds_remote_device *remote_device,
711 u32 reason_code);
712
713#if !defined(DISABLE_ATAPI)
714/**
715 * scic_cb_stp_packet_io_request_get_cdb_address() - This user callback gets
716 * from stp packet io's user request the CDB address.
717 * @scic_user_io_request:
718 *
719 * The cdb adress.
720 */
721void *scic_cb_stp_packet_io_request_get_cdb_address(
722 void *scic_user_io_request);
723
724/**
725 * scic_cb_stp_packet_io_request_get_cdb_length() - This user callback gets
726 * from stp packet io's user request the CDB length.
727 * @scic_user_io_request:
728 *
729 * The cdb length.
730 */
731u32 scic_cb_stp_packet_io_request_get_cdb_length(
732 void *scic_user_io_request);
733#else /* !defined(DISABLE_ATAPI) */
734#define scic_cb_stp_packet_io_request_get_cdb_address(scic_user_io_request) NULL
735#define scic_cb_stp_packet_io_request_get_cdb_length(scic_user_io_request) 0
736#endif /* !defined(DISABLE_ATAPI) */
737
738
739#endif /* _SCIC_USER_CALLBACK_H_ */
740
diff --git a/drivers/scsi/isci/core/scu_completion_codes.h b/drivers/scsi/isci/core/scu_completion_codes.h
new file mode 100644
index 000000000000..17ee4c8b9122
--- /dev/null
+++ b/drivers/scsi/isci/core/scu_completion_codes.h
@@ -0,0 +1,280 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCU_COMPLETION_CODES_HEADER_
57#define _SCU_COMPLETION_CODES_HEADER_
58
59/**
60 * This file contains the constants and macros for the SCU hardware completion
61 * codes.
62 *
63 *
64 */
65
66#define SCU_COMPLETION_TYPE_SHIFT 28
67#define SCU_COMPLETION_TYPE_MASK 0x70000000
68
69/**
70 * SCU_COMPLETION_TYPE() -
71 *
72 * This macro constructs an SCU completion type
73 */
74#define SCU_COMPLETION_TYPE(type) \
75 ((u32)(type) << SCU_COMPLETION_TYPE_SHIFT)
76
77/**
78 * SCU_COMPLETION_TYPE() -
79 *
80 * These macros contain the SCU completion types SCU_COMPLETION_TYPE
81 */
82#define SCU_COMPLETION_TYPE_TASK SCU_COMPLETION_TYPE(0)
83#define SCU_COMPLETION_TYPE_SDMA SCU_COMPLETION_TYPE(1)
84#define SCU_COMPLETION_TYPE_UFI SCU_COMPLETION_TYPE(2)
85#define SCU_COMPLETION_TYPE_EVENT SCU_COMPLETION_TYPE(3)
86#define SCU_COMPLETION_TYPE_NOTIFY SCU_COMPLETION_TYPE(4)
87
88/**
89 *
90 *
91 * These constants provide the shift and mask values for the various parts of
92 * an SCU completion code.
93 */
94#define SCU_COMPLETION_STATUS_MASK 0x0FFC0000
95#define SCU_COMPLETION_TL_STATUS_MASK 0x0FC00000
96#define SCU_COMPLETION_TL_STATUS_SHIFT 22
97#define SCU_COMPLETION_SDMA_STATUS_MASK 0x003C0000
98#define SCU_COMPLETION_PEG_MASK 0x00010000
99#define SCU_COMPLETION_PORT_MASK 0x00007000
100#define SCU_COMPLETION_PE_MASK SCU_COMPLETION_PORT_MASK
101#define SCU_COMPLETION_PE_SHIFT 12
102#define SCU_COMPLETION_INDEX_MASK 0x00000FFF
103
104/**
105 * SCU_GET_COMPLETION_TYPE() -
106 *
107 * This macro returns the SCU completion type.
108 */
109#define SCU_GET_COMPLETION_TYPE(completion_code) \
110 ((completion_code) & SCU_COMPLETION_TYPE_MASK)
111
112/**
113 * SCU_GET_COMPLETION_STATUS() -
114 *
115 * This macro returns the SCU completion status.
116 */
117#define SCU_GET_COMPLETION_STATUS(completion_code) \
118 ((completion_code) & SCU_COMPLETION_STATUS_MASK)
119
120/**
121 * SCU_GET_COMPLETION_TL_STATUS() -
122 *
123 * This macro returns the transport layer completion status.
124 */
125#define SCU_GET_COMPLETION_TL_STATUS(completion_code) \
126 ((completion_code) & SCU_COMPLETION_TL_STATUS_MASK)
127
128/**
129 * SCU_MAKE_COMPLETION_STATUS() -
130 *
131 * This macro takes a completion code and performs the shift and mask
132 * operations to turn it into a completion code that can be compared to a
133 * SCU_GET_COMPLETION_TL_STATUS.
134 */
135#define SCU_MAKE_COMPLETION_STATUS(completion_code) \
136 ((u32)(completion_code) << SCU_COMPLETION_TL_STATUS_SHIFT)
137
138/**
139 * SCU_NORMALIZE_COMPLETION_STATUS() -
140 *
141 * This macro takes a SCU_GET_COMPLETION_TL_STATUS and normalizes it for a
142 * return code.
143 */
144#define SCU_NORMALIZE_COMPLETION_STATUS(completion_code) \
145 (\
146 ((completion_code) & SCU_COMPLETION_TL_STATUS_MASK) \
147 >> SCU_COMPLETION_TL_STATUS_SHIFT \
148 )
149
150/**
151 * SCU_GET_COMPLETION_SDMA_STATUS() -
152 *
153 * This macro returns the SDMA completion status.
154 */
155#define SCU_GET_COMPLETION_SDMA_STATUS(completion_code) \
156 ((completion_code) & SCU_COMPLETION_SDMA_STATUS_MASK)
157
158/**
159 * SCU_GET_COMPLETION_PEG() -
160 *
161 * This macro returns the Protocol Engine Group from the completion code.
162 */
163#define SCU_GET_COMPLETION_PEG(completion_code) \
164 ((completion_code) & SCU_COMPLETION_PEG_MASK)
165
166/**
167 * SCU_GET_COMPLETION_PORT() -
168 *
169 * This macro reuturns the logical port index from the completion code.
170 */
171#define SCU_GET_COMPLETION_PORT(completion_code) \
172 ((completion_code) & SCU_COMPLETION_PORT_MASK)
173
174/**
175 * SCU_GET_PROTOCOL_ENGINE_INDEX() -
176 *
177 * This macro returns the PE index from the completion code.
178 */
179#define SCU_GET_PROTOCOL_ENGINE_INDEX(completion_code) \
180 (((completion_code) & SCU_COMPLETION_PE_MASK) >> SCU_COMPLETION_PE_SHIFT)
181
182/**
183 * SCU_GET_COMPLETION_INDEX() -
184 *
185 * This macro returns the index of the completion which is either a TCi or an
186 * RNi depending on the completion type.
187 */
188#define SCU_GET_COMPLETION_INDEX(completion_code) \
189 ((completion_code) & SCU_COMPLETION_INDEX_MASK)
190
191#define SCU_UNSOLICITED_FRAME_MASK 0x0FFF0000
192#define SCU_UNSOLICITED_FRAME_SHIFT 16
193
194/**
195 * SCU_GET_FRAME_INDEX() -
196 *
197 * This macro returns a normalized frame index from an unsolicited frame
198 * completion.
199 */
200#define SCU_GET_FRAME_INDEX(completion_code) \
201 (\
202 ((completion_code) & SCU_UNSOLICITED_FRAME_MASK) \
203 >> SCU_UNSOLICITED_FRAME_SHIFT \
204 )
205
206#define SCU_UNSOLICITED_FRAME_ERROR_MASK 0x00008000
207
208/**
209 * SCU_GET_FRAME_ERROR() -
210 *
211 * This macro returns a zero (0) value if there is no frame error otherwise it
212 * returns non-zero (!0).
213 */
214#define SCU_GET_FRAME_ERROR(completion_code) \
215 ((completion_code) & SCU_UNSOLICITED_FRAME_ERROR_MASK)
216
217/**
218 *
219 *
220 * These constants represent normalized completion codes which must be shifted
221 * 18 bits to match it with the hardware completion code. In a 16-bit compiler,
222 * immediate constants are 16-bit values (the size of an int). If we shift
223 * those by 18 bits, we completely lose the value. To ensure the value is a
224 * 32-bit value like we want, each immediate value must be cast to a u32.
225 */
226#define SCU_TASK_DONE_GOOD ((u32)0x00)
227#define SCU_TASK_DONE_CRC_ERR ((u32)0x14)
228#define SCU_TASK_DONE_CHECK_RESPONSE ((u32)0x14)
229#define SCU_TASK_DONE_GEN_RESPONSE ((u32)0x15)
230#define SCU_TASK_DONE_NAK_CMD_ERR ((u32)0x16)
231#define SCU_TASK_DONE_LL_R_ERR ((u32)0x17)
232#define SCU_TASK_DONE_ACK_NAK_TO ((u32)0x17)
233#define SCU_TASK_DONE_LL_PERR ((u32)0x18)
234#define SCU_TASK_DONE_LL_SY_TERM ((u32)0x19)
235#define SCU_TASK_DONE_NAK_ERR ((u32)0x19)
236#define SCU_TASK_DONE_LL_LF_TERM ((u32)0x1A)
237#define SCU_TASK_DONE_DATA_LEN_ERR ((u32)0x1A)
238#define SCU_TASK_DONE_LL_CL_TERM ((u32)0x1B)
239#define SCU_TASK_DONE_LL_ABORT_ERR ((u32)0x1B)
240#define SCU_TASK_DONE_SEQ_INV_TYPE ((u32)0x1C)
241#define SCU_TASK_DONE_UNEXP_XR ((u32)0x1C)
242#define SCU_TASK_DONE_INV_FIS_TYPE ((u32)0x1D)
243#define SCU_TASK_DONE_XR_IU_LEN_ERR ((u32)0x1D)
244#define SCU_TASK_DONE_INV_FIS_LEN ((u32)0x1E)
245#define SCU_TASK_DONE_XR_WD_LEN ((u32)0x1E)
246#define SCU_TASK_DONE_SDMA_ERR ((u32)0x1F)
247#define SCU_TASK_DONE_OFFSET_ERR ((u32)0x20)
248#define SCU_TASK_DONE_MAX_PLD_ERR ((u32)0x21)
249#define SCU_TASK_DONE_EXCESS_DATA ((u32)0x22)
250#define SCU_TASK_DONE_LF_ERR ((u32)0x23)
251#define SCU_TASK_DONE_UNEXP_FIS ((u32)0x24)
252#define SCU_TASK_DONE_UNEXP_RESP ((u32)0x24)
253#define SCU_TASK_DONE_EARLY_RESP ((u32)0x25)
254#define SCU_TASK_DONE_SMP_RESP_TO_ERR ((u32)0x26)
255#define SCU_TASK_DONE_DMASETUP_DIRERR ((u32)0x27)
256#define SCU_TASK_DONE_SMP_UFI_ERR ((u32)0x27)
257#define SCU_TASK_DONE_XFERCNT_ERR ((u32)0x28)
258#define SCU_TASK_DONE_SMP_FRM_TYPE_ERR ((u32)0x28)
259#define SCU_TASK_DONE_SMP_LL_RX_ERR ((u32)0x29)
260#define SCU_TASK_DONE_RESP_LEN_ERR ((u32)0x2A)
261#define SCU_TASK_DONE_UNEXP_DATA ((u32)0x2B)
262#define SCU_TASK_DONE_OPEN_FAIL ((u32)0x2C)
263#define SCU_TASK_DONE_UNEXP_SDBFIS ((u32)0x2D)
264#define SCU_TASK_DONE_REG_ERR ((u32)0x2E)
265#define SCU_TASK_DONE_SDB_ERR ((u32)0x2F)
266#define SCU_TASK_DONE_TASK_ABORT ((u32)0x30)
267#define SCU_TASK_OPEN_REJECT_WRONG_DESTINATION ((u32)0x34)
268#define SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1 ((u32)0x35)
269#define SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2 ((u32)0x36)
270#define SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3 ((u32)0x37)
271#define SCU_TASK_OPEN_REJECT_BAD_DESTINATION ((u32)0x38)
272#define SCU_TASK_OPEN_REJECT_ZONE_VIOLATION ((u32)0x39)
273#define SCU_TASK_DONE_VIIT_ENTRY_NV ((u32)0x3A)
274#define SCU_TASK_DONE_IIT_ENTRY_NV ((u32)0x3B)
275#define SCU_TASK_DONE_RNCNV_OUTBOUND ((u32)0x3C)
276#define SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY ((u32)0x3D)
277#define SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED ((u32)0x3E)
278#define SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED ((u32)0x3F)
279
280#endif /* _SCU_COMPLETION_CODES_HEADER_ */
diff --git a/drivers/scsi/isci/core/scu_constants.h b/drivers/scsi/isci/core/scu_constants.h
new file mode 100644
index 000000000000..a99d1103ad3b
--- /dev/null
+++ b/drivers/scsi/isci/core/scu_constants.h
@@ -0,0 +1,151 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCU_CONSTANTS_H_
57#define _SCU_CONSTANTS_H_
58
59/**
60 * This file contains the SCU hardware constants.
61 *
62 *
63 */
64
65#include "sci_controller_constants.h"
66
67/**
68 *
69 *
70 * 2 indicates the maximum number of UFs that can occur for a given IO request.
71 * The hardware handles reception of additional unsolicited frames while all
72 * UFs are in use, by holding off the transmitting device. This number could
73 * be theoretically reduced to 1, but 2 provides for more reliable operation.
74 * During SATA PIO operation, it is possible under some conditions for there to
75 * be 3 separate FISes received, back to back to back (PIO Setup, Data, D2H
76 * Register). It is unlikely to have all 3 pending all at once without some of
77 * them already being processed.
78 */
79#define SCU_MIN_UNSOLICITED_FRAMES (1)
80#define SCU_MIN_CRITICAL_NOTIFICATIONS (24)
81#define SCU_MIN_EVENTS (4)
82#define SCU_MIN_COMPLETION_QUEUE_SCRATCH (2)
83#define SCU_MIN_COMPLETION_QUEUE_ENTRIES (SCU_MIN_CRITICAL_NOTIFICATIONS \
84 + SCU_MIN_EVENTS \
85 + SCU_MIN_UNSOLICITED_FRAMES \
86 + SCI_MIN_IO_REQUESTS \
87 + SCU_MIN_COMPLETION_QUEUE_SCRATCH)
88
89#define SCU_MAX_CRITICAL_NOTIFICATIONS (384)
90#define SCU_MAX_EVENTS (128)
91#define SCU_MAX_UNSOLICITED_FRAMES (128)
92#define SCU_MAX_COMPLETION_QUEUE_SCRATCH (128)
93#define SCU_MAX_COMPLETION_QUEUE_ENTRIES (SCU_MAX_CRITICAL_NOTIFICATIONS \
94 + SCU_MAX_EVENTS \
95 + SCU_MAX_UNSOLICITED_FRAMES \
96 + SCI_MAX_IO_REQUESTS \
97 + SCU_MAX_COMPLETION_QUEUE_SCRATCH)
98
99#if !defined(ENABLE_MINIMUM_MEMORY_MODE)
100#define SCU_UNSOLICITED_FRAME_COUNT SCU_MAX_UNSOLICITED_FRAMES
101#define SCU_CRITICAL_NOTIFICATION_COUNT SCU_MAX_CRITICAL_NOTIFICATIONS
102#define SCU_EVENT_COUNT SCU_MAX_EVENTS
103#define SCU_COMPLETION_QUEUE_SCRATCH SCU_MAX_COMPLETION_QUEUE_SCRATCH
104#define SCU_IO_REQUEST_COUNT SCI_MAX_IO_REQUESTS
105#define SCU_IO_REQUEST_SGE_COUNT SCI_MAX_SCATTER_GATHER_ELEMENTS
106#define SCU_COMPLETION_QUEUE_COUNT SCU_MAX_COMPLETION_QUEUE_ENTRIES
107#else
108#define SCU_UNSOLICITED_FRAME_COUNT SCU_MIN_UNSOLICITED_FRAMES
109#define SCU_CRITICAL_NOTIFICATION_COUNT SCU_MIN_CRITICAL_NOTIFICATIONS
110#define SCU_EVENT_COUNT SCU_MIN_EVENTS
111#define SCU_COMPLETION_QUEUE_SCRATCH SCU_MIN_COMPLETION_QUEUE_SCRATCH
112#define SCU_IO_REQUEST_COUNT SCI_MIN_IO_REQUESTS
113#define SCU_IO_REQUEST_SGE_COUNT SCI_MIN_SCATTER_GATHER_ELEMENTS
114#define SCU_COMPLETION_QUEUE_COUNT SCU_MIN_COMPLETION_QUEUE_ENTRIES
115#endif /* !defined(ENABLE_MINIMUM_MEMORY_OPERATION) */
116
117/**
118 *
119 *
120 * The SCU_COMPLETION_QUEUE_COUNT constant indicates the size of the completion
121 * queue into which the hardware DMAs 32-bit quantas (completion entries).
122 */
123
124/**
125 *
126 *
127 * This queue must be programmed to a power of 2 size (e.g. 32, 64, 1024, etc.).
128 */
129#if (SCU_COMPLETION_QUEUE_COUNT != 16) && \
130 (SCU_COMPLETION_QUEUE_COUNT != 32) && \
131 (SCU_COMPLETION_QUEUE_COUNT != 64) && \
132 (SCU_COMPLETION_QUEUE_COUNT != 128) && \
133 (SCU_COMPLETION_QUEUE_COUNT != 256) && \
134 (SCU_COMPLETION_QUEUE_COUNT != 512) && \
135 (SCU_COMPLETION_QUEUE_COUNT != 1024)
136#error "SCU_COMPLETION_QUEUE_COUNT must be set to a power of 2."
137#endif
138
139#if SCU_MIN_UNSOLICITED_FRAMES > SCU_MAX_UNSOLICITED_FRAMES
140#error "Invalid configuration of unsolicited frame constants"
141#endif /* SCU_MIN_UNSOLICITED_FRAMES > SCU_MAX_UNSOLICITED_FRAMES */
142
143#define SCU_MIN_UF_TABLE_ENTRIES (8)
144#define SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES (4096)
145#define SCU_UNSOLICITED_FRAME_BUFFER_SIZE (1024)
146#define SCU_INVALID_FRAME_INDEX (0xFFFF)
147
148#define SCU_IO_REQUEST_MAX_SGE_SIZE (0x00FFFFFF)
149#define SCU_IO_REQUEST_MAX_TRANSFER_LENGTH (0x00FFFFFF)
150
151#endif /* _SCU_CONSTANTS_H_ */
diff --git a/drivers/scsi/isci/core/scu_event_codes.h b/drivers/scsi/isci/core/scu_event_codes.h
new file mode 100644
index 000000000000..36a945ad5722
--- /dev/null
+++ b/drivers/scsi/isci/core/scu_event_codes.h
@@ -0,0 +1,336 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef __SCU_EVENT_CODES_HEADER__
57#define __SCU_EVENT_CODES_HEADER__
58
59/**
60 * This file contains the constants and macros for the SCU event codes.
61 *
62 *
63 */
64
65#define SCU_EVENT_TYPE_CODE_SHIFT 24
66#define SCU_EVENT_TYPE_CODE_MASK 0x0F000000
67
68#define SCU_EVENT_SPECIFIC_CODE_SHIFT 18
69#define SCU_EVENT_SPECIFIC_CODE_MASK 0x00FC0000
70
71#define SCU_EVENT_CODE_MASK \
72 (SCU_EVENT_TYPE_CODE_MASK | SCU_EVENT_SPECIFIC_CODE_MASK)
73
74/**
75 * SCU_EVENT_TYPE() -
76 *
77 * This macro constructs an SCU event type from the type value.
78 */
79#define SCU_EVENT_TYPE(type) \
80 ((u32)(type) << SCU_EVENT_TYPE_CODE_SHIFT)
81
82/**
83 * SCU_EVENT_SPECIFIC() -
84 *
85 * This macro constructs an SCU event specifier from the code value.
86 */
87#define SCU_EVENT_SPECIFIC(code) \
88 ((u32)(code) << SCU_EVENT_SPECIFIC_CODE_SHIFT)
89
90/**
91 * SCU_EVENT_MESSAGE() -
92 *
93 * This macro constructs a combines an SCU event type and SCU event specifier
94 * from the type and code values.
95 */
96#define SCU_EVENT_MESSAGE(type, code) \
97 ((type) | SCU_EVENT_SPECIFIC(code))
98
99/**
100 * SCU_EVENT_TYPE() -
101 *
102 * SCU_EVENT_TYPES
103 */
104#define SCU_EVENT_TYPE_SMU_COMMAND_ERROR SCU_EVENT_TYPE(0x08)
105#define SCU_EVENT_TYPE_SMU_PCQ_ERROR SCU_EVENT_TYPE(0x09)
106#define SCU_EVENT_TYPE_SMU_ERROR SCU_EVENT_TYPE(0x00)
107#define SCU_EVENT_TYPE_TRANSPORT_ERROR SCU_EVENT_TYPE(0x01)
108#define SCU_EVENT_TYPE_BROADCAST_CHANGE SCU_EVENT_TYPE(0x02)
109#define SCU_EVENT_TYPE_OSSP_EVENT SCU_EVENT_TYPE(0x03)
110#define SCU_EVENT_TYPE_FATAL_MEMORY_ERROR SCU_EVENT_TYPE(0x0F)
111#define SCU_EVENT_TYPE_RNC_SUSPEND_TX SCU_EVENT_TYPE(0x04)
112#define SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX SCU_EVENT_TYPE(0x05)
113#define SCU_EVENT_TYPE_RNC_OPS_MISC SCU_EVENT_TYPE(0x06)
114#define SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT SCU_EVENT_TYPE(0x07)
115#define SCU_EVENT_TYPE_ERR_CNT_EVENT SCU_EVENT_TYPE(0x0A)
116
117/**
118 *
119 *
120 * SCU_EVENT_SPECIFIERS
121 */
122#define SCU_EVENT_SPECIFIER_DRIVER_SUSPEND 0x20
123#define SCU_EVENT_SPECIFIER_RNC_RELEASE 0x00
124
125/**
126 *
127 *
128 * SMU_COMMAND_EVENTS
129 */
130#define SCU_EVENT_INVALID_CONTEXT_COMMAND \
131 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_SMU_COMMAND_ERROR, 0x00)
132
133/**
134 *
135 *
136 * SMU_PCQ_EVENTS
137 */
138#define SCU_EVENT_UNCORRECTABLE_PCQ_ERROR \
139 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_SMU_PCQ_ERROR, 0x00)
140
141/**
142 *
143 *
144 * SMU_EVENTS
145 */
146#define SCU_EVENT_UNCORRECTABLE_REGISTER_WRITE \
147 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_SMU_ERROR, 0x02)
148#define SCU_EVENT_UNCORRECTABLE_REGISTER_READ \
149 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_SMU_ERROR, 0x03)
150#define SCU_EVENT_PCIE_INTERFACE_ERROR \
151 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_SMU_ERROR, 0x04)
152#define SCU_EVENT_FUNCTION_LEVEL_RESET \
153 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_SMU_ERROR, 0x05)
154
155/**
156 *
157 *
158 * TRANSPORT_LEVEL_ERRORS
159 */
160#define SCU_EVENT_ACK_NAK_TIMEOUT_ERROR \
161 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_TRANSPORT_ERROR, 0x00)
162
163/**
164 *
165 *
166 * BROADCAST_CHANGE_EVENTS
167 */
168#define SCU_EVENT_BROADCAST_CHANGE \
169 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x01)
170#define SCU_EVENT_BROADCAST_RESERVED0 \
171 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x02)
172#define SCU_EVENT_BROADCAST_RESERVED1 \
173 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x03)
174#define SCU_EVENT_BROADCAST_SES \
175 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x04)
176#define SCU_EVENT_BROADCAST_EXPANDER \
177 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x05)
178#define SCU_EVENT_BROADCAST_AEN \
179 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x06)
180#define SCU_EVENT_BROADCAST_RESERVED3 \
181 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x07)
182#define SCU_EVENT_BROADCAST_RESERVED4 \
183 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x08)
184#define SCU_EVENT_PE_SUSPENDED \
185 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x09)
186
187/**
188 *
189 *
190 * OSSP_EVENTS
191 */
192#define SCU_EVENT_PORT_SELECTOR_DETECTED \
193 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x10)
194#define SCU_EVENT_SENT_PORT_SELECTION \
195 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x11)
196#define SCU_EVENT_HARD_RESET_TRANSMITTED \
197 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x12)
198#define SCU_EVENT_HARD_RESET_RECEIVED \
199 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x13)
200#define SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT \
201 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x15)
202#define SCU_EVENT_LINK_FAILURE \
203 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x16)
204#define SCU_EVENT_SATA_SPINUP_HOLD \
205 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x17)
206#define SCU_EVENT_SAS_15_SSC \
207 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x18)
208#define SCU_EVENT_SAS_15 \
209 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x19)
210#define SCU_EVENT_SAS_30_SSC \
211 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x1A)
212#define SCU_EVENT_SAS_30 \
213 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x1B)
214#define SCU_EVENT_SAS_60_SSC \
215 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x1C)
216#define SCU_EVENT_SAS_60 \
217 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x1D)
218#define SCU_EVENT_SATA_15_SSC \
219 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x1E)
220#define SCU_EVENT_SATA_15 \
221 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x1F)
222#define SCU_EVENT_SATA_30_SSC \
223 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x20)
224#define SCU_EVENT_SATA_30 \
225 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x21)
226#define SCU_EVENT_SATA_60_SSC \
227 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x22)
228#define SCU_EVENT_SATA_60 \
229 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x23)
230#define SCU_EVENT_SAS_PHY_DETECTED \
231 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x24)
232#define SCU_EVENT_SATA_PHY_DETECTED \
233 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x25)
234
235/**
236 *
237 *
238 * FATAL_INTERNAL_MEMORY_ERROR_EVENTS
239 */
240#define SCU_EVENT_TSC_RNSC_UNCORRECTABLE_ERROR \
241 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_FATAL_MEMORY_ERROR, 0x00)
242#define SCU_EVENT_TC_RNC_UNCORRECTABLE_ERROR \
243 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_FATAL_MEMORY_ERROR, 0x01)
244#define SCU_EVENT_ZPT_UNCORRECTABLE_ERROR \
245 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_FATAL_MEMORY_ERROR, 0x02)
246
247/**
248 *
249 *
250 * REMOTE_NODE_SUSPEND_EVENTS
251 */
252#define SCU_EVENT_TL_RNC_SUSPEND_TX \
253 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_SUSPEND_TX, 0x00)
254#define SCU_EVENT_TL_RNC_SUSPEND_TX_RX \
255 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX, 0x00)
256#define SCU_EVENT_DRIVER_POST_RNC_SUSPEND_TX \
257 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_SUSPEND_TX, 0x20)
258#define SCU_EVENT_DRIVER_POST_RNC_SUSPEND_TX_RX \
259 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX, 0x20)
260
261/**
262 *
263 *
264 * REMOTE_NODE_MISC_EVENTS
265 */
266#define SCU_EVENT_POST_RCN_RELEASE \
267 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_OPS_MISC, SCU_EVENT_SPECIFIER_RNC_RELEASE)
268#define SCU_EVENT_POST_IT_NEXUS_LOSS_TIMER_ENABLE \
269 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_OPS_MISC, 0x01)
270#define SCU_EVENT_POST_IT_NEXUS_LOSS_TIMER_DISABLE \
271 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_OPS_MISC, 0x02)
272#define SCU_EVENT_POST_RNC_COMPLETE \
273 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_OPS_MISC, 0x03)
274#define SCU_EVENT_POST_RNC_INVALIDATE_COMPLETE \
275 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_OPS_MISC, 0x04)
276
277/**
278 *
279 *
280 * ERROR_COUNT_EVENT
281 */
282#define SCU_EVENT_RX_CREDIT_BLOCKED_RECEIVED \
283 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_ERR_CNT_EVENT, 0x00)
284#define SCU_EVENT_TX_DONE_CREDIT_TIMEOUT \
285 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_ERR_CNT_EVENT, 0x01)
286#define SCU_EVENT_RX_DONE_CREDIT_TIMEOUT \
287 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_ERR_CNT_EVENT, 0x02)
288
289/**
290 * scu_get_event_type() -
291 *
292 * This macro returns the SCU event type from the event code.
293 */
294#define scu_get_event_type(event_code) \
295 ((event_code) & SCU_EVENT_TYPE_CODE_MASK)
296
297/**
298 * scu_get_event_specifier() -
299 *
300 * This macro returns the SCU event specifier from the event code.
301 */
302#define scu_get_event_specifier(event_code) \
303 ((event_code) & SCU_EVENT_SPECIFIC_CODE_MASK)
304
305/**
306 * scu_get_event_code() -
307 *
308 * This macro returns the combined SCU event type and SCU event specifier from
309 * the event code.
310 */
311#define scu_get_event_code(event_code) \
312 ((event_code) & SCU_EVENT_CODE_MASK)
313
314
315/**
316 *
317 *
318 * PTS_SCHEDULE_EVENT
319 */
320#define SCU_EVENT_SMP_RESPONSE_NO_PE \
321 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT, 0x00)
322#define SCU_EVENT_SPECIFIC_SMP_RESPONSE_NO_PE \
323 scu_get_event_specifier(SCU_EVENT_SMP_RESPONSE_NO_PE)
324
325#define SCU_EVENT_TASK_TIMEOUT \
326 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT, 0x01)
327#define SCU_EVENT_SPECIFIC_TASK_TIMEOUT \
328 scu_get_event_specifier(SCU_EVENT_TASK_TIMEOUT)
329
330#define SCU_EVENT_IT_NEXUS_TIMEOUT \
331 SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT, 0x02)
332#define SCU_EVENT_SPECIFIC_IT_NEXUS_TIMEOUT \
333 scu_get_event_specifier(SCU_EVENT_IT_NEXUS_TIMEOUT)
334
335
336#endif /* __SCU_EVENT_CODES_HEADER__ */
diff --git a/drivers/scsi/isci/core/scu_registers.h b/drivers/scsi/isci/core/scu_registers.h
new file mode 100644
index 000000000000..175d2b98bdf2
--- /dev/null
+++ b/drivers/scsi/isci/core/scu_registers.h
@@ -0,0 +1,1824 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCU_REGISTERS_H_
57#define _SCU_REGISTERS_H_
58
59/**
60 * This file contains the constants and structures for the SCU memory mapped
61 * registers.
62 *
63 *
64 */
65
66#include "sci_types.h"
67#include "scu_viit_data.h"
68
69
70/* Generate a value for an SCU register */
71#define SCU_GEN_VALUE(name, value) \
72 (((value) << name ## _SHIFT) & (name ## _MASK))
73
74/*
75 * Generate a bit value for an SCU register
76 * Make sure that the register MASK is just a single bit */
77#define SCU_GEN_BIT(name) \
78 SCU_GEN_VALUE(name, ((u32)1))
79
80#define SCU_SET_BIT(name, reg_value) \
81 ((reg_value) | SCU_GEN_BIT(name))
82
83#define SCU_CLEAR_BIT(name, reg_value) \
84 ((reg_value)$ ~(SCU_GEN_BIT(name)))
85
86/*
87 * *****************************************************************************
88 * Unions for bitfield definitions of SCU Registers
89 * SMU Post Context Port
90 * ***************************************************************************** */
91#define SMU_POST_CONTEXT_PORT_CONTEXT_INDEX_SHIFT (0)
92#define SMU_POST_CONTEXT_PORT_CONTEXT_INDEX_MASK (0x00000FFF)
93#define SMU_POST_CONTEXT_PORT_LOGICAL_PORT_INDEX_SHIFT (12)
94#define SMU_POST_CONTEXT_PORT_LOGICAL_PORT_INDEX_MASK (0x0000F000)
95#define SMU_POST_CONTEXT_PORT_PROTOCOL_ENGINE_SHIFT (16)
96#define SMU_POST_CONTEXT_PORT_PROTOCOL_ENGINE_MASK (0x00030000)
97#define SMU_POST_CONTEXT_PORT_COMMAND_CONTEXT_SHIFT (18)
98#define SMU_POST_CONTEXT_PORT_COMMAND_CONTEXT_MASK (0x00FC0000)
99#define SMU_POST_CONTEXT_PORT_RESERVED_MASK (0xFF000000)
100
101#define SMU_PCP_GEN_VAL(name, value) \
102 SCU_GEN_VALUE(SMU_POST_CONTEXT_PORT_ ## name, value)
103
104/* ***************************************************************************** */
105#define SMU_INTERRUPT_STATUS_COMPLETION_SHIFT (31)
106#define SMU_INTERRUPT_STATUS_COMPLETION_MASK (0x80000000)
107#define SMU_INTERRUPT_STATUS_QUEUE_SUSPEND_SHIFT (1)
108#define SMU_INTERRUPT_STATUS_QUEUE_SUSPEND_MASK (0x00000002)
109#define SMU_INTERRUPT_STATUS_QUEUE_ERROR_SHIFT (0)
110#define SMU_INTERRUPT_STATUS_QUEUE_ERROR_MASK (0x00000001)
111#define SMU_INTERRUPT_STATUS_RESERVED_MASK (0x7FFFFFFC)
112
113#define SMU_ISR_GEN_BIT(name) \
114 SCU_GEN_BIT(SMU_INTERRUPT_STATUS_ ## name)
115
116#define SMU_ISR_QUEUE_ERROR SMU_ISR_GEN_BIT(QUEUE_ERROR)
117#define SMU_ISR_QUEUE_SUSPEND SMU_ISR_GEN_BIT(QUEUE_SUSPEND)
118#define SMU_ISR_COMPLETION SMU_ISR_GEN_BIT(COMPLETION)
119
120/* ***************************************************************************** */
121#define SMU_INTERRUPT_MASK_COMPLETION_SHIFT (31)
122#define SMU_INTERRUPT_MASK_COMPLETION_MASK (0x80000000)
123#define SMU_INTERRUPT_MASK_QUEUE_SUSPEND_SHIFT (1)
124#define SMU_INTERRUPT_MASK_QUEUE_SUSPEND_MASK (0x00000002)
125#define SMU_INTERRUPT_MASK_QUEUE_ERROR_SHIFT (0)
126#define SMU_INTERRUPT_MASK_QUEUE_ERROR_MASK (0x00000001)
127#define SMU_INTERRUPT_MASK_RESERVED_MASK (0x7FFFFFFC)
128
129#define SMU_IMR_GEN_BIT(name) \
130 SCU_GEN_BIT(SMU_INTERRUPT_MASK_ ## name)
131
132#define SMU_IMR_QUEUE_ERROR SMU_IMR_GEN_BIT(QUEUE_ERROR)
133#define SMU_IMR_QUEUE_SUSPEND SMU_IMR_GEN_BIT(QUEUE_SUSPEND)
134#define SMU_IMR_COMPLETION SMU_IMR_GEN_BIT(COMPLETION)
135
136/* ***************************************************************************** */
137#define SMU_INTERRUPT_COALESCING_CONTROL_TIMER_SHIFT (0)
138#define SMU_INTERRUPT_COALESCING_CONTROL_TIMER_MASK (0x0000001F)
139#define SMU_INTERRUPT_COALESCING_CONTROL_NUMBER_SHIFT (8)
140#define SMU_INTERRUPT_COALESCING_CONTROL_NUMBER_MASK (0x0000FF00)
141#define SMU_INTERRUPT_COALESCING_CONTROL_RESERVED_MASK (0xFFFF00E0)
142
143#define SMU_ICC_GEN_VAL(name, value) \
144 SCU_GEN_VALUE(SMU_INTERRUPT_COALESCING_CONTROL_ ## name, value)
145
146/* ***************************************************************************** */
147#define SMU_TASK_CONTEXT_RANGE_START_SHIFT (0)
148#define SMU_TASK_CONTEXT_RANGE_START_MASK (0x00000FFF)
149#define SMU_TASK_CONTEXT_RANGE_ENDING_SHIFT (16)
150#define SMU_TASK_CONTEXT_RANGE_ENDING_MASK (0x0FFF0000)
151#define SMU_TASK_CONTEXT_RANGE_ENABLE_SHIFT (31)
152#define SMU_TASK_CONTEXT_RANGE_ENABLE_MASK (0x80000000)
153#define SMU_TASK_CONTEXT_RANGE_RESERVED_MASK (0x7000F000)
154
155#define SMU_TCR_GEN_VAL(name, value) \
156 SCU_GEN_VALUE(SMU_TASK_CONTEXT_RANGE_ ## name, value)
157
158#define SMU_TCR_GEN_BIT(name, value) \
159 SCU_GEN_BIT(SMU_TASK_CONTEXT_RANGE_ ## name)
160
161/* ***************************************************************************** */
162
163#define SMU_COMPLETION_QUEUE_PUT_POINTER_SHIFT (0)
164#define SMU_COMPLETION_QUEUE_PUT_POINTER_MASK (0x00003FFF)
165#define SMU_COMPLETION_QUEUE_PUT_CYCLE_BIT_SHIFT (15)
166#define SMU_COMPLETION_QUEUE_PUT_CYCLE_BIT_MASK (0x00008000)
167#define SMU_COMPLETION_QUEUE_PUT_EVENT_POINTER_SHIFT (16)
168#define SMU_COMPLETION_QUEUE_PUT_EVENT_POINTER_MASK (0x03FF0000)
169#define SMU_COMPLETION_QUEUE_PUT_EVENT_CYCLE_BIT_SHIFT (26)
170#define SMU_COMPLETION_QUEUE_PUT_EVENT_CYCLE_BIT_MASK (0x04000000)
171#define SMU_COMPLETION_QUEUE_PUT_RESERVED_MASK (0xF8004000)
172
173#define SMU_CQPR_GEN_VAL(name, value) \
174 SCU_GEN_VALUE(SMU_COMPLETION_QUEUE_PUT_ ## name, value)
175
176#define SMU_CQPR_GEN_BIT(name) \
177 SCU_GEN_BIT(SMU_COMPLETION_QUEUE_PUT_ ## name)
178
179/* ***************************************************************************** */
180
181#define SMU_COMPLETION_QUEUE_GET_POINTER_SHIFT (0)
182#define SMU_COMPLETION_QUEUE_GET_POINTER_MASK (0x00003FFF)
183#define SMU_COMPLETION_QUEUE_GET_CYCLE_BIT_SHIFT (15)
184#define SMU_COMPLETION_QUEUE_GET_CYCLE_BIT_MASK (0x00008000)
185#define SMU_COMPLETION_QUEUE_GET_EVENT_POINTER_SHIFT (16)
186#define SMU_COMPLETION_QUEUE_GET_EVENT_POINTER_MASK (0x03FF0000)
187#define SMU_COMPLETION_QUEUE_GET_EVENT_CYCLE_BIT_SHIFT (26)
188#define SMU_COMPLETION_QUEUE_GET_EVENT_CYCLE_BIT_MASK (0x04000000)
189#define SMU_COMPLETION_QUEUE_GET_ENABLE_SHIFT (30)
190#define SMU_COMPLETION_QUEUE_GET_ENABLE_MASK (0x40000000)
191#define SMU_COMPLETION_QUEUE_GET_EVENT_ENABLE_SHIFT (31)
192#define SMU_COMPLETION_QUEUE_GET_EVENT_ENABLE_MASK (0x80000000)
193#define SMU_COMPLETION_QUEUE_GET_RESERVED_MASK (0x38004000)
194
195#define SMU_CQGR_GEN_VAL(name, value) \
196 SCU_GEN_VALUE(SMU_COMPLETION_QUEUE_GET_ ## name, value)
197
198#define SMU_CQGR_GEN_BIT(name) \
199 SCU_GEN_BIT(SMU_COMPLETION_QUEUE_GET_ ## name)
200
201#define SMU_CQGR_CYCLE_BIT \
202 SMU_CQGR_GEN_BIT(CYCLE_BIT)
203
204#define SMU_CQGR_EVENT_CYCLE_BIT \
205 SMU_CQGR_GEN_BIT(EVENT_CYCLE_BIT)
206
207#define SMU_CQGR_GET_POINTER_SET(value) \
208 SMU_CQGR_GEN_VAL(POINTER, value)
209
210
211/* ***************************************************************************** */
212#define SMU_COMPLETION_QUEUE_CONTROL_QUEUE_LIMIT_SHIFT (0)
213#define SMU_COMPLETION_QUEUE_CONTROL_QUEUE_LIMIT_MASK (0x00003FFF)
214#define SMU_COMPLETION_QUEUE_CONTROL_EVENT_LIMIT_SHIFT (16)
215#define SMU_COMPLETION_QUEUE_CONTROL_EVENT_LIMIT_MASK (0x03FF0000)
216#define SMU_COMPLETION_QUEUE_CONTROL_RESERVED_MASK (0xFC00C000)
217
218#define SMU_CQC_GEN_VAL(name, value) \
219 SCU_GEN_VALUE(SMU_COMPLETION_QUEUE_CONTROL_ ## name, value)
220
221#define SMU_CQC_QUEUE_LIMIT_SET(value) \
222 SMU_CQC_GEN_VAL(QUEUE_LIMIT, value)
223
224#define SMU_CQC_EVENT_LIMIT_SET(value) \
225 SMU_CQC_GEN_VAL(EVENT_LIMIT, value)
226
227
228/* ***************************************************************************** */
229#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_SHIFT (0)
230#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_MASK (0x00000FFF)
231#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_SHIFT (12)
232#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_MASK (0x00007000)
233#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_SHIFT (15)
234#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_MASK (0x07FF8000)
235#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_PEG_SHIFT (27)
236#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_PEG_MASK (0x08000000)
237#define SMU_DEVICE_CONTEXT_CAPACITY_RESERVED_MASK (0xF0000000)
238
239#define SMU_DCC_GEN_VAL(name, value) \
240 SCU_GEN_VALUE(SMU_DEVICE_CONTEXT_CAPACITY_ ## name, value)
241
242#define SMU_DCC_GET_MAX_PEG(value) \
243 (\
244 ((value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_PEG_MASK) \
245 >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_SHIFT \
246 )
247
248#define SMU_DCC_GET_MAX_LP(value) \
249 (\
250 ((value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_MASK) \
251 >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_SHIFT \
252 )
253
254#define SMU_DCC_GET_MAX_TC(value) \
255 (\
256 ((value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_MASK) \
257 >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_SHIFT \
258 )
259
260#define SMU_DCC_GET_MAX_RNC(value) \
261 (\
262 ((value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_MASK) \
263 >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_SHIFT \
264 )
265
266/* -------------------------------------------------------------------------- */
267
268#define SMU_CONTROL_STATUS_TASK_CONTEXT_RANGE_ENABLE_SHIFT (0)
269#define SMU_CONTROL_STATUS_TASK_CONTEXT_RANGE_ENABLE_MASK (0x00000001)
270#define SMU_CONTROL_STATUS_COMPLETION_BYTE_SWAP_ENABLE_SHIFT (1)
271#define SMU_CONTROL_STATUS_COMPLETION_BYTE_SWAP_ENABLE_MASK (0x00000002)
272#define SMU_CONTROL_STATUS_CONTEXT_RAM_INIT_COMPLETED_SHIFT (16)
273#define SMU_CONTROL_STATUS_CONTEXT_RAM_INIT_COMPLETED_MASK (0x00010000)
274#define SMU_CONTROL_STATUS_SCHEDULER_RAM_INIT_COMPLETED_SHIFT (17)
275#define SMU_CONTROL_STATUS_SCHEDULER_RAM_INIT_COMPLETED_MASK (0x00020000)
276#define SMU_CONTROL_STATUS_RESERVED_MASK (0xFFFCFFFC)
277
278#define SMU_SMUCSR_GEN_BIT(name) \
279 SCU_GEN_BIT(SMU_CONTROL_STATUS_ ## name)
280
281#define SMU_SMUCSR_SCHEDULER_RAM_INIT_COMPLETED \
282 (SMU_SMUCSR_GEN_BIT(SCHEDULER_RAM_INIT_COMPLETED))
283
284#define SMU_SMUCSR_CONTEXT_RAM_INIT_COMPLETED \
285 (SMU_SMUCSR_GEN_BIT(CONTEXT_RAM_INIT_COMPLETED))
286
287#define SCU_RAM_INIT_COMPLETED \
288 (\
289 SMU_SMUCSR_CONTEXT_RAM_INIT_COMPLETED \
290 | SMU_SMUCSR_SCHEDULER_RAM_INIT_COMPLETED \
291 )
292
293/* -------------------------------------------------------------------------- */
294
295#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE0_SHIFT (0)
296#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE0_MASK (0x00000001)
297#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE1_SHIFT (1)
298#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE1_MASK (0x00000002)
299#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE2_SHIFT (2)
300#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE2_MASK (0x00000004)
301#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE3_SHIFT (3)
302#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE3_MASK (0x00000008)
303#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE0_SHIFT (8)
304#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE0_MASK (0x00000100)
305#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE1_SHIFT (9)
306#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE1_MASK (0x00000200)
307#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE2_SHIFT (10)
308#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE2_MASK (0x00000400)
309#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE3_SHIFT (11)
310#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE3_MASK (0x00000800)
311
312#define SMU_RESET_PROTOCOL_ENGINE(peg, pe) \
313 ((1 << (pe)) << ((peg) * 8))
314
315#define SMU_RESET_PEG_PROTOCOL_ENGINES(peg) \
316 (\
317 SMU_RESET_PROTOCOL_ENGINE(peg, 0) \
318 | SMU_RESET_PROTOCOL_ENGINE(peg, 1) \
319 | SMU_RESET_PROTOCOL_ENGINE(peg, 2) \
320 | SMU_RESET_PROTOCOL_ENGINE(peg, 3) \
321 )
322
323#define SMU_RESET_ALL_PROTOCOL_ENGINES() \
324 (\
325 SMU_RESET_PEG_PROTOCOL_ENGINES(0) \
326 | SMU_RESET_PEG_PROTOCOL_ENGINES(1) \
327 )
328
329#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG0_LP0_SHIFT (16)
330#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG0_LP0_MASK (0x00010000)
331#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG0_LP2_SHIFT (17)
332#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG0_LP2_MASK (0x00020000)
333#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG1_LP0_SHIFT (18)
334#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG1_LP0_MASK (0x00040000)
335#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG1_LP2_SHIFT (19)
336#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG1_LP2_MASK (0x00080000)
337
338#define SMU_RESET_WIDE_PORT_QUEUE(peg, wide_port) \
339 ((1 << ((wide_port) / 2)) << ((peg) * 2) << 16)
340
341#define SMU_SOFTRESET_CONTROL_RESET_PEG0_SHIFT (20)
342#define SMU_SOFTRESET_CONTROL_RESET_PEG0_MASK (0x00100000)
343#define SMU_SOFTRESET_CONTROL_RESET_PEG1_SHIFT (21)
344#define SMU_SOFTRESET_CONTROL_RESET_PEG1_MASK (0x00200000)
345#define SMU_SOFTRESET_CONTROL_RESET_SCU_SHIFT (22)
346#define SMU_SOFTRESET_CONTROL_RESET_SCU_MASK (0x00400000)
347
348/*
349 * It seems to make sense that if you are going to reset the protocol
350 * engine group that you would also reset all of the protocol engines */
351#define SMU_RESET_PROTOCOL_ENGINE_GROUP(peg) \
352 (\
353 (1 << ((peg) + 20)) \
354 | SMU_RESET_WIDE_PORT_QUEUE(peg, 0) \
355 | SMU_RESET_WIDE_PORT_QUEUE(peg, 1) \
356 | SMU_RESET_PEG_PROTOCOL_ENGINES(peg) \
357 )
358
359#define SMU_RESET_ALL_PROTOCOL_ENGINE_GROUPS() \
360 (\
361 SMU_RESET_PROTOCOL_ENGINE_GROUP(0) \
362 | SMU_RESET_PROTOCOL_ENGINE_GROUP(1) \
363 )
364
365#define SMU_RESET_SCU() (0xFFFFFFFF)
366
367
368
369/* ***************************************************************************** */
370#define SMU_TASK_CONTEXT_ASSIGNMENT_STARTING_SHIFT (0)
371#define SMU_TASK_CONTEXT_ASSIGNMENT_STARTING_MASK (0x00000FFF)
372#define SMU_TASK_CONTEXT_ASSIGNMENT_ENDING_SHIFT (16)
373#define SMU_TASK_CONTEXT_ASSIGNMENT_ENDING_MASK (0x0FFF0000)
374#define SMU_TASK_CONTEXT_ASSIGNMENT_RANGE_CHECK_ENABLE_SHIFT (31)
375#define SMU_TASK_CONTEXT_ASSIGNMENT_RANGE_CHECK_ENABLE_MASK (0x80000000)
376#define SMU_TASK_CONTEXT_ASSIGNMENT_RESERVED_MASK (0x7000F000)
377
378#define SMU_TCA_GEN_VAL(name, value) \
379 SCU_GEN_VALUE(SMU_TASK_CONTEXT_ASSIGNMENT_ ## name, value)
380
381#define SMU_TCA_GEN_BIT(name) \
382 SCU_GEN_BIT(SMU_TASK_CONTEXT_ASSIGNMENT_ ## name)
383
384/* ***************************************************************************** */
385#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_CONTROL_QUEUE_SIZE_SHIFT (0)
386#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_CONTROL_QUEUE_SIZE_MASK (0x00000FFF)
387#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_CONTROL_RESERVED_MASK (0xFFFFF000)
388
389#define SCU_UFQC_GEN_VAL(name, value) \
390 SCU_GEN_VALUE(SCU_SDMA_UNSOLICITED_FRAME_QUEUE_CONTROL_ ## name, value)
391
392#define SCU_UFQC_QUEUE_SIZE_SET(value) \
393 SCU_UFQC_GEN_VAL(QUEUE_SIZE, value)
394
395/* ***************************************************************************** */
396#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_PUT_POINTER_SHIFT (0)
397#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_PUT_POINTER_MASK (0x00000FFF)
398#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_PUT_CYCLE_BIT_SHIFT (12)
399#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_PUT_CYCLE_BIT_MASK (0x00001000)
400#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_PUT_RESERVED_MASK (0xFFFFE000)
401
402#define SCU_UFQPP_GEN_VAL(name, value) \
403 SCU_GEN_VALUE(SCU_SDMA_UNSOLICITED_FRAME_QUEUE_PUT_ ## name, value)
404
405#define SCU_UFQPP_GEN_BIT(name) \
406 SCU_GEN_BIT(SCU_SDMA_UNSOLICITED_FRAME_QUEUE_PUT_ ## name)
407
408/*
409 * *****************************************************************************
410 * * SDMA Registers
411 * ***************************************************************************** */
412#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_POINTER_SHIFT (0)
413#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_POINTER_MASK (0x00000FFF)
414#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_CYCLE_BIT_SHIFT (12)
415#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_CYCLE_BIT_MASK (12)
416#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_ENABLE_BIT_SHIFT (31)
417#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_ENABLE_BIT_MASK (0x80000000)
418#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_RESERVED_MASK (0x7FFFE000)
419
420#define SCU_UFQGP_GEN_VAL(name, value) \
421 SCU_GEN_VALUE(SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_ ## name, value)
422
423#define SCU_UFQGP_GEN_BIT(name) \
424 SCU_GEN_BIT(SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_ ## name)
425
426#define SCU_UFQGP_CYCLE_BIT(value) \
427 SCU_UFQGP_GEN_BIT(CYCLE_BIT, value)
428
429#define SCU_UFQGP_GET_POINTER(value) \
430 SCU_UFQGP_GEN_VALUE(POINTER, value)
431
432#define SCU_UFQGP_ENABLE(value) \
433 (SCU_UFQGP_GEN_BIT(ENABLE) | value)
434
435#define SCU_UFQGP_DISABLE(value) \
436 (~SCU_UFQGP_GEN_BIT(ENABLE) & value)
437
438#define SCU_UFQGP_VALUE(bit, value) \
439 (SCU_UFQGP_CYCLE_BIT(bit) | SCU_UFQGP_GET_POINTER(value))
440
441/* ***************************************************************************** */
442#define SCU_PDMA_CONFIGURATION_ADDRESS_MODIFIER_SHIFT (0)
443#define SCU_PDMA_CONFIGURATION_ADDRESS_MODIFIER_MASK (0x0000FFFF)
444#define SCU_PDMA_CONFIGURATION_PCI_RELAXED_ORDERING_ENABLE_SHIFT (16)
445#define SCU_PDMA_CONFIGURATION_PCI_RELAXED_ORDERING_ENABLE_MASK (0x00010000)
446#define SCU_PDMA_CONFIGURATION_PCI_NO_SNOOP_ENABLE_SHIFT (17)
447#define SCU_PDMA_CONFIGURATION_PCI_NO_SNOOP_ENABLE_MASK (0x00020000)
448#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_BYTE_SWAP_SHIFT (18)
449#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_BYTE_SWAP_MASK (0x00040000)
450#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_XPI_SGL_FETCH_SHIFT (19)
451#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_XPI_SGL_FETCH_MASK (0x00080000)
452#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_XPI_RX_HEADER_RAM_WRITE_SHIFT (20)
453#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_XPI_RX_HEADER_RAM_WRITE_MASK (0x00100000)
454#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_XPI_UF_ADDRESS_FETCH_SHIFT (21)
455#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_XPI_UF_ADDRESS_FETCH_MASK (0x00200000)
456#define SCU_PDMA_CONFIGURATION_ADDRESS_MODIFIER_SELECT_SHIFT (22)
457#define SCU_PDMA_CONFIGURATION_ADDRESS_MODIFIER_SELECT_MASK (0x00400000)
458#define SCU_PDMA_CONFIGURATION_RESERVED_MASK (0xFF800000)
459
460#define SCU_PDMACR_GEN_VALUE(name, value) \
461 SCU_GEN_VALUE(SCU_PDMA_CONFIGURATION_ ## name, value)
462
463#define SCU_PDMACR_GEN_BIT(name) \
464 SCU_GEN_BIT(SCU_PDMA_CONFIGURATION_ ## name)
465
466#define SCU_PDMACR_BE_GEN_BIT(name) \
467 SCU_PCMACR_GEN_BIT(BIG_ENDIAN_CONTROL_ ## name)
468
469/* ***************************************************************************** */
470#define SCU_CDMA_CONFIGURATION_PCI_RELAXED_ORDERING_ENABLE_SHIFT (8)
471#define SCU_CDMA_CONFIGURATION_PCI_RELAXED_ORDERING_ENABLE_MASK (0x00000100)
472
473#define SCU_CDMACR_GEN_BIT(name) \
474 SCU_GEN_BIT(SCU_CDMA_CONFIGURATION_ ## name)
475
476/*
477 * *****************************************************************************
478 * * SCU Link Layer Registers
479 * ***************************************************************************** */
480#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_TIMEOUT_SHIFT (0)
481#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_TIMEOUT_MASK (0x000000FF)
482#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_LOCK_TIME_SHIFT (8)
483#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_LOCK_TIME_MASK (0x0000FF00)
484#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_RATE_CHANGE_DELAY_SHIFT (16)
485#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_RATE_CHANGE_DELAY_MASK (0x00FF0000)
486#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_DWORD_SYNC_TIMEOUT_SHIFT (24)
487#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_DWORD_SYNC_TIMEOUT_MASK (0xFF000000)
488#define SCU_LINK_LAYER_SPEED_NECGOIATION_TIMER_VALUES_REQUIRED_MASK (0x00000000)
489#define SCU_LINK_LAYER_SPEED_NECGOIATION_TIMER_VALUES_DEFAULT_MASK (0x7D00676F)
490#define SCU_LINK_LAYER_SPEED_NECGOIATION_TIMER_VALUES_RESERVED_MASK (0x00FF0000)
491
492#define SCU_SAS_SPDTOV_GEN_VALUE(name, value) \
493 SCU_GEN_VALUE(SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_ ## name, value)
494
495
496#define SCU_LINK_STATUS_DWORD_SYNC_AQUIRED_SHIFT (2)
497#define SCU_LINK_STATUS_DWORD_SYNC_AQUIRED_MASK (0x00000004)
498#define SCU_LINK_STATUS_TRANSMIT_PORT_SELECTION_DONE_SHIFT (4)
499#define SCU_LINK_STATUS_TRANSMIT_PORT_SELECTION_DONE_MASK (0x00000010)
500#define SCU_LINK_STATUS_RECEIVER_CREDIT_EXHAUSTED_SHIFT (5)
501#define SCU_LINK_STATUS_RECEIVER_CREDIT_EXHAUSTED_MASK (0x00000020)
502#define SCU_LINK_STATUS_RESERVED_MASK (0xFFFFFFCD)
503
504#define SCU_SAS_LLSTA_GEN_BIT(name) \
505 SCU_GEN_BIT(SCU_LINK_STATUS_ ## name)
506
507
508/* TODO: Where is the SATA_PSELTOV register? */
509
510/*
511 * *****************************************************************************
512 * * SCU SAS Maximum Arbitration Wait Time Timeout Register
513 * ***************************************************************************** */
514#define SCU_SAS_MAX_ARBITRATION_WAIT_TIME_TIMEOUT_VALUE_SHIFT (0)
515#define SCU_SAS_MAX_ARBITRATION_WAIT_TIME_TIMEOUT_VALUE_MASK (0x00007FFF)
516#define SCU_SAS_MAX_ARBITRATION_WAIT_TIME_TIMEOUT_SCALE_SHIFT (15)
517#define SCU_SAS_MAX_ARBITRATION_WAIT_TIME_TIMEOUT_SCALE_MASK (0x00008000)
518
519#define SCU_SAS_MAWTTOV_GEN_VALUE(name, value) \
520 SCU_GEN_VALUE(SCU_SAS_MAX_ARBITRATION_WAIT_TIME_TIMEOUT_ ## name, value)
521
522#define SCU_SAS_MAWTTOV_GEN_BIT(name) \
523 SCU_GEN_BIT(SCU_SAS_MAX_ARBITRATION_WAIT_TIME_TIMEOUT_ ## name)
524
525
526/*
527 * TODO: Where is the SAS_LNKTOV regsiter?
528 * TODO: Where is the SAS_PHYTOV register? */
529
530#define SCU_SAS_TRANSMIT_IDENTIFICATION_SMP_TARGET_SHIFT (1)
531#define SCU_SAS_TRANSMIT_IDENTIFICATION_SMP_TARGET_MASK (0x00000002)
532#define SCU_SAS_TRANSMIT_IDENTIFICATION_STP_TARGET_SHIFT (2)
533#define SCU_SAS_TRANSMIT_IDENTIFICATION_STP_TARGET_MASK (0x00000004)
534#define SCU_SAS_TRANSMIT_IDENTIFICATION_SSP_TARGET_SHIFT (3)
535#define SCU_SAS_TRANSMIT_IDENTIFICATION_SSP_TARGET_MASK (0x00000008)
536#define SCU_SAS_TRANSMIT_IDENTIFICATION_DA_SATA_HOST_SHIFT (8)
537#define SCU_SAS_TRANSMIT_IDENTIFICATION_DA_SATA_HOST_MASK (0x00000100)
538#define SCU_SAS_TRANSMIT_IDENTIFICATION_SMP_INITIATOR_SHIFT (9)
539#define SCU_SAS_TRANSMIT_IDENTIFICATION_SMP_INITIATOR_MASK (0x00000200)
540#define SCU_SAS_TRANSMIT_IDENTIFICATION_STP_INITIATOR_SHIFT (10)
541#define SCU_SAS_TRANSMIT_IDENTIFICATION_STP_INITIATOR_MASK (0x00000400)
542#define SCU_SAS_TRANSMIT_IDENTIFICATION_SSP_INITIATOR_SHIFT (11)
543#define SCU_SAS_TRANSMIT_IDENTIFICATION_SSP_INITIATOR_MASK (0x00000800)
544#define SCU_SAS_TRANSMIT_IDENTIFICATION_REASON_CODE_SHIFT (16)
545#define SCU_SAS_TRANSMIT_IDENTIFICATION_REASON_CODE_MASK (0x000F0000)
546#define SCU_SAS_TRANSMIT_IDENTIFICATION_ADDRESS_FRAME_TYPE_SHIFT (24)
547#define SCU_SAS_TRANSMIT_IDENTIFICATION_ADDRESS_FRAME_TYPE_MASK (0x0F000000)
548#define SCU_SAS_TRANSMIT_IDENTIFICATION_DEVICE_TYPE_SHIFT (28)
549#define SCU_SAS_TRANSMIT_IDENTIFICATION_DEVICE_TYPE_MASK (0x70000000)
550#define SCU_SAS_TRANSMIT_IDENTIFICATION_RESERVED_MASK (0x80F0F1F1)
551
552#define SCU_SAS_TIID_GEN_VAL(name, value) \
553 SCU_GEN_VALUE(SCU_SAS_TRANSMIT_IDENTIFICATION_ ## name, value)
554
555#define SCU_SAS_TIID_GEN_BIT(name) \
556 SCU_GEN_BIT(SCU_SAS_TRANSMIT_IDENTIFICATION_ ## name)
557
558/* SAS Identify Frame PHY Identifier Register */
559#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_BREAK_REPLY_CAPABLE_SHIFT (16)
560#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_BREAK_REPLY_CAPABLE_MASK (0x00010000)
561#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_REQUESTED_INSIDE_ZPSDS_SHIFT (17)
562#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_REQUESTED_INSIDE_ZPSDS_MASK (0x00020000)
563#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_INSIDE_ZPSDS_PERSISTENT_SHIFT (18)
564#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_INSIDE_ZPSDS_PERSISTENT_MASK (0x00040000)
565#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_ID_SHIFT (24)
566#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_ID_MASK (0xFF000000)
567#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_RESERVED_MASK (0x00F800FF)
568
569#define SCU_SAS_TIPID_GEN_VALUE(name, value) \
570 SCU_GEN_VALUE(SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_ ## name, value)
571
572#define SCU_SAS_TIPID_GEN_BIT(name) \
573 SCU_GEN_BIT(SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_ ## name)
574
575
576#define SCU_SAS_PHY_CONFIGURATION_TX_PARITY_CHECK_SHIFT (4)
577#define SCU_SAS_PHY_CONFIGURATION_TX_PARITY_CHECK_MASK (0x00000010)
578#define SCU_SAS_PHY_CONFIGURATION_TX_BAD_CRC_SHIFT (6)
579#define SCU_SAS_PHY_CONFIGURATION_TX_BAD_CRC_MASK (0x00000040)
580#define SCU_SAS_PHY_CONFIGURATION_DISABLE_SCRAMBLER_SHIFT (7)
581#define SCU_SAS_PHY_CONFIGURATION_DISABLE_SCRAMBLER_MASK (0x00000080)
582#define SCU_SAS_PHY_CONFIGURATION_DISABLE_DESCRAMBLER_SHIFT (8)
583#define SCU_SAS_PHY_CONFIGURATION_DISABLE_DESCRAMBLER_MASK (0x00000100)
584#define SCU_SAS_PHY_CONFIGURATION_DISABLE_CREDIT_INSERTION_SHIFT (9)
585#define SCU_SAS_PHY_CONFIGURATION_DISABLE_CREDIT_INSERTION_MASK (0x00000200)
586#define SCU_SAS_PHY_CONFIGURATION_SUSPEND_PROTOCOL_ENGINE_SHIFT (11)
587#define SCU_SAS_PHY_CONFIGURATION_SUSPEND_PROTOCOL_ENGINE_MASK (0x00000800)
588#define SCU_SAS_PHY_CONFIGURATION_SATA_SPINUP_HOLD_SHIFT (12)
589#define SCU_SAS_PHY_CONFIGURATION_SATA_SPINUP_HOLD_MASK (0x00001000)
590#define SCU_SAS_PHY_CONFIGURATION_TRANSMIT_PORT_SELECTION_SIGNAL_SHIFT (13)
591#define SCU_SAS_PHY_CONFIGURATION_TRANSMIT_PORT_SELECTION_SIGNAL_MASK (0x00002000)
592#define SCU_SAS_PHY_CONFIGURATION_HARD_RESET_SHIFT (14)
593#define SCU_SAS_PHY_CONFIGURATION_HARD_RESET_MASK (0x00004000)
594#define SCU_SAS_PHY_CONFIGURATION_OOB_ENABLE_SHIFT (15)
595#define SCU_SAS_PHY_CONFIGURATION_OOB_ENABLE_MASK (0x00008000)
596#define SCU_SAS_PHY_CONFIGURATION_ENABLE_FRAME_TX_INSERT_ALIGN_SHIFT (23)
597#define SCU_SAS_PHY_CONFIGURATION_ENABLE_FRAME_TX_INSERT_ALIGN_MASK (0x00800000)
598#define SCU_SAS_PHY_CONFIGURATION_FORWARD_IDENTIFY_FRAME_SHIFT (27)
599#define SCU_SAS_PHY_CONFIGURATION_FORWARD_IDENTIFY_FRAME_MASK (0x08000000)
600#define SCU_SAS_PHY_CONFIGURATION_DISABLE_BYTE_TRANSPOSE_STP_FRAME_SHIFT (28)
601#define SCU_SAS_PHY_CONFIGURATION_DISABLE_BYTE_TRANSPOSE_STP_FRAME_MASK (0x10000000)
602#define SCU_SAS_PHY_CONFIGURATION_OOB_RESET_SHIFT (29)
603#define SCU_SAS_PHY_CONFIGURATION_OOB_RESET_MASK (0x20000000)
604#define SCU_SAS_PHY_CONFIGURATION_THREE_IAF_ENABLE_SHIFT (30)
605#define SCU_SAS_PHY_CONFIGURATION_THREE_IAF_ENABLE_MASK (0x40000000)
606#define SCU_SAS_PHY_CONFIGURATION_OOB_ALIGN0_ENABLE_SHIFT (31)
607#define SCU_SAS_PHY_CONFIGURATION_OOB_ALIGN0_ENABLE_MASK (0x80000000)
608#define SCU_SAS_PHY_CONFIGURATION_REQUIRED_MASK (0x0100000F)
609#define SCU_SAS_PHY_CONFIGURATION_DEFAULT_MASK (0x4180100F)
610#define SCU_SAS_PHY_CONFIGURATION_RESERVED_MASK (0x00000000)
611
612#define SCU_SAS_PCFG_GEN_BIT(name) \
613 SCU_GEN_BIT(SCU_SAS_PHY_CONFIGURATION_ ## name)
614
615
616#define SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_COUNT_SHIFT (0)
617#define SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_COUNT_MASK (0x0003FFFF)
618#define SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_ENABLE_SHIFT (31)
619#define SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_ENABLE_MASK (0x80000000)
620#define SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_RESERVED_MASK (0x7FFC0000)
621
622#define SCU_ENSPINUP_GEN_VAL(name, value) \
623 SCU_GEN_VALUE(SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_ ## name, value)
624
625#define SCU_ENSPINUP_GEN_BIT(name) \
626 SCU_GEN_BIT(SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_ ## name)
627
628
629#define SCU_LINK_LAYER_PHY_CAPABILITIES_TXSSCTYPE_SHIFT (1)
630#define SCU_LINK_LAYER_PHY_CAPABILITIES_TXSSCTYPE_MASK (0x00000002)
631#define SCU_LINK_LAYER_PHY_CAPABILITIES_RLLRATE_SHIFT (4)
632#define SCU_LINK_LAYER_PHY_CAPABILITIES_RLLRATE_MASK (0x000000F0)
633#define SCU_LINK_LAYER_PHY_CAPABILITIES_SWO15GBPS_SHIFT (8)
634#define SCU_LINK_LAYER_PHY_CAPABILITIES_SWO15GBPS_MASK (0x00000100)
635#define SCU_LINK_LAYER_PHY_CAPABILITIES_SW15GBPS_SHIFT (9)
636#define SCU_LINK_LAYER_PHY_CAPABILITIES_SW15GBPS_MASK (0x00000201)
637#define SCU_LINK_LAYER_PHY_CAPABILITIES_SWO30GBPS_SHIFT (10)
638#define SCU_LINK_LAYER_PHY_CAPABILITIES_SWO30GBPS_MASK (0x00000401)
639#define SCU_LINK_LAYER_PHY_CAPABILITIES_SW30GBPS_SHIFT (11)
640#define SCU_LINK_LAYER_PHY_CAPABILITIES_SW30GBPS_MASK (0x00000801)
641#define SCU_LINK_LAYER_PHY_CAPABILITIES_SWO60GBPS_SHIFT (12)
642#define SCU_LINK_LAYER_PHY_CAPABILITIES_SWO60GBPS_MASK (0x00001001)
643#define SCU_LINK_LAYER_PHY_CAPABILITIES_SW60GBPS_SHIFT (13)
644#define SCU_LINK_LAYER_PHY_CAPABILITIES_SW60GBPS_MASK (0x00002001)
645#define SCU_LINK_LAYER_PHY_CAPABILITIES_EVEN_PARITY_SHIFT (31)
646#define SCU_LINK_LAYER_PHY_CAPABILITIES_EVEN_PARITY_MASK (0x80000000)
647#define SCU_LINK_LAYER_PHY_CAPABILITIES_DEFAULT_MASK (0x00003F01)
648#define SCU_LINK_LAYER_PHY_CAPABILITIES_REQUIRED_MASK (0x00000001)
649#define SCU_LINK_LAYER_PHY_CAPABILITIES_RESERVED_MASK (0x7FFFC00D)
650
651#define SCU_SAS_PHYCAP_GEN_VAL(name, value) \
652 SCU_GEN_VALUE(SCU_LINK_LAYER_PHY_CAPABILITIES_ ## name, value)
653
654#define SCU_SAS_PHYCAP_GEN_BIT(name) \
655 SCU_GEN_BIT(SCU_LINK_LAYER_PHY_CAPABILITIES_ ## name)
656
657
658#define SCU_LINK_LAYER_PHY_SOURCE_ZONE_GROUP_CONTROL_VIRTUAL_EXPANDER_PHY_ZONE_GROUP_SHIFT (0)
659#define SCU_LINK_LAYER_PHY_SOURCE_ZONE_GROUP_CONTROL_VIRTUAL_EXPANDER_PHY_ZONE_GROUP_MASK (0x000000FF)
660#define SCU_LINK_LAYER_PHY_SOURCE_ZONE_GROUP_CONTROL_INSIDE_SOURCE_ZONE_GROUP_SHIFT (31)
661#define SCU_LINK_LAYER_PHY_SOURCE_ZONE_GROUP_CONTROL_INSIDE_SOURCE_ZONE_GROUP_MASK (0x80000000)
662#define SCU_LINK_LAYER_PHY_SOURCE_ZONE_GROUP_CONTROL_RESERVED_MASK (0x7FFFFF00)
663
664#define SCU_PSZGCR_GEN_VAL(name, value) \
665 SCU_GEN_VALUE(SCU_LINK_LAYER_PHY_SOURCE_ZONE_GROUP_CONTROL_ ## name, value)
666
667#define SCU_PSZGCR_GEN_BIT(name) \
668 SCU_GEN_BIT(SCU_LINK_LAYER_PHY_SOURCE_ZONE_GROUP_CONTROL_ ## name)
669
670#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE0_LOCKED_SHIFT (1)
671#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE0_LOCKED_MASK (0x00000002)
672#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE0_UPDATING_SHIFT (2)
673#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE0_UPDATING_MASK (0x00000004)
674#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE1_LOCKED_SHIFT (4)
675#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE1_LOCKED_MASK (0x00000010)
676#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE1_UPDATING_SHIFT (5)
677#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE1_UPDATING_MASK (0x00000020)
678#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE0_SHIFT (16)
679#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE0_MASK (0x00030000)
680#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE0_SHIFT (19)
681#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE0_MASK (0x00080000)
682#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE1_SHIFT (20)
683#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE1_MASK (0x00300000)
684#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE1_SHIFT (23)
685#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE1_MASK (0x00800000)
686#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE2_SHIFT (24)
687#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE2_MASK (0x03000000)
688#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE2_SHIFT (27)
689#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE2_MASK (0x08000000)
690#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE3_SHIFT (28)
691#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE3_MASK (0x30000000)
692#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE3_SHIFT (31)
693#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE3_MASK (0x80000000)
694#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_RESERVED_MASK (0x4444FFC9)
695
696#define SCU_PEG_SCUVZECR_GEN_VAL(name, val) \
697 SCU_GEN_VALUE(SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ ## name, val)
698
699#define SCU_PEG_SCUVZECR_GEN_BIT(name) \
700 SCU_GEN_BIT(SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ ## name)
701
702
703/*
704 * *****************************************************************************
705 * * Port Task Scheduler registers shift and mask values
706 * ***************************************************************************** */
707#define SCU_PTSG_CONTROL_IT_NEXUS_TIMEOUT_SHIFT (0)
708#define SCU_PTSG_CONTROL_IT_NEXUS_TIMEOUT_MASK (0x0000FFFF)
709#define SCU_PTSG_CONTROL_TASK_TIMEOUT_SHIFT (16)
710#define SCU_PTSG_CONTROL_TASK_TIMEOUT_MASK (0x00FF0000)
711#define SCU_PTSG_CONTROL_PTSG_ENABLE_SHIFT (24)
712#define SCU_PTSG_CONTROL_PTSG_ENABLE_MASK (0x01000000)
713#define SCU_PTSG_CONTROL_ETM_ENABLE_SHIFT (25)
714#define SCU_PTSG_CONTROL_ETM_ENABLE_MASK (0x02000000)
715#define SCU_PTSG_CONTROL_DEFAULT_MASK (0x00020002)
716#define SCU_PTSG_CONTROL_REQUIRED_MASK (0x00000000)
717#define SCU_PTSG_CONTROL_RESERVED_MASK (0xFC000000)
718
719#define SCU_PTSGCR_GEN_VAL(name, val) \
720 SCU_GEN_VALUE(SCU_PTSG_CONTROL_ ## name, val)
721
722#define SCU_PTSGCR_GEN_BIT(name) \
723 SCU_GEN_BIT(SCU_PTSG_CONTROL_ ## name)
724
725
726/* ***************************************************************************** */
727#define SCU_PTSG_REAL_TIME_CLOCK_SHIFT (0)
728#define SCU_PTSG_REAL_TIME_CLOCK_MASK (0x0000FFFF)
729#define SCU_PTSG_REAL_TIME_CLOCK_RESERVED_MASK (0xFFFF0000)
730
731#define SCU_RTCR_GEN_VAL(name, val) \
732 SCU_GEN_VALUE(SCU_PTSG_ ## name, val)
733
734
735#define SCU_PTSG_REAL_TIME_CLOCK_CONTROL_PRESCALER_VALUE_SHIFT (0)
736#define SCU_PTSG_REAL_TIME_CLOCK_CONTROL_PRESCALER_VALUE_MASK (0x00FFFFFF)
737#define SCU_PTSG_REAL_TIME_CLOCK_CONTROL_RESERVED_MASK (0xFF000000)
738
739#define SCU_RTCCR_GEN_VAL(name, val) \
740 SCU_GEN_VALUE(SCU_PTSG_REAL_TIME_CLOCK_CONTROL_ ## name, val)
741
742
743#define SCU_PTSG_PORT_TASK_SCHEDULER_CONTROL_SUSPEND_SHIFT (0)
744#define SCU_PTSG_PORT_TASK_SCHEDULER_CONTROL_SUSPEND_MASK (0x00000001)
745#define SCU_PTSG_PORT_TASK_SCHEDULER_CONTROL_ENABLE_SHIFT (1)
746#define SCU_PTSG_PORT_TASK_SCHEDULER_CONTROL_ENABLE_MASK (0x00000002)
747#define SCU_PTSG_PORT_TASK_SCHEDULER_CONTROL_RESERVED_MASK (0xFFFFFFFC)
748
749#define SCU_PTSxCR_GEN_BIT(name) \
750 SCU_GEN_BIT(SCU_PTSG_PORT_TASK_SCHEDULER_CONTROL_ ## name)
751
752
753#define SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_NEXT_RN_VALID_SHIFT (0)
754#define SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_NEXT_RN_VALID_MASK (0x00000001)
755#define SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_ACTIVE_RNSC_LIST_VALID_SHIFT (1)
756#define SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_ACTIVE_RNSC_LIST_VALID_MASK (0x00000002)
757#define SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_PTS_SUSPENDED_SHIFT (2)
758#define SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_PTS_SUSPENDED_MASK (0x00000004)
759#define SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_RESERVED_MASK (0xFFFFFFF8)
760
761#define SCU_PTSxSR_GEN_BIT(name) \
762 SCU_GEN_BIT(SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_ ## name)
763
764
765/*
766 * *****************************************************************************
767 * * SGPIO Register shift and mask values
768 * ***************************************************************************** */
769#define SCU_SGPIO_CONTROL_SGPIO_ENABLE_SHIFT (0)
770#define SCU_SGPIO_CONTROL_SGPIO_ENABLE_MASK (0x00000001)
771#define SCU_SGPIO_CONTROL_SGPIO_SERIAL_CLOCK_SELECT_SHIFT (1)
772#define SCU_SGPIO_CONTROL_SGPIO_SERIAL_CLOCK_SELECT_MASK (0x00000002)
773#define SCU_SGPIO_CONTROL_SGPIO_SERIAL_SHIFT_WIDTH_SELECT_SHIFT (2)
774#define SCU_SGPIO_CONTROL_SGPIO_SERIAL_SHIFT_WIDTH_SELECT_MASK (0x00000004)
775#define SCU_SGPIO_CONTROL_SGPIO_TEST_BIT_SHIFT (15)
776#define SCU_SGPIO_CONTROL_SGPIO_TEST_BIT_MASK (0x00008000)
777#define SCU_SGPIO_CONTROL_SGPIO_RESERVED_MASK (0xFFFF7FF8)
778
779#define SCU_SGICRx_GEN_BIT(name) \
780 SCU_GEN_BIT(SCU_SGPIO_CONTROL_SGPIO_ ## name)
781
782#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R0_SHIFT (0)
783#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R0_MASK (0x0000000F)
784#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R1_SHIFT (4)
785#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R1_MASK (0x000000F0)
786#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R2_SHIFT (8)
787#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R2_MASK (0x00000F00)
788#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R3_SHIFT (12)
789#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R3_MASK (0x0000F000)
790#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_RESERVED_MASK (0xFFFF0000)
791
792#define SCU_SGPBRx_GEN_VAL(name, value) \
793 SCU_GEN_VALUE(SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_ ## name, value)
794
795#define SCU_SGPIO_START_DRIVE_LOWER_R0_SHIFT (0)
796#define SCU_SGPIO_START_DRIVE_LOWER_R0_MASK (0x00000003)
797#define SCU_SGPIO_START_DRIVE_LOWER_R1_SHIFT (4)
798#define SCU_SGPIO_START_DRIVE_LOWER_R1_MASK (0x00000030)
799#define SCU_SGPIO_START_DRIVE_LOWER_R2_SHIFT (8)
800#define SCU_SGPIO_START_DRIVE_LOWER_R2_MASK (0x00000300)
801#define SCU_SGPIO_START_DRIVE_LOWER_R3_SHIFT (12)
802#define SCU_SGPIO_START_DRIVE_LOWER_R3_MASK (0x00003000)
803#define SCU_SGPIO_START_DRIVE_LOWER_RESERVED_MASK (0xFFFF8888)
804
805#define SCU_SGSDLRx_GEN_VAL(name, value) \
806 SCU_GEN_VALUE(SCU_SGPIO_START_DRIVE_LOWER_ ## name, value)
807
808#define SCU_SGPIO_START_DRIVE_UPPER_R0_SHIFT (0)
809#define SCU_SGPIO_START_DRIVE_UPPER_R0_MASK (0x00000003)
810#define SCU_SGPIO_START_DRIVE_UPPER_R1_SHIFT (4)
811#define SCU_SGPIO_START_DRIVE_UPPER_R1_MASK (0x00000030)
812#define SCU_SGPIO_START_DRIVE_UPPER_R2_SHIFT (8)
813#define SCU_SGPIO_START_DRIVE_UPPER_R2_MASK (0x00000300)
814#define SCU_SGPIO_START_DRIVE_UPPER_R3_SHIFT (12)
815#define SCU_SGPIO_START_DRIVE_UPPER_R3_MASK (0x00003000)
816#define SCU_SGPIO_START_DRIVE_UPPER_RESERVED_MASK (0xFFFF8888)
817
818#define SCU_SGSDURx_GEN_VAL(name, value) \
819 SCU_GEN_VALUE(SCU_SGPIO_START_DRIVE_LOWER_ ## name, value)
820
821#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D0_SHIFT (0)
822#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D0_MASK (0x00000003)
823#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D1_SHIFT (4)
824#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D1_MASK (0x00000030)
825#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D2_SHIFT (8)
826#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D2_MASK (0x00000300)
827#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D3_SHIFT (12)
828#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D3_MASK (0x00003000)
829#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_RESERVED_MASK (0xFFFF8888)
830
831#define SCU_SGSIDLRx_GEN_VAL(name, value) \
832 SCU_GEN_VALUE(SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_ ## name, value)
833
834#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D0_SHIFT (0)
835#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D0_MASK (0x00000003)
836#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D1_SHIFT (4)
837#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D1_MASK (0x00000030)
838#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D2_SHIFT (8)
839#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D2_MASK (0x00000300)
840#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D3_SHIFT (12)
841#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D3_MASK (0x00003000)
842#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_RESERVED_MASK (0xFFFF8888)
843
844#define SCU_SGSIDURx_GEN_VAL(name, value) \
845 SCU_GEN_VALUE(SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_ ## name, value)
846
847#define SCU_SGPIO_VENDOR_SPECIFIC_CODE_SHIFT (0)
848#define SCU_SGPIO_VENDOR_SPECIFIC_CODE_MASK (0x0000000F)
849#define SCU_SGPIO_VENDOR_SPECIFIC_CODE_RESERVED_MASK (0xFFFFFFF0)
850
851#define SCU_SGVSCR_GEN_VAL(value) \
852 SCU_GEN_VALUE(SCU_SGPIO_VENDOR_SPECIFIC_CODE ## name, value)
853
854#define SCU_SGPIO_OUPUT_DATA_SELECT_INPUT_DATA0_SHIFT (0)
855#define SCU_SGPIO_OUPUT_DATA_SELECT_INPUT_DATA0_MASK (0x00000003)
856#define SCU_SGPIO_OUPUT_DATA_SELECT_INVERT_INPUT_DATA0_SHIFT (2)
857#define SCU_SGPIO_OUPUT_DATA_SELECT_INVERT_INPUT_DATA0_MASK (0x00000004)
858#define SCU_SGPIO_OUPUT_DATA_SELECT_JOG_ENABLE_DATA0_SHIFT (3)
859#define SCU_SGPIO_OUPUT_DATA_SELECT_JOG_ENABLE_DATA0_MASK (0x00000008)
860#define SCU_SGPIO_OUPUT_DATA_SELECT_INPUT_DATA1_SHIFT (4)
861#define SCU_SGPIO_OUPUT_DATA_SELECT_INPUT_DATA1_MASK (0x00000030)
862#define SCU_SGPIO_OUPUT_DATA_SELECT_INVERT_INPUT_DATA1_SHIFT (6)
863#define SCU_SGPIO_OUPUT_DATA_SELECT_INVERT_INPUT_DATA1_MASK (0x00000040)
864#define SCU_SGPIO_OUPUT_DATA_SELECT_JOG_ENABLE_DATA1_SHIFT (7)
865#define SCU_SGPIO_OUPUT_DATA_SELECT_JOG_ENABLE_DATA1_MASK (0x00000080)
866#define SCU_SGPIO_OUPUT_DATA_SELECT_INPUT_DATA2_SHIFT (8)
867#define SCU_SGPIO_OUPUT_DATA_SELECT_INPUT_DATA2_MASK (0x00000300)
868#define SCU_SGPIO_OUPUT_DATA_SELECT_INVERT_INPUT_DATA2_SHIFT (10)
869#define SCU_SGPIO_OUPUT_DATA_SELECT_INVERT_INPUT_DATA2_MASK (0x00000400)
870#define SCU_SGPIO_OUPUT_DATA_SELECT_JOG_ENABLE_DATA2_SHIFT (11)
871#define SCU_SGPIO_OUPUT_DATA_SELECT_JOG_ENABLE_DATA2_MASK (0x00000800)
872#define SCU_SGPIO_OUPUT_DATA_SELECT_RESERVED_MASK (0xFFFFF000)
873
874#define SCU_SGODSR_GEN_VAL(name, value) \
875 SCU_GEN_VALUE(SCU_SGPIO_OUPUT_DATA_SELECT_ ## name, value)
876
877#define SCU_SGODSR_GEN_BIT(name) \
878 SCU_GEN_BIT(SCU_SGPIO_OUPUT_DATA_SELECT_ ## name)
879
880/*
881 * *****************************************************************************
882 * * SMU Registers
883 * ***************************************************************************** */
884
885/*
886 * ----------------------------------------------------------------------------
887 * SMU Registers
888 * These registers are based off of BAR0
889 *
890 * To calculate the offset for other functions use
891 * BAR0 + FN# * SystemPageSize * 2
892 *
893 * The TCA is only accessable from FN#0 (Physical Function) and each
894 * is programmed by (BAR0 + SCU_SMU_TCA_OFFSET + (FN# * 0x04)) or
895 * TCA0 for FN#0 is at BAR0 + 0x0400
896 * TCA1 for FN#1 is at BAR0 + 0x0404
897 * etc.
898 * ----------------------------------------------------------------------------
899 * Accessable to all FN#s */
900#define SCU_SMU_PCP_OFFSET 0x0000
901#define SCU_SMU_AMR_OFFSET 0x0004
902#define SCU_SMU_ISR_OFFSET 0x0010
903#define SCU_SMU_IMR_OFFSET 0x0014
904#define SCU_SMU_ICC_OFFSET 0x0018
905#define SCU_SMU_HTTLBAR_OFFSET 0x0020
906#define SCU_SMU_HTTUBAR_OFFSET 0x0024
907#define SCU_SMU_TCR_OFFSET 0x0028
908#define SCU_SMU_CQLBAR_OFFSET 0x0030
909#define SCU_SMU_CQUBAR_OFFSET 0x0034
910#define SCU_SMU_CQPR_OFFSET 0x0040
911#define SCU_SMU_CQGR_OFFSET 0x0044
912#define SCU_SMU_CQC_OFFSET 0x0048
913/* Accessable to FN#0 only */
914#define SCU_SMU_RNCLBAR_OFFSET 0x0080
915#define SCU_SMU_RNCUBAR_OFFSET 0x0084
916#define SCU_SMU_DCC_OFFSET 0x0090
917#define SCU_SMU_DFC_OFFSET 0x0094
918#define SCU_SMU_SMUCSR_OFFSET 0x0098
919#define SCU_SMU_SCUSRCR_OFFSET 0x009C
920#define SCU_SMU_SMAW_OFFSET 0x00A0
921#define SCU_SMU_SMDW_OFFSET 0x00A4
922/* Accessable to FN#0 only */
923#define SCU_SMU_TCA_OFFSET 0x0400
924/* Accessable to all FN#s */
925#define SCU_SMU_MT_MLAR0_OFFSET 0x2000
926#define SCU_SMU_MT_MUAR0_OFFSET 0x2004
927#define SCU_SMU_MT_MDR0_OFFSET 0x2008
928#define SCU_SMU_MT_VCR0_OFFSET 0x200C
929#define SCU_SMU_MT_MLAR1_OFFSET 0x2010
930#define SCU_SMU_MT_MUAR1_OFFSET 0x2014
931#define SCU_SMU_MT_MDR1_OFFSET 0x2018
932#define SCU_SMU_MT_VCR1_OFFSET 0x201C
933#define SCU_SMU_MPBA_OFFSET 0x3000
934
935/**
936 * struct smu_registers - These are the SMU registers
937 *
938 *
939 */
940struct smu_registers {
941/* 0x0000 PCP */
942 u32 post_context_port;
943/* 0x0004 AMR */
944 u32 address_modifier;
945 u32 reserved_08;
946 u32 reserved_0C;
947/* 0x0010 ISR */
948 u32 interrupt_status;
949/* 0x0014 IMR */
950 u32 interrupt_mask;
951/* 0x0018 ICC */
952 u32 interrupt_coalesce_control;
953 u32 reserved_1C;
954/* 0x0020 HTTLBAR */
955 u32 host_task_table_lower;
956/* 0x0024 HTTUBAR */
957 u32 host_task_table_upper;
958/* 0x0028 TCR */
959 u32 task_context_range;
960 u32 reserved_2C;
961/* 0x0030 CQLBAR */
962 u32 completion_queue_lower;
963/* 0x0034 CQUBAR */
964 u32 completion_queue_upper;
965 u32 reserved_38;
966 u32 reserved_3C;
967/* 0x0040 CQPR */
968 u32 completion_queue_put;
969/* 0x0044 CQGR */
970 u32 completion_queue_get;
971/* 0x0048 CQC */
972 u32 completion_queue_control;
973 u32 reserved_4C;
974 u32 reserved_5x[4];
975 u32 reserved_6x[4];
976 u32 reserved_7x[4];
977/*
978 * Accessable to FN#0 only
979 * 0x0080 RNCLBAR */
980 u32 remote_node_context_lower;
981/* 0x0084 RNCUBAR */
982 u32 remote_node_context_upper;
983 u32 reserved_88;
984 u32 reserved_8C;
985/* 0x0090 DCC */
986 u32 device_context_capacity;
987/* 0x0094 DFC */
988 u32 device_function_capacity;
989/* 0x0098 SMUCSR */
990 u32 control_status;
991/* 0x009C SCUSRCR */
992 u32 soft_reset_control;
993/* 0x00A0 SMAW */
994 u32 mmr_address_window;
995/* 0x00A4 SMDW */
996 u32 mmr_data_window;
997 u32 reserved_A8;
998 u32 reserved_AC;
999/* A whole bunch of reserved space */
1000 u32 reserved_Bx[4];
1001 u32 reserved_Cx[4];
1002 u32 reserved_Dx[4];
1003 u32 reserved_Ex[4];
1004 u32 reserved_Fx[4];
1005 u32 reserved_1xx[64];
1006 u32 reserved_2xx[64];
1007 u32 reserved_3xx[64];
1008/*
1009 * Accessable to FN#0 only
1010 * 0x0400 TCA */
1011 u32 task_context_assignment[256];
1012/* MSI-X registers not included */
1013};
1014
1015/*
1016 * *****************************************************************************
1017 * SDMA Registers
1018 * ***************************************************************************** */
1019#define SCU_SDMA_BASE 0x6000
1020#define SCU_SDMA_PUFATLHAR_OFFSET 0x0000
1021#define SCU_SDMA_PUFATUHAR_OFFSET 0x0004
1022#define SCU_SDMA_UFLHBAR_OFFSET 0x0008
1023#define SCU_SDMA_UFUHBAR_OFFSET 0x000C
1024#define SCU_SDMA_UFQC_OFFSET 0x0010
1025#define SCU_SDMA_UFQPP_OFFSET 0x0014
1026#define SCU_SDMA_UFQGP_OFFSET 0x0018
1027#define SCU_SDMA_PDMACR_OFFSET 0x001C
1028#define SCU_SDMA_CDMACR_OFFSET 0x0080
1029
1030/**
1031 * struct scu_sdma_registers - These are the SCU SDMA Registers
1032 *
1033 *
1034 */
1035struct scu_sdma_registers {
1036/* 0x0000 PUFATLHAR */
1037 u32 uf_address_table_lower;
1038/* 0x0004 PUFATUHAR */
1039 u32 uf_address_table_upper;
1040/* 0x0008 UFLHBAR */
1041 u32 uf_header_base_address_lower;
1042/* 0x000C UFUHBAR */
1043 u32 uf_header_base_address_upper;
1044/* 0x0010 UFQC */
1045 u32 unsolicited_frame_queue_control;
1046/* 0x0014 UFQPP */
1047 u32 unsolicited_frame_put_pointer;
1048/* 0x0018 UFQGP */
1049 u32 unsolicited_frame_get_pointer;
1050/* 0x001C PDMACR */
1051 u32 pdma_configuration;
1052/* Reserved until offset 0x80 */
1053 u32 reserved_0020_007C[0x18];
1054/* 0x0080 CDMACR */
1055 u32 cdma_configuration;
1056/* Remainder SDMA register space */
1057 u32 reserved_0084_0400[0xDF];
1058
1059};
1060
1061/*
1062 * *****************************************************************************
1063 * * SCU Link Registers
1064 * ***************************************************************************** */
1065#define SCU_PEG0_OFFSET 0x0000
1066#define SCU_PEG1_OFFSET 0x8000
1067
1068#define SCU_TL0_OFFSET 0x0000
1069#define SCU_TL1_OFFSET 0x0400
1070#define SCU_TL2_OFFSET 0x0800
1071#define SCU_TL3_OFFSET 0x0C00
1072
1073#define SCU_LL_OFFSET 0x0080
1074#define SCU_LL0_OFFSET (SCU_TL0_OFFSET + SCU_LL_OFFSET)
1075#define SCU_LL1_OFFSET (SCU_TL1_OFFSET + SCU_LL_OFFSET)
1076#define SCU_LL2_OFFSET (SCU_TL2_OFFSET + SCU_LL_OFFSET)
1077#define SCU_LL3_OFFSET (SCU_TL3_OFFSET + SCU_LL_OFFSET)
1078
1079/* Transport Layer Offsets (PEG + TL) */
1080#define SCU_TLCR_OFFSET 0x0000
1081#define SCU_TLADTR_OFFSET 0x0004
1082#define SCU_TLTTMR_OFFSET 0x0008
1083#define SCU_TLEECR0_OFFSET 0x000C
1084#define SCU_STPTLDARNI_OFFSET 0x0010
1085
1086
1087#define SCU_TLCR_HASH_SAS_CHECKING_ENABLE_SHIFT (0)
1088#define SCU_TLCR_HASH_SAS_CHECKING_ENABLE_MASK (0x00000001)
1089#define SCU_TLCR_CLEAR_TCI_NCQ_MAPPING_TABLE_SHIFT (1)
1090#define SCU_TLCR_CLEAR_TCI_NCQ_MAPPING_TABLE_MASK (0x00000002)
1091#define SCU_TLCR_STP_WRITE_DATA_PREFETCH_SHIFT (3)
1092#define SCU_TLCR_STP_WRITE_DATA_PREFETCH_MASK (0x00000008)
1093#define SCU_TLCR_CMD_NAK_STATUS_CODE_SHIFT (4)
1094#define SCU_TLCR_CMD_NAK_STATUS_CODE_MASK (0x00000010)
1095#define SCU_TLCR_RESERVED_MASK (0xFFFFFFEB)
1096
1097#define SCU_TLCR_GEN_BIT(name) \
1098 SCU_GEN_BIT(SCU_TLCR_ ## name)
1099
1100/**
1101 * struct scu_transport_layer_registers - These are the SCU Transport Layer
1102 * registers
1103 *
1104 *
1105 */
1106struct scu_transport_layer_registers {
1107 /* 0x0000 TLCR */
1108 u32 control;
1109 /* 0x0004 TLADTR */
1110 u32 arbitration_delay_timer;
1111 /* 0x0008 TLTTMR */
1112 u32 timer_test_mode;
1113 /* 0x000C reserved */
1114 u32 reserved_0C;
1115 /* 0x0010 STPTLDARNI */
1116 u32 stp_rni;
1117 /* 0x0014 TLFEWPORCTRL */
1118 u32 tlfe_wpo_read_control;
1119 /* 0x0018 TLFEWPORDATA */
1120 u32 tlfe_wpo_read_data;
1121 /* 0x001C RXTLSSCSR1 */
1122 u32 rxtl_single_step_control_status_1;
1123 /* 0x0020 RXTLSSCSR2 */
1124 u32 rxtl_single_step_control_status_2;
1125 /* 0x0024 AWTRDDCR */
1126 u32 tlfe_awt_retry_delay_debug_control;
1127 /* Remainder of TL memory space */
1128 u32 reserved_0028_007F[0x16];
1129
1130};
1131
1132/* Protocol Engine Group Registers */
1133#define SCU_SCUVZECRx_OFFSET 0x1080
1134
1135/* Link Layer Offsets (PEG + TL + LL) */
1136#define SCU_SAS_SPDTOV_OFFSET 0x0000
1137#define SCU_SAS_LLSTA_OFFSET 0x0004
1138#define SCU_SATA_PSELTOV_OFFSET 0x0008
1139#define SCU_SAS_TIMETOV_OFFSET 0x0010
1140#define SCU_SAS_LOSTOT_OFFSET 0x0014
1141#define SCU_SAS_LNKTOV_OFFSET 0x0018
1142#define SCU_SAS_PHYTOV_OFFSET 0x001C
1143#define SCU_SAS_AFERCNT_OFFSET 0x0020
1144#define SCU_SAS_WERCNT_OFFSET 0x0024
1145#define SCU_SAS_TIID_OFFSET 0x0028
1146#define SCU_SAS_TIDNH_OFFSET 0x002C
1147#define SCU_SAS_TIDNL_OFFSET 0x0030
1148#define SCU_SAS_TISSAH_OFFSET 0x0034
1149#define SCU_SAS_TISSAL_OFFSET 0x0038
1150#define SCU_SAS_TIPID_OFFSET 0x003C
1151#define SCU_SAS_TIRES2_OFFSET 0x0040
1152#define SCU_SAS_ADRSTA_OFFSET 0x0044
1153#define SCU_SAS_MAWTTOV_OFFSET 0x0048
1154#define SCU_SAS_FRPLDFIL_OFFSET 0x0054
1155#define SCU_SAS_RFCNT_OFFSET 0x0060
1156#define SCU_SAS_TFCNT_OFFSET 0x0064
1157#define SCU_SAS_RFDCNT_OFFSET 0x0068
1158#define SCU_SAS_TFDCNT_OFFSET 0x006C
1159#define SCU_SAS_LERCNT_OFFSET 0x0070
1160#define SCU_SAS_RDISERRCNT_OFFSET 0x0074
1161#define SCU_SAS_CRERCNT_OFFSET 0x0078
1162#define SCU_STPCTL_OFFSET 0x007C
1163#define SCU_SAS_PCFG_OFFSET 0x0080
1164#define SCU_SAS_CLKSM_OFFSET 0x0084
1165#define SCU_SAS_TXCOMWAKE_OFFSET 0x0088
1166#define SCU_SAS_TXCOMINIT_OFFSET 0x008C
1167#define SCU_SAS_TXCOMSAS_OFFSET 0x0090
1168#define SCU_SAS_COMINIT_OFFSET 0x0094
1169#define SCU_SAS_COMWAKE_OFFSET 0x0098
1170#define SCU_SAS_COMSAS_OFFSET 0x009C
1171#define SCU_SAS_SFERCNT_OFFSET 0x00A0
1172#define SCU_SAS_CDFERCNT_OFFSET 0x00A4
1173#define SCU_SAS_DNFERCNT_OFFSET 0x00A8
1174#define SCU_SAS_PRSTERCNT_OFFSET 0x00AC
1175#define SCU_SAS_CNTCTL_OFFSET 0x00B0
1176#define SCU_SAS_SSPTOV_OFFSET 0x00B4
1177#define SCU_FTCTL_OFFSET 0x00B8
1178#define SCU_FRCTL_OFFSET 0x00BC
1179#define SCU_FTWMRK_OFFSET 0x00C0
1180#define SCU_ENSPINUP_OFFSET 0x00C4
1181#define SCU_SAS_TRNTOV_OFFSET 0x00C8
1182#define SCU_SAS_PHYCAP_OFFSET 0x00CC
1183#define SCU_SAS_PHYCTL_OFFSET 0x00D0
1184#define SCU_SAS_LLCTL_OFFSET 0x00D8
1185#define SCU_AFE_XCVRCR_OFFSET 0x00DC
1186#define SCU_AFE_LUTCR_OFFSET 0x00E0
1187
1188#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_SHIFT (0)
1189#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_MASK (0x00000003)
1190#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1 (0)
1191#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2 (1)
1192#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3 (2)
1193#define SCU_SAS_LINK_LAYER_CONTROL_BROADCAST_PRIMITIVE_SHIFT (2)
1194#define SCU_SAS_LINK_LAYER_CONTROL_BROADCAST_PRIMITIVE_MASK (0x000003FC)
1195#define SCU_SAS_LINK_LAYER_CONTROL_CLOSE_NO_ACTIVE_TASK_DISABLE_SHIFT (16)
1196#define SCU_SAS_LINK_LAYER_CONTROL_CLOSE_NO_ACTIVE_TASK_DISABLE_MASK (0x00010000)
1197#define SCU_SAS_LINK_LAYER_CONTROL_CLOSE_NO_OUTBOUND_TASK_DISABLE_SHIFT (17)
1198#define SCU_SAS_LINK_LAYER_CONTROL_CLOSE_NO_OUTBOUND_TASK_DISABLE_MASK (0x00020000)
1199#define SCU_SAS_LINK_LAYER_CONTROL_NO_OUTBOUND_TASK_TIMEOUT_SHIFT (24)
1200#define SCU_SAS_LINK_LAYER_CONTROL_NO_OUTBOUND_TASK_TIMEOUT_MASK (0xFF000000)
1201#define SCU_SAS_LINK_LAYER_CONTROL_RESERVED (0x00FCFC00)
1202
1203#define SCU_SAS_LLCTL_GEN_VAL(name, value) \
1204 SCU_GEN_VALUE(SCU_SAS_LINK_LAYER_CONTROL_ ## name, value)
1205
1206#define SCU_SAS_LLCTL_GEN_BIT(name) \
1207 SCU_GEN_BIT(SCU_SAS_LINK_LAYER_CONTROL_ ## name)
1208
1209
1210/* #define SCU_FRXHECR_DCNT_OFFSET 0x00B0 */
1211#define SCU_PSZGCR_OFFSET 0x00E4
1212#define SCU_SAS_RECPHYCAP_OFFSET 0x00E8
1213/* #define SCU_TX_LUTSEL_OFFSET 0x00B8 */
1214
1215#define SCU_SAS_PTxC_OFFSET 0x00D4 /* Same offset as SAS_TCTSTM */
1216
1217/**
1218 * struct scu_link_layer_registers - SCU Link Layer Registers
1219 *
1220 *
1221 */
1222struct scu_link_layer_registers {
1223/* 0x0000 SAS_SPDTOV */
1224 u32 speed_negotiation_timers;
1225/* 0x0004 SAS_LLSTA */
1226 u32 link_layer_status;
1227/* 0x0008 SATA_PSELTOV */
1228 u32 port_selector_timeout;
1229 u32 reserved0C;
1230/* 0x0010 SAS_TIMETOV */
1231 u32 timeout_unit_value;
1232/* 0x0014 SAS_RCDTOV */
1233 u32 rcd_timeout;
1234/* 0x0018 SAS_LNKTOV */
1235 u32 link_timer_timeouts;
1236/* 0x001C SAS_PHYTOV */
1237 u32 sas_phy_timeouts;
1238/* 0x0020 SAS_AFERCNT */
1239 u32 received_address_frame_error_counter;
1240/* 0x0024 SAS_WERCNT */
1241 u32 invalid_dword_counter;
1242/* 0x0028 SAS_TIID */
1243 u32 transmit_identification;
1244/* 0x002C SAS_TIDNH */
1245 u32 sas_device_name_high;
1246/* 0x0030 SAS_TIDNL */
1247 u32 sas_device_name_low;
1248/* 0x0034 SAS_TISSAH */
1249 u32 source_sas_address_high;
1250/* 0x0038 SAS_TISSAL */
1251 u32 source_sas_address_low;
1252/* 0x003C SAS_TIPID */
1253 u32 identify_frame_phy_id;
1254/* 0x0040 SAS_TIRES2 */
1255 u32 identify_frame_reserved;
1256/* 0x0044 SAS_ADRSTA */
1257 u32 received_address_frame;
1258/* 0x0048 SAS_MAWTTOV */
1259 u32 maximum_arbitration_wait_timer_timeout;
1260/* 0x004C SAS_PTxC */
1261 u32 transmit_primitive;
1262/* 0x0050 SAS_RORES */
1263 u32 error_counter_event_notification_control;
1264/* 0x0054 SAS_FRPLDFIL */
1265 u32 frxq_payload_fill_threshold;
1266/* 0x0058 SAS_LLHANG_TOT */
1267 u32 link_layer_hang_detection_timeout;
1268 u32 reserved_5C;
1269/* 0x0060 SAS_RFCNT */
1270 u32 received_frame_count;
1271/* 0x0064 SAS_TFCNT */
1272 u32 transmit_frame_count;
1273/* 0x0068 SAS_RFDCNT */
1274 u32 received_dword_count;
1275/* 0x006C SAS_TFDCNT */
1276 u32 transmit_dword_count;
1277/* 0x0070 SAS_LERCNT */
1278 u32 loss_of_sync_error_count;
1279/* 0x0074 SAS_RDISERRCNT */
1280 u32 running_disparity_error_count;
1281/* 0x0078 SAS_CRERCNT */
1282 u32 received_frame_crc_error_count;
1283/* 0x007C STPCTL */
1284 u32 stp_control;
1285/* 0x0080 SAS_PCFG */
1286 u32 phy_configuration;
1287/* 0x0084 SAS_CLKSM */
1288 u32 clock_skew_management;
1289/* 0x0088 SAS_TXCOMWAKE */
1290 u32 transmit_comwake_signal;
1291/* 0x008C SAS_TXCOMINIT */
1292 u32 transmit_cominit_signal;
1293/* 0x0090 SAS_TXCOMSAS */
1294 u32 transmit_comsas_signal;
1295/* 0x0094 SAS_COMINIT */
1296 u32 cominit_control;
1297/* 0x0098 SAS_COMWAKE */
1298 u32 comwake_control;
1299/* 0x009C SAS_COMSAS */
1300 u32 comsas_control;
1301/* 0x00A0 SAS_SFERCNT */
1302 u32 received_short_frame_count;
1303/* 0x00A4 SAS_CDFERCNT */
1304 u32 received_frame_without_credit_count;
1305/* 0x00A8 SAS_DNFERCNT */
1306 u32 received_frame_after_done_count;
1307/* 0x00AC SAS_PRSTERCNT */
1308 u32 phy_reset_problem_count;
1309/* 0x00B0 SAS_CNTCTL */
1310 u32 counter_control;
1311/* 0x00B4 SAS_SSPTOV */
1312 u32 ssp_timer_timeout_values;
1313/* 0x00B8 FTCTL */
1314 u32 ftx_control;
1315/* 0x00BC FRCTL */
1316 u32 frx_control;
1317/* 0x00C0 FTWMRK */
1318 u32 ftx_watermark;
1319/* 0x00C4 ENSPINUP */
1320 u32 notify_enable_spinup_control;
1321/* 0x00C8 SAS_TRNTOV */
1322 u32 sas_training_sequence_timer_values;
1323/* 0x00CC SAS_PHYCAP */
1324 u32 phy_capabilities;
1325/* 0x00D0 SAS_PHYCTL */
1326 u32 phy_control;
1327 u32 reserved_d4;
1328/* 0x00D8 LLCTL */
1329 u32 link_layer_control;
1330/* 0x00DC AFE_XCVRCR */
1331 u32 afe_xcvr_control;
1332/* 0x00E0 AFE_LUTCR */
1333 u32 afe_lookup_table_control;
1334/* 0x00E4 PSZGCR */
1335 u32 phy_source_zone_group_control;
1336/* 0x00E8 SAS_RECPHYCAP */
1337 u32 receive_phycap;
1338 u32 reserved_ec;
1339/* 0x00F0 SNAFERXRSTCTL */
1340 u32 speed_negotiation_afe_rx_reset_control;
1341/* 0x00F4 SAS_SSIPMCTL */
1342 u32 power_management_control;
1343/* 0x00F8 SAS_PSPREQ_PRIM */
1344 u32 sas_pm_partial_request_primitive;
1345/* 0x00FC SAS_PSSREQ_PRIM */
1346 u32 sas_pm_slumber_request_primitive;
1347/* 0x0100 SAS_PPSACK_PRIM */
1348 u32 sas_pm_ack_primitive_register;
1349/* 0x0104 SAS_PSNAK_PRIM */
1350 u32 sas_pm_nak_primitive_register;
1351/* 0x0108 SAS_SSIPMTOV */
1352 u32 sas_primitive_timeout;
1353 u32 reserved_10c;
1354/* 0x0110 - 0x011C PLAPRDCTRLxREG */
1355 u32 pla_product_control[4];
1356/* 0x0120 PLAPRDSUMREG */
1357 u32 pla_product_sum;
1358/* 0x0124 PLACONTROLREG */
1359 u32 pla_control;
1360/* Remainder of memory space 896 bytes */
1361 u32 reserved_0128_037f[0x96];
1362
1363};
1364
1365/*
1366 * 0x00D4 // Same offset as SAS_TCTSTM SAS_PTxC
1367 * u32 primitive_transmit_control; */
1368
1369/*
1370 * ----------------------------------------------------------------------------
1371 * SGPIO
1372 * ---------------------------------------------------------------------------- */
1373#define SCU_SGPIO_OFFSET 0x1400
1374
1375/* #define SCU_SGPIO_OFFSET 0x6000 // later moves to 0x1400 see HSD 652625 */
1376#define SCU_SGPIO_SGICR_OFFSET 0x0000
1377#define SCU_SGPIO_SGPBR_OFFSET 0x0004
1378#define SCU_SGPIO_SGSDLR_OFFSET 0x0008
1379#define SCU_SGPIO_SGSDUR_OFFSET 0x000C
1380#define SCU_SGPIO_SGSIDLR_OFFSET 0x0010
1381#define SCU_SGPIO_SGSIDUR_OFFSET 0x0014
1382#define SCU_SGPIO_SGVSCR_OFFSET 0x0018
1383/* Address from 0x0820 to 0x083C */
1384#define SCU_SGPIO_SGODSR_OFFSET 0x0020
1385
1386/**
1387 * struct scu_sgpio_registers - SCU SGPIO Registers
1388 *
1389 *
1390 */
1391struct scu_sgpio_registers {
1392/* 0x0000 SGPIO_SGICR */
1393 u32 interface_control;
1394/* 0x0004 SGPIO_SGPBR */
1395 u32 blink_rate;
1396/* 0x0008 SGPIO_SGSDLR */
1397 u32 start_drive_lower;
1398/* 0x000C SGPIO_SGSDUR */
1399 u32 start_drive_upper;
1400/* 0x0010 SGPIO_SGSIDLR */
1401 u32 serial_input_lower;
1402/* 0x0014 SGPIO_SGSIDUR */
1403 u32 serial_input_upper;
1404/* 0x0018 SGPIO_SGVSCR */
1405 u32 vendor_specific_code;
1406/* 0x0020 SGPIO_SGODSR */
1407 u32 ouput_data_select[8];
1408/* Remainder of memory space 256 bytes */
1409 u32 reserved_1444_14ff[0x31];
1410
1411};
1412
1413/*
1414 * *****************************************************************************
1415 * * Defines for VIIT entry offsets
1416 * * Access additional entries by SCU_VIIT_BASE + index * 0x10
1417 * ***************************************************************************** */
1418#define SCU_VIIT_BASE 0x1c00
1419
1420struct SCU_VIIT_REGISTERS {
1421 u32 registers[256];
1422};
1423
1424/*
1425 * *****************************************************************************
1426 * * SCU PORT TASK SCHEDULER REGISTERS
1427 * ***************************************************************************** */
1428
1429#define SCU_PTSG_BASE 0x1000
1430
1431#define SCU_PTSG_PTSGCR_OFFSET 0x0000
1432#define SCU_PTSG_RTCR_OFFSET 0x0004
1433#define SCU_PTSG_RTCCR_OFFSET 0x0008
1434#define SCU_PTSG_PTS0CR_OFFSET 0x0010
1435#define SCU_PTSG_PTS0SR_OFFSET 0x0014
1436#define SCU_PTSG_PTS1CR_OFFSET 0x0018
1437#define SCU_PTSG_PTS1SR_OFFSET 0x001C
1438#define SCU_PTSG_PTS2CR_OFFSET 0x0020
1439#define SCU_PTSG_PTS2SR_OFFSET 0x0024
1440#define SCU_PTSG_PTS3CR_OFFSET 0x0028
1441#define SCU_PTSG_PTS3SR_OFFSET 0x002C
1442#define SCU_PTSG_PCSPE0CR_OFFSET 0x0030
1443#define SCU_PTSG_PCSPE1CR_OFFSET 0x0034
1444#define SCU_PTSG_PCSPE2CR_OFFSET 0x0038
1445#define SCU_PTSG_PCSPE3CR_OFFSET 0x003C
1446#define SCU_PTSG_ETMTSCCR_OFFSET 0x0040
1447#define SCU_PTSG_ETMRNSCCR_OFFSET 0x0044
1448
1449/**
1450 * struct scu_port_task_scheduler_registers - These are the control/stats pairs
1451 * for each Port Task Scheduler.
1452 *
1453 *
1454 */
1455struct scu_port_task_scheduler_registers {
1456 u32 control;
1457 u32 status;
1458};
1459
1460typedef u32 SCU_PORT_PE_CONFIGURATION_REGISTER_T;
1461
1462/**
1463 * struct scu_port_task_scheduler_group_registers - These are the PORT Task
1464 * Scheduler registers
1465 *
1466 *
1467 */
1468struct scu_port_task_scheduler_group_registers {
1469/* 0x0000 PTSGCR */
1470 u32 control;
1471/* 0x0004 RTCR */
1472 u32 real_time_clock;
1473/* 0x0008 RTCCR */
1474 u32 real_time_clock_control;
1475/* 0x000C */
1476 u32 reserved_0C;
1477/*
1478 * 0x0010 PTS0CR
1479 * 0x0014 PTS0SR
1480 * 0x0018 PTS1CR
1481 * 0x001C PTS1SR
1482 * 0x0020 PTS2CR
1483 * 0x0024 PTS2SR
1484 * 0x0028 PTS3CR
1485 * 0x002C PTS3SR */
1486 struct scu_port_task_scheduler_registers port[4];
1487/*
1488 * 0x0030 PCSPE0CR
1489 * 0x0034 PCSPE1CR
1490 * 0x0038 PCSPE2CR
1491 * 0x003C PCSPE3CR */
1492 SCU_PORT_PE_CONFIGURATION_REGISTER_T protocol_engine[4];
1493/* 0x0040 ETMTSCCR */
1494 u32 tc_scanning_interval_control;
1495/* 0x0044 ETMRNSCCR */
1496 u32 rnc_scanning_interval_control;
1497/* Remainder of memory space 128 bytes */
1498 u32 reserved_1048_107f[0x0E];
1499
1500};
1501
1502#define SCU_PTSG_SCUVZECR_OFFSET 0x003C
1503
1504/*
1505 * *****************************************************************************
1506 * * AFE REGISTERS
1507 * ***************************************************************************** */
1508#define SCU_AFE_MMR_BASE 0xE000
1509
1510/*
1511 * AFE 0 is at offset 0x0800
1512 * AFE 1 is at offset 0x0900
1513 * AFE 2 is at offset 0x0a00
1514 * AFE 3 is at offset 0x0b00 */
1515struct scu_afe_transceiver {
1516 /* 0x0000 AFE_XCVR_CTRL0 */
1517 u32 afe_xcvr_control0;
1518 /* 0x0004 AFE_XCVR_CTRL1 */
1519 u32 afe_xcvr_control1;
1520 /* 0x0008 */
1521 u32 reserved_0008;
1522 /* 0x000c afe_dfx_rx_control0 */
1523 u32 afe_dfx_rx_control0;
1524 /* 0x0010 AFE_DFX_RX_CTRL1 */
1525 u32 afe_dfx_rx_control1;
1526 /* 0x0014 */
1527 u32 reserved_0014;
1528 /* 0x0018 AFE_DFX_RX_STS0 */
1529 u32 afe_dfx_rx_status0;
1530 /* 0x001c AFE_DFX_RX_STS1 */
1531 u32 afe_dfx_rx_status1;
1532 /* 0x0020 */
1533 u32 reserved_0020;
1534 /* 0x0024 AFE_TX_CTRL */
1535 u32 afe_tx_control;
1536 /* 0x0028 AFE_TX_AMP_CTRL0 */
1537 u32 afe_tx_amp_control0;
1538 /* 0x002c AFE_TX_AMP_CTRL1 */
1539 u32 afe_tx_amp_control1;
1540 /* 0x0030 AFE_TX_AMP_CTRL2 */
1541 u32 afe_tx_amp_control2;
1542 /* 0x0034 AFE_TX_AMP_CTRL3 */
1543 u32 afe_tx_amp_control3;
1544 /* 0x0038 afe_tx_ssc_control */
1545 u32 afe_tx_ssc_control;
1546 /* 0x003c */
1547 u32 reserved_003c;
1548 /* 0x0040 AFE_RX_SSC_CTRL0 */
1549 u32 afe_rx_ssc_control0;
1550 /* 0x0044 AFE_RX_SSC_CTRL1 */
1551 u32 afe_rx_ssc_control1;
1552 /* 0x0048 AFE_RX_SSC_CTRL2 */
1553 u32 afe_rx_ssc_control2;
1554 /* 0x004c AFE_RX_EQ_STS0 */
1555 u32 afe_rx_eq_status0;
1556 /* 0x0050 AFE_RX_EQ_STS1 */
1557 u32 afe_rx_eq_status1;
1558 /* 0x0054 AFE_RX_CDR_STS */
1559 u32 afe_rx_cdr_status;
1560 /* 0x0058 */
1561 u32 reserved_0058;
1562 /* 0x005c AFE_CHAN_CTRL */
1563 u32 afe_channel_control;
1564 /* 0x0060-0x006c */
1565 u32 reserved_0060_006c[0x04];
1566 /* 0x0070 AFE_XCVR_EC_STS0 */
1567 u32 afe_xcvr_error_capture_status0;
1568 /* 0x0074 AFE_XCVR_EC_STS1 */
1569 u32 afe_xcvr_error_capture_status1;
1570 /* 0x0078 AFE_XCVR_EC_STS2 */
1571 u32 afe_xcvr_error_capture_status2;
1572 /* 0x007c afe_xcvr_ec_status3 */
1573 u32 afe_xcvr_error_capture_status3;
1574 /* 0x0080 AFE_XCVR_EC_STS4 */
1575 u32 afe_xcvr_error_capture_status4;
1576 /* 0x0084 AFE_XCVR_EC_STS5 */
1577 u32 afe_xcvr_error_capture_status5;
1578 /* 0x0088-0x00fc */
1579 u32 reserved_008c_00fc[0x1e];
1580};
1581
1582/**
1583 * struct scu_afe_registers - AFE Regsiters
1584 *
1585 *
1586 */
1587/* Uaoa AFE registers */
1588struct scu_afe_registers {
1589 /* 0Xe000 AFE_BIAS_CTRL */
1590 u32 afe_bias_control;
1591 u32 reserved_0004;
1592 /* 0x0008 AFE_PLL_CTRL0 */
1593 u32 afe_pll_control0;
1594 /* 0x000c AFE_PLL_CTRL1 */
1595 u32 afe_pll_control1;
1596 /* 0x0010 AFE_PLL_CTRL2 */
1597 u32 afe_pll_control2;
1598 /* 0x0014 AFE_CB_STS */
1599 u32 afe_common_block_status;
1600 /* 0x0018-0x007c */
1601 u32 reserved_18_7c[0x1a];
1602 /* 0x0080 AFE_PMSN_MCTRL0 */
1603 u32 afe_pmsn_master_control0;
1604 /* 0x0084 AFE_PMSN_MCTRL1 */
1605 u32 afe_pmsn_master_control1;
1606 /* 0x0088 AFE_PMSN_MCTRL2 */
1607 u32 afe_pmsn_master_control2;
1608 /* 0x008C-0x00fc */
1609 u32 reserved_008c_00fc[0x1D];
1610 /* 0x0100 AFE_DFX_MST_CTRL0 */
1611 u32 afe_dfx_master_control0;
1612 /* 0x0104 AFE_DFX_MST_CTRL1 */
1613 u32 afe_dfx_master_control1;
1614 /* 0x0108 AFE_DFX_DCL_CTRL */
1615 u32 afe_dfx_dcl_control;
1616 /* 0x010c AFE_DFX_DMON_CTRL */
1617 u32 afe_dfx_digital_monitor_control;
1618 /* 0x0110 AFE_DFX_AMONP_CTRL */
1619 u32 afe_dfx_analog_p_monitor_control;
1620 /* 0x0114 AFE_DFX_AMONN_CTRL */
1621 u32 afe_dfx_analog_n_monitor_control;
1622 /* 0x0118 AFE_DFX_NTL_STS */
1623 u32 afe_dfx_ntl_status;
1624 /* 0x011c AFE_DFX_FIFO_STS0 */
1625 u32 afe_dfx_fifo_status0;
1626 /* 0x0120 AFE_DFX_FIFO_STS1 */
1627 u32 afe_dfx_fifo_status1;
1628 /* 0x0124 AFE_DFX_MPAT_CTRL */
1629 u32 afe_dfx_master_pattern_control;
1630 /* 0x0128 AFE_DFX_P0_CTRL */
1631 u32 afe_dfx_p0_control;
1632 /* 0x012c-0x01a8 AFE_DFX_P0_DRx */
1633 u32 afe_dfx_p0_data[32];
1634 /* 0x01ac */
1635 u32 reserved_01ac;
1636 /* 0x01b0-0x020c AFE_DFX_P0_IRx */
1637 u32 afe_dfx_p0_instruction[24];
1638 /* 0x0210 */
1639 u32 reserved_0210;
1640 /* 0x0214 AFE_DFX_P1_CTRL */
1641 u32 afe_dfx_p1_control;
1642 /* 0x0218-0x245 AFE_DFX_P1_DRx */
1643 u32 afe_dfx_p1_data[16];
1644 /* 0x0258-0x029c */
1645 u32 reserved_0258_029c[0x12];
1646 /* 0x02a0-0x02bc AFE_DFX_P1_IRx */
1647 u32 afe_dfx_p1_instruction[8];
1648 /* 0x02c0-0x2fc */
1649 u32 reserved_02c0_02fc[0x10];
1650 /* 0x0300 AFE_DFX_TX_PMSN_CTRL */
1651 u32 afe_dfx_tx_pmsn_control;
1652 /* 0x0304 AFE_DFX_RX_PMSN_CTRL */
1653 u32 afe_dfx_rx_pmsn_control;
1654 u32 reserved_0308;
1655 /* 0x030c AFE_DFX_NOA_CTRL0 */
1656 u32 afe_dfx_noa_control0;
1657 /* 0x0310 AFE_DFX_NOA_CTRL1 */
1658 u32 afe_dfx_noa_control1;
1659 /* 0x0314 AFE_DFX_NOA_CTRL2 */
1660 u32 afe_dfx_noa_control2;
1661 /* 0x0318 AFE_DFX_NOA_CTRL3 */
1662 u32 afe_dfx_noa_control3;
1663 /* 0x031c AFE_DFX_NOA_CTRL4 */
1664 u32 afe_dfx_noa_control4;
1665 /* 0x0320 AFE_DFX_NOA_CTRL5 */
1666 u32 afe_dfx_noa_control5;
1667 /* 0x0324 AFE_DFX_NOA_CTRL6 */
1668 u32 afe_dfx_noa_control6;
1669 /* 0x0328 AFE_DFX_NOA_CTRL7 */
1670 u32 afe_dfx_noa_control7;
1671 /* 0x032c-0x07fc */
1672 u32 reserved_032c_07fc[0x135];
1673
1674 /* 0x0800-0x0bfc */
1675 struct scu_afe_transceiver scu_afe_xcvr[4];
1676
1677 /* 0x0c00-0x0ffc */
1678 u32 reserved_0c00_0ffc[0x0100];
1679};
1680
1681struct SCU_PROTOCOL_ENGINE_GROUP_REGISTERS {
1682 u32 table[0xE0];
1683};
1684
1685
1686struct SCU_VIIT_IIT {
1687 u32 table[256];
1688};
1689
1690/**
1691 * Placeholder for the ZONE Partition Table information ZONING will not be
1692 * included in the 1.1 release.
1693 *
1694 *
1695 */
1696struct SCU_ZONE_PARTITION_TABLE {
1697 u32 table[2048];
1698};
1699
1700/**
1701 * Placeholder for the CRAM register since I am not sure if we need to
1702 * read/write to these registers as yet.
1703 *
1704 *
1705 */
1706struct SCU_COMPLETION_RAM {
1707 u32 ram[128];
1708};
1709
1710/**
1711 * Placeholder for the FBRAM registers since I am not sure if we need to
1712 * read/write to these registers as yet.
1713 *
1714 *
1715 */
1716struct SCU_FRAME_BUFFER_RAM {
1717 u32 ram[128];
1718};
1719
1720#define SCU_SCRATCH_RAM_SIZE_IN_DWORDS 256
1721
1722/**
1723 * Placeholder for the scratch RAM registers.
1724 *
1725 *
1726 */
1727struct SCU_SCRATCH_RAM {
1728 u32 ram[SCU_SCRATCH_RAM_SIZE_IN_DWORDS];
1729};
1730
1731/**
1732 * Placeholder since I am not yet sure what these registers are here for.
1733 *
1734 *
1735 */
1736struct NOA_PROTOCOL_ENGINE_PARTITION {
1737 u32 reserved[64];
1738};
1739
1740/**
1741 * Placeholder since I am not yet sure what these registers are here for.
1742 *
1743 *
1744 */
1745struct NOA_HUB_PARTITION {
1746 u32 reserved[64];
1747};
1748
1749/**
1750 * Placeholder since I am not yet sure what these registers are here for.
1751 *
1752 *
1753 */
1754struct NOA_HOST_INTERFACE_PARTITION {
1755 u32 reserved[64];
1756};
1757
1758/**
1759 * struct TRANSPORT_LINK_LAYER_PAIR - The SCU Hardware pairs up the TL
1760 * registers with the LL registers so we must place them adjcent to make the
1761 * array of registers in the PEG.
1762 *
1763 *
1764 */
1765struct TRANSPORT_LINK_LAYER_PAIR {
1766 struct scu_transport_layer_registers tl;
1767 struct scu_link_layer_registers ll;
1768};
1769
1770/**
1771 * struct SCU_PEG_REGISTERS - SCU Protocol Engine Memory mapped register space.
1772 * These registers are unique to each protocol engine group. There can be
1773 * at most two PEG for a single SCU part.
1774 *
1775 *
1776 */
1777struct SCU_PEG_REGISTERS {
1778 struct TRANSPORT_LINK_LAYER_PAIR pe[4];
1779 struct scu_port_task_scheduler_group_registers ptsg;
1780 struct SCU_PROTOCOL_ENGINE_GROUP_REGISTERS peg;
1781 struct scu_sgpio_registers sgpio;
1782 u32 reserved_01500_1BFF[0x1C0];
1783 struct scu_viit_entry viit[64];
1784 struct SCU_ZONE_PARTITION_TABLE zpt0;
1785 struct SCU_ZONE_PARTITION_TABLE zpt1;
1786};
1787
1788/**
1789 * struct scu_registers - SCU regsiters including both PEG registers if we turn
1790 * on that compile option. All of these registers are in the memory mapped
1791 * space returned from BAR1.
1792 *
1793 *
1794 */
1795struct scu_registers {
1796 /* 0x0000 - PEG 0 */
1797 struct SCU_PEG_REGISTERS peg0;
1798
1799 /* 0x6000 - SDMA and Miscellaneous */
1800 struct scu_sdma_registers sdma;
1801 struct SCU_COMPLETION_RAM cram;
1802 struct SCU_FRAME_BUFFER_RAM fbram;
1803 u32 reserved_6800_69FF[0x80];
1804 struct NOA_PROTOCOL_ENGINE_PARTITION noa_pe;
1805 struct NOA_HUB_PARTITION noa_hub;
1806 struct NOA_HOST_INTERFACE_PARTITION noa_if;
1807 u32 reserved_6d00_7fff[0x4c0];
1808
1809 /* 0x8000 - PEG 1 */
1810 struct SCU_PEG_REGISTERS peg1;
1811
1812 /* 0xE000 - AFE Registers */
1813 struct scu_afe_registers afe;
1814
1815 /* 0xF000 - reserved */
1816 u32 reserved_f000_211fff[0x80c00];
1817
1818 /* 0x212000 - scratch RAM */
1819 struct SCU_SCRATCH_RAM scratch_ram;
1820
1821};
1822
1823
1824#endif /* _SCU_REGISTERS_HEADER_ */
diff --git a/drivers/scsi/isci/core/scu_remote_node_context.h b/drivers/scsi/isci/core/scu_remote_node_context.h
new file mode 100644
index 000000000000..8006f2ee2d1d
--- /dev/null
+++ b/drivers/scsi/isci/core/scu_remote_node_context.h
@@ -0,0 +1,230 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef __SCU_REMOTE_NODE_CONTEXT_HEADER__
57#define __SCU_REMOTE_NODE_CONTEXT_HEADER__
58
59/**
60 * This file contains the structures and constatns used by the SCU hardware to
61 * describe a remote node context.
62 *
63 *
64 */
65#include "sci_types.h"
66
67/**
68 * struct ssp_remote_node_context - This structure contains the SCU hardware
69 * definition for an SSP remote node.
70 *
71 *
72 */
73struct ssp_remote_node_context {
74 /* WORD 0 */
75
76 /**
77 * This field is the remote node index assigned for this remote node. All
78 * remote nodes must have a unique remote node index. The value of the remote
79 * node index can not exceed the maximum number of remote nodes reported in
80 * the SCU device context capacity register.
81 */
82 u32 remote_node_index:12;
83 u32 reserved0_1:4;
84
85 /**
86 * This field tells the SCU hardware how many simultaneous connections that
87 * this remote node will support.
88 */
89 u32 remote_node_port_width:4;
90
91 /**
92 * This field tells the SCU hardware which logical port to associate with this
93 * remote node.
94 */
95 u32 logical_port_index:3;
96 u32 reserved0_2:5;
97
98 /**
99 * This field will enable the I_T nexus loss timer for this remote node.
100 */
101 u32 nexus_loss_timer_enable:1;
102
103 /**
104 * This field is the for driver debug only and is not used.
105 */
106 u32 check_bit:1;
107
108 /**
109 * This field must be set to true when the hardware DMAs the remote node
110 * context to the hardware SRAM. When the remote node is being invalidated
111 * this field must be set to false.
112 */
113 u32 is_valid:1;
114
115 /**
116 * This field must be set to true.
117 */
118 u32 is_remote_node_context:1;
119
120 /* WORD 1 - 2 */
121
122 /**
123 * This is the low word of the remote device SAS Address
124 */
125 u32 remote_sas_address_lo;
126
127 /**
128 * This field is the high word of the remote device SAS Address
129 */
130 u32 remote_sas_address_hi;
131
132 /* WORD 3 */
133 /**
134 * This field reprensets the function number assigned to this remote device.
135 * This value must match the virtual function number that is being used to
136 * communicate to the device.
137 */
138 u32 function_number:8;
139 u32 reserved3_1:8;
140
141 /**
142 * This field provides the driver a way to cheat on the arbitration wait time
143 * for this remote node.
144 */
145 u32 arbitration_wait_time:16;
146
147 /* WORD 4 */
148 /**
149 * This field tells the SCU hardware how long this device may occupy the
150 * connection before it must be closed.
151 */
152 u32 connection_occupancy_timeout:16;
153
154 /**
155 * This field tells the SCU hardware how long to maintain a connection when
156 * there are no frames being transmitted on the link.
157 */
158 u32 connection_inactivity_timeout:16;
159
160 /* WORD 5 */
161 /**
162 * This field allows the driver to cheat on the arbitration wait time for this
163 * remote node.
164 */
165 u32 initial_arbitration_wait_time:16;
166
167 /**
168 * This field is tells the hardware what to program for the connection rate in
169 * the open address frame. See the SAS spec for valid values.
170 */
171 u32 oaf_connection_rate:4;
172
173 /**
174 * This field tells the SCU hardware what to program for the features in the
175 * open address frame. See the SAS spec for valid values.
176 */
177 u32 oaf_features:4;
178
179 /**
180 * This field tells the SCU hardware what to use for the source zone group in
181 * the open address frame. See the SAS spec for more details on zoning.
182 */
183 u32 oaf_source_zone_group:8;
184
185 /* WORD 6 */
186 /**
187 * This field tells the SCU hardware what to use as the more capibilities in
188 * the open address frame. See the SAS Spec for details.
189 */
190 u32 oaf_more_compatibility_features;
191
192 /* WORD 7 */
193 u32 reserved7;
194
195};
196
197/**
198 * struct stp_remote_node_context - This structure contains the SCU hardware
199 * definition for a STP remote node.
200 *
201 * STP Targets are not yet supported so this definition is a placeholder until
202 * we do support them.
203 */
204struct stp_remote_node_context {
205 /**
206 * Placeholder data for the STP remote node.
207 */
208 u32 data[8];
209
210};
211
212/**
213 * This union combines the SAS and SATA remote node definitions.
214 *
215 * union scu_remote_node_context
216 */
217union scu_remote_node_context {
218 /**
219 * SSP Remote Node
220 */
221 struct ssp_remote_node_context ssp;
222
223 /**
224 * STP Remote Node
225 */
226 struct stp_remote_node_context stp;
227
228};
229
230#endif /* __SCU_REMOTE_NODE_CONTEXT_HEADER__ */
diff --git a/drivers/scsi/isci/core/scu_task_context.h b/drivers/scsi/isci/core/scu_task_context.h
new file mode 100644
index 000000000000..d08c51bb2262
--- /dev/null
+++ b/drivers/scsi/isci/core/scu_task_context.h
@@ -0,0 +1,943 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCU_TASK_CONTEXT_H_
57#define _SCU_TASK_CONTEXT_H_
58
59/**
60 * This file contains the structures and constants for the SCU hardware task
61 * context.
62 *
63 *
64 */
65
66#include "sci_types.h"
67
68/**
69 * enum SCU_SSP_TASK_TYPE - This enumberation defines the various SSP task
70 * types the SCU hardware will accept. The definition for the various task
71 * types the SCU hardware will accept can be found in the DS specification.
72 *
73 *
74 */
75typedef enum {
76 SCU_TASK_TYPE_IOREAD, /* /< IO READ direction or no direction */
77 SCU_TASK_TYPE_IOWRITE, /* /< IO Write direction */
78 SCU_TASK_TYPE_SMP_REQUEST, /* /< SMP Request type */
79 SCU_TASK_TYPE_RESPONSE, /* /< Driver generated response frame (targt mode) */
80 SCU_TASK_TYPE_RAW_FRAME, /* /< Raw frame request type */
81 SCU_TASK_TYPE_PRIMITIVE /* /< Request for a primitive to be transmitted */
82} SCU_SSP_TASK_TYPE;
83
84/**
85 * enum SCU_SATA_TASK_TYPE - This enumeration defines the various SATA task
86 * types the SCU hardware will accept. The definition for the various task
87 * types the SCU hardware will accept can be found in the DS specification.
88 *
89 *
90 */
91typedef enum {
92 SCU_TASK_TYPE_DMA_IN, /* /< Read request */
93 SCU_TASK_TYPE_FPDMAQ_READ, /* /< NCQ read request */
94 SCU_TASK_TYPE_PACKET_DMA_IN, /* /< Packet read request */
95 SCU_TASK_TYPE_SATA_RAW_FRAME, /* /< Raw frame request */
96 RESERVED_4,
97 RESERVED_5,
98 RESERVED_6,
99 RESERVED_7,
100 SCU_TASK_TYPE_DMA_OUT, /* /< Write request */
101 SCU_TASK_TYPE_FPDMAQ_WRITE, /* /< NCQ write Request */
102 SCU_TASK_TYPE_PACKET_DMA_OUT /* /< Packet write request */
103} SCU_SATA_TASK_TYPE;
104
105
106/**
107 *
108 *
109 * SCU_CONTEXT_TYPE
110 */
111#define SCU_TASK_CONTEXT_TYPE 0
112#define SCU_RNC_CONTEXT_TYPE 1
113
114/**
115 *
116 *
117 * SCU_TASK_CONTEXT_VALIDITY
118 */
119#define SCU_TASK_CONTEXT_INVALID 0
120#define SCU_TASK_CONTEXT_VALID 1
121
122/**
123 *
124 *
125 * SCU_COMMAND_CODE
126 */
127#define SCU_COMMAND_CODE_INITIATOR_NEW_TASK 0
128#define SCU_COMMAND_CODE_ACTIVE_TASK 1
129#define SCU_COMMAND_CODE_PRIMITIVE_SEQ_TASK 2
130#define SCU_COMMAND_CODE_TARGET_RAW_FRAMES 3
131
132/**
133 *
134 *
135 * SCU_TASK_PRIORITY
136 */
137/**
138 *
139 *
140 * This priority is used when there is no priority request for this request.
141 */
142#define SCU_TASK_PRIORITY_NORMAL 0
143
144/**
145 *
146 *
147 * This priority indicates that the task should be scheduled to the head of the
148 * queue. The task will NOT be executed if the TX is suspended for the remote
149 * node.
150 */
151#define SCU_TASK_PRIORITY_HEAD_OF_Q 1
152
153/**
154 *
155 *
156 * This priority indicates that the task will be executed before all
157 * SCU_TASK_PRIORITY_NORMAL and SCU_TASK_PRIORITY_HEAD_OF_Q tasks. The task
158 * WILL be executed if the TX is suspended for the remote node.
159 */
160#define SCU_TASK_PRIORITY_HIGH 2
161
162/**
163 *
164 *
165 * This task priority is reserved and should not be used.
166 */
167#define SCU_TASK_PRIORITY_RESERVED 3
168
169#define SCU_TASK_INITIATOR_MODE 1
170#define SCU_TASK_TARGET_MODE 0
171
172#define SCU_TASK_REGULAR 0
173#define SCU_TASK_ABORTED 1
174
175/* direction bit defintion */
176/**
177 *
178 *
179 * SATA_DIRECTION
180 */
181#define SCU_SATA_WRITE_DATA_DIRECTION 0
182#define SCU_SATA_READ_DATA_DIRECTION 1
183
184/**
185 *
186 *
187 * SCU_COMMAND_CONTEXT_MACROS These macros provide the mask and shift
188 * operations to construct the various SCU commands
189 */
190#define SCU_CONTEXT_COMMAND_REQUEST_TYPE_SHIFT 21
191#define SCU_CONTEXT_COMMAND_REQUEST_TYPE_MASK 0x00E00000
192#define scu_get_command_request_type(x) \
193 ((x) & SCU_CONTEXT_COMMAND_REQUEST_TYPE_MASK)
194
195#define SCU_CONTEXT_COMMAND_REQUEST_SUBTYPE_SHIFT 18
196#define SCU_CONTEXT_COMMAND_REQUEST_SUBTYPE_MASK 0x001C0000
197#define scu_get_command_request_subtype(x) \
198 ((x) & SCU_CONTEXT_COMMAND_REQUEST_SUBTYPE_MASK)
199
200#define SCU_CONTEXT_COMMAND_REQUEST_FULLTYPE_MASK \
201 (\
202 SCU_CONTEXT_COMMAND_REQUEST_TYPE_MASK \
203 | SCU_CONTEXT_COMMAND_REQUEST_SUBTYPE_MASK \
204 )
205#define scu_get_command_request_full_type(x) \
206 ((x) & SCU_CONTEXT_COMMAND_REQUEST_FULLTYPE_MASK)
207
208#define SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT 16
209#define SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_MASK 0x00010000
210#define scu_get_command_protocl_engine_group(x) \
211 ((x) & SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_MASK)
212
213#define SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT 12
214#define SCU_CONTEXT_COMMAND_LOGICAL_PORT_MASK 0x00007000
215#define scu_get_command_reqeust_logical_port(x) \
216 ((x) & SCU_CONTEXT_COMMAND_LOGICAL_PORT_MASK)
217
218
219#define MAKE_SCU_CONTEXT_COMMAND_TYPE(type) \
220 ((u32)(type) << SCU_CONTEXT_COMMAND_REQUEST_TYPE_SHIFT)
221
222/**
223 * MAKE_SCU_CONTEXT_COMMAND_TYPE() -
224 *
225 * SCU_COMMAND_TYPES These constants provide the grouping of the different SCU
226 * command types.
227 */
228#define SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC MAKE_SCU_CONTEXT_COMMAND_TYPE(0)
229#define SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_TC MAKE_SCU_CONTEXT_COMMAND_TYPE(1)
230#define SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_RNC MAKE_SCU_CONTEXT_COMMAND_TYPE(2)
231#define SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_RNC MAKE_SCU_CONTEXT_COMMAND_TYPE(3)
232#define SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC MAKE_SCU_CONTEXT_COMMAND_TYPE(6)
233
234#define MAKE_SCU_CONTEXT_COMMAND_REQUEST(type, command) \
235 ((type) | ((command) << SCU_CONTEXT_COMMAND_REQUEST_SUBTYPE_SHIFT))
236
237/**
238 *
239 *
240 * SCU_REQUEST_TYPES These constants are the various request types that can be
241 * posted to the SCU hardware.
242 */
243#define SCU_CONTEXT_COMMAND_REQUST_POST_TC \
244 (MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC, 0))
245
246#define SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT \
247 (MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC, 1))
248
249#define SCU_CONTEXT_COMMAND_REQUST_DUMP_TC \
250 (MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_TC, 0))
251
252#define SCU_CONTEXT_COMMAND_POST_RNC_32 \
253 (MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_RNC, 0))
254
255#define SCU_CONTEXT_COMMAND_POST_RNC_96 \
256 (MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_RNC, 1))
257
258#define SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE \
259 (MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_RNC, 2))
260
261#define SCU_CONTEXT_COMMAND_DUMP_RNC_32 \
262 (MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_RNC, 0))
263
264#define SCU_CONTEXT_COMMAND_DUMP_RNC_96 \
265 (MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_RNC, 1))
266
267#define SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX \
268 (MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC, 0))
269
270#define SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX_RX \
271 (MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC, 1))
272
273#define SCU_CONTEXT_COMMAND_POST_RNC_RESUME \
274 (MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC, 2))
275
276#define SCU_CONTEXT_IT_NEXUS_LOSS_TIMER_ENABLE \
277 (MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC, 3))
278
279#define SCU_CONTEXT_IT_NEXUS_LOSS_TIMER_DISABLE \
280 (MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC, 4))
281
282/**
283 *
284 *
285 * SCU_TASK_CONTEXT_PROTOCOL SCU Task context protocol types this is uesd to
286 * program the SCU Task context protocol field in word 0x00.
287 */
288#define SCU_TASK_CONTEXT_PROTOCOL_SMP 0x00
289#define SCU_TASK_CONTEXT_PROTOCOL_SSP 0x01
290#define SCU_TASK_CONTEXT_PROTOCOL_STP 0x02
291#define SCU_TASK_CONTEXT_PROTOCOL_NONE 0x07
292
293/**
294 * struct SSP_TASK_CONTEXT - This is the SCU hardware definition for an SSP
295 * request.
296 *
297 *
298 */
299struct SSP_TASK_CONTEXT {
300 /* OFFSET 0x18 */
301 u32 reserved00:24;
302 u32 frame_type:8;
303
304 /* OFFSET 0x1C */
305 u32 reserved01;
306
307 /* OFFSET 0x20 */
308 u32 fill_bytes:2;
309 u32 reserved02:6;
310 u32 changing_data_pointer:1;
311 u32 retransmit:1;
312 u32 retry_data_frame:1;
313 u32 tlr_control:2;
314 u32 reserved03:19;
315
316 /* OFFSET 0x24 */
317 u32 uiRsvd4;
318
319 /* OFFSET 0x28 */
320 u32 target_port_transfer_tag:16;
321 u32 tag:16;
322
323 /* OFFSET 0x2C */
324 u32 data_offset;
325};
326
327/**
328 * struct STP_TASK_CONTEXT - This is the SCU hardware definition for an STP
329 * request.
330 *
331 *
332 */
333struct STP_TASK_CONTEXT {
334 /* OFFSET 0x18 */
335 u32 fis_type:8;
336 u32 pm_port:4;
337 u32 reserved0:3;
338 u32 control:1;
339 u32 command:8;
340 u32 features:8;
341
342 /* OFFSET 0x1C */
343 u32 reserved1;
344
345 /* OFFSET 0x20 */
346 u32 reserved2;
347
348 /* OFFSET 0x24 */
349 u32 reserved3;
350
351 /* OFFSET 0x28 */
352 u32 ncq_tag:5;
353 u32 reserved4:27;
354
355 /* OFFSET 0x2C */
356 u32 data_offset; /* TODO: What is this used for? */
357};
358
359/**
360 * struct SMP_TASK_CONTEXT - This is the SCU hardware definition for an SMP
361 * request.
362 *
363 *
364 */
365struct SMP_TASK_CONTEXT {
366 /* OFFSET 0x18 */
367 u32 response_length:8;
368 u32 function_result:8;
369 u32 function:8;
370 u32 frame_type:8;
371
372 /* OFFSET 0x1C */
373 u32 smp_response_ufi:12;
374 u32 reserved1:20;
375
376 /* OFFSET 0x20 */
377 u32 reserved2;
378
379 /* OFFSET 0x24 */
380 u32 reserved3;
381
382 /* OFFSET 0x28 */
383 u32 reserved4;
384
385 /* OFFSET 0x2C */
386 u32 reserved5;
387};
388
389/**
390 * struct PRIMITIVE_TASK_CONTEXT - This is the SCU hardware definition used
391 * when the driver wants to send a primitive on the link.
392 *
393 *
394 */
395struct PRIMITIVE_TASK_CONTEXT {
396 /* OFFSET 0x18 */
397 /**
398 * This field is the control word and it must be 0.
399 */
400 u32 control; /* /< must be set to 0 */
401
402 /* OFFSET 0x1C */
403 /**
404 * This field specifies the primitive that is to be transmitted.
405 */
406 u32 sequence;
407
408 /* OFFSET 0x20 */
409 u32 reserved0;
410
411 /* OFFSET 0x24 */
412 u32 reserved1;
413
414 /* OFFSET 0x28 */
415 u32 reserved2;
416
417 /* OFFSET 0x2C */
418 u32 reserved3;
419};
420
421/**
422 * The union of the protocols that can be selected in the SCU task context
423 * field.
424 *
425 * PROTOCOL_CONTEXT
426 */
427union PROTOCOL_CONTEXT {
428 struct SSP_TASK_CONTEXT ssp;
429 struct STP_TASK_CONTEXT stp;
430 struct SMP_TASK_CONTEXT smp;
431 struct PRIMITIVE_TASK_CONTEXT primitive;
432 u32 words[6];
433};
434
435/**
436 * struct scu_sgl_element - This structure represents a single SCU defined SGL
437 * element. SCU SGLs contain a 64 bit address with the maximum data transfer
438 * being 24 bits in size. The SGL can not cross a 4GB boundary.
439 *
440 * struct scu_sgl_element
441 */
442struct scu_sgl_element {
443 /**
444 * This field is the upper 32 bits of the 64 bit physical address.
445 */
446 u32 address_upper;
447
448 /**
449 * This field is the lower 32 bits of the 64 bit physical address.
450 */
451 u32 address_lower;
452
453 /**
454 * This field is the number of bytes to transfer.
455 */
456 u32 length:24;
457
458 /**
459 * This field is the address modifier to be used when a virtual function is
460 * requesting a data transfer.
461 */
462 u32 address_modifier:8;
463
464};
465
466#define SCU_SGL_ELEMENT_PAIR_A 0
467#define SCU_SGL_ELEMENT_PAIR_B 1
468
469/**
470 * struct scu_sgl_element_pair - This structure is the SCU hardware definition
471 * of a pair of SGL elements. The SCU hardware always works on SGL pairs.
472 * They are refered to in the DS specification as SGL A and SGL B. Each SGL
473 * pair is followed by the address of the next pair.
474 *
475 *
476 */
477struct scu_sgl_element_pair {
478 /* OFFSET 0x60-0x68 */
479 /**
480 * This field is the SGL element A of the SGL pair.
481 */
482 struct scu_sgl_element A;
483
484 /* OFFSET 0x6C-0x74 */
485 /**
486 * This field is the SGL element B of the SGL pair.
487 */
488 struct scu_sgl_element B;
489
490 /* OFFSET 0x78-0x7C */
491 /**
492 * This field is the upper 32 bits of the 64 bit address to the next SGL
493 * element pair.
494 */
495 u32 next_pair_upper;
496
497 /**
498 * This field is the lower 32 bits of the 64 bit address to the next SGL
499 * element pair.
500 */
501 u32 next_pair_lower;
502
503};
504
505/**
506 * struct TRANSPORT_SNAPSHOT - This structure is the SCU hardware scratch area
507 * for the task context. This is set to 0 by the driver but can be read by
508 * issuing a dump TC request to the SCU.
509 *
510 *
511 */
512struct TRANSPORT_SNAPSHOT {
513 /* OFFSET 0x48 */
514 u32 xfer_rdy_write_data_length;
515
516 /* OFFSET 0x4C */
517 u32 data_offset;
518
519 /* OFFSET 0x50 */
520 u32 data_transfer_size:24;
521 u32 reserved_50_0:8;
522
523 /* OFFSET 0x54 */
524 u32 next_initiator_write_data_offset;
525
526 /* OFFSET 0x58 */
527 u32 next_initiator_write_data_xfer_size:24;
528 u32 reserved_58_0:8;
529};
530
531/**
532 * struct scu_task_context - This structure defines the contents of the SCU
533 * silicon task context. It lays out all of the fields according to the
534 * expected order and location for the Storage Controller unit.
535 *
536 *
537 */
538struct scu_task_context {
539 /* OFFSET 0x00 ------ */
540 /**
541 * This field must be encoded to one of the valid SCU task priority values
542 * - SCU_TASK_PRIORITY_NORMAL
543 * - SCU_TASK_PRIORITY_HEAD_OF_Q
544 * - SCU_TASK_PRIORITY_HIGH
545 */
546 u32 priority:2;
547
548 /**
549 * This field must be set to true if this is an initiator generated request.
550 * Until target mode is supported all task requests are initiator requests.
551 */
552 u32 initiator_request:1;
553
554 /**
555 * This field must be set to one of the valid connection rates valid values
556 * are 0x8, 0x9, and 0xA.
557 */
558 u32 connection_rate:4;
559
560 /**
561 * This field muse be programed when generating an SMP response since the SMP
562 * connection remains open until the SMP response is generated.
563 */
564 u32 protocol_engine_index:3;
565
566 /**
567 * This field must contain the logical port for the task request.
568 */
569 u32 logical_port_index:3;
570
571 /**
572 * This field must be set to one of the SCU_TASK_CONTEXT_PROTOCOL values
573 * - SCU_TASK_CONTEXT_PROTOCOL_SMP
574 * - SCU_TASK_CONTEXT_PROTOCOL_SSP
575 * - SCU_TASK_CONTEXT_PROTOCOL_STP
576 * - SCU_TASK_CONTEXT_PROTOCOL_NONE
577 */
578 u32 protocol_type:3;
579
580 /**
581 * This filed must be set to the TCi allocated for this task
582 */
583 u32 task_index:12;
584
585 /**
586 * This field is reserved and must be set to 0x00
587 */
588 u32 reserved_00_0:1;
589
590 /**
591 * For a normal task request this must be set to 0. If this is an abort of
592 * this task request it must be set to 1.
593 */
594 u32 abort:1;
595
596 /**
597 * This field must be set to true for the SCU hardware to process the task.
598 */
599 u32 valid:1;
600
601 /**
602 * This field must be set to SCU_TASK_CONTEXT_TYPE
603 */
604 u32 context_type:1;
605
606 /* OFFSET 0x04 */
607 /**
608 * This field contains the RNi that is the target of this request.
609 */
610 u32 remote_node_index:12;
611
612 /**
613 * This field is programmed if this is a mirrored request, which we are not
614 * using, in which case it is the RNi for the mirrored target.
615 */
616 u32 mirrored_node_index:12;
617
618 /**
619 * This field is programmed with the direction of the SATA reqeust
620 * - SCU_SATA_WRITE_DATA_DIRECTION
621 * - SCU_SATA_READ_DATA_DIRECTION
622 */
623 u32 sata_direction:1;
624
625 /**
626 * This field is programmsed with one of the following SCU_COMMAND_CODE
627 * - SCU_COMMAND_CODE_INITIATOR_NEW_TASK
628 * - SCU_COMMAND_CODE_ACTIVE_TASK
629 * - SCU_COMMAND_CODE_PRIMITIVE_SEQ_TASK
630 * - SCU_COMMAND_CODE_TARGET_RAW_FRAMES
631 */
632 u32 command_code:2;
633
634 /**
635 * This field is set to true if the remote node should be suspended.
636 * This bit is only valid for SSP & SMP target devices.
637 */
638 u32 suspend_node:1;
639
640 /**
641 * This field is programmed with one of the following command type codes
642 *
643 * For SAS requests use the SCU_SSP_TASK_TYPE
644 * - SCU_TASK_TYPE_IOREAD
645 * - SCU_TASK_TYPE_IOWRITE
646 * - SCU_TASK_TYPE_SMP_REQUEST
647 * - SCU_TASK_TYPE_RESPONSE
648 * - SCU_TASK_TYPE_RAW_FRAME
649 * - SCU_TASK_TYPE_PRIMITIVE
650 *
651 * For SATA requests use the SCU_SATA_TASK_TYPE
652 * - SCU_TASK_TYPE_DMA_IN
653 * - SCU_TASK_TYPE_FPDMAQ_READ
654 * - SCU_TASK_TYPE_PACKET_DMA_IN
655 * - SCU_TASK_TYPE_SATA_RAW_FRAME
656 * - SCU_TASK_TYPE_DMA_OUT
657 * - SCU_TASK_TYPE_FPDMAQ_WRITE
658 * - SCU_TASK_TYPE_PACKET_DMA_OUT
659 */
660 u32 task_type:4;
661
662 /* OFFSET 0x08 */
663 /**
664 * This field is reserved and the must be set to 0x00
665 */
666 u32 link_layer_control:8; /* presently all reserved */
667
668 /**
669 * This field is set to true when TLR is to be enabled
670 */
671 u32 ssp_tlr_enable:1;
672
673 /**
674 * This is field specifies if the SCU DMAs a response frame to host
675 * memory for good response frames when operating in target mode.
676 */
677 u32 dma_ssp_target_good_response:1;
678
679 /**
680 * This field indicates if the SCU should DMA the response frame to
681 * host memory.
682 */
683 u32 do_not_dma_ssp_good_response:1;
684
685 /**
686 * This field is set to true when strict ordering is to be enabled
687 */
688 u32 strict_ordering:1;
689
690 /**
691 * This field indicates the type of endianess to be utilized for the
692 * frame. command, task, and response frames utilized control_frame
693 * set to 1.
694 */
695 u32 control_frame:1;
696
697 /**
698 * This field is reserved and the driver should set to 0x00
699 */
700 u32 tl_control_reserved:3;
701
702 /**
703 * This field is set to true when the SCU hardware task timeout control is to
704 * be enabled
705 */
706 u32 timeout_enable:1;
707
708 /**
709 * This field is reserved and the driver should set it to 0x00
710 */
711 u32 pts_control_reserved:7;
712
713 /**
714 * This field should be set to true when block guard is to be enabled
715 */
716 u32 block_guard_enable:1;
717
718 /**
719 * This field is reserved and the driver should set to 0x00
720 */
721 u32 sdma_control_reserved:7;
722
723 /* OFFSET 0x0C */
724 /**
725 * This field is the address modifier for this io request it should be
726 * programmed with the virtual function that is making the request.
727 */
728 u32 address_modifier:16;
729
730 /**
731 * @todo What we support mirrored SMP response frame?
732 */
733 u32 mirrored_protocol_engine:3; /* mirrored protocol Engine Index */
734
735 /**
736 * If this is a mirrored request the logical port index for the mirrored RNi
737 * must be programmed.
738 */
739 u32 mirrored_logical_port:4; /* mirrored local port index */
740
741 /**
742 * This field is reserved and the driver must set it to 0x00
743 */
744 u32 reserved_0C_0:8;
745
746 /**
747 * This field must be set to true if the mirrored request processing is to be
748 * enabled.
749 */
750 u32 mirror_request_enable:1; /* Mirrored request Enable */
751
752 /* OFFSET 0x10 */
753 /**
754 * This field is the command iu length in dwords
755 */
756 u32 ssp_command_iu_length:8;
757
758 /**
759 * This is the target TLR enable bit it must be set to 0 when creatning the
760 * task context.
761 */
762 u32 xfer_ready_tlr_enable:1;
763
764 /**
765 * This field is reserved and the driver must set it to 0x00
766 */
767 u32 reserved_10_0:7;
768
769 /**
770 * This is the maximum burst size that the SCU hardware will send in one
771 * connection its value is (N x 512) and N must be a multiple of 2. If the
772 * value is 0x00 then maximum burst size is disabled.
773 */
774 u32 ssp_max_burst_size:16;
775
776 /* OFFSET 0x14 */
777 /**
778 * This filed is set to the number of bytes to be transfered in the request.
779 */
780 u32 transfer_length_bytes:24; /* In terms of bytes */
781
782 /**
783 * This field is reserved and the driver should set it to 0x00
784 */
785 u32 reserved_14_0:8;
786
787 /* OFFSET 0x18-0x2C */
788 /**
789 * This union provides for the protocol specif part of the SCU Task Context.
790 */
791 union PROTOCOL_CONTEXT type;
792
793 /* OFFSET 0x30-0x34 */
794 /**
795 * This field is the upper 32 bits of the 64 bit physical address of the
796 * command iu buffer
797 */
798 u32 command_iu_upper;
799
800 /**
801 * This field is the lower 32 bits of the 64 bit physical address of the
802 * command iu buffer
803 */
804 u32 command_iu_lower;
805
806 /* OFFSET 0x38-0x3C */
807 /**
808 * This field is the upper 32 bits of the 64 bit physical address of the
809 * response iu buffer
810 */
811 u32 response_iu_upper;
812
813 /**
814 * This field is the lower 32 bits of the 64 bit physical address of the
815 * response iu buffer
816 */
817 u32 response_iu_lower;
818
819 /* OFFSET 0x40 */
820 /**
821 * This field is set to the task phase of the SCU hardware. The driver must
822 * set this to 0x01
823 */
824 u32 task_phase:8;
825
826 /**
827 * This field is set to the transport layer task status. The driver must set
828 * this to 0x00
829 */
830 u32 task_status:8;
831
832 /**
833 * This field is used during initiator write TLR
834 */
835 u32 previous_extended_tag:4;
836
837 /**
838 * This field is set the maximum number of retries for a STP non-data FIS
839 */
840 u32 stp_retry_count:2;
841
842 /**
843 * This field is reserved and the driver must set it to 0x00
844 */
845 u32 reserved_40_1:2;
846
847 /**
848 * This field is used by the SCU TL to determine when to take a snapshot when
849 * tranmitting read data frames.
850 * - 0x00 The entire IO
851 * - 0x01 32k
852 * - 0x02 64k
853 * - 0x04 128k
854 * - 0x08 256k
855 */
856 u32 ssp_tlr_threshold:4;
857
858 /**
859 * This field is reserved and the driver must set it to 0x00
860 */
861 u32 reserved_40_2:4;
862
863 /* OFFSET 0x44 */
864 u32 write_data_length; /* read only set to 0 */
865
866 /* OFFSET 0x48-0x58 */
867 struct TRANSPORT_SNAPSHOT snapshot; /* read only set to 0 */
868
869 /* OFFSET 0x5C */
870 u32 block_protection_enable:1;
871 u32 block_size:2;
872 u32 block_protection_function:2;
873 u32 reserved_5C_0:9;
874 u32 active_sgl_element:2; /* read only set to 0 */
875 u32 sgl_exhausted:1; /* read only set to 0 */
876 u32 payload_data_transfer_error:4; /* read only set to 0 */
877 u32 frame_buffer_offset:11; /* read only set to 0 */
878
879 /* OFFSET 0x60-0x7C */
880 /**
881 * This field is the first SGL element pair found in the TC data structure.
882 */
883 struct scu_sgl_element_pair sgl_pair_ab;
884 /* OFFSET 0x80-0x9C */
885 /**
886 * This field is the second SGL element pair found in the TC data structure.
887 */
888 struct scu_sgl_element_pair sgl_pair_cd;
889
890 /* OFFSET 0xA0-BC */
891 struct scu_sgl_element_pair sgl_snapshot_ac;
892
893 /* OFFSET 0xC0 */
894 u32 active_sgl_element_pair; /* read only set to 0 */
895
896 /* OFFSET 0xC4-0xCC */
897 u32 reserved_C4_CC[3];
898
899 /* OFFSET 0xD0 */
900 u32 intermediate_crc_value:16;
901 u32 initial_crc_seed:16;
902
903 /* OFFSET 0xD4 */
904 u32 application_tag_for_verify:16;
905 u32 application_tag_for_generate:16;
906
907 /* OFFSET 0xD8 */
908 u32 reference_tag_seed_for_verify_function;
909
910 /* OFFSET 0xDC */
911 u32 reserved_DC;
912
913 /* OFFSET 0xE0 */
914 u32 reserved_E0_0:16;
915 u32 application_tag_mask_for_generate:16;
916
917 /* OFFSET 0xE4 */
918 u32 block_protection_control:16;
919 u32 application_tag_mask_for_verify:16;
920
921 /* OFFSET 0xE8 */
922 u32 block_protection_error:8;
923 u32 reserved_E8_0:24;
924
925 /* OFFSET 0xEC */
926 u32 reference_tag_seed_for_verify;
927
928 /* OFFSET 0xF0 */
929 u32 intermediate_crc_valid_snapshot:16;
930 u32 reserved_F0_0:16;
931
932 /* OFFSET 0xF4 */
933 u32 reference_tag_seed_for_verify_function_snapshot;
934
935 /* OFFSET 0xF8 */
936 u32 snapshot_of_reserved_dword_DC_of_tc;
937
938 /* OFFSET 0xFC */
939 u32 reference_tag_seed_for_generate_function_snapshot;
940
941};
942
943#endif /* _SCU_TASK_CONTEXT_H_ */
diff --git a/drivers/scsi/isci/core/scu_unsolicited_frame.h b/drivers/scsi/isci/core/scu_unsolicited_frame.h
new file mode 100644
index 000000000000..590ea02745fd
--- /dev/null
+++ b/drivers/scsi/isci/core/scu_unsolicited_frame.h
@@ -0,0 +1,117 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This field defines the SCU format of an unsolicited frame (UF). A UF is a
58 * frame received by the SCU for which there is no known corresponding task
59 * context (TC).
60 *
61 *
62 */
63
64#ifndef _SCU_UNSOLICITED_FRAME_H_
65#define _SCU_UNSOLICITED_FRAME_H_
66
67#include "sci_types.h"
68
69/**
70 *
71 *
72 * This constant defines the number of DWORDS found the unsolicited frame
73 * header data member.
74 */
75#define SCU_UNSOLICITED_FRAME_HEADER_DATA_DWORDS 15
76
77/**
78 * struct scu_unsolicited_frame_header -
79 *
80 * This structure delineates the format of an unsolicited frame header. The
81 * first DWORD are UF attributes defined by the silicon architecture. The data
82 * depicts actual header information received on the link.
83 */
84struct scu_unsolicited_frame_header {
85 /**
86 * This field indicates if there is an Initiator Index Table entry with
87 * which this header is associated.
88 */
89 u32 iit_exists:1;
90
91 /**
92 * This field simply indicates the protocol type (i.e. SSP, STP, SMP).
93 */
94 u32 protocol_type:3;
95
96 /**
97 * This field indicates if the frame is an address frame (IAF or OAF)
98 * or if it is a information unit frame.
99 */
100 u32 is_address_frame:1;
101
102 /**
103 * This field simply indicates the connection rate at which the frame
104 * was received.
105 */
106 u32 connection_rate:4;
107
108 u32 reserved:23;
109
110 /**
111 * This field represents the actual header data received on the link.
112 */
113 u32 data[SCU_UNSOLICITED_FRAME_HEADER_DATA_DWORDS];
114
115};
116
117#endif /* _SCU_UNSOLICITED_FRAME_H_ */
diff --git a/drivers/scsi/isci/core/scu_viit_data.h b/drivers/scsi/isci/core/scu_viit_data.h
new file mode 100644
index 000000000000..4601d1962ca3
--- /dev/null
+++ b/drivers/scsi/isci/core/scu_viit_data.h
@@ -0,0 +1,179 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCU_VIIT_DATA_HEADER_
57#define _SCU_VIIT_DATA_HEADER_
58
59/**
60 * This file contains the constants and structures for the SCU hardware VIIT
61 * table entries.
62 *
63 *
64 */
65
66#include "sci_types.h"
67
68#define SCU_VIIT_ENTRY_ID_MASK (0xC0000000)
69#define SCU_VIIT_ENTRY_ID_SHIFT (30)
70
71#define SCU_VIIT_ENTRY_FUNCTION_MASK (0x0FF00000)
72#define SCU_VIIT_ENTRY_FUNCTION_SHIFT (20)
73
74#define SCU_VIIT_ENTRY_IPPTMODE_MASK (0x0001F800)
75#define SCU_VIIT_ENTRY_IPPTMODE_SHIFT (12)
76
77#define SCU_VIIT_ENTRY_LPVIE_MASK (0x00000F00)
78#define SCU_VIIT_ENTRY_LPVIE_SHIFT (8)
79
80#define SCU_VIIT_ENTRY_STATUS_MASK (0x000000FF)
81#define SCU_VIIT_ENTRY_STATUS_SHIFT (0)
82
83#define SCU_VIIT_ENTRY_ID_INVALID (0 << SCU_VIIT_ENTRY_ID_SHIFT)
84#define SCU_VIIT_ENTRY_ID_VIIT (1 << SCU_VIIT_ENTRY_ID_SHIFT)
85#define SCU_VIIT_ENTRY_ID_IIT (2 << SCU_VIIT_ENTRY_ID_SHIFT)
86#define SCU_VIIT_ENTRY_ID_VIRT_EXP (3 << SCU_VIIT_ENTRY_ID_SHIFT)
87
88#define SCU_VIIT_IPPT_SSP_INITIATOR (0x01 << SCU_VIIT_ENTRY_IPPTMODE_SHIFT)
89#define SCU_VIIT_IPPT_SMP_INITIATOR (0x02 << SCU_VIIT_ENTRY_IPPTMODE_SHIFT)
90#define SCU_VIIT_IPPT_STP_INITIATOR (0x04 << SCU_VIIT_ENTRY_IPPTMODE_SHIFT)
91#define SCU_VIIT_IPPT_INITIATOR \
92 (\
93 SCU_VIIT_IPPT_SSP_INITIATOR \
94 | SCU_VIIT_IPPT_SMP_INITIATOR \
95 | SCU_VIIT_IPPT_STP_INITIATOR \
96 )
97
98#define SCU_VIIT_STATUS_RNC_VALID (0x01 << SCU_VIIT_ENTRY_STATUS_SHIFT)
99#define SCU_VIIT_STATUS_ADDRESS_VALID (0x02 << SCU_VIIT_ENTRY_STATUS_SHIFT)
100#define SCU_VIIT_STATUS_RNI_VALID (0x04 << SCU_VIIT_ENTRY_STATUS_SHIFT)
101#define SCU_VIIT_STATUS_ALL_VALID \
102 (\
103 SCU_VIIT_STATUS_RNC_VALID \
104 | SCU_VIIT_STATUS_ADDRESS_VALID \
105 | SCU_VIIT_STATUS_RNI_VALID \
106 )
107
108#define SCU_VIIT_IPPT_SMP_TARGET (0x10 << SCU_VIIT_ENTRY_IPPTMODE_SHIFT)
109
110/**
111 * struct scu_viit_entry - This is the SCU Virtual Initiator Table Entry
112 *
113 *
114 */
115struct scu_viit_entry {
116 /**
117 * This must be encoded as to the type of initiator that is being constructed
118 * for this port.
119 */
120 u32 status;
121
122 /**
123 * Virtual initiator high SAS Address
124 */
125 u32 initiator_sas_address_hi;
126
127 /**
128 * Virtual initiator low SAS Address
129 */
130 u32 initiator_sas_address_lo;
131
132 /**
133 * This must be 0
134 */
135 u32 reserved;
136
137};
138
139
140/* IIT Status Defines */
141#define SCU_IIT_ENTRY_ID_MASK (0xC0000000)
142#define SCU_IIT_ENTRY_ID_SHIFT (30)
143
144#define SCU_IIT_ENTRY_STATUS_UPDATE_MASK (0x20000000)
145#define SCU_IIT_ENTRY_STATUS_UPDATE_SHIFT (29)
146
147#define SCU_IIT_ENTRY_LPI_MASK (0x00000F00)
148#define SCU_IIT_ENTRY_LPI_SHIFT (8)
149
150#define SCU_IIT_ENTRY_STATUS_MASK (0x000000FF)
151#define SCU_IIT_ENTRY_STATUS_SHIFT (0)
152
153/* IIT Remote Initiator Defines */
154#define SCU_IIT_ENTRY_REMOTE_TAG_MASK (0x0000FFFF)
155#define SCU_IIT_ENTRY_REMOTE_TAG_SHIFT (0)
156
157#define SCU_IIT_ENTRY_REMOTE_RNC_MASK (0x0FFF0000)
158#define SCU_IIT_ENTRY_REMOTE_RNC_SHIFT (16)
159
160#define SCU_IIT_ENTRY_ID_INVALID (0 << SCU_IIT_ENTRY_ID_SHIFT)
161#define SCU_IIT_ENTRY_ID_VIIT (1 << SCU_IIT_ENTRY_ID_SHIFT)
162#define SCU_IIT_ENTRY_ID_IIT (2 << SCU_IIT_ENTRY_ID_SHIFT)
163#define SCU_IIT_ENTRY_ID_VIRT_EXP (3 << SCU_IIT_ENTRY_ID_SHIFT)
164
165/**
166 * struct scu_iit_entry - This will be implemented later when we support
167 * virtual functions
168 *
169 *
170 */
171struct scu_iit_entry {
172 u32 status;
173 u32 remote_initiator_sas_address_hi;
174 u32 remote_initiator_sas_address_lo;
175 u32 remote_initiator;
176
177};
178
179#endif /* _SCU_VIIT_DATA_HEADER_ */
diff --git a/drivers/scsi/isci/deprecated.c b/drivers/scsi/isci/deprecated.c
new file mode 100644
index 000000000000..847e6874e1a8
--- /dev/null
+++ b/drivers/scsi/isci/deprecated.c
@@ -0,0 +1,491 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56
57/**
58 * This file contains isci module object implementation.
59 *
60 *
61 */
62
63#include "isci.h"
64#include "request.h"
65#include "sata.h"
66#include "task.h"
67
68
69/**
70 * scic_cb_stall_execution() - This method is called when the core requires the
71 * OS driver to stall execution. This method is utilized during
72 * initialization or non-performance paths only.
73 * @microseconds: This parameter specifies the number of microseconds for which
74 * to stall. The operating system driver is allowed to round this value up
75 * where necessary.
76 *
77 * none.
78 */
79void scic_cb_stall_execution(
80 u32 microseconds)
81{
82 udelay(microseconds);
83}
84
85
86/**
87 * scic_cb_io_request_get_physical_address() - This callback method asks the
88 * user to provide the physical address for the supplied virtual address
89 * when building an io request object.
90 * @controller: This parameter is the core controller object handle.
91 * @io_request: This parameter is the io request object handle for which the
92 * physical address is being requested.
93 *
94 *
95 */
96void scic_cb_io_request_get_physical_address(
97 struct scic_sds_controller *controller,
98 struct scic_sds_request *io_request,
99 void *virtual_address,
100 dma_addr_t *physical_address)
101{
102 struct isci_request *request =
103 (struct isci_request *)sci_object_get_association(io_request);
104
105 char *requested_address = (char *)virtual_address;
106 char *base_address = (char *)request;
107
108 BUG_ON(requested_address < base_address);
109 BUG_ON((requested_address - base_address) >=
110 request->request_alloc_size);
111
112 *physical_address = request->request_daddr +
113 (requested_address - base_address);
114}
115
116/**
117 * scic_cb_io_request_get_transfer_length() - This callback method asks the
118 * user to provide the number of bytes to be transfered as part of this
119 * request.
120 * @scic_user_io_request: This parameter points to the user's IO request
121 * object. It is a cookie that allows the user to provide the necessary
122 * information for this callback.
123 *
124 * This method returns the number of payload data bytes to be transfered for
125 * this IO request.
126 */
127u32 scic_cb_io_request_get_transfer_length(
128 void *scic_user_io_request)
129{
130 return isci_request_io_request_get_transfer_length(
131 scic_user_io_request
132 );
133}
134
135
136/**
137 * scic_cb_io_request_get_data_direction() - This callback method asks the user
138 * to provide the data direction for this request.
139 * @scic_user_io_request: This parameter points to the user's IO request
140 * object. It is a cookie that allows the user to provide the necessary
141 * information for this callback.
142 *
143 * This method returns the value of SCI_IO_REQUEST_DATA_OUT or
144 * SCI_IO_REQUEST_DATA_IN, or SCI_IO_REQUEST_NO_DATA.
145 */
146SCI_IO_REQUEST_DATA_DIRECTION scic_cb_io_request_get_data_direction(
147 void *scic_user_io_request)
148{
149 return isci_request_io_request_get_data_direction(
150 scic_user_io_request
151 );
152}
153
154
155/**
156 * scic_cb_io_request_get_next_sge() - This callback method asks the user to
157 * provide the address to where the next Scatter-Gather Element is located.
158 * @scic_user_io_request: This parameter points to the user's IO request
159 * object. It is a cookie that allows the user to provide the necessary
160 * information for this callback.
161 * @current_sge_address: This parameter specifies the address for the current
162 * SGE (i.e. the one that has just processed).
163 *
164 * An address specifying the location for the next scatter gather element to be
165 * processed.
166 */
167void scic_cb_io_request_get_next_sge(
168 void *scic_user_io_request,
169 void *current_sge_address,
170 void **next_sge)
171{
172 *next_sge = isci_request_io_request_get_next_sge(
173 scic_user_io_request,
174 current_sge_address
175 );
176}
177
178/**
179 * scic_cb_sge_get_address_field() - This callback method asks the user to
180 * provide the contents of the "address" field in the Scatter-Gather Element.
181 * @scic_user_io_request: This parameter points to the user's IO request
182 * object. It is a cookie that allows the user to provide the necessary
183 * information for this callback.
184 * @sge_address: This parameter specifies the address for the SGE from which to
185 * retrieve the address field.
186 *
187 * A physical address specifying the contents of the SGE's address field.
188 */
189dma_addr_t scic_cb_sge_get_address_field(
190 void *scic_user_io_request,
191 void *sge_address)
192{
193 return isci_request_sge_get_address_field(
194 scic_user_io_request,
195 sge_address
196 );
197}
198
199/**
200 * scic_cb_sge_get_length_field() - This callback method asks the user to
201 * provide the contents of the "length" field in the Scatter-Gather Element.
202 * @scic_user_io_request: This parameter points to the user's IO request
203 * object. It is a cookie that allows the user to provide the necessary
204 * information for this callback.
205 * @sge_address: This parameter specifies the address for the SGE from which to
206 * retrieve the address field.
207 *
208 * This method returns the length field specified inside the SGE referenced by
209 * the sge_address parameter.
210 */
211u32 scic_cb_sge_get_length_field(
212 void *scic_user_io_request,
213 void *sge_address)
214{
215 return isci_request_sge_get_length_field(
216 scic_user_io_request,
217 sge_address
218 );
219}
220
221/**
222 * scic_cb_ssp_io_request_get_cdb_address() - This callback method asks the
223 * user to provide the address for the command descriptor block (CDB)
224 * associated with this IO request.
225 * @scic_user_io_request: This parameter points to the user's IO request
226 * object. It is a cookie that allows the user to provide the necessary
227 * information for this callback.
228 *
229 * This method returns the virtual address of the CDB.
230 */
231void *scic_cb_ssp_io_request_get_cdb_address(
232 void *scic_user_io_request)
233{
234 return isci_request_ssp_io_request_get_cdb_address(
235 scic_user_io_request
236 );
237}
238
239/**
240 * scic_cb_ssp_io_request_get_cdb_length() - This callback method asks the user
241 * to provide the length of the command descriptor block (CDB) associated
242 * with this IO request.
243 * @scic_user_io_request: This parameter points to the user's IO request
244 * object. It is a cookie that allows the user to provide the necessary
245 * information for this callback.
246 *
247 * This method returns the length of the CDB.
248 */
249u32 scic_cb_ssp_io_request_get_cdb_length(
250 void *scic_user_io_request)
251{
252 return isci_request_ssp_io_request_get_cdb_length(
253 scic_user_io_request
254 );
255}
256
257/**
258 * scic_cb_ssp_io_request_get_lun() - This callback method asks the user to
259 * provide the Logical Unit (LUN) associated with this IO request.
260 * @scic_user_io_request: This parameter points to the user's IO request
261 * object. It is a cookie that allows the user to provide the necessary
262 * information for this callback.
263 *
264 * This method returns the LUN associated with this request. This should be u64?
265 */
266u32 scic_cb_ssp_io_request_get_lun(
267 void *scic_user_io_request)
268{
269 return isci_request_ssp_io_request_get_lun(scic_user_io_request);
270}
271
272/**
273 * scic_cb_ssp_io_request_get_task_attribute() - This callback method asks the
274 * user to provide the task attribute associated with this IO request.
275 * @scic_user_io_request: This parameter points to the user's IO request
276 * object. It is a cookie that allows the user to provide the necessary
277 * information for this callback.
278 *
279 * This method returns the task attribute associated with this IO request.
280 */
281u32 scic_cb_ssp_io_request_get_task_attribute(
282 void *scic_user_io_request)
283{
284 return isci_request_ssp_io_request_get_task_attribute(
285 scic_user_io_request
286 );
287}
288
289/**
290 * scic_cb_ssp_io_request_get_command_priority() - This callback method asks
291 * the user to provide the command priority associated with this IO request.
292 * @scic_user_io_request: This parameter points to the user's IO request
293 * object. It is a cookie that allows the user to provide the necessary
294 * information for this callback.
295 *
296 * This method returns the command priority associated with this IO request.
297 */
298u32 scic_cb_ssp_io_request_get_command_priority(
299 void *scic_user_io_request)
300{
301 return isci_request_ssp_io_request_get_command_priority(
302 scic_user_io_request
303 );
304}
305
306/**
307 * scic_cb_ssp_task_request_get_lun() - This method returns the Logical Unit to
308 * be utilized for this task management request.
309 * @scic_user_task_request: This parameter points to the user's task request
310 * object. It is a cookie that allows the user to provide the necessary
311 * information for this callback.
312 *
313 * This method returns the LUN associated with this request. This should be u64?
314 */
315u32 scic_cb_ssp_task_request_get_lun(
316 void *scic_user_task_request)
317{
318 return isci_task_ssp_request_get_lun(
319 (struct isci_request *)scic_user_task_request
320 );
321}
322
323/**
324 * scic_cb_ssp_task_request_get_function() - This method returns the task
325 * management function to be utilized for this task request.
326 * @scic_user_task_request: This parameter points to the user's task request
327 * object. It is a cookie that allows the user to provide the necessary
328 * information for this callback.
329 *
330 * This method returns an unsigned byte representing the task management
331 * function to be performed.
332 */
333u8 scic_cb_ssp_task_request_get_function(
334 void *scic_user_task_request)
335{
336 return isci_task_ssp_request_get_function(
337 (struct isci_request *)scic_user_task_request
338 );
339}
340
341/**
342 * scic_cb_ssp_task_request_get_io_tag_to_manage() - This method returns the
343 * task management IO tag to be managed. Depending upon the task management
344 * function the value returned from this method may be ignored.
345 * @scic_user_task_request: This parameter points to the user's task request
346 * object. It is a cookie that allows the user to provide the necessary
347 * information for this callback.
348 *
349 * This method returns an unsigned 16-bit word depicting the IO tag to be
350 * managed.
351 */
352u16 scic_cb_ssp_task_request_get_io_tag_to_manage(
353 void *scic_user_task_request)
354{
355 return isci_task_ssp_request_get_io_tag_to_manage(
356 (struct isci_request *)scic_user_task_request
357 );
358}
359
360/**
361 * scic_cb_ssp_task_request_get_response_data_address() - This callback method
362 * asks the user to provide the virtual address of the response data buffer
363 * for the supplied IO request.
364 * @scic_user_task_request: This parameter points to the user's task request
365 * object. It is a cookie that allows the user to provide the necessary
366 * information for this callback.
367 *
368 * This method returns the virtual address for the response data buffer
369 * associated with this IO request.
370 */
371void *scic_cb_ssp_task_request_get_response_data_address(
372 void *scic_user_task_request)
373{
374 return isci_task_ssp_request_get_response_data_address(
375 (struct isci_request *)scic_user_task_request
376 );
377}
378
379/**
380 * scic_cb_ssp_task_request_get_response_data_length() - This callback method
381 * asks the user to provide the length of the response data buffer for the
382 * supplied IO request.
383 * @scic_user_task_request: This parameter points to the user's task request
384 * object. It is a cookie that allows the user to provide the necessary
385 * information for this callback.
386 *
387 * This method returns the length of the response buffer data associated with
388 * this IO request.
389 */
390u32 scic_cb_ssp_task_request_get_response_data_length(
391 void *scic_user_task_request)
392{
393 return isci_task_ssp_request_get_response_data_length(
394 (struct isci_request *)scic_user_task_request
395 );
396}
397
398#if !defined(DISABLE_ATAPI)
399/**
400 * scic_cb_stp_packet_io_request_get_cdb_address() - This user callback asks
401 * the user to provide stp packet io's the CDB address.
402 * @scic_user_io_request:
403 *
404 * The packet IO's cdb adress.
405 */
406void *scic_cb_stp_packet_io_request_get_cdb_address(
407 void *scic_user_io_request)
408{
409 return isci_request_stp_packet_io_request_get_cdb_address(
410 scic_user_io_request
411 );
412}
413
414
415/**
416 * scic_cb_stp_packet_io_request_get_cdb_length() - This user callback asks the
417 * user to provide stp packet io's the CDB length.
418 * @scic_user_io_request:
419 *
420 * The packet IO's cdb length.
421 */
422u32 scic_cb_stp_packet_io_request_get_cdb_length(
423 void *scic_user_io_request)
424{
425 return isci_request_stp_packet_io_request_get_cdb_length(
426 scic_user_io_request
427 );
428}
429#endif /* #if !defined(DISABLE_ATAPI) */
430
431
432/**
433 * scic_cb_io_request_do_copy_rx_frames() - This callback method asks the user
434 * if the received RX frame data is to be copied to the SGL or should be
435 * stored by the SCI core to be retrieved later with the
436 * scic_io_request_get_rx_frame().
437 * @scic_user_io_request: This parameter points to the user's IO request
438 * object. It is a cookie that allows the user to provide the necessary
439 * information for this callback.
440 *
441 * This method returns true if the SCI core should copy the received frame data
442 * to the SGL location or false if the SCI user wants to retrieve the frame
443 * data at a later time.
444 */
445bool scic_cb_io_request_do_copy_rx_frames(
446 void *scic_user_io_request)
447{
448 struct sas_task *task
449 = isci_request_access_task(
450 (struct isci_request *)scic_user_io_request
451 );
452
453 return (task->data_dir == DMA_NONE) ? false : true;
454}
455
456/**
457 * scic_cb_get_virtual_address() - This callback method asks the user to
458 * provide the virtual address for the supplied physical address.
459 * @controller: This parameter is the core controller object handle.
460 * @physical_address: This parameter is the physical address which is to be
461 * returned as a virtual address.
462 *
463 * The method returns the virtual address for the supplied physical address.
464 */
465void *scic_cb_get_virtual_address(
466 struct scic_sds_controller *controller,
467 dma_addr_t physical_address)
468{
469 void *virt_addr = (void *)phys_to_virt(physical_address);
470
471 return virt_addr;
472}
473
474/**
475 * scic_cb_request_get_sat_protocol() - This callback method asks the user to
476 * return the SAT protocol definition for this IO request. This method is
477 * only called by the SCI core if the request type constructed is SATA.
478 * @scic_user_io_request: This parameter points to the user's IO request
479 * object. It is a cookie that allows the user to provide the necessary
480 * information for this callback.
481 *
482 * This method returns one of the sat.h defined protocols for the given io
483 * request.
484 */
485u8 scic_cb_request_get_sat_protocol(
486 void *scic_user_io_request)
487{
488 return isci_sata_get_sat_protocol(
489 (struct isci_request *)scic_user_io_request
490 );
491}
diff --git a/drivers/scsi/isci/events.c b/drivers/scsi/isci/events.c
new file mode 100644
index 000000000000..75f9cd551278
--- /dev/null
+++ b/drivers/scsi/isci/events.c
@@ -0,0 +1,619 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56
57/**
58 * This file contains isci module object implementation.
59 *
60 *
61 */
62
63#include "isci.h"
64#include "request.h"
65#include "sata.h"
66#include "task.h"
67
68/**
69 * scic_cb_timer_create() - This callback method asks the user to create a
70 * timer and provide a handle for this timer for use in further timer
71 * interactions. The appropriate isci timer object function is called to
72 * create a timer object.
73 * @timer_callback: This parameter specifies the callback method to be invoked
74 * whenever the timer expires.
75 * @controller: This parameter specifies the controller with which this timer
76 * is to be associated.
77 * @cookie: This parameter specifies a piece of information that the user must
78 * retain. This cookie is to be supplied by the user anytime a timeout
79 * occurs for the created timer.
80 *
81 * This method returns a handle to a timer object created by the user. The
82 * handle will be utilized for all further interactions relating to this timer.
83 */
84void *scic_cb_timer_create(
85 struct scic_sds_controller *controller,
86 void (*timer_callback)(void *),
87 void *cookie)
88{
89 struct isci_host *isci_host;
90 struct isci_timer *timer = NULL;
91
92 isci_host = (struct isci_host *)sci_object_get_association(controller);
93
94 dev_dbg(&isci_host->pdev->dev,
95 "%s: isci_host = %p",
96 __func__, isci_host);
97
98 timer = isci_timer_create(&isci_host->timer_list_struct,
99 isci_host,
100 cookie,
101 timer_callback);
102
103 dev_dbg(&isci_host->pdev->dev, "%s: timer = %p\n", __func__, timer);
104
105 return (void *)timer;
106}
107
108
109/**
110 * scic_cb_timer_start() - This callback method asks the user to start the
111 * supplied timer. The appropriate isci timer object function is called to
112 * start the timer.
113 * @controller: This parameter specifies the controller with which this timer
114 * is to associated.
115 * @timer: This parameter specifies the timer to be started.
116 * @milliseconds: This parameter specifies the number of milliseconds for which
117 * to stall. The operating system driver is allowed to round this value up
118 * where necessary.
119 *
120 */
121void scic_cb_timer_start(
122 struct scic_sds_controller *controller,
123 void *timer,
124 u32 milliseconds)
125{
126 struct isci_host *isci_host;
127
128 isci_host =
129 (struct isci_host *)sci_object_get_association(controller);
130
131 dev_dbg(&isci_host->pdev->dev,
132 "%s: isci_host = %p, timer = %p, milliseconds = %d\n",
133 __func__, isci_host, timer, milliseconds);
134
135 isci_timer_start((struct isci_timer *)timer, milliseconds);
136
137}
138
139/**
140 * scic_cb_timer_stop() - This callback method asks the user to stop the
141 * supplied timer. The appropriate isci timer object function is called to
142 * stop the timer.
143 * @controller: This parameter specifies the controller with which this timer
144 * is to associated.
145 * @timer: This parameter specifies the timer to be stopped.
146 *
147 */
148void scic_cb_timer_stop(
149 struct scic_sds_controller *controller,
150 void *timer)
151{
152 struct isci_host *isci_host;
153
154 isci_host =
155 (struct isci_host *)sci_object_get_association(controller);
156
157 dev_dbg(&isci_host->pdev->dev,
158 "%s: isci_host = %p, timer = %p\n",
159 __func__, isci_host, timer);
160
161 isci_timer_stop((struct isci_timer *)timer);
162}
163
164/**
165 * scic_cb_controller_start_complete() - This user callback will inform the
166 * user that the controller has finished the start process. The associated
167 * isci host adapter's start_complete function is called.
168 * @controller: This parameter specifies the controller that was started.
169 * @completion_status: This parameter specifies the results of the start
170 * operation. SCI_SUCCESS indicates successful completion.
171 *
172 */
173void scic_cb_controller_start_complete(
174 struct scic_sds_controller *controller,
175 enum sci_status completion_status)
176{
177 struct isci_host *isci_host =
178 (struct isci_host *)sci_object_get_association(controller);
179
180 dev_dbg(&isci_host->pdev->dev,
181 "%s: isci_host = %p\n", __func__, isci_host);
182
183 isci_host_start_complete(isci_host, completion_status);
184}
185
186/**
187 * scic_cb_controller_stop_complete() - This user callback will inform the user
188 * that the controller has finished the stop process. The associated isci
189 * host adapter's start_complete function is called.
190 * @controller: This parameter specifies the controller that was stopped.
191 * @completion_status: This parameter specifies the results of the stop
192 * operation. SCI_SUCCESS indicates successful completion.
193 *
194 */
195void scic_cb_controller_stop_complete(
196 struct scic_sds_controller *controller,
197 enum sci_status completion_status)
198{
199 struct isci_host *isci_host =
200 (struct isci_host *)sci_object_get_association(controller);
201
202 dev_dbg(&isci_host->pdev->dev,
203 "%s: status = 0x%x\n", __func__, completion_status);
204 isci_host_stop_complete(isci_host, completion_status);
205}
206
207/**
208 * scic_cb_io_request_complete() - This user callback will inform the user that
209 * an IO request has completed.
210 * @controller: This parameter specifies the controller on which the IO is
211 * completing.
212 * @remote_device: This parameter specifies the remote device on which this IO
213 * request is completing.
214 * @io_request: This parameter specifies the IO request that has completed.
215 * @completion_status: This parameter specifies the results of the IO request
216 * operation. SCI_SUCCESS indicates successful completion.
217 *
218 */
219void scic_cb_io_request_complete(
220 struct scic_sds_controller *controller,
221 struct scic_sds_remote_device *remote_device,
222 struct scic_sds_request *scic_io_request,
223 enum sci_io_status completion_status)
224{
225 struct isci_request *request;
226 struct isci_host *isci_host;
227
228 isci_host =
229 (struct isci_host *)sci_object_get_association(controller);
230
231 request =
232 (struct isci_request *)sci_object_get_association(
233 scic_io_request
234 );
235
236 isci_request_io_request_complete(isci_host,
237 request,
238 completion_status);
239}
240
241/**
242 * scic_cb_task_request_complete() - This user callback will inform the user
243 * that a task management request completed.
244 * @controller: This parameter specifies the controller on which the task
245 * management request is completing.
246 * @remote_device: This parameter specifies the remote device on which this
247 * task management request is completing.
248 * @task_request: This parameter specifies the task management request that has
249 * completed.
250 * @completion_status: This parameter specifies the results of the IO request
251 * operation. SCI_SUCCESS indicates successful completion.
252 *
253 */
254void scic_cb_task_request_complete(
255 struct scic_sds_controller *controller,
256 struct scic_sds_remote_device *remote_device,
257 struct scic_sds_request *scic_task_request,
258 enum sci_task_status completion_status)
259{
260 struct isci_request *request;
261 struct isci_host *isci_host;
262
263 isci_host =
264 (struct isci_host *)sci_object_get_association(controller);
265
266 request =
267 (struct isci_request *)sci_object_get_association(
268 scic_task_request);
269
270 isci_task_request_complete(isci_host, request, completion_status);
271}
272
273/**
274 * scic_cb_port_stop_complete() - This method informs the user when a stop
275 * operation on the port has completed.
276 * @controller: This parameter represents the controller which contains the
277 * port.
278 * @port: This parameter specifies the SCI port object for which the callback
279 * is being invoked.
280 * @completion_status: This parameter specifies the status for the operation
281 * being completed.
282 *
283 */
284void scic_cb_port_stop_complete(
285 struct scic_sds_controller *controller,
286 struct scic_sds_port *port,
287 enum sci_status completion_status)
288{
289 pr_warn("%s:************************************************\n",
290 __func__);
291}
292
293/**
294 * scic_cb_port_hard_reset_complete() - This method informs the user when a
295 * hard reset on the port has completed. This hard reset could have been
296 * initiated by the user or by the remote port.
297 * @controller: This parameter represents the controller which contains the
298 * port.
299 * @port: This parameter specifies the SCI port object for which the callback
300 * is being invoked.
301 * @completion_status: This parameter specifies the status for the operation
302 * being completed.
303 *
304 */
305void scic_cb_port_hard_reset_complete(
306 struct scic_sds_controller *controller,
307 struct scic_sds_port *port,
308 enum sci_status completion_status)
309{
310 struct isci_port *isci_port
311 = (struct isci_port *)sci_object_get_association(port);
312
313 isci_port_hard_reset_complete(isci_port, completion_status);
314}
315
316/**
317 * scic_cb_port_ready() - This method informs the user that the port is now in
318 * a ready state and can be utilized to issue IOs.
319 * @controller: This parameter represents the controller which contains the
320 * port.
321 * @port: This parameter specifies the SCI port object for which the callback
322 * is being invoked.
323 *
324 */
325void scic_cb_port_ready(
326 struct scic_sds_controller *controller,
327 struct scic_sds_port *port)
328{
329 struct isci_port *isci_port;
330 struct isci_host *isci_host;
331
332 isci_host =
333 (struct isci_host *)sci_object_get_association(controller);
334
335 isci_port =
336 (struct isci_port *)sci_object_get_association(port);
337
338 dev_dbg(&isci_host->pdev->dev,
339 "%s: isci_port = %p\n", __func__, isci_port);
340
341 isci_port_ready(isci_host, isci_port);
342}
343
344/**
345 * scic_cb_port_not_ready() - This method informs the user that the port is now
346 * not in a ready (i.e. busy) state and can't be utilized to issue IOs.
347 * @controller: This parameter represents the controller which contains the
348 * port.
349 * @port: This parameter specifies the SCI port object for which the callback
350 * is being invoked.
351 *
352 */
353void scic_cb_port_not_ready(
354 struct scic_sds_controller *controller,
355 struct scic_sds_port *port,
356 u32 reason_code)
357{
358 struct isci_port *isci_port;
359 struct isci_host *isci_host;
360
361 isci_host =
362 (struct isci_host *)sci_object_get_association(controller);
363
364 isci_port =
365 (struct isci_port *)sci_object_get_association(port);
366
367 dev_dbg(&isci_host->pdev->dev,
368 "%s: isci_port = %p\n", __func__, isci_port);
369
370 isci_port_not_ready(isci_host, isci_port);
371}
372
373/**
374 * scic_cb_port_invalid_link_up() - This method informs the SCI Core user that
375 * a phy/link became ready, but the phy is not allowed in the port. In some
376 * situations the underlying hardware only allows for certain phy to port
377 * mappings. If these mappings are violated, then this API is invoked.
378 * @controller: This parameter represents the controller which contains the
379 * port.
380 * @port: This parameter specifies the SCI port object for which the callback
381 * is being invoked.
382 * @phy: This parameter specifies the phy that came ready, but the phy can't be
383 * a valid member of the port.
384 *
385 */
386void scic_cb_port_invalid_link_up(
387 struct scic_sds_controller *controller,
388 struct scic_sds_port *port,
389 struct scic_sds_phy *phy)
390{
391 pr_warn("%s:************************************************\n",
392 __func__);
393}
394
395/**
396 * scic_cb_port_bc_change_primitive_received() - This callback method informs
397 * the user that a broadcast change primitive was received.
398 * @controller: This parameter represents the controller which contains the
399 * port.
400 * @port: This parameter specifies the SCI port object for which the callback
401 * is being invoked. For instances where the phy on which the primitive was
402 * received is not part of a port, this parameter will be
403 * SCI_INVALID_HANDLE_T.
404 * @phy: This parameter specifies the phy on which the primitive was received.
405 *
406 */
407void scic_cb_port_bc_change_primitive_received(
408 struct scic_sds_controller *controller,
409 struct scic_sds_port *port,
410 struct scic_sds_phy *phy)
411{
412 struct isci_host *isci_host;
413
414 isci_host =
415 (struct isci_host *)sci_object_get_association(controller);
416
417 dev_dbg(&isci_host->pdev->dev,
418 "%s: port = %p, phy = %p\n", __func__, port, phy);
419 isci_port_bc_change_received(isci_host, port, phy);
420}
421
422
423
424
425/**
426 * scic_cb_port_link_up() - This callback method informs the user that a phy
427 * has become operational and is capable of communicating with the remote
428 * end point.
429 * @controller: This parameter represents the controller associated with the
430 * phy.
431 * @port: This parameter specifies the port object for which the user callback
432 * is being invoked. There may be conditions where this parameter can be
433 * SCI_INVALID_HANDLE
434 * @phy: This parameter specifies the phy object for which the user callback is
435 * being invoked.
436 *
437 * none.
438 */
439void scic_cb_port_link_up(
440 struct scic_sds_controller *controller,
441 struct scic_sds_port *port,
442 struct scic_sds_phy *phy)
443{
444 struct isci_host *isci_host;
445
446 isci_host =
447 (struct isci_host *)sci_object_get_association(controller);
448
449 dev_dbg(&isci_host->pdev->dev,
450 "%s: phy = %p\n", __func__, phy);
451
452 isci_port_link_up(isci_host, port, phy);
453}
454
455/**
456 * scic_cb_port_link_down() - This callback method informs the user that a phy
457 * is no longer operational and is not capable of communicating with the
458 * remote end point.
459 * @controller: This parameter represents the controller associated with the
460 * phy.
461 * @port: This parameter specifies the port object for which the user callback
462 * is being invoked. There may be conditions where this parameter can be
463 * SCI_INVALID_HANDLE
464 * @phy: This parameter specifies the phy object for which the user callback is
465 * being invoked.
466 *
467 * none.
468 */
469void scic_cb_port_link_down(
470 struct scic_sds_controller *controller,
471 struct scic_sds_port *port,
472 struct scic_sds_phy *phy)
473{
474 struct isci_host *isci_host;
475 struct isci_phy *isci_phy;
476 struct isci_port *isci_port;
477
478 isci_host =
479 (struct isci_host *)sci_object_get_association(controller);
480
481 isci_phy =
482 (struct isci_phy *)sci_object_get_association(phy);
483
484 isci_port =
485 (struct isci_port *)sci_object_get_association(port);
486
487 dev_dbg(&isci_host->pdev->dev,
488 "%s: isci_port = %p\n", __func__, isci_port);
489
490 isci_port_link_down(isci_host, isci_phy, isci_port);
491}
492
493/**
494 * scic_cb_remote_device_start_complete() - This user callback method will
495 * inform the user that a start operation has completed.
496 * @controller: This parameter specifies the core controller associated with
497 * the completion callback.
498 * @remote_device: This parameter specifies the remote device associated with
499 * the completion callback.
500 * @completion_status: This parameter specifies the completion status for the
501 * operation.
502 *
503 */
504void scic_cb_remote_device_start_complete(
505 struct scic_sds_controller *controller,
506 struct scic_sds_remote_device *remote_device,
507 enum sci_status completion_status)
508{
509 struct isci_host *isci_host;
510 struct isci_remote_device *isci_device;
511
512 isci_host =
513 (struct isci_host *)sci_object_get_association(controller);
514
515 isci_device =
516 (struct isci_remote_device *)sci_object_get_association(
517 remote_device
518 );
519
520 dev_dbg(&isci_host->pdev->dev,
521 "%s: isci_device = %p\n", __func__, isci_device);
522
523 isci_remote_device_start_complete(
524 isci_host, isci_device, completion_status);
525
526}
527
528/**
529 * scic_cb_remote_device_stop_complete() - This user callback method will
530 * inform the user that a stop operation has completed.
531 * @controller: This parameter specifies the core controller associated with
532 * the completion callback.
533 * @remote_device: This parameter specifies the remote device associated with
534 * the completion callback.
535 * @completion_status: This parameter specifies the completion status for the
536 * operation.
537 *
538 */
539void scic_cb_remote_device_stop_complete(
540 struct scic_sds_controller *controller,
541 struct scic_sds_remote_device *remote_device,
542 enum sci_status completion_status)
543{
544 struct isci_host *isci_host;
545 struct isci_remote_device *isci_device;
546
547 isci_host =
548 (struct isci_host *)sci_object_get_association(controller);
549
550 isci_device =
551 (struct isci_remote_device *)sci_object_get_association(
552 remote_device
553 );
554
555 dev_dbg(&isci_host->pdev->dev,
556 "%s: isci_device = %p\n", __func__, isci_device);
557
558 isci_remote_device_stop_complete(
559 isci_host, isci_device, completion_status);
560
561}
562
563/**
564 * scic_cb_remote_device_ready() - This user callback method will inform the
565 * user that a remote device is now capable of handling IO requests.
566 * @controller: This parameter specifies the core controller associated with
567 * the completion callback.
568 * @remote_device: This parameter specifies the remote device associated with
569 * the callback.
570 *
571 */
572void scic_cb_remote_device_ready(
573 struct scic_sds_controller *controller,
574 struct scic_sds_remote_device *remote_device)
575{
576 struct isci_remote_device *isci_device =
577 (struct isci_remote_device *)
578 sci_object_get_association(remote_device);
579
580 dev_dbg(&isci_device->isci_port->isci_host->pdev->dev,
581 "%s: isci_device = %p\n", __func__, isci_device);
582
583 isci_remote_device_ready(isci_device);
584}
585
586/**
587 * scic_cb_remote_device_not_ready() - This user callback method will inform
588 * the user that a remote device is no longer capable of handling IO
589 * requests (until a ready callback is invoked).
590 * @controller: This parameter specifies the core controller associated with
591 * the completion callback.
592 * @remote_device: This parameter specifies the remote device associated with
593 * the callback.
594 * @reason_code: This parameter specifies the reason for the remote device
595 * going to a not ready state.
596 *
597 */
598void scic_cb_remote_device_not_ready(
599 struct scic_sds_controller *controller,
600 struct scic_sds_remote_device *remote_device,
601 u32 reason_code)
602{
603 struct isci_remote_device *isci_device =
604 (struct isci_remote_device *)
605 sci_object_get_association(remote_device);
606
607 struct isci_host *isci_host;
608
609 isci_host =
610 (struct isci_host *)sci_object_get_association(controller);
611
612 dev_dbg(&isci_host->pdev->dev,
613 "%s: isci_device = %p, reason_code = %x\n",
614 __func__, isci_device, reason_code);
615
616 isci_remote_device_not_ready(isci_device, reason_code);
617}
618
619
diff --git a/drivers/scsi/isci/firmware/Makefile b/drivers/scsi/isci/firmware/Makefile
new file mode 100644
index 000000000000..5f54461cabc5
--- /dev/null
+++ b/drivers/scsi/isci/firmware/Makefile
@@ -0,0 +1,19 @@
1# Makefile for create_fw
2#
3CC=gcc
4CFLAGS=-c -Wall -O2 -g
5LDFLAGS=
6SOURCES=create_fw.c
7OBJECTS=$(SOURCES:.cpp=.o)
8EXECUTABLE=create_fw
9
10all: $(SOURCES) $(EXECUTABLE)
11
12$(EXECUTABLE): $(OBJECTS)
13 $(CC) $(LDFLAGS) $(OBJECTS) -o $@
14
15.c.o:
16 $(CC) $(CFLAGS) $< -O $@
17
18clean:
19 rm -f *.o $(EXECUTABLE)
diff --git a/drivers/scsi/isci/firmware/README b/drivers/scsi/isci/firmware/README
new file mode 100644
index 000000000000..cf7e4286e896
--- /dev/null
+++ b/drivers/scsi/isci/firmware/README
@@ -0,0 +1,36 @@
1This defines the temporary binary blow we are to pass to the SCU
2driver to emulate the binary firmware that we will eventually be
3able to access via NVRAM on the SCU controller.
4
5The current size of the binary blob is expected to be 149 bytes or larger
6
7Header Types:
80x1: Phy Masks
90x2: Phy Gens
100x3: SAS Addrs
110xff: End of Data
12
13ID string - u8[12]: "#SCU MAGIC#\0"
14Version - u8: 1
15SubVersion - u8: 0
16
17Header Type - u8: 0x1
18Size - u8: 8
19Phy Mask - u32[8]
20
21Header Type - u8: 0x2
22Size - u8: 8
23Phy Gen - u32[8]
24
25Header Type - u8: 0x3
26Size - u8: 8
27Sas Addr - u64[8]
28
29Header Type - u8: 0xf
30
31
32==============================================================================
33
34Place isci_firmware.bin in /lib/firmware
35Be sure to recreate the initramfs image to include the firmware.
36
diff --git a/drivers/scsi/isci/firmware/create_fw.c b/drivers/scsi/isci/firmware/create_fw.c
new file mode 100644
index 000000000000..442caac9675d
--- /dev/null
+++ b/drivers/scsi/isci/firmware/create_fw.c
@@ -0,0 +1,177 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <fcntl.h>
7#include <string.h>
8#include <errno.h>
9
10char blob_name[] = "isci_firmware.bin";
11char id[] = "#SCU MAGIC#";
12unsigned char version = 1;
13unsigned char sub_version = 0;
14
15
16/*
17 * For all defined arrays:
18 * elements 0-3 are for SCU0, ports 0-3
19 * elements 4-7 are for SCU1, ports 0-3
20 *
21 * valid configurations for one SCU are:
22 * P0 P1 P2 P3
23 * ----------------
24 * 0xF,0x0,0x0,0x0 # 1 x4 port
25 * 0x3,0x0,0x4,0x8 # Phys 0 and 1 are a x2 port, phy 2 and phy 3 are each x1
26 * # ports
27 * 0x1,0x2,0xC,0x0 # Phys 0 and 1 are each x1 ports, phy 2 and phy 3 are a x2
28 * # port
29 * 0x3,0x0,0xC,0x0 # Phys 0 and 1 are a x2 port, phy 2 and phy 3 are a x2 port
30 * 0x1,0x2,0x4,0x8 # Each phy is a x1 port (this is the default configuration)
31 *
32 * if there is a port/phy on which you do not wish to override the default
33 * values, use the value assigned to UNINIT_PARAM (255).
34 */
35unsigned int phy_mask[] = { 1, 2, 4, 8, 1, 2, 4, 8 };
36
37
38/* denotes SAS generation. i.e. 3: SAS Gen 3 6G */
39unsigned int phy_gen[] = { 3, 3, 3, 3, 3, 3, 3, 3 };
40
41/*
42 * if there is a port/phy on which you do not wish to override the default
43 * values, use the value "0000000000000000". SAS address of zero's is
44 * considered invalid and will not be used.
45 */
46unsigned long long sas_addr[] = { 0x5FCFFFFFF0000000ULL,
47 0x5FCFFFFFF1000000ULL,
48 0x5FCFFFFFF2000000ULL,
49 0x5FCFFFFFF3000000ULL,
50 0x5FCFFFFFF4000000ULL,
51 0x5FCFFFFFF5000000ULL,
52 0x5FCFFFFFF6000000ULL,
53 0x5FCFFFFFF7000000ULL };
54
55int write_blob(void)
56{
57 FILE *fd;
58 int err;
59
60 fd = fopen(blob_name, "w+");
61 if (!fd) {
62 perror("Open file for write failed");
63 return -EIO;
64 }
65
66 /* write id */
67 err = fwrite((void *)id, sizeof(char), strlen(id)+1, fd);
68 if (err == 0) {
69 perror("write id failed");
70 return err;
71 }
72
73 /* write version */
74 err = fwrite((void *)&version, sizeof(version), 1, fd);
75 if (err == 0) {
76 perror("write version failed");
77 return err;
78 }
79
80 /* write sub version */
81 err = fwrite((void *)&sub_version, sizeof(sub_version), 1, fd);
82 if (err == 0) {
83 perror("write subversion failed");
84 return err;
85 }
86
87 /* write phy mask header */
88 err = fputc(0x1, fd);
89 if (err == EOF) {
90 perror("write phy mask header failed");
91 return -EIO;
92 }
93
94 /* write size */
95 err = fputc(8, fd);
96 if (err == EOF) {
97 perror("write phy mask size failed");
98 return -EIO;
99 }
100
101 /* write phy masks */
102 err = fwrite((void *)phy_mask, 1, sizeof(phy_mask), fd);
103 if (err == 0) {
104 perror("write phy_mask failed");
105 return err;
106 }
107
108 /* write phy gen header */
109 err = fputc(0x2, fd);
110 if (err == EOF) {
111 perror("write phy gen header failed");
112 return -EIO;
113 }
114
115 /* write size */
116 err = fputc(8, fd);
117 if (err == EOF) {
118 perror("write phy gen size failed");
119 return -EIO;
120 }
121
122 /* write phy_gen */
123 err = fwrite((void *)phy_gen,
124 1,
125 sizeof(phy_gen),
126 fd);
127 if (err == 0) {
128 perror("write phy_gen failed");
129 return err;
130 }
131
132 /* write phy gen header */
133 err = fputc(0x3, fd);
134 if (err == EOF) {
135 perror("write sas addr header failed");
136 return -EIO;
137 }
138
139 /* write size */
140 err = fputc(8, fd);
141 if (err == EOF) {
142 perror("write sas addr size failed");
143 return -EIO;
144 }
145
146 /* write sas_addr */
147 err = fwrite((void *)sas_addr,
148 1,
149 sizeof(sas_addr),
150 fd);
151 if (err == 0) {
152 perror("write sas_addr failed");
153 return err;
154 }
155
156 /* write end header */
157 err = fputc(0xff, fd);
158 if (err == EOF) {
159 perror("write end header failed");
160 return -EIO;
161 }
162
163 fclose(fd);
164
165 return 0;
166}
167
168int main(void)
169{
170 int err;
171
172 err = write_blob();
173 if (err < 0)
174 return err;
175
176 return 0;
177}
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
new file mode 100644
index 000000000000..6f16f4d6c82b
--- /dev/null
+++ b/drivers/scsi/isci/host.c
@@ -0,0 +1,781 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include "isci.h"
57#include "scic_io_request.h"
58#include "scic_remote_device.h"
59#include "scic_port.h"
60
61#include "port.h"
62#include "request.h"
63#include "host.h"
64
65/**
66 * isci_isr() - This function is the interrupt service routine for the
67 * controller. It schedules the tasklet and returns.
68 * @vec: This parameter specifies the interrupt vector.
69 * @data: This parameter specifies the ISCI host object.
70 *
71 * IRQ_HANDLED if out interrupt otherwise, IRQ_NONE
72 */
73irqreturn_t isci_isr(int vec, void *data)
74{
75 struct isci_host *isci_host
76 = (struct isci_host *)data;
77 struct scic_controller_handler_methods *handlers
78 = &isci_host->scic_irq_handlers[SCI_MSIX_NORMAL_VECTOR];
79 irqreturn_t ret = IRQ_NONE;
80
81 if (isci_host_get_state(isci_host) != isci_starting
82 && handlers->interrupt_handler) {
83
84 if (handlers->interrupt_handler(isci_host->core_controller)) {
85 if (isci_host_get_state(isci_host) != isci_stopped) {
86 tasklet_schedule(
87 &isci_host->completion_tasklet);
88 } else
89 dev_dbg(&isci_host->pdev->dev,
90 "%s: controller stopped\n",
91 __func__);
92 ret = IRQ_HANDLED;
93 }
94 } else
95 dev_warn(&isci_host->pdev->dev,
96 "%s: get_handler_methods failed, "
97 "isci_host->status = 0x%x\n",
98 __func__,
99 isci_host_get_state(isci_host));
100
101 return ret;
102}
103
104irqreturn_t isci_legacy_isr(int vec, void *data)
105{
106 struct pci_dev *pdev = data;
107 struct isci_host *isci_host;
108 struct scic_controller_handler_methods *handlers;
109 irqreturn_t ret = IRQ_NONE;
110
111 /*
112 * Since this is a legacy interrupt, either or both
113 * controllers could have triggered it. Thus, we have to call
114 * the legacy interrupt handler for all controllers on the
115 * PCI function.
116 */
117 for_each_isci_host(isci_host, pdev) {
118 handlers = &isci_host->scic_irq_handlers[SCI_MSIX_NORMAL_VECTOR];
119
120 if (isci_host_get_state(isci_host) != isci_starting
121 && handlers->interrupt_handler) {
122
123 if (handlers->interrupt_handler(isci_host->core_controller)) {
124 if (isci_host_get_state(isci_host) != isci_stopped) {
125 tasklet_schedule(
126 &isci_host->completion_tasklet);
127 } else
128 dev_dbg(&isci_host->pdev->dev,
129 "%s: controller stopped\n",
130 __func__);
131 ret = IRQ_HANDLED;
132 }
133 } else
134 dev_warn(&isci_host->pdev->dev,
135 "%s: get_handler_methods failed, "
136 "isci_host->status = 0x%x\n",
137 __func__,
138 isci_host_get_state(isci_host));
139 }
140 return ret;
141}
142
143
144/**
145 * isci_host_start_complete() - This function is called by the core library,
146 * through the ISCI Module, to indicate controller start status.
147 * @isci_host: This parameter specifies the ISCI host object
148 * @completion_status: This parameter specifies the completion status from the
149 * core library.
150 *
151 */
152void isci_host_start_complete(
153 struct isci_host *isci_host,
154 enum sci_status completion_status)
155{
156 if (completion_status == SCI_SUCCESS) {
157 dev_dbg(&isci_host->pdev->dev,
158 "%s: completion_status: SCI_SUCCESS\n", __func__);
159 isci_host_change_state(isci_host, isci_ready);
160 complete_all(&isci_host->start_complete);
161 } else
162 dev_err(&isci_host->pdev->dev,
163 "controller start failed with "
164 "completion_status = 0x%x;",
165 completion_status);
166
167}
168
169
170
171/**
172 * isci_host_scan_finished() - This function is one of the SCSI Host Template
173 * functions. The SCSI midlayer calls this function during a target scan,
174 * approx. once every 10 millisecs.
175 * @shost: This parameter specifies the SCSI host being scanned
176 * @time: This parameter specifies the number of ticks since the scan started.
177 *
178 * scan status, zero indicates the SCSI midlayer should continue to poll,
179 * otherwise assume controller is ready.
180 */
181int isci_host_scan_finished(
182 struct Scsi_Host *shost,
183 unsigned long time)
184{
185 struct isci_host *isci_host
186 = isci_host_from_sas_ha(SHOST_TO_SAS_HA(shost));
187
188 struct scic_controller_handler_methods *handlers
189 = &isci_host->scic_irq_handlers[SCI_MSIX_NORMAL_VECTOR];
190
191 if (handlers->interrupt_handler == NULL) {
192 dev_err(&isci_host->pdev->dev,
193 "%s: scic_controller_get_handler_methods failed\n",
194 __func__);
195 return 1;
196 }
197
198 /**
199 * check interrupt_handler's status and call completion_handler if true,
200 * link_up events should be coming from the scu core lib, as phy's come
201 * online. for each link_up from the core, call
202 * get_received_identify_address_frame, copy the frame into the
203 * sas_phy object and call libsas notify_port_event(PORTE_BYTES_DMAED).
204 * continue to return zero from thee scan_finished routine until
205 * the scic_cb_controller_start_complete() call comes from the core.
206 **/
207 if (handlers->interrupt_handler(isci_host->core_controller))
208 handlers->completion_handler(isci_host->core_controller);
209
210 if (isci_starting == isci_host_get_state(isci_host)
211 && time < (HZ * 10)) {
212 dev_dbg(&isci_host->pdev->dev,
213 "%s: isci_host->status = %d, time = %ld\n",
214 __func__, isci_host_get_state(isci_host), time);
215 return 0;
216 }
217
218
219 dev_dbg(&isci_host->pdev->dev,
220 "%s: isci_host->status = %d, time = %ld\n",
221 __func__, isci_host_get_state(isci_host), time);
222
223 scic_controller_enable_interrupts(isci_host->core_controller);
224
225 return 1;
226
227}
228
229
230/**
231 * isci_host_scan_start() - This function is one of the SCSI Host Template
232 * function, called by the SCSI mid layer berfore a target scan begins. The
233 * core library controller start routine is called from here.
234 * @shost: This parameter specifies the SCSI host to be scanned
235 *
236 */
237void isci_host_scan_start(struct Scsi_Host *shost)
238{
239 struct isci_host *isci_host;
240
241 isci_host = isci_host_from_sas_ha(SHOST_TO_SAS_HA(shost));
242 isci_host_change_state(isci_host, isci_starting);
243
244 scic_controller_disable_interrupts(isci_host->core_controller);
245 init_completion(&isci_host->start_complete);
246 scic_controller_start(
247 isci_host->core_controller,
248 scic_controller_get_suggested_start_timeout(
249 isci_host->core_controller)
250 );
251}
252
253void isci_host_stop_complete(
254 struct isci_host *isci_host,
255 enum sci_status completion_status)
256{
257 isci_host_change_state(isci_host, isci_stopped);
258 scic_controller_disable_interrupts(
259 isci_host->core_controller
260 );
261 complete(&isci_host->stop_complete);
262}
263
264static struct coherent_memory_info *isci_host_alloc_mdl_struct(
265 struct isci_host *isci_host,
266 u32 size)
267{
268 struct coherent_memory_info *mdl_struct;
269 void *uncached_address = NULL;
270
271
272 mdl_struct = devm_kzalloc(&isci_host->pdev->dev,
273 sizeof(*mdl_struct),
274 GFP_KERNEL);
275 if (!mdl_struct)
276 return NULL;
277
278 INIT_LIST_HEAD(&mdl_struct->node);
279
280 uncached_address = dmam_alloc_coherent(&isci_host->pdev->dev,
281 size,
282 &mdl_struct->dma_handle,
283 GFP_KERNEL);
284 if (!uncached_address)
285 return NULL;
286
287 /* memset the whole memory area. */
288 memset((char *)uncached_address, 0, size);
289 mdl_struct->vaddr = uncached_address;
290 mdl_struct->size = (size_t)size;
291
292 return mdl_struct;
293}
294
295static void isci_host_build_mde(
296 struct sci_physical_memory_descriptor *mde_struct,
297 struct coherent_memory_info *mdl_struct)
298{
299 unsigned long address = 0;
300 dma_addr_t dma_addr = 0;
301
302 address = (unsigned long)mdl_struct->vaddr;
303 dma_addr = mdl_struct->dma_handle;
304
305 /* to satisfy the alignment. */
306 if ((address % mde_struct->constant_memory_alignment) != 0) {
307 int align_offset
308 = (mde_struct->constant_memory_alignment
309 - (address % mde_struct->constant_memory_alignment));
310 address += align_offset;
311 dma_addr += align_offset;
312 }
313
314 mde_struct->virtual_address = (void *)address;
315 mde_struct->physical_address = dma_addr;
316 mdl_struct->mde = mde_struct;
317}
318
319static int isci_host_mdl_allocate_coherent(
320 struct isci_host *isci_host)
321{
322 struct sci_physical_memory_descriptor *current_mde;
323 struct coherent_memory_info *mdl_struct;
324 u32 size = 0;
325
326 struct sci_base_memory_descriptor_list *mdl_handle
327 = sci_controller_get_memory_descriptor_list_handle(
328 isci_host->core_controller);
329
330 sci_mdl_first_entry(mdl_handle);
331
332 current_mde = sci_mdl_get_current_entry(mdl_handle);
333
334 while (current_mde != NULL) {
335
336 size = (current_mde->constant_memory_size
337 + current_mde->constant_memory_alignment);
338
339 mdl_struct = isci_host_alloc_mdl_struct(isci_host, size);
340 if (!mdl_struct)
341 return -ENOMEM;
342
343 list_add_tail(&mdl_struct->node, &isci_host->mdl_struct_list);
344
345 isci_host_build_mde(current_mde, mdl_struct);
346
347 sci_mdl_next_entry(mdl_handle);
348 current_mde = sci_mdl_get_current_entry(mdl_handle);
349 }
350
351 return 0;
352}
353
354
355/**
356 * isci_host_completion_routine() - This function is the delayed service
357 * routine that calls the sci core library's completion handler. It's
358 * scheduled as a tasklet from the interrupt service routine when interrupts
359 * in use, or set as the timeout function in polled mode.
360 * @data: This parameter specifies the ISCI host object
361 *
362 */
363static void isci_host_completion_routine(unsigned long data)
364{
365 struct isci_host *isci_host = (struct isci_host *)data;
366 struct scic_controller_handler_methods *handlers
367 = &isci_host->scic_irq_handlers[SCI_MSIX_NORMAL_VECTOR];
368 struct list_head completed_request_list;
369 struct list_head aborted_request_list;
370 struct list_head *current_position;
371 struct list_head *next_position;
372 struct isci_request *request;
373 struct isci_request *next_request;
374 struct sas_task *task;
375
376 INIT_LIST_HEAD(&completed_request_list);
377 INIT_LIST_HEAD(&aborted_request_list);
378
379 spin_lock_irq(&isci_host->scic_lock);
380
381 if (handlers->completion_handler) {
382 handlers->completion_handler(
383 isci_host->core_controller
384 );
385 }
386 /* Take the lists of completed I/Os from the host. */
387 list_splice_init(&isci_host->requests_to_complete,
388 &completed_request_list);
389
390 list_splice_init(&isci_host->requests_to_abort,
391 &aborted_request_list);
392
393 spin_unlock_irq(&isci_host->scic_lock);
394
395 /* Process any completions in the lists. */
396 list_for_each_safe(current_position, next_position,
397 &completed_request_list) {
398
399 request = list_entry(current_position, struct isci_request,
400 completed_node);
401 task = isci_request_access_task(request);
402
403 /* Normal notification (task_done) */
404 dev_dbg(&isci_host->pdev->dev,
405 "%s: Normal - request/task = %p/%p\n",
406 __func__,
407 request,
408 task);
409
410 task->task_done(task);
411 task->lldd_task = NULL;
412
413 /* Free the request object. */
414 isci_request_free(isci_host, request);
415 }
416 list_for_each_entry_safe(request, next_request, &aborted_request_list,
417 completed_node) {
418
419 task = isci_request_access_task(request);
420
421 /* Use sas_task_abort */
422 dev_warn(&isci_host->pdev->dev,
423 "%s: Error - request/task = %p/%p\n",
424 __func__,
425 request,
426 task);
427
428 /* Put the task into the abort path. */
429 sas_task_abort(task);
430 }
431
432}
433
434void isci_host_deinit(
435 struct isci_host *isci_host)
436{
437 int i;
438
439 isci_host_change_state(isci_host, isci_stopping);
440 for (i = 0; i < SCI_MAX_PORTS; i++) {
441 struct isci_port *port = &isci_host->isci_ports[i];
442 struct isci_remote_device *device, *tmpdev;
443 list_for_each_entry_safe(device, tmpdev,
444 &port->remote_dev_list, node) {
445 isci_remote_device_change_state(device, isci_stopping);
446 isci_remote_device_stop(device);
447 }
448 }
449
450 /* stop the comtroller and wait for completion. */
451 init_completion(&isci_host->stop_complete);
452 scic_controller_stop(
453 isci_host->core_controller,
454 SCIC_CONTROLLER_STOP_TIMEOUT
455 );
456 wait_for_completion(&isci_host->stop_complete);
457 /* next, reset the controller. */
458 scic_controller_reset(isci_host->core_controller);
459}
460
461static int isci_verify_firmware(const struct firmware *fw,
462 struct isci_firmware *isci_fw)
463{
464 const u8 *tmp;
465
466 if (fw->size < ISCI_FIRMWARE_MIN_SIZE)
467 return -EINVAL;
468
469 tmp = fw->data;
470
471 /* 12th char should be the NULL terminate for the ID string */
472 if (tmp[11] != '\0')
473 return -EINVAL;
474
475 if (strncmp("#SCU MAGIC#", tmp, 11) != 0)
476 return -EINVAL;
477
478 isci_fw->id = tmp;
479 isci_fw->version = fw->data[ISCI_FW_VER_OFS];
480 isci_fw->subversion = fw->data[ISCI_FW_SUBVER_OFS];
481
482 tmp = fw->data + ISCI_FW_DATA_OFS;
483
484 while (*tmp != ISCI_FW_HDR_EOF) {
485 switch (*tmp) {
486 case ISCI_FW_HDR_PHYMASK:
487 tmp++;
488 isci_fw->phy_masks_size = *tmp;
489 tmp++;
490 isci_fw->phy_masks = (const u32 *)tmp;
491 tmp += sizeof(u32) * isci_fw->phy_masks_size;
492 break;
493
494 case ISCI_FW_HDR_PHYGEN:
495 tmp++;
496 isci_fw->phy_gens_size = *tmp;
497 tmp++;
498 isci_fw->phy_gens = (const u32 *)tmp;
499 tmp += sizeof(u32) * isci_fw->phy_gens_size;
500 break;
501
502 case ISCI_FW_HDR_SASADDR:
503 tmp++;
504 isci_fw->sas_addrs_size = *tmp;
505 tmp++;
506 isci_fw->sas_addrs = (const u64 *)tmp;
507 tmp += sizeof(u64) * isci_fw->sas_addrs_size;
508 break;
509
510 default:
511 pr_err("bad field in firmware binary blob\n");
512 return -EINVAL;
513 }
514 }
515
516 pr_info("isci firmware v%u.%u loaded.\n",
517 isci_fw->version, isci_fw->subversion);
518
519 return SCI_SUCCESS;
520}
521
522static void __iomem *scu_base(struct isci_host *isci_host)
523{
524 struct pci_dev *pdev = isci_host->pdev;
525 int id = isci_host->id;
526
527 return pcim_iomap_table(pdev)[SCI_SCU_BAR * 2] + SCI_SCU_BAR_SIZE * id;
528}
529
530static void __iomem *smu_base(struct isci_host *isci_host)
531{
532 struct pci_dev *pdev = isci_host->pdev;
533 int id = isci_host->id;
534
535 return pcim_iomap_table(pdev)[SCI_SMU_BAR * 2] + SCI_SMU_BAR_SIZE * id;
536}
537
538#define SCI_MAX_TIMER_COUNT 25
539
540int isci_host_init(struct isci_host *isci_host)
541{
542 int err = 0;
543 int index = 0;
544 enum sci_status status;
545 struct scic_sds_controller *controller;
546 struct scic_sds_port *scic_port;
547 struct scic_controller_handler_methods *handlers
548 = &isci_host->scic_irq_handlers[0];
549 union scic_oem_parameters scic_oem_params;
550 union scic_user_parameters scic_user_params;
551 const struct firmware *fw = NULL;
552 struct isci_firmware *isci_fw = NULL;
553
554 INIT_LIST_HEAD(&isci_host->timer_list_struct.timers);
555 isci_timer_list_construct(
556 &isci_host->timer_list_struct,
557 SCI_MAX_TIMER_COUNT
558 );
559
560 controller = scic_controller_alloc(&isci_host->pdev->dev);
561
562 if (!controller) {
563 err = -ENOMEM;
564 dev_err(&isci_host->pdev->dev, "%s: failed (%d)\n", __func__, err);
565 goto out;
566 }
567
568 isci_host->core_controller = controller;
569 spin_lock_init(&isci_host->state_lock);
570 spin_lock_init(&isci_host->scic_lock);
571 spin_lock_init(&isci_host->queue_lock);
572
573 isci_host_change_state(isci_host, isci_starting);
574 isci_host->can_queue = ISCI_CAN_QUEUE_VAL;
575
576 status = scic_controller_construct(controller, scu_base(isci_host),
577 smu_base(isci_host));
578
579 if (status != SCI_SUCCESS) {
580 dev_err(&isci_host->pdev->dev,
581 "%s: scic_controller_construct failed - status = %x\n",
582 __func__,
583 status);
584 err = -ENODEV;
585 goto out;
586 }
587
588 isci_host->sas_ha.dev = &isci_host->pdev->dev;
589 isci_host->sas_ha.lldd_ha = isci_host;
590
591 /*----------- SCIC controller Initialization Stuff ------------------
592 * set association host adapter struct in core controller.
593 */
594 sci_object_set_association(isci_host->core_controller,
595 (void *)isci_host
596 );
597
598 /* grab initial values stored in the controller object for OEM and USER
599 * parameters */
600 scic_oem_parameters_get(controller, &scic_oem_params);
601 scic_user_parameters_get(controller, &scic_user_params);
602
603 isci_fw = devm_kzalloc(&isci_host->pdev->dev,
604 sizeof(struct isci_firmware),
605 GFP_KERNEL);
606 if (!isci_fw) {
607 dev_warn(&isci_host->pdev->dev,
608 "allocating firmware struct failed\n");
609 dev_warn(&isci_host->pdev->dev,
610 "Default OEM configuration being used:"
611 " 4 narrow ports, and default SAS Addresses\n");
612 goto set_default_params;
613 }
614
615 status = request_firmware(&fw, ISCI_FW_NAME, &isci_host->pdev->dev);
616 if (status) {
617 dev_warn(&isci_host->pdev->dev,
618 "Loading firmware failed, using default values\n");
619 dev_warn(&isci_host->pdev->dev,
620 "Default OEM configuration being used:"
621 " 4 narrow ports, and default SAS Addresses\n");
622 goto set_default_params;
623 }
624 else {
625 status = isci_verify_firmware(fw, isci_fw);
626 if (status != SCI_SUCCESS) {
627 dev_warn(&isci_host->pdev->dev,
628 "firmware verification failed\n");
629 dev_warn(&isci_host->pdev->dev,
630 "Default OEM configuration being used:"
631 " 4 narrow ports, and default SAS "
632 "Addresses\n");
633 goto set_default_params;
634 }
635
636 /* grab any OEM and USER parameters specified at module load */
637 status = isci_parse_oem_parameters(&scic_oem_params,
638 isci_host->id, isci_fw);
639 if (status != SCI_SUCCESS) {
640 dev_warn(&isci_host->pdev->dev,
641 "parsing firmware oem parameters failed\n");
642 err = -EINVAL;
643 goto out;
644 }
645
646 status = isci_parse_user_parameters(&scic_user_params,
647 isci_host->id, isci_fw);
648 if (status != SCI_SUCCESS) {
649 dev_warn(&isci_host->pdev->dev,
650 "%s: isci_parse_user_parameters"
651 " failed\n", __func__);
652 err = -EINVAL;
653 goto out;
654 }
655 }
656
657 set_default_params:
658
659 status = scic_oem_parameters_set(isci_host->core_controller,
660 &scic_oem_params
661 );
662
663 if (status != SCI_SUCCESS) {
664 dev_warn(&isci_host->pdev->dev,
665 "%s: scic_oem_parameters_set failed\n",
666 __func__);
667 err = -ENODEV;
668 goto out;
669 }
670
671
672 status = scic_user_parameters_set(isci_host->core_controller,
673 &scic_user_params
674 );
675
676 if (status != SCI_SUCCESS) {
677 dev_warn(&isci_host->pdev->dev,
678 "%s: scic_user_parameters_set failed\n",
679 __func__);
680 err = -ENODEV;
681 goto out;
682 }
683
684 status = scic_controller_initialize(isci_host->core_controller);
685 if (status != SCI_SUCCESS) {
686 dev_warn(&isci_host->pdev->dev,
687 "%s: scic_controller_initialize failed -"
688 " status = 0x%x\n",
689 __func__, status);
690 err = -ENODEV;
691 goto out;
692 }
693
694 /* @todo: use both MSI-X interrupts, and don't do indirect
695 * calls to the handlers just register direct calls
696 */
697 if (isci_host->pdev->msix_enabled) {
698 status = scic_controller_get_handler_methods(
699 SCIC_MSIX_INTERRUPT_TYPE,
700 SCI_MSIX_DOUBLE_VECTOR,
701 handlers
702 );
703 } else {
704 status = scic_controller_get_handler_methods(
705 SCIC_LEGACY_LINE_INTERRUPT_TYPE,
706 0,
707 handlers
708 );
709 }
710
711 if (status != SCI_SUCCESS) {
712 handlers->interrupt_handler = NULL;
713 handlers->completion_handler = NULL;
714 dev_err(&isci_host->pdev->dev,
715 "%s: scic_controller_get_handler_methods failed\n",
716 __func__);
717 }
718
719 tasklet_init(&isci_host->completion_tasklet,
720 isci_host_completion_routine,
721 (unsigned long)isci_host
722 );
723
724 INIT_LIST_HEAD(&(isci_host->mdl_struct_list));
725
726 INIT_LIST_HEAD(&isci_host->requests_to_complete);
727 INIT_LIST_HEAD(&isci_host->requests_to_abort);
728
729 /* populate mdl with dma memory. scu_mdl_allocate_coherent() */
730 err = isci_host_mdl_allocate_coherent(isci_host);
731
732 if (err)
733 goto err_out;
734
735 /*
736 * keep the pool alloc size around, will use it for a bounds checking
737 * when trying to convert virtual addresses to physical addresses
738 */
739 isci_host->dma_pool_alloc_size = sizeof(struct isci_request) +
740 scic_io_request_get_object_size();
741 isci_host->dma_pool = dmam_pool_create(DRV_NAME, &isci_host->pdev->dev,
742 isci_host->dma_pool_alloc_size,
743 SLAB_HWCACHE_ALIGN, 0);
744
745 if (!isci_host->dma_pool) {
746 err = -ENOMEM;
747 goto req_obj_err_out;
748 }
749
750 for (index = 0; index < SCI_MAX_PORTS; index++) {
751 isci_port_init(&isci_host->isci_ports[index],
752 isci_host, index);
753 }
754
755 for (index = 0; index < SCI_MAX_PHYS; index++)
756 isci_phy_init(&isci_host->phys[index], isci_host, index);
757
758 /* Why are we doing this? Is this even necessary? */
759 memcpy(&isci_host->sas_addr[0], &isci_host->phys[0].sas_addr[0],
760 SAS_ADDR_SIZE);
761
762 /* Start the ports */
763 for (index = 0; index < SCI_MAX_PORTS; index++) {
764
765 scic_controller_get_port_handle(controller, index, &scic_port);
766 scic_port_start(scic_port);
767 }
768
769 goto out;
770
771/* SPB_Debug: destroy request object cache */
772 req_obj_err_out:
773/* SPB_Debug: destroy remote object cache */
774 err_out:
775/* SPB_Debug: undo controller init, construct and alloc, remove from parent
776 * controller list. */
777 out:
778 if (fw)
779 release_firmware(fw);
780 return err;
781}
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
new file mode 100644
index 000000000000..3530076d6107
--- /dev/null
+++ b/drivers/scsi/isci/host.h
@@ -0,0 +1,283 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file contains the isci_module initialization routines.
58 *
59 * host.h
60 */
61
62
63
64#if !defined(_SCI_HOST_H_)
65#define _SCI_HOST_H_
66
67#include "phy.h"
68/*#include "task.h"*/
69#include "timers.h"
70#include "remote_device.h"
71#include "scic_user_callback.h"
72
73#define DRV_NAME "isci"
74#define SCI_PCI_BAR_COUNT 2
75#define SCI_NUM_MSI_X_INT 2
76#define SCI_SMU_BAR 0
77#define SCI_SMU_BAR_SIZE (16*1024)
78#define SCI_SCU_BAR 1
79#define SCI_SCU_BAR_SIZE (4*1024*1024)
80#define SCI_IO_SPACE_BAR0 2
81#define SCI_IO_SPACE_BAR1 3
82#define SCI_MSIX_NORMAL_VECTOR 0
83#define SCI_MSIX_ERROR_VECTOR 1
84#define SCI_MSIX_SINGLE_VECTOR 1
85#define SCI_MSIX_DOUBLE_VECTOR 2
86#define ISCI_CAN_QUEUE_VAL 250 /* < SCI_MAX_IO_REQUESTS ? */
87#define SCIC_CONTROLLER_STOP_TIMEOUT 5000
88
89struct coherent_memory_info {
90 struct list_head node;
91 dma_addr_t dma_handle;
92 void *vaddr;
93 size_t size;
94 struct sci_physical_memory_descriptor *mde;
95};
96
97struct isci_host {
98 struct scic_sds_controller *core_controller;
99 struct scic_controller_handler_methods scic_irq_handlers[SCI_NUM_MSI_X_INT];
100 union scic_oem_parameters oem_parameters;
101
102 int id; /* unique within a given pci device */
103 struct isci_timer_list timer_list_struct;
104 void *core_ctrl_memory;
105 struct dma_pool *dma_pool;
106 unsigned int dma_pool_alloc_size;
107 struct isci_phy phys[SCI_MAX_PHYS];
108
109 /* isci_ports and sas_ports are implicitly parallel to the
110 * ports maintained by the core
111 */
112 struct isci_port isci_ports[SCI_MAX_PORTS];
113 struct asd_sas_port sas_ports[SCI_MAX_PORTS];
114 struct sas_ha_struct sas_ha;
115
116 int can_queue;
117 spinlock_t queue_lock;
118 spinlock_t state_lock;
119
120 struct pci_dev *pdev;
121 u8 sas_addr[SAS_ADDR_SIZE];
122
123 enum isci_status status;
124 struct Scsi_Host *shost;
125 struct tasklet_struct completion_tasklet;
126 struct list_head mdl_struct_list;
127 struct list_head requests_to_complete;
128 struct list_head requests_to_abort;
129 struct completion stop_complete;
130 struct completion start_complete;
131 spinlock_t scic_lock;
132 struct isci_host *next;
133};
134
135
136/**
137 * struct isci_pci_info - This class represents the pci function containing the
138 * controllers. Depending on PCI SKU, there could be up to 2 controllers in
139 * the PCI function.
140 */
141#define SCI_MAX_MSIX_INT (SCI_NUM_MSI_X_INT*SCI_MAX_CONTROLLERS)
142
143struct isci_pci_info {
144 struct msix_entry msix_entries[SCI_MAX_MSIX_INT];
145 int core_lib_array_index;
146 SCI_LIBRARY_HANDLE_T core_lib_handle;
147 struct isci_host *hosts;
148};
149
150static inline struct isci_pci_info *to_pci_info(struct pci_dev *pdev)
151{
152 return pci_get_drvdata(pdev);
153}
154
155#define for_each_isci_host(isci_host, pdev) \
156 for (isci_host = to_pci_info(pdev)->hosts;\
157 isci_host; isci_host = isci_host->next)
158
159static inline
160enum isci_status isci_host_get_state(
161 struct isci_host *isci_host)
162{
163 return isci_host->status;
164}
165
166
167static inline void isci_host_change_state(
168 struct isci_host *isci_host,
169 enum isci_status status)
170{
171 unsigned long flags;
172
173 dev_dbg(&isci_host->pdev->dev,
174 "%s: isci_host = %p, state = 0x%x",
175 __func__,
176 isci_host,
177 status);
178 spin_lock_irqsave(&isci_host->state_lock, flags);
179 isci_host->status = status;
180 spin_unlock_irqrestore(&isci_host->state_lock, flags);
181
182}
183
184static inline int isci_host_can_queue(
185 struct isci_host *isci_host,
186 int num)
187{
188 int ret = 0;
189 unsigned long flags;
190
191 spin_lock_irqsave(&isci_host->queue_lock, flags);
192 if ((isci_host->can_queue - num) < 0) {
193 dev_dbg(&isci_host->pdev->dev,
194 "%s: isci_host->can_queue = %d\n",
195 __func__,
196 isci_host->can_queue);
197 ret = -SAS_QUEUE_FULL;
198
199 } else
200 isci_host->can_queue -= num;
201
202 spin_unlock_irqrestore(&isci_host->queue_lock, flags);
203
204 return ret;
205}
206
207static inline void isci_host_can_dequeue(
208 struct isci_host *isci_host,
209 int num)
210{
211 unsigned long flags;
212
213 spin_lock_irqsave(&isci_host->queue_lock, flags);
214 isci_host->can_queue += num;
215 spin_unlock_irqrestore(&isci_host->queue_lock, flags);
216}
217
218/**
219 * isci_host_from_sas_ha() - This accessor retrieves the isci_host object
220 * reference from the Linux sas_ha_struct reference.
221 * @ha_struct,: This parameter points to the Linux sas_ha_struct object
222 *
223 * A reference to the associated isci_host structure.
224 */
225#define isci_host_from_sas_ha(ha_struct) \
226 ((struct isci_host *)(ha_struct)->lldd_ha)
227
228/**
229 * isci_host_scan_finished() -
230 *
231 * This function is one of the SCSI Host Template functions. The SCSI midlayer
232 * calls this function during a target scan, approx. once every 10 millisecs.
233 */
234int isci_host_scan_finished(
235 struct Scsi_Host *,
236 unsigned long);
237
238
239/**
240 * isci_host_scan_start() -
241 *
242 * This function is one of the SCSI Host Template function, called by the SCSI
243 * mid layer berfore a target scan begins. The core library controller start
244 * routine is called from here.
245 */
246void isci_host_scan_start(
247 struct Scsi_Host *);
248
249/**
250 * isci_host_start_complete() -
251 *
252 * This function is called by the core library, through the ISCI Module, to
253 * indicate controller start status.
254 */
255void isci_host_start_complete(
256 struct isci_host *,
257 enum sci_status);
258
259void isci_host_stop_complete(
260 struct isci_host *isci_host,
261 enum sci_status completion_status);
262
263int isci_host_init(struct isci_host *);
264
265void isci_host_init_controller_names(
266 struct isci_host *isci_host,
267 unsigned int controller_idx);
268
269void isci_host_deinit(
270 struct isci_host *);
271
272void isci_host_port_link_up(
273 struct isci_host *,
274 struct scic_sds_port *,
275 struct scic_sds_phy *);
276int isci_host_dev_found(struct domain_device *);
277
278void isci_host_remote_device_start_complete(
279 struct isci_host *,
280 struct isci_remote_device *,
281 enum sci_status);
282
283#endif /* !defined(_SCI_HOST_H_) */
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
new file mode 100644
index 000000000000..07b072f3004d
--- /dev/null
+++ b/drivers/scsi/isci/init.c
@@ -0,0 +1,613 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include <linux/kernel.h>
57#include <linux/init.h>
58#include <linux/module.h>
59#include <asm/string.h>
60#include "isci.h"
61#include "task.h"
62#include "sci_controller_constants.h"
63#include "scic_remote_device.h"
64#include "sci_environment.h"
65
66static struct scsi_transport_template *isci_transport_template;
67struct kmem_cache *isci_kmem_cache;
68
69static DEFINE_PCI_DEVICE_TABLE(isci_id_table) = {
70 { PCI_VDEVICE(INTEL, 0x1D61),},
71 { PCI_VDEVICE(INTEL, 0x1D63),},
72 { PCI_VDEVICE(INTEL, 0x1D65),},
73 { PCI_VDEVICE(INTEL, 0x1D67),},
74 { PCI_VDEVICE(INTEL, 0x1D69),},
75 { PCI_VDEVICE(INTEL, 0x1D6B),},
76 { PCI_VDEVICE(INTEL, 0x1D60),},
77 { PCI_VDEVICE(INTEL, 0x1D62),},
78 { PCI_VDEVICE(INTEL, 0x1D64),},
79 { PCI_VDEVICE(INTEL, 0x1D66),},
80 { PCI_VDEVICE(INTEL, 0x1D68),},
81 { PCI_VDEVICE(INTEL, 0x1D6A),},
82 {}
83};
84
85static int __devinit isci_pci_probe(
86 struct pci_dev *pdev,
87 const struct pci_device_id *device_id_p);
88
89static void __devexit isci_pci_remove(struct pci_dev *pdev);
90
91MODULE_DEVICE_TABLE(pci, isci_id_table);
92
93static struct pci_driver isci_pci_driver = {
94 .name = DRV_NAME,
95 .id_table = isci_id_table,
96 .probe = isci_pci_probe,
97 .remove = __devexit_p(isci_pci_remove),
98};
99
100/* linux isci specific settings */
101int loglevel = 3;
102module_param(loglevel, int, S_IRUGO | S_IWUSR);
103
104#if defined(CONFIG_PBG_HBA_A0)
105int isci_si_rev = ISCI_SI_REVA0;
106#elif defined(CONFIG_PBG_HBA_A2)
107int isci_si_rev = ISCI_SI_REVA2;
108#else
109int isci_si_rev = ISCI_SI_REVB0;
110#endif
111module_param(isci_si_rev, int, S_IRUGO | S_IWUSR);
112MODULE_PARM_DESC(isci_si_rev, "override default si rev (0: A0 1: A2 2: B0)");
113
114static struct scsi_host_template isci_sht = {
115
116 .module = THIS_MODULE,
117 .name = DRV_NAME,
118 .queuecommand = sas_queuecommand,
119 .target_alloc = sas_target_alloc,
120 .slave_configure = sas_slave_configure,
121 .slave_destroy = sas_slave_destroy,
122 .scan_finished = isci_host_scan_finished,
123 .scan_start = isci_host_scan_start,
124 .change_queue_depth = sas_change_queue_depth,
125 .change_queue_type = sas_change_queue_type,
126 .bios_param = sas_bios_param,
127 .can_queue = ISCI_CAN_QUEUE_VAL,
128 .cmd_per_lun = 1,
129 .this_id = -1,
130 .sg_tablesize = SG_ALL,
131 .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
132 .use_clustering = ENABLE_CLUSTERING,
133 .eh_device_reset_handler = sas_eh_device_reset_handler,
134 .eh_bus_reset_handler = isci_bus_reset_handler,
135 .slave_alloc = sas_slave_alloc,
136 .target_destroy = sas_target_destroy,
137 .ioctl = sas_ioctl,
138};
139
140static struct sas_domain_function_template isci_transport_ops = {
141
142 /* The class calls these to notify the LLDD of an event. */
143 .lldd_port_formed = isci_port_formed,
144 .lldd_port_deformed = isci_port_deformed,
145
146 /* The class calls these when a device is found or gone. */
147 .lldd_dev_found = isci_remote_device_found,
148 .lldd_dev_gone = isci_remote_device_gone,
149
150 .lldd_execute_task = isci_task_execute_task,
151 /* Task Management Functions. Must be called from process context. */
152 .lldd_abort_task = isci_task_abort_task,
153 .lldd_abort_task_set = isci_task_abort_task_set,
154 .lldd_clear_aca = isci_task_clear_aca,
155 .lldd_clear_task_set = isci_task_clear_task_set,
156 .lldd_I_T_nexus_reset = isci_task_I_T_nexus_reset,
157 .lldd_lu_reset = isci_task_lu_reset,
158 .lldd_query_task = isci_task_query_task,
159
160 /* Port and Adapter management */
161 .lldd_clear_nexus_port = isci_task_clear_nexus_port,
162 .lldd_clear_nexus_ha = isci_task_clear_nexus_ha,
163
164 /* Phy management */
165 .lldd_control_phy = isci_phy_control,
166};
167
168
169/******************************************************************************
170* P R O T E C T E D M E T H O D S
171******************************************************************************/
172
173
174
175/**
176 * isci_register_sas_ha() - This method initializes various lldd
177 * specific members of the sas_ha struct and calls the libsas
178 * sas_register_ha() function.
179 * @isci_host: This parameter specifies the lldd specific wrapper for the
180 * libsas sas_ha struct.
181 *
182 * This method returns an error code indicating sucess or failure. The user
183 * should check for possible memory allocation error return otherwise, a zero
184 * indicates success.
185 */
186static int isci_register_sas_ha(struct isci_host *isci_host)
187{
188 int i;
189 struct sas_ha_struct *sas_ha = &(isci_host->sas_ha);
190 struct asd_sas_phy **sas_phys;
191 struct asd_sas_port **sas_ports;
192
193 sas_phys = devm_kzalloc(&isci_host->pdev->dev,
194 SCI_MAX_PHYS * sizeof(void *),
195 GFP_KERNEL);
196 if (!sas_phys)
197 return -ENOMEM;
198
199 sas_ports = devm_kzalloc(&isci_host->pdev->dev,
200 SCI_MAX_PORTS * sizeof(void *),
201 GFP_KERNEL);
202 if (!sas_ports)
203 return -ENOMEM;
204
205 /*----------------- Libsas Initialization Stuff----------------------
206 * Set various fields in the sas_ha struct:
207 */
208
209 sas_ha->sas_ha_name = DRV_NAME;
210 sas_ha->lldd_module = THIS_MODULE;
211 sas_ha->sas_addr = &(isci_host->sas_addr[0]);
212
213 /* set the array of phy and port structs. */
214 for (i = 0; i < SCI_MAX_PHYS; i++) {
215 sas_phys[i] = &(isci_host->phys[i].sas_phy);
216 sas_ports[i] = &(isci_host->sas_ports[i]);
217 }
218
219 sas_ha->sas_phy = sas_phys;
220 sas_ha->sas_port = sas_ports;
221 sas_ha->num_phys = SCI_MAX_PHYS;
222
223 sas_ha->lldd_queue_size = ISCI_CAN_QUEUE_VAL;
224 sas_ha->lldd_max_execute_num = 1;
225 sas_ha->strict_wide_ports = 1;
226
227 sas_register_ha(sas_ha);
228
229 return 0;
230}
231
232static void isci_unregister_sas_ha(struct isci_host *isci_host)
233{
234 if (!isci_host)
235 return;
236
237 sas_unregister_ha(&(isci_host->sas_ha));
238
239 sas_remove_host(isci_host->shost);
240 scsi_remove_host(isci_host->shost);
241 scsi_host_put(isci_host->shost);
242}
243
244static int __devinit isci_pci_init(struct pci_dev *pdev)
245{
246 int err, bar_num, bar_mask;
247 void __iomem * const *iomap;
248
249 err = pcim_enable_device(pdev);
250 if (err) {
251 dev_err(&pdev->dev,
252 "failed enable PCI device %s!\n",
253 pci_name(pdev));
254 return err;
255 }
256
257 for (bar_num = 0; bar_num < SCI_PCI_BAR_COUNT; bar_num++)
258 bar_mask |= 1 << (bar_num * 2);
259
260 err = pcim_iomap_regions(pdev, bar_mask, DRV_NAME);
261 if (err)
262 return err;
263
264 iomap = pcim_iomap_table(pdev);
265 if (!iomap)
266 return -ENOMEM;
267
268 pci_set_master(pdev);
269
270 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
271 if (err) {
272 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
273 if (err)
274 return err;
275 }
276
277 err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
278 if (err) {
279 err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
280 if (err)
281 return err;
282 }
283
284 return 0;
285}
286
287static struct isci_host *isci_host_by_id(struct pci_dev *pdev, int id)
288{
289 struct isci_host *h;
290
291 for_each_isci_host(h, pdev)
292 if (h->id == id)
293 return h;
294 return NULL;
295}
296
297static int num_controllers(struct pci_dev *pdev)
298{
299 /* bar size alone can tell us if we are running with a dual controller
300 * part, no need to trust revision ids that might be under broken firmware
301 * control
302 */
303 resource_size_t scu_bar_size = pci_resource_len(pdev, SCI_SCU_BAR*2);
304 resource_size_t smu_bar_size = pci_resource_len(pdev, SCI_SMU_BAR*2);
305
306 if (scu_bar_size >= SCI_SCU_BAR_SIZE*SCI_MAX_CONTROLLERS &&
307 smu_bar_size >= SCI_SMU_BAR_SIZE*SCI_MAX_CONTROLLERS)
308 return SCI_MAX_CONTROLLERS;
309 else
310 return 1;
311}
312
313static int isci_setup_interrupts(struct pci_dev *pdev)
314{
315 int err, i, num_msix;
316 struct isci_pci_info *pci_info = to_pci_info(pdev);
317
318 /*
319 * Determine the number of vectors associated with this
320 * PCI function.
321 */
322 num_msix = num_controllers(pdev) * SCI_NUM_MSI_X_INT;
323
324 for (i = 0; i < num_msix; i++)
325 pci_info->msix_entries[i].entry = i;
326
327 err = pci_enable_msix(pdev, pci_info->msix_entries, num_msix);
328 if (err)
329 goto intx;
330
331 for (i = 0; i < num_msix; i++) {
332 int id = i / SCI_NUM_MSI_X_INT;
333 struct msix_entry *msix = &pci_info->msix_entries[i];
334 struct isci_host *isci_host = isci_host_by_id(pdev, id);
335
336 BUG_ON(!isci_host);
337
338 /* @todo: need to handle error case. */
339 err = devm_request_irq(&pdev->dev, msix->vector, isci_isr, 0,
340 DRV_NAME"-msix", isci_host);
341 if (!err)
342 continue;
343
344 dev_info(&pdev->dev, "msix setup failed falling back to intx\n");
345 while (i--) {
346 id = i / SCI_NUM_MSI_X_INT;
347 isci_host = isci_host_by_id(pdev, id);
348 msix = &pci_info->msix_entries[i];
349 devm_free_irq(&pdev->dev, msix->vector, isci_host);
350 }
351 pci_disable_msix(pdev);
352 goto intx;
353 }
354
355 return 0;
356
357 intx:
358 err = devm_request_irq(&pdev->dev, pdev->irq, isci_legacy_isr,
359 IRQF_SHARED, DRV_NAME"-intx", pdev);
360
361 return err;
362}
363
364/**
365 * isci_parse_oem_parameters() - This method will take OEM parameters
366 * from the module init parameters and copy them to oem_params. This will
367 * only copy values that are not set to the module parameter default values
368 * @oem_parameters: This parameter specifies the controller default OEM
369 * parameters. It is expected that this has been initialized to the default
370 * parameters for the controller
371 *
372 *
373 */
374enum sci_status isci_parse_oem_parameters(union scic_oem_parameters *oem_params,
375 int scu_index,
376 struct isci_firmware *fw)
377{
378 int i;
379
380 /* check for valid inputs */
381 if (!(scu_index >= 0
382 && scu_index < SCI_MAX_CONTROLLERS
383 && oem_params != NULL)) {
384 return SCI_FAILURE;
385 }
386
387 for (i = 0; i < SCI_MAX_PHYS; i++) {
388 int array_idx = i + (SCI_MAX_PHYS * scu_index);
389 u64 sas_addr = fw->sas_addrs[array_idx];
390
391 if (sas_addr != 0) {
392 oem_params->sds1.phys[i].sas_address.low =
393 (u32)(sas_addr & 0xffffffff);
394 oem_params->sds1.phys[i].sas_address.high =
395 (u32)((sas_addr >> 32) & 0xffffffff);
396 }
397 }
398
399 for (i = 0; i < SCI_MAX_PORTS; i++) {
400 int array_idx = i + (SCI_MAX_PORTS * scu_index);
401 u32 pmask = fw->phy_masks[array_idx];
402
403 oem_params->sds1.ports[i].phy_mask = pmask;
404 }
405
406 return SCI_SUCCESS;
407}
408
409/**
410 * isci_parse_user_parameters() - This method will take user parameters
411 * from the module init parameters and copy them to user_params. This will
412 * only copy values that are not set to the module parameter default values
413 * @user_parameters: This parameter specifies the controller default user
414 * parameters. It is expected that this has been initialized to the default
415 * parameters for the controller
416 *
417 *
418 */
419enum sci_status isci_parse_user_parameters(
420 union scic_user_parameters *user_params,
421 int scu_index,
422 struct isci_firmware *fw)
423{
424 int i;
425
426 if (!(scu_index >= 0
427 && scu_index < SCI_MAX_CONTROLLERS
428 && user_params != NULL)) {
429 return SCI_FAILURE;
430 }
431
432 for (i = 0; i < SCI_MAX_PORTS; i++) {
433 int array_idx = i + (SCI_MAX_PORTS * scu_index);
434 u32 gen = fw->phy_gens[array_idx];
435
436 user_params->sds1.phys[i].max_speed_generation = gen;
437
438 }
439
440 return SCI_SUCCESS;
441}
442
443static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id)
444{
445 struct isci_host *isci_host;
446 struct Scsi_Host *shost;
447 int err;
448
449 isci_host = devm_kzalloc(&pdev->dev, sizeof(*isci_host), GFP_KERNEL);
450 if (!isci_host)
451 return NULL;
452
453 isci_host->pdev = pdev;
454 isci_host->id = id;
455
456 shost = scsi_host_alloc(&isci_sht, sizeof(void *));
457 if (!shost)
458 return NULL;
459 isci_host->shost = shost;
460
461 err = isci_host_init(isci_host);
462 if (err)
463 goto err_shost;
464
465 SHOST_TO_SAS_HA(shost) = &isci_host->sas_ha;
466 isci_host->sas_ha.core.shost = shost;
467 shost->transportt = isci_transport_template;
468
469 shost->max_id = ~0;
470 shost->max_lun = ~0;
471 shost->max_cmd_len = MAX_COMMAND_SIZE;
472
473 err = scsi_add_host(shost, &pdev->dev);
474 if (err)
475 goto err_shost;
476
477 err = isci_register_sas_ha(isci_host);
478 if (err)
479 goto err_shost_remove;
480
481 return isci_host;
482
483 err_shost_remove:
484 scsi_remove_host(shost);
485 err_shost:
486 scsi_host_put(shost);
487
488 return NULL;
489}
490
491static void check_si_rev(struct pci_dev *pdev)
492{
493 if (num_controllers(pdev) > 1)
494 isci_si_rev = ISCI_SI_REVB0;
495 else {
496 switch (pdev->revision) {
497 case 0:
498 case 1:
499 /* if the id is ambiguous don't update isci_si_rev */
500 break;
501 case 3:
502 isci_si_rev = ISCI_SI_REVA2;
503 break;
504 default:
505 case 4:
506 isci_si_rev = ISCI_SI_REVB0;
507 break;
508 }
509 }
510
511 dev_info(&pdev->dev, "driver configured for %s silicon (rev: %d)\n",
512 isci_si_rev == ISCI_SI_REVA0 ? "A0" :
513 isci_si_rev == ISCI_SI_REVA2 ? "A2" : "B0", pdev->revision);
514
515}
516
517static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
518{
519 struct isci_pci_info *pci_info;
520 int err, i;
521 struct isci_host *isci_host;
522
523 check_si_rev(pdev);
524
525 pci_info = devm_kzalloc(&pdev->dev, sizeof(*pci_info), GFP_KERNEL);
526 if (!pci_info)
527 return -ENOMEM;
528 pci_set_drvdata(pdev, pci_info);
529
530 err = isci_pci_init(pdev);
531 if (err)
532 return err;
533
534 for (i = 0; i < num_controllers(pdev); i++) {
535 struct isci_host *h = isci_host_alloc(pdev, i);
536
537 if (!h) {
538 err = -ENOMEM;
539 goto err_host_alloc;
540 }
541
542 h->next = pci_info->hosts;
543 pci_info->hosts = h;
544 }
545
546 err = isci_setup_interrupts(pdev);
547 if (err)
548 goto err_host_alloc;
549
550 for_each_isci_host(isci_host, pdev)
551 scsi_scan_host(isci_host->shost);
552
553 return 0;
554
555 err_host_alloc:
556 for_each_isci_host(isci_host, pdev)
557 isci_unregister_sas_ha(isci_host);
558 return err;
559}
560
561static void __devexit isci_pci_remove(struct pci_dev *pdev)
562{
563 struct isci_host *isci_host;
564
565 for_each_isci_host(isci_host, pdev) {
566 isci_unregister_sas_ha(isci_host);
567 isci_host_deinit(isci_host);
568 scic_controller_disable_interrupts(isci_host->core_controller);
569 }
570}
571
572static __init int isci_init(void)
573{
574 int err = -ENOMEM;
575
576 pr_info("%s: Intel(R) C600 SAS Controller Driver\n", DRV_NAME);
577
578 isci_kmem_cache = kmem_cache_create(DRV_NAME,
579 sizeof(struct isci_remote_device) +
580 scic_remote_device_get_object_size(),
581 0, 0, NULL);
582 if (!isci_kmem_cache)
583 return err;
584
585 isci_transport_template = sas_domain_attach_transport(&isci_transport_ops);
586 if (!isci_transport_template)
587 goto err_kmem;
588
589 err = pci_register_driver(&isci_pci_driver);
590 if (err)
591 goto err_sas;
592
593 return 0;
594
595 err_sas:
596 sas_release_transport(isci_transport_template);
597 err_kmem:
598 kmem_cache_destroy(isci_kmem_cache);
599
600 return err;
601}
602
603static __exit void isci_exit(void)
604{
605 pci_unregister_driver(&isci_pci_driver);
606 sas_release_transport(isci_transport_template);
607 kmem_cache_destroy(isci_kmem_cache);
608}
609
610MODULE_LICENSE("Dual BSD/GPL");
611MODULE_FIRMWARE(ISCI_FW_NAME);
612module_init(isci_init);
613module_exit(isci_exit);
diff --git a/drivers/scsi/isci/isci.h b/drivers/scsi/isci/isci.h
new file mode 100644
index 000000000000..7d984f408f24
--- /dev/null
+++ b/drivers/scsi/isci/isci.h
@@ -0,0 +1,138 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file contains the isci_module object definition.
58 *
59 * isci.h
60 */
61
62#if !defined(_SCI_MODULE_H_)
63#define _SCI_MODULE_H_
64
65/**
66 * This file contains the SCI low level driver interface to the SCI and Libsas
67 * Libraries.
68 *
69 * isci.h
70 */
71
72#include <linux/kernel.h>
73#include <linux/list.h>
74#include <linux/types.h>
75#include <linux/spinlock.h>
76#include <linux/interrupt.h>
77#include <linux/firmware.h>
78#include <linux/bug.h>
79#include <scsi/libsas.h>
80#include <scsi/scsi.h>
81
82#include "sci_types.h"
83#include "sci_base_controller.h"
84#include "scic_controller.h"
85#include "host.h"
86#include "timers.h"
87#include "sci_status.h"
88
89extern int loglevel;
90extern struct kmem_cache *isci_kmem_cache;
91
92#define ISCI_FW_NAME "isci/isci_firmware.bin"
93
94#define ISCI_FIRMWARE_MIN_SIZE 149
95
96#define ISCI_FW_IDSIZE 12
97#define ISCI_FW_VER_OFS ISCI_FW_IDSIZE
98#define ISCI_FW_SUBVER_OFS ISCI_FW_VER_OFS + 1
99#define ISCI_FW_DATA_OFS ISCI_FW_SUBVER_OFS + 1
100
101#define ISCI_FW_HDR_PHYMASK 0x1
102#define ISCI_FW_HDR_PHYGEN 0x2
103#define ISCI_FW_HDR_SASADDR 0x3
104#define ISCI_FW_HDR_EOF 0xff
105
106struct isci_firmware {
107 const u8 *id;
108 u8 version;
109 u8 subversion;
110 const u32 *phy_masks;
111 u8 phy_masks_size;
112 const u32 *phy_gens;
113 u8 phy_gens_size;
114 const u64 *sas_addrs;
115 u8 sas_addrs_size;
116};
117
118irqreturn_t isci_isr(int vec, void *data);
119irqreturn_t isci_legacy_isr(int vec, void *data);
120
121enum sci_status isci_parse_oem_parameters(
122 union scic_oem_parameters *oem_params,
123 int scu_index,
124 struct isci_firmware *fw);
125
126enum sci_status isci_parse_user_parameters(
127 union scic_user_parameters *user_params,
128 int scu_index,
129 struct isci_firmware *fw);
130
131#ifdef ISCI_SLAVE_ALLOC
132extern int ISCI_SLAVE_ALLOC(struct scsi_device *scsi_dev);
133#endif /* ISCI_SLAVE_ALLOC */
134
135#ifdef ISCI_SLAVE_DESTROY
136extern void ISCI_SLAVE_DESTROY(struct scsi_device *scsi_dev);
137#endif /* ISCI_SLAVE_DESTROY */
138#endif /* !defined(_SCI_MODULE_H_) */
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c
new file mode 100644
index 000000000000..fbda570d25e1
--- /dev/null
+++ b/drivers/scsi/isci/phy.c
@@ -0,0 +1,179 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include "isci.h"
57#include "phy.h"
58#include "scic_port.h"
59#include "scic_config_parameters.h"
60
61
62/**
63 * isci_phy_init() - This function is called by the probe function to
64 * initialize the phy objects. This func assumes that the isci_port objects
65 * associated with the SCU have been initialized.
66 * @isci_phy: This parameter specifies the isci_phy object to initialize
67 * @isci_host: This parameter specifies the parent SCU host object for this
68 * isci_phy
69 * @index: This parameter specifies which SCU phy associates with this
70 * isci_phy. Generally, SCU phy 0 relates isci_phy 0, etc.
71 *
72 */
73void isci_phy_init(
74 struct isci_phy *phy,
75 struct isci_host *isci_host,
76 int index)
77{
78 struct scic_sds_controller *controller = isci_host->core_controller;
79 struct scic_sds_phy *scic_phy;
80 union scic_oem_parameters oem_parameters;
81 enum sci_status status = SCI_SUCCESS;
82
83 /*--------------- SCU_Phy Initialization Stuff -----------------------*/
84
85 status = scic_controller_get_phy_handle(controller, index, &scic_phy);
86 if (status == SCI_SUCCESS) {
87 sci_object_set_association(scic_phy, (void *)phy);
88 phy->sci_phy_handle = scic_phy;
89 } else
90 dev_err(&isci_host->pdev->dev,
91 "failed scic_controller_get_phy_handle\n");
92
93 scic_oem_parameters_get(controller, &oem_parameters);
94
95 phy->sas_addr[0] = oem_parameters.sds1.phys[index].sas_address.low
96 & 0xFF;
97 phy->sas_addr[1] = (oem_parameters.sds1.phys[index].sas_address.low
98 >> 8) & 0xFF;
99 phy->sas_addr[2] = (oem_parameters.sds1.phys[index].sas_address.low
100 >> 16) & 0xFF;
101 phy->sas_addr[3] = (oem_parameters.sds1.phys[index].sas_address.low
102 >> 24) & 0xFF;
103 phy->sas_addr[4] = oem_parameters.sds1.phys[index].sas_address.high
104 & 0xFF;
105 phy->sas_addr[5] = (oem_parameters.sds1.phys[index].sas_address.high
106 >> 8) & 0xFF;
107 phy->sas_addr[6] = (oem_parameters.sds1.phys[index].sas_address.high
108 >> 16) & 0xFF;
109 phy->sas_addr[7] = (oem_parameters.sds1.phys[index].sas_address.high
110 >> 24) & 0xFF;
111
112 phy->isci_port = NULL;
113 phy->sas_phy.enabled = 0;
114 phy->sas_phy.id = index;
115 phy->sas_phy.sas_addr = &phy->sas_addr[0];
116 phy->sas_phy.frame_rcvd = (u8 *)&phy->frame_rcvd;
117 phy->sas_phy.ha = &isci_host->sas_ha;
118 phy->sas_phy.lldd_phy = phy;
119 phy->sas_phy.enabled = 1;
120 phy->sas_phy.class = SAS;
121 phy->sas_phy.iproto = SAS_PROTOCOL_ALL;
122 phy->sas_phy.tproto = 0;
123 phy->sas_phy.type = PHY_TYPE_PHYSICAL;
124 phy->sas_phy.role = PHY_ROLE_INITIATOR;
125 phy->sas_phy.oob_mode = OOB_NOT_CONNECTED;
126 phy->sas_phy.linkrate = SAS_LINK_RATE_UNKNOWN;
127 memset((u8 *)&phy->frame_rcvd, 0, sizeof(phy->frame_rcvd));
128}
129
130
131/**
132 * isci_phy_control() - This function is one of the SAS Domain Template
133 * functions. This is a phy management function.
134 * @phy: This parameter specifies the sphy being controlled.
135 * @func: This parameter specifies the phy control function being invoked.
136 * @buf: This parameter is specific to the phy function being invoked.
137 *
138 * status, zero indicates success.
139 */
140int isci_phy_control(
141 struct asd_sas_phy *phy,
142 enum phy_func func,
143 void *buf)
144{
145 int ret = TMF_RESP_FUNC_COMPLETE;
146 struct isci_phy *isci_phy_ptr = (struct isci_phy *)phy->lldd_phy;
147 struct isci_port *isci_port_ptr = NULL;
148
149 if (isci_phy_ptr != NULL)
150 isci_port_ptr = isci_phy_ptr->isci_port;
151
152 if ((isci_phy_ptr == NULL) || (isci_port_ptr == NULL)) {
153 pr_err("%s: asd_sas_phy %p: lldd_phy %p or "
154 "isci_port %p == NULL!\n",
155 __func__, phy, isci_phy_ptr, isci_port_ptr);
156 return TMF_RESP_FUNC_FAILED;
157 }
158
159 pr_debug("%s: phy %p; func %d; buf %p; isci phy %p, port %p\n",
160 __func__, phy, func, buf, isci_phy_ptr, isci_port_ptr);
161
162 switch (func) {
163 case PHY_FUNC_HARD_RESET:
164 case PHY_FUNC_LINK_RESET:
165
166 /* Perform the port reset. */
167 ret = isci_port_perform_hard_reset(isci_port_ptr, isci_phy_ptr);
168
169 break;
170
171 case PHY_FUNC_DISABLE:
172 default:
173 pr_debug("%s: phy %p; func %d NOT IMPLEMENTED!\n",
174 __func__, phy, func);
175 ret = TMF_RESP_FUNC_FAILED;
176 break;
177 }
178 return ret;
179}
diff --git a/drivers/scsi/isci/phy.h b/drivers/scsi/isci/phy.h
new file mode 100644
index 000000000000..44b727f1c455
--- /dev/null
+++ b/drivers/scsi/isci/phy.h
@@ -0,0 +1,104 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56
57#if !defined(_ISCI_PHY_H_)
58#define _ISCI_PHY_H_
59
60#include "port.h"
61#include "host.h"
62#include <scsi/libsas.h>
63
64
65/**
66 * struct isci_phy - This class implements the ISCI specific representation of
67 * the phy object.
68 *
69 *
70 */
71
72struct isci_phy {
73
74 struct scic_sds_phy *sci_phy_handle;
75
76 struct asd_sas_phy sas_phy;
77 struct sas_identify_frame *frame;
78 struct isci_port *isci_port;
79 u8 sas_addr[SAS_ADDR_SIZE];
80
81 union {
82
83 u8 aif[sizeof(struct sci_sas_identify_address_frame)];
84 u8 fis[sizeof(struct sata_fis_reg_d2h)];
85
86 } frame_rcvd;
87};
88
89#define to_isci_phy(p) \
90 container_of(p, struct isci_phy, sas_phy);
91
92struct isci_host;
93
94void isci_phy_init(
95 struct isci_phy *phy,
96 struct isci_host *isci_host,
97 int index);
98
99int isci_phy_control(
100 struct asd_sas_phy *phy,
101 enum phy_func func,
102 void *buf);
103
104#endif /* !defined(_ISCI_PHY_H_) */
diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c
new file mode 100644
index 000000000000..2343f6556428
--- /dev/null
+++ b/drivers/scsi/isci/port.c
@@ -0,0 +1,484 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file contains the isci port implementation.
58 *
59 *
60 */
61
62
63#include <linux/workqueue.h>
64#include "isci.h"
65#include "scic_io_request.h"
66#include "scic_remote_device.h"
67#include "scic_phy.h"
68#include "scic_sds_phy.h"
69#include "scic_port.h"
70#include "port.h"
71#include "request.h"
72
73static void isci_port_change_state(
74 struct isci_port *isci_port,
75 enum isci_status status);
76
77
78
79/**
80 * isci_port_init() - This function initializes the given isci_port object.
81 * @isci_port: This parameter specifies the port object to be initialized.
82 * @isci_host: This parameter specifies parent controller object for the port.
83 * @index: This parameter specifies which SCU port the isci_port associates
84 * with. Generally, SCU port 0 relates to isci_port 0, etc.
85 *
86 */
87void isci_port_init(
88 struct isci_port *isci_port,
89 struct isci_host *isci_host,
90 int index)
91{
92 struct scic_sds_port *scic_port;
93 struct scic_sds_controller *controller = isci_host->core_controller;
94
95 INIT_LIST_HEAD(&isci_port->remote_dev_list);
96 INIT_LIST_HEAD(&isci_port->domain_dev_list);
97 spin_lock_init(&isci_port->remote_device_lock);
98 spin_lock_init(&isci_port->state_lock);
99 init_completion(&isci_port->start_complete);
100 isci_port->isci_host = isci_host;
101 isci_port_change_state(isci_port, isci_freed);
102
103 (void)scic_controller_get_port_handle(controller, index, &scic_port);
104 sci_object_set_association(scic_port, isci_port);
105 isci_port->sci_port_handle = scic_port;
106}
107
108
109/**
110 * isci_port_get_state() - This function gets the status of the port object.
111 * @isci_port: This parameter points to the isci_port object
112 *
113 * status of the object as a isci_status enum.
114 */
115enum isci_status isci_port_get_state(
116 struct isci_port *isci_port)
117{
118 return isci_port->status;
119}
120
121static void isci_port_change_state(
122 struct isci_port *isci_port,
123 enum isci_status status)
124{
125 unsigned long flags;
126
127 dev_dbg(&isci_port->isci_host->pdev->dev,
128 "%s: isci_port = %p, state = 0x%x\n",
129 __func__, isci_port, status);
130
131 spin_lock_irqsave(&isci_port->state_lock, flags);
132 isci_port->status = status;
133 spin_unlock_irqrestore(&isci_port->state_lock, flags);
134}
135
136void isci_port_bc_change_received(
137 struct isci_host *isci_host,
138 struct scic_sds_port *port,
139 struct scic_sds_phy *phy)
140{
141 struct isci_phy *isci_phy =
142 (struct isci_phy *)sci_object_get_association(phy);
143
144 dev_dbg(&isci_host->pdev->dev,
145 "%s: isci_phy = %p, sas_phy = %p\n",
146 __func__,
147 isci_phy,
148 &isci_phy->sas_phy);
149
150 isci_host->sas_ha.notify_port_event(
151 &isci_phy->sas_phy,
152 PORTE_BROADCAST_RCVD
153 );
154
155 scic_port_enable_broadcast_change_notification(port);
156}
157
158/**
159 * isci_port_link_up() - This function is called by the sci core when a link
160 * becomes active. the identify address frame is retrieved from the core and
161 * a notify port event is sent to libsas.
162 * @isci_host: This parameter specifies the isci host object.
163 * @port: This parameter specifies the sci port with the active link.
164 * @phy: This parameter specifies the sci phy with the active link.
165 *
166 */
167void isci_port_link_up(
168 struct isci_host *isci_host,
169 struct scic_sds_port *port,
170 struct scic_sds_phy *phy)
171{
172 unsigned long flags;
173 struct scic_port_properties properties;
174 struct isci_phy *isci_phy
175 = (struct isci_phy *)sci_object_get_association(phy);
176 struct isci_port *isci_port
177 = (struct isci_port *)sci_object_get_association(port);
178 enum sci_status call_status;
179 unsigned long success = true;
180
181 BUG_ON(isci_phy->isci_port != NULL);
182 isci_phy->isci_port = isci_port;
183
184 dev_dbg(&isci_host->pdev->dev,
185 "%s: isci_port = %p\n",
186 __func__, isci_port);
187
188 spin_lock_irqsave(&isci_phy->sas_phy.frame_rcvd_lock, flags);
189
190 isci_port_change_state(isci_phy->isci_port, isci_starting);
191
192 scic_port_get_properties(port, &properties);
193
194 if (properties.remote.protocols.u.bits.stp_target) {
195
196 struct scic_sata_phy_properties sata_phy_properties;
197
198 isci_phy->sas_phy.oob_mode = SATA_OOB_MODE;
199
200 /* Get a copy of the signature fis for libsas */
201 call_status = scic_sata_phy_get_properties(phy,
202 &sata_phy_properties);
203
204 /*
205 * XXX I am concerned about this "assert". shouldn't we
206 * handle the return appropriately?
207 */
208 BUG_ON(call_status != SCI_SUCCESS);
209
210 memcpy(isci_phy->frame_rcvd.fis,
211 &sata_phy_properties.signature_fis,
212 sizeof(struct sata_fis_reg_d2h));
213
214 isci_phy->sas_phy.frame_rcvd_size = sizeof(struct sata_fis_reg_d2h);
215
216 /*
217 * For direct-attached SATA devices, the SCI core will
218 * automagically assign a SAS address to the end device
219 * for the purpose of creating a port. This SAS address
220 * will not be the same as assigned to the PHY and needs
221 * to be obtained from struct scic_port_properties properties.
222 */
223
224 BUG_ON(((size_t)SAS_ADDR_SIZE / 2)
225 != sizeof(properties.remote.sas_address.low));
226
227 memcpy(&isci_phy->sas_phy.attached_sas_addr[0],
228 &properties.remote.sas_address.low,
229 SAS_ADDR_SIZE / 2);
230
231 memcpy(&isci_phy->sas_phy.attached_sas_addr[4],
232 &properties.remote.sas_address.high,
233 SAS_ADDR_SIZE / 2);
234
235 } else if (properties.remote.protocols.u.bits.ssp_target ||
236 properties.remote.protocols.u.bits.smp_target) {
237
238 struct scic_sas_phy_properties sas_phy_properties;
239
240 isci_phy->sas_phy.oob_mode = SAS_OOB_MODE;
241
242 /* Get a copy of the identify address frame for libsas */
243 call_status = scic_sas_phy_get_properties(phy,
244 &sas_phy_properties);
245
246 BUG_ON(call_status != SCI_SUCCESS);
247
248 memcpy(isci_phy->frame_rcvd.aif,
249 &(sas_phy_properties.received_iaf),
250 sizeof(struct sci_sas_identify_address_frame));
251
252 isci_phy->sas_phy.frame_rcvd_size
253 = sizeof(struct sci_sas_identify_address_frame);
254
255 /* Copy the attached SAS address from the IAF */
256 memcpy(isci_phy->sas_phy.attached_sas_addr,
257 ((struct sas_identify_frame *)
258 (&isci_phy->frame_rcvd.aif))->sas_addr,
259 SAS_ADDR_SIZE);
260
261 } else {
262 dev_err(&isci_host->pdev->dev, "%s: unkown target\n", __func__);
263 success = false;
264 }
265
266 spin_unlock_irqrestore(&isci_phy->sas_phy.frame_rcvd_lock, flags);
267
268 /* Notify libsas that we have an address frame, if indeed
269 * we've found an SSP, SMP, or STP target */
270 if (success)
271 isci_host->sas_ha.notify_port_event(&isci_phy->sas_phy,
272 PORTE_BYTES_DMAED);
273}
274
275
276/**
277 * isci_port_link_down() - This function is called by the sci core when a link
278 * becomes inactive.
279 * @isci_host: This parameter specifies the isci host object.
280 * @phy: This parameter specifies the isci phy with the active link.
281 * @port: This parameter specifies the isci port with the active link.
282 *
283 */
284void isci_port_link_down(
285 struct isci_host *isci_host,
286 struct isci_phy *isci_phy,
287 struct isci_port *isci_port)
288{
289 struct isci_remote_device *isci_device;
290
291 dev_dbg(&isci_host->pdev->dev,
292 "%s: isci_port = %p\n", __func__, isci_port);
293
294 if (isci_port) {
295
296 /* check to see if this is the last phy on this port. */
297 if (isci_phy->sas_phy.port
298 && isci_phy->sas_phy.port->num_phys == 1) {
299
300 /* change the state for all devices on this port.
301 * The next task sent to this device will be returned
302 * as SAS_TASK_UNDELIVERED, and the scsi mid layer
303 * will remove the target
304 */
305 list_for_each_entry(isci_device,
306 &isci_port->remote_dev_list,
307 node) {
308 dev_dbg(&isci_host->pdev->dev,
309 "%s: isci_device = %p\n",
310 __func__, isci_device);
311 isci_remote_device_change_state(isci_device,
312 isci_stopping);
313 }
314 }
315 isci_port_change_state(isci_port, isci_stopping);
316 }
317
318 /* Notify libsas of the borken link, this will trigger calls to our
319 * isci_port_deformed and isci_dev_gone functions.
320 */
321 sas_phy_disconnected(&isci_phy->sas_phy);
322 isci_host->sas_ha.notify_phy_event(&isci_phy->sas_phy,
323 PHYE_LOSS_OF_SIGNAL);
324
325 isci_phy->isci_port = NULL;
326
327 dev_dbg(&isci_host->pdev->dev,
328 "%s: isci_port = %p - Done\n", __func__, isci_port);
329}
330
331
332/**
333 * isci_port_deformed() - This function is called by libsas when a port becomes
334 * inactive.
335 * @phy: This parameter specifies the libsas phy with the inactive port.
336 *
337 */
338void isci_port_deformed(
339 struct asd_sas_phy *phy)
340{
341 pr_debug("%s: sas_phy = %p\n", __func__, phy);
342}
343
344/**
345 * isci_port_formed() - This function is called by libsas when a port becomes
346 * active.
347 * @phy: This parameter specifies the libsas phy with the active port.
348 *
349 */
350void isci_port_formed(
351 struct asd_sas_phy *phy)
352{
353 pr_debug("%s: sas_phy = %p, sas_port = %p\n", __func__, phy, phy->port);
354}
355
356/**
357 * isci_port_ready() - This function is called by the sci core when a link
358 * becomes ready.
359 * @isci_host: This parameter specifies the isci host object.
360 * @port: This parameter specifies the sci port with the active link.
361 *
362 */
363void isci_port_ready(
364 struct isci_host *isci_host,
365 struct isci_port *isci_port)
366{
367 dev_dbg(&isci_host->pdev->dev,
368 "%s: isci_port = %p\n", __func__, isci_port);
369
370 complete_all(&isci_port->start_complete);
371 isci_port_change_state(isci_port, isci_ready);
372 return;
373}
374
375/**
376 * isci_port_not_ready() - This function is called by the sci core when a link
377 * is not ready. All remote devices on this link will be removed if they are
378 * in the stopping state.
379 * @isci_host: This parameter specifies the isci host object.
380 * @port: This parameter specifies the sci port with the active link.
381 *
382 */
383void isci_port_not_ready(
384 struct isci_host *isci_host,
385 struct isci_port *isci_port)
386{
387 dev_dbg(&isci_host->pdev->dev,
388 "%s: isci_port = %p\n", __func__, isci_port);
389}
390
391/**
392 * isci_port_hard_reset_complete() - This function is called by the sci core
393 * when the hard reset complete notification has been received.
394 * @port: This parameter specifies the sci port with the active link.
395 * @completion_status: This parameter specifies the core status for the reset
396 * process.
397 *
398 */
399void isci_port_hard_reset_complete(
400 struct isci_port *isci_port,
401 enum sci_status completion_status)
402{
403 dev_dbg(&isci_port->isci_host->pdev->dev,
404 "%s: isci_port = %p, completion_status=%x\n",
405 __func__, isci_port, completion_status);
406
407 /* Save the status of the hard reset from the port. */
408 isci_port->hard_reset_status = completion_status;
409
410 complete_all(&isci_port->hard_reset_complete);
411}
412/**
413 * isci_port_perform_hard_reset() - This function is one of the SAS Domain
414 * Template functions. This is a phy management function.
415 * @isci_port:
416 * @isci_phy:
417 *
418 * status, TMF_RESP_FUNC_COMPLETE indicates success.
419 */
420int isci_port_perform_hard_reset(
421 struct isci_port *isci_port,
422 struct isci_phy *isci_phy)
423{
424 enum sci_status status;
425 int ret = TMF_RESP_FUNC_COMPLETE;
426 unsigned long flags;
427
428
429 dev_dbg(&isci_port->isci_host->pdev->dev,
430 "%s: isci_port = %p\n",
431 __func__, isci_port);
432
433 BUG_ON(isci_port == NULL);
434
435 init_completion(&isci_port->hard_reset_complete);
436
437 spin_lock_irqsave(&isci_port->isci_host->scic_lock, flags);
438
439 #define ISCI_PORT_RESET_TIMEOUT SCIC_SDS_SIGNATURE_FIS_TIMEOUT
440 status = scic_port_hard_reset(isci_port->sci_port_handle,
441 ISCI_PORT_RESET_TIMEOUT);
442
443 spin_unlock_irqrestore(&isci_port->isci_host->scic_lock, flags);
444
445 if (status == SCI_SUCCESS) {
446 wait_for_completion(&isci_port->hard_reset_complete);
447
448 dev_dbg(&isci_port->isci_host->pdev->dev,
449 "%s: isci_port = %p; hard reset completion\n",
450 __func__, isci_port);
451
452 if (isci_port->hard_reset_status != SCI_SUCCESS)
453 ret = TMF_RESP_FUNC_FAILED;
454 } else {
455 ret = TMF_RESP_FUNC_FAILED;
456
457 dev_err(&isci_port->isci_host->pdev->dev,
458 "%s: isci_port = %p; scic_port_hard_reset call"
459 " failed 0x%x\n",
460 __func__, isci_port, status);
461
462 }
463
464 /* If the hard reset for the port has failed, consider this
465 * the same as link failures on all phys in the port.
466 */
467 if (ret != TMF_RESP_FUNC_COMPLETE) {
468 BUG_ON(isci_port->isci_host == NULL);
469
470 dev_err(&isci_port->isci_host->pdev->dev,
471 "%s: isci_port = %p; hard reset failed "
472 "(0x%x) - sending link down to libsas for phy %p\n",
473 __func__,
474 isci_port,
475 isci_port->hard_reset_status,
476 isci_phy);
477
478 isci_port_link_down(isci_port->isci_host,
479 isci_phy,
480 isci_port);
481 }
482
483 return ret;
484}
diff --git a/drivers/scsi/isci/port.h b/drivers/scsi/isci/port.h
new file mode 100644
index 000000000000..b01b0c63e53f
--- /dev/null
+++ b/drivers/scsi/isci/port.h
@@ -0,0 +1,153 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56/**
57 * This file contains the isci_port object definition.
58 *
59 * port.h
60 */
61
62#if !defined(_ISCI_PORT_H_)
63#define _ISCI_PORT_H_
64
65struct isci_phy;
66struct isci_host;
67
68
69enum isci_status {
70 isci_freed = 0x00,
71 isci_starting = 0x01,
72 isci_ready = 0x02,
73 isci_ready_for_io = 0x03,
74 isci_stopping = 0x04,
75 isci_stopped = 0x05,
76 isci_host_quiesce = 0x06
77};
78
79/**
80 * struct isci_port - This class represents the port object used to internally
81 * represent libsas port objects. It also keeps a list of remote device
82 * objects.
83 *
84 *
85 */
86struct isci_port {
87
88 struct scic_sds_port *sci_port_handle;
89
90 enum isci_status status;
91 struct isci_host *isci_host;
92 struct asd_sas_port sas_port;
93 struct list_head remote_dev_list;
94 spinlock_t remote_device_lock;
95 spinlock_t state_lock;
96 struct list_head domain_dev_list;
97 struct completion start_complete;
98 struct completion hard_reset_complete;
99 enum sci_status hard_reset_status;
100};
101
102#define to_isci_port(p) \
103 container_of(p, struct isci_port, sas_port);
104
105enum isci_status isci_port_get_state(
106 struct isci_port *isci_port);
107
108
109
110void isci_port_formed(
111 struct asd_sas_phy *);
112
113void isci_port_deformed(
114 struct asd_sas_phy *);
115
116void isci_port_bc_change_received(
117 struct isci_host *isci_host,
118 struct scic_sds_port *port,
119 struct scic_sds_phy *phy);
120
121void isci_port_link_up(
122 struct isci_host *isci_host,
123 struct scic_sds_port *port,
124 struct scic_sds_phy *phy);
125
126void isci_port_link_down(
127 struct isci_host *isci_host,
128 struct isci_phy *isci_phy,
129 struct isci_port *port);
130
131void isci_port_ready(
132 struct isci_host *isci_host,
133 struct isci_port *isci_port);
134
135void isci_port_not_ready(
136 struct isci_host *isci_host,
137 struct isci_port *port);
138
139void isci_port_init(
140 struct isci_port *port,
141 struct isci_host *host,
142 int index);
143
144void isci_port_hard_reset_complete(
145 struct isci_port *isci_port,
146 enum sci_status completion_status);
147
148int isci_port_perform_hard_reset(
149 struct isci_port *isci_port_ptr,
150 struct isci_phy *isci_phy_ptr);
151
152#endif /* !defined(_ISCI_PORT_H_) */
153
diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c
new file mode 100644
index 000000000000..dbf3c82f6195
--- /dev/null
+++ b/drivers/scsi/isci/remote_device.c
@@ -0,0 +1,698 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include "isci.h"
57#include "scic_io_request.h"
58#include "scic_remote_device.h"
59#include "scic_phy.h"
60#include "scic_port.h"
61#include "port.h"
62#include "remote_device.h"
63#include "request.h"
64#include "task.h"
65
66
67
68/**
69 * isci_remote_device_deconstruct() - This function frees an isci_remote_device.
70 * @isci_host: This parameter specifies the isci host object.
71 * @isci_device: This parameter specifies the remote device to be freed.
72 *
73 */
74static void isci_remote_device_deconstruct(
75 struct isci_host *isci_host,
76 struct isci_remote_device *isci_device)
77{
78 dev_dbg(&isci_host->pdev->dev,
79 "%s: isci_device = %p\n", __func__, isci_device);
80
81 /* There should not be any outstanding io's. All paths to
82 * here should go through isci_remote_device_nuke_requests.
83 * If we hit this condition, we will need a way to complete
84 * io requests in process */
85 while (!list_empty(&isci_device->reqs_in_process)) {
86
87 dev_err(&isci_host->pdev->dev,
88 "%s: ** request list not empty! **\n", __func__);
89 BUG();
90 }
91
92 /* Remove all related references to this device and free
93 * the cache object.
94 */
95 scic_remote_device_destruct(isci_device->sci_device_handle);
96 isci_device->domain_dev->lldd_dev = NULL;
97 list_del(&isci_device->node);
98 kmem_cache_free(isci_kmem_cache, isci_device);
99}
100
101
102/**
103 * isci_remote_device_construct() - This function calls the scic remote device
104 * construct and start functions, it waits on the remote device start
105 * completion.
106 * @port: This parameter specifies the isci port with the remote device.
107 * @isci_device: This parameter specifies the isci remote device
108 *
109 * status from the scic calls, the caller to this function should clean up
110 * resources as appropriate.
111 */
112static enum sci_status isci_remote_device_construct(
113 struct isci_port *port,
114 struct isci_remote_device *isci_device)
115{
116 enum sci_status status = SCI_SUCCESS;
117
118 /* let the core do it's common constuction. */
119 scic_remote_device_construct(port->sci_port_handle,
120 isci_device->sci_device_handle);
121
122 /* let the core do it's device specific constuction. */
123 if (isci_device->domain_dev->parent &&
124 (isci_device->domain_dev->parent->dev_type == EDGE_DEV)) {
125 int i;
126
127 /* struct smp_response_discover discover_response; */
128 struct discover_resp discover_response;
129 struct domain_device *parent =
130 isci_device->domain_dev->parent;
131
132 struct expander_device *parent_ex = &parent->ex_dev;
133
134 for (i = 0; i < parent_ex->num_phys; i++) {
135
136 struct ex_phy *phy = &parent_ex->ex_phy[i];
137
138 if ((phy->phy_state == PHY_VACANT) ||
139 (phy->phy_state == PHY_NOT_PRESENT))
140 continue;
141
142 if (SAS_ADDR(phy->attached_sas_addr)
143 == SAS_ADDR(isci_device->domain_dev->sas_addr)) {
144
145 discover_response.attached_dev_type
146 = phy->attached_dev_type;
147 discover_response.linkrate
148 = phy->linkrate;
149 discover_response.attached_sata_host
150 = phy->attached_sata_host;
151 discover_response.attached_sata_dev
152 = phy->attached_sata_dev;
153 discover_response.attached_sata_ps
154 = phy->attached_sata_ps;
155 discover_response.iproto
156 = phy->attached_iproto >> 1;
157 discover_response.tproto
158 = phy->attached_tproto >> 1;
159 memcpy(
160 discover_response.attached_sas_addr,
161 phy->attached_sas_addr,
162 SAS_ADDR_SIZE
163 );
164 discover_response.attached_phy_id
165 = phy->attached_phy_id;
166 discover_response.change_count
167 = phy->phy_change_count;
168 discover_response.routing_attr
169 = phy->routing_attr;
170 discover_response.hmin_linkrate
171 = phy->phy->minimum_linkrate_hw;
172 discover_response.hmax_linkrate
173 = phy->phy->maximum_linkrate_hw;
174 discover_response.pmin_linkrate
175 = phy->phy->minimum_linkrate;
176 discover_response.pmax_linkrate
177 = phy->phy->maximum_linkrate;
178 }
179 }
180
181
182 dev_dbg(&port->isci_host->pdev->dev,
183 "%s: parent->dev_type = EDGE_DEV\n",
184 __func__);
185
186 status = scic_remote_device_ea_construct(
187 isci_device->sci_device_handle,
188 (struct smp_response_discover *)&discover_response
189 );
190
191 } else
192 status = scic_remote_device_da_construct(
193 isci_device->sci_device_handle
194 );
195
196
197 if (status != SCI_SUCCESS) {
198 dev_dbg(&port->isci_host->pdev->dev,
199 "%s: scic_remote_device_da_construct failed - "
200 "isci_device = %p\n",
201 __func__,
202 isci_device);
203
204 return status;
205 }
206
207 sci_object_set_association(
208 isci_device->sci_device_handle,
209 isci_device
210 );
211
212 BUG_ON(port->isci_host == NULL);
213
214 /* start the device. */
215 status = scic_remote_device_start(
216 isci_device->sci_device_handle,
217 ISCI_REMOTE_DEVICE_START_TIMEOUT
218 );
219
220 if (status != SCI_SUCCESS) {
221 dev_warn(&port->isci_host->pdev->dev,
222 "%s: scic_remote_device_start failed\n",
223 __func__);
224 return status;
225 }
226
227 return status;
228}
229
230
231/**
232 * isci_remote_device_nuke_requests() - This function terminates all requests
233 * for a given remote device.
234 * @isci_device: This parameter specifies the remote device
235 *
236 */
237void isci_remote_device_nuke_requests(
238 struct isci_remote_device *isci_device)
239{
240 DECLARE_COMPLETION_ONSTACK(aborted_task_completion);
241 struct isci_host *isci_host;
242
243 isci_host = isci_device->isci_port->isci_host;
244
245 dev_dbg(&isci_host->pdev->dev,
246 "%s: isci_device = %p\n", __func__, isci_device);
247
248 /* Cleanup all requests pending for this device. */
249 isci_terminate_pending_requests(isci_host, isci_device, terminating);
250
251 dev_dbg(&isci_host->pdev->dev,
252 "%s: isci_device = %p, done\n", __func__, isci_device);
253}
254
255
256
257/**
258 * This function builds the isci_remote_device when a libsas dev_found message
259 * is received.
260 * @isci_host: This parameter specifies the isci host object.
261 * @port: This parameter specifies the isci_port conected to this device.
262 *
263 * pointer to new isci_remote_device.
264 */
265static struct isci_remote_device *
266isci_remote_device_alloc(struct isci_host *isci_host, struct isci_port *port)
267{
268 struct isci_remote_device *isci_device;
269 struct scic_sds_remote_device *sci_dev;
270
271 isci_device = kmem_cache_zalloc(isci_kmem_cache, GFP_KERNEL);
272
273 if (!isci_device) {
274 dev_warn(&isci_host->pdev->dev, "%s: failed\n", __func__);
275 return NULL;
276 }
277
278 sci_dev = (struct scic_sds_remote_device *) &isci_device[1];
279 isci_device->sci_device_handle = sci_dev;
280 INIT_LIST_HEAD(&isci_device->reqs_in_process);
281 INIT_LIST_HEAD(&isci_device->node);
282 isci_device->host_quiesce = false;
283
284 spin_lock_init(&isci_device->state_lock);
285 spin_lock_init(&isci_device->host_quiesce_lock);
286 isci_remote_device_change_state(isci_device, isci_freed);
287
288 return isci_device;
289
290}
291/**
292 * isci_device_set_host_quiesce_lock_state() - This function sets the host I/O
293 * quiesce lock state for the remote_device object.
294 * @isci_device,: This parameter points to the isci_remote_device object
295 * @isci_device: This parameter specifies the new quiesce state.
296 *
297 */
298void isci_device_set_host_quiesce_lock_state(
299 struct isci_remote_device *isci_device,
300 bool lock_state)
301{
302 unsigned long flags;
303
304 dev_dbg(&isci_device->isci_port->isci_host->pdev->dev,
305 "%s: isci_device=%p, lock_state=%d\n",
306 __func__, isci_device, lock_state);
307
308 spin_lock_irqsave(&isci_device->host_quiesce_lock, flags);
309 isci_device->host_quiesce = lock_state;
310 spin_unlock_irqrestore(&isci_device->host_quiesce_lock, flags);
311}
312
313/**
314 * isci_remote_device_ready() - This function is called by the scic when the
315 * remote device is ready. We mark the isci device as ready and signal the
316 * waiting proccess.
317 * @isci_host: This parameter specifies the isci host object.
318 * @isci_device: This parameter specifies the remote device
319 *
320 */
321void isci_remote_device_ready(struct isci_remote_device *isci_device)
322{
323 unsigned long flags;
324
325 dev_dbg(&isci_device->isci_port->isci_host->pdev->dev,
326 "%s: isci_device = %p\n", __func__, isci_device);
327
328 /* device ready is actually a "ready for io" state. */
329 if ((isci_starting == isci_remote_device_get_state(isci_device)) ||
330 (isci_ready == isci_remote_device_get_state(isci_device))) {
331 spin_lock_irqsave(&isci_device->isci_port->remote_device_lock,
332 flags);
333 isci_remote_device_change_state(isci_device, isci_ready_for_io);
334 if (isci_device->completion)
335 complete(isci_device->completion);
336 spin_unlock_irqrestore(
337 &isci_device->isci_port->remote_device_lock,
338 flags);
339 }
340
341}
342
343/**
344 * isci_remote_device_not_ready() - This function is called by the scic when
345 * the remote device is not ready. We mark the isci device as ready (not
346 * "ready_for_io") and signal the waiting proccess.
347 * @isci_host: This parameter specifies the isci host object.
348 * @isci_device: This parameter specifies the remote device
349 *
350 */
351void isci_remote_device_not_ready(
352 struct isci_remote_device *isci_device,
353 u32 reason_code)
354{
355 dev_dbg(&isci_device->isci_port->isci_host->pdev->dev,
356 "%s: isci_device = %p\n", __func__, isci_device);
357
358 if (reason_code == SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED)
359 isci_remote_device_change_state(isci_device, isci_stopping);
360 else
361 /* device ready is actually a "not ready for io" state. */
362 isci_remote_device_change_state(isci_device, isci_ready);
363}
364
365/**
366 * isci_remote_device_stop_complete() - This function is called by the scic
367 * when the remote device stop has completed. We mark the isci device as not
368 * ready and remove the isci remote device.
369 * @isci_host: This parameter specifies the isci host object.
370 * @isci_device: This parameter specifies the remote device.
371 * @status: This parameter specifies status of the completion.
372 *
373 */
374void isci_remote_device_stop_complete(
375 struct isci_host *isci_host,
376 struct isci_remote_device *isci_device,
377 enum sci_status status)
378{
379 struct completion *completion = isci_device->completion;
380
381 dev_dbg(&isci_host->pdev->dev,
382 "%s: complete isci_device = %p, status = 0x%x\n",
383 __func__,
384 isci_device,
385 status);
386
387 isci_remote_device_change_state(isci_device, isci_stopped);
388
389 /* after stop, we can tear down resources. */
390 isci_remote_device_deconstruct(isci_host, isci_device);
391
392 /* notify interested parties. */
393 if (completion)
394 complete(completion);
395}
396
397/**
398 * isci_remote_device_start_complete() - This function is called by the scic
399 * when the remote device start has completed
400 * @isci_host: This parameter specifies the isci host object.
401 * @isci_device: This parameter specifies the remote device.
402 * @status: This parameter specifies status of the completion.
403 *
404 */
405void isci_remote_device_start_complete(
406 struct isci_host *isci_host,
407 struct isci_remote_device *isci_device,
408 enum sci_status status)
409{
410
411
412}
413
414
415/**
416 * isci_remote_device_stop() - This function is called internally to stop the
417 * remote device.
418 * @isci_host: This parameter specifies the isci host object.
419 * @isci_device: This parameter specifies the remote device.
420 *
421 * The status of the scic request to stop.
422 */
423enum sci_status isci_remote_device_stop(
424 struct isci_remote_device *isci_device)
425{
426 enum sci_status status;
427 unsigned long flags;
428
429 DECLARE_COMPLETION_ONSTACK(completion);
430
431 dev_dbg(&isci_device->isci_port->isci_host->pdev->dev,
432 "%s: isci_device = %p\n", __func__, isci_device);
433
434 isci_remote_device_change_state(isci_device, isci_stopping);
435
436 /* We need comfirmation that stop completed. */
437 isci_device->completion = &completion;
438
439 BUG_ON(isci_device->isci_port == NULL);
440 BUG_ON(isci_device->isci_port->isci_host == NULL);
441
442 spin_lock_irqsave(&isci_device->isci_port->isci_host->scic_lock, flags);
443
444 status = scic_remote_device_stop(
445 isci_device->sci_device_handle,
446 50
447 );
448
449 spin_unlock_irqrestore(&isci_device->isci_port->isci_host->scic_lock, flags);
450
451 /* Wait for the stop complete callback. */
452 if (status == SCI_SUCCESS)
453 wait_for_completion(&completion);
454
455 dev_dbg(&isci_device->isci_port->isci_host->pdev->dev,
456 "%s: isci_device = %p - after completion wait\n",
457 __func__, isci_device);
458
459 isci_device->completion = NULL;
460 return status;
461}
462
463/**
464 * isci_remote_device_gone() - This function is called by libsas when a domain
465 * device is removed.
466 * @domain_device: This parameter specifies the libsas domain device.
467 *
468 */
469void isci_remote_device_gone(
470 struct domain_device *domain_dev)
471{
472 struct isci_remote_device *isci_device = isci_dev_from_domain_dev(
473 domain_dev);
474
475 dev_err(&isci_device->isci_port->isci_host->pdev->dev,
476 "%s: domain_device = %p, isci_device = %p, isci_port = %p\n",
477 __func__, domain_dev, isci_device, isci_device->isci_port);
478
479 if (isci_device != NULL)
480 isci_remote_device_stop(isci_device);
481}
482
483
484/**
485 * isci_remote_device_found() - This function is called by libsas when a remote
486 * device is discovered. A remote device object is created and started. the
487 * function then sleeps until the sci core device started message is
488 * received.
489 * @domain_device: This parameter specifies the libsas domain device.
490 *
491 * status, zero indicates success.
492 */
493int isci_remote_device_found(struct domain_device *domain_dev)
494{
495 unsigned long flags;
496 struct isci_host *isci_host;
497 struct isci_port *isci_port;
498 struct isci_phy *isci_phy;
499 struct asd_sas_port *sas_port;
500 struct asd_sas_phy *sas_phy;
501 struct isci_remote_device *isci_device;
502 enum sci_status status;
503 DECLARE_COMPLETION_ONSTACK(completion);
504
505 isci_host = isci_host_from_sas_ha(domain_dev->port->ha);
506
507 dev_dbg(&isci_host->pdev->dev,
508 "%s: domain_device = %p\n", __func__, domain_dev);
509
510 sas_port = domain_dev->port;
511 sas_phy = list_first_entry(&sas_port->phy_list, struct asd_sas_phy,
512 port_phy_el);
513 isci_phy = to_isci_phy(sas_phy);
514 isci_port = isci_phy->isci_port;
515
516 /* we are being called for a device on this port,
517 * so it has to come up eventually
518 */
519 wait_for_completion(&isci_port->start_complete);
520
521 if ((isci_stopping == isci_port_get_state(isci_port)) ||
522 (isci_stopped == isci_port_get_state(isci_port)))
523 return -ENODEV;
524
525 isci_device = isci_remote_device_alloc(isci_host, isci_port);
526
527 INIT_LIST_HEAD(&isci_device->node);
528 domain_dev->lldd_dev = isci_device;
529 isci_device->domain_dev = domain_dev;
530 isci_device->isci_port = isci_port;
531 isci_remote_device_change_state(isci_device, isci_starting);
532
533
534 spin_lock_irqsave(&isci_port->remote_device_lock, flags);
535 list_add_tail(&isci_device->node, &isci_port->remote_dev_list);
536
537 /* for the device ready event. */
538 isci_device->completion = &completion;
539
540 status = isci_remote_device_construct(isci_port, isci_device);
541
542 spin_unlock_irqrestore(&isci_port->remote_device_lock, flags);
543
544 /* wait for the device ready callback. */
545 wait_for_completion(isci_device->completion);
546 isci_device->completion = NULL;
547
548 dev_dbg(&isci_host->pdev->dev,
549 "%s: isci_device = %p\n",
550 __func__, isci_device);
551
552 if (status != SCI_SUCCESS) {
553
554 spin_lock_irqsave(&isci_port->remote_device_lock, flags);
555 isci_remote_device_deconstruct(
556 isci_host,
557 isci_device
558 );
559 spin_unlock_irqrestore(&isci_port->remote_device_lock, flags);
560 return -ENODEV;
561 }
562
563 wait_for_completion(&isci_host->start_complete);
564
565 return 0;
566}
567/**
568 * isci_device_is_reset_pending() - This function will check if there is any
569 * pending reset condition on the device.
570 * @request: This parameter is the isci_device object.
571 *
572 * true if there is a reset pending for the device.
573 */
574bool isci_device_is_reset_pending(
575 struct isci_host *isci_host,
576 struct isci_remote_device *isci_device)
577{
578 struct isci_request *isci_request;
579 struct isci_request *tmp_req;
580 bool reset_is_pending = false;
581 unsigned long flags;
582
583 dev_dbg(&isci_host->pdev->dev,
584 "%s: isci_device = %p\n", __func__, isci_device);
585
586 spin_lock_irqsave(&isci_host->scic_lock, flags);
587
588 /* Check for reset on all pending requests. */
589 list_for_each_entry_safe(isci_request, tmp_req,
590 &isci_device->reqs_in_process, dev_node) {
591 dev_dbg(&isci_host->pdev->dev,
592 "%s: isci_device = %p request = %p\n",
593 __func__, isci_device, isci_request);
594
595 if (isci_request->ttype == io_task) {
596
597 unsigned long flags;
598 struct sas_task *task = isci_request_access_task(
599 isci_request);
600
601 spin_lock_irqsave(&task->task_state_lock, flags);
602 if (task->task_state_flags & SAS_TASK_NEED_DEV_RESET)
603 reset_is_pending = true;
604 spin_unlock_irqrestore(&task->task_state_lock, flags);
605 }
606 }
607
608 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
609
610 dev_dbg(&isci_host->pdev->dev,
611 "%s: isci_device = %p reset_is_pending = %d\n",
612 __func__, isci_device, reset_is_pending);
613
614 return reset_is_pending;
615}
616
617/**
618 * isci_device_clear_reset_pending() - This function will clear if any pending
619 * reset condition flags on the device.
620 * @request: This parameter is the isci_device object.
621 *
622 * true if there is a reset pending for the device.
623 */
624void isci_device_clear_reset_pending(struct isci_remote_device *isci_device)
625{
626 struct isci_request *isci_request;
627 struct isci_request *tmp_req;
628 struct isci_host *isci_host = NULL;
629 unsigned long flags = 0;
630
631 /* FIXME more port gone confusion, and this time it makes the
632 * locking "fun"
633 */
634 if (isci_device->isci_port != NULL)
635 isci_host = isci_device->isci_port->isci_host;
636
637 /*
638 * FIXME when the isci_host gets sorted out
639 * use dev_dbg()
640 */
641 pr_debug("%s: isci_device=%p, isci_host=%p\n",
642 __func__, isci_device, isci_host);
643
644 if (isci_host != NULL)
645 spin_lock_irqsave(&isci_host->scic_lock, flags);
646 else
647 pr_err("%s: isci_device %p; isci_host == NULL!\n",
648 __func__, isci_device);
649
650 /* Clear reset pending on all pending requests. */
651 list_for_each_entry_safe(isci_request, tmp_req,
652 &isci_device->reqs_in_process, dev_node) {
653 /*
654 * FIXME when the conditional spinlock is gone
655 * change to dev_dbg()
656 */
657 pr_debug("%s: isci_device = %p request = %p\n",
658 __func__, isci_device, isci_request);
659
660 if (isci_request->ttype == io_task) {
661
662 unsigned long flags2;
663 struct sas_task *task = isci_request_access_task(
664 isci_request);
665
666 spin_lock_irqsave(&task->task_state_lock, flags2);
667 task->task_state_flags &= ~SAS_TASK_NEED_DEV_RESET;
668 spin_unlock_irqrestore(&task->task_state_lock, flags2);
669 }
670 }
671
672 if (isci_host != NULL)
673 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
674}
675
676/**
677 * isci_remote_device_change_state() - This function gets the status of the
678 * remote_device object.
679 * @isci_device: This parameter points to the isci_remote_device object
680 *
681 * status of the object as a isci_status enum.
682 */
683void isci_remote_device_change_state(
684 struct isci_remote_device *isci_device,
685 enum isci_status status)
686{
687 unsigned long flags;
688
689 dev_dbg(&isci_device->isci_port->isci_host->pdev->dev,
690 "%s: isci_device = %p, state = 0x%x",
691 __func__,
692 isci_device,
693 status);
694
695 spin_lock_irqsave(&isci_device->state_lock, flags);
696 isci_device->status = status;
697 spin_unlock_irqrestore(&isci_device->state_lock, flags);
698}
diff --git a/drivers/scsi/isci/remote_device.h b/drivers/scsi/isci/remote_device.h
new file mode 100644
index 000000000000..a208f81785eb
--- /dev/null
+++ b/drivers/scsi/isci/remote_device.h
@@ -0,0 +1,154 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#if !defined(_ISCI_REMOTE_DEVICE_H_)
57#define _ISCI_REMOTE_DEVICE_H_
58#include "scic_user_callback.h"
59
60struct isci_host;
61struct scic_sds_remote_device;
62
63struct isci_remote_device {
64 struct scic_sds_remote_device *sci_device_handle;
65 enum isci_status status;
66 struct isci_port *isci_port;
67 struct domain_device *domain_dev;
68 struct completion *completion;
69 struct list_head node;
70 struct list_head reqs_in_process;
71 struct work_struct stop_work;
72 spinlock_t state_lock;
73 spinlock_t host_quiesce_lock;
74 bool host_quiesce;
75};
76
77#define to_isci_remote_device(p) \
78 container_of(p, struct isci_remote_device, sci_remote_device);
79
80#define ISCI_REMOTE_DEVICE_START_TIMEOUT 5000
81
82
83/**
84 * This function gets the status of the remote_device object.
85 * @isci_device: This parameter points to the isci_remote_device object
86 *
87 * status of the object as a isci_status enum.
88 */
89static inline
90enum isci_status isci_remote_device_get_state(
91 struct isci_remote_device *isci_device)
92{
93 return (isci_device->host_quiesce)
94 ? isci_host_quiesce
95 : isci_device->status;
96}
97
98
99/**
100 * isci_dev_from_domain_dev() - This accessor retrieves the remote_device
101 * object reference from the Linux domain_device reference.
102 * @domdev,: This parameter points to the Linux domain_device object .
103 *
104 * A reference to the associated isci remote device.
105 */
106#define isci_dev_from_domain_dev(domdev) \
107 ((struct isci_remote_device *)(domdev)->lldd_dev)
108
109void isci_remote_device_start_complete(
110 struct isci_host *,
111 struct isci_remote_device *,
112 enum sci_status);
113
114void isci_remote_device_stop_complete(
115 struct isci_host *,
116 struct isci_remote_device *,
117 enum sci_status);
118
119enum sci_status isci_remote_device_stop(
120 struct isci_remote_device *isci_device);
121
122void isci_remote_device_nuke_requests(
123 struct isci_remote_device *isci_device);
124
125void isci_remote_device_ready(
126 struct isci_remote_device *);
127
128void isci_remote_device_not_ready(
129 struct isci_remote_device *,
130 u32);
131
132void isci_remote_device_gone(
133 struct domain_device *domain_dev);
134
135int isci_remote_device_found(
136 struct domain_device *domain_dev);
137
138bool isci_device_is_reset_pending(
139 struct isci_host *isci_host,
140 struct isci_remote_device *isci_device);
141
142void isci_device_clear_reset_pending(
143 struct isci_remote_device *isci_device);
144
145void isci_device_set_host_quiesce_lock_state(
146 struct isci_remote_device *isci_device,
147 bool lock_state);
148
149void isci_remote_device_change_state(
150 struct isci_remote_device *isci_device,
151 enum isci_status status);
152
153#endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */
154
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
new file mode 100644
index 000000000000..e564121b6726
--- /dev/null
+++ b/drivers/scsi/isci/request.c
@@ -0,0 +1,1472 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include "isci.h"
57#include "scic_remote_device.h"
58#include "scic_io_request.h"
59#include "scic_task_request.h"
60#include "scic_port.h"
61#include "task.h"
62#include "request.h"
63#include "sata.h"
64#include "scu_completion_codes.h"
65
66
67static enum sci_status isci_request_ssp_request_construct(
68 struct isci_request *request)
69{
70 enum sci_status status;
71
72 dev_dbg(&request->isci_host->pdev->dev,
73 "%s: request = %p\n",
74 __func__,
75 request);
76 status = scic_io_request_construct_basic_ssp(
77 request->sci_request_handle
78 );
79 return status;
80}
81
82static enum sci_status isci_request_stp_request_construct(
83 struct isci_request *request)
84{
85 struct sas_task *task = isci_request_access_task(request);
86 enum sci_status status;
87 struct host_to_dev_fis *register_fis;
88
89 dev_dbg(&request->isci_host->pdev->dev,
90 "%s: request = %p\n",
91 __func__,
92 request);
93
94 /* Get the host_to_dev_fis from the core and copy
95 * the fis from the task into it.
96 */
97 register_fis = isci_sata_task_to_fis_copy(task);
98
99 status = scic_io_request_construct_basic_sata(
100 request->sci_request_handle
101 );
102
103 /* Set the ncq tag in the fis, from the queue
104 * command in the task.
105 */
106 if (isci_sata_is_task_ncq(task)) {
107
108 isci_sata_set_ncq_tag(
109 register_fis,
110 task
111 );
112 }
113
114 return status;
115}
116
117/**
118 * isci_smp_request_build() - This function builds the smp request object.
119 * @isci_host: This parameter specifies the ISCI host object
120 * @request: This parameter points to the isci_request object allocated in the
121 * request construct function.
122 * @sci_device: This parameter is the handle for the sci core's remote device
123 * object that is the destination for this request.
124 *
125 * SCI_SUCCESS on successfull completion, or specific failure code.
126 */
127static enum sci_status isci_smp_request_build(
128 struct isci_request *request)
129{
130 enum sci_status status = SCI_FAILURE;
131 struct sas_task *task = isci_request_access_task(request);
132
133 void *command_iu_address =
134 scic_io_request_get_command_iu_address(
135 request->sci_request_handle
136 );
137
138 dev_dbg(&request->isci_host->pdev->dev,
139 "%s: request = %p\n",
140 __func__,
141 request);
142 dev_dbg(&request->isci_host->pdev->dev,
143 "%s: smp_req len = %d\n",
144 __func__,
145 task->smp_task.smp_req.length);
146
147 /* copy the smp_command to the address; */
148 sg_copy_to_buffer(&task->smp_task.smp_req, 1,
149 (char *)command_iu_address,
150 sizeof(struct smp_request)
151 );
152
153 status = scic_io_request_construct_smp(request->sci_request_handle);
154 if (status != SCI_SUCCESS)
155 dev_warn(&request->isci_host->pdev->dev,
156 "%s: scic_io_request_construct_smp failed with "
157 "status = %d\n",
158 __func__,
159 status);
160
161 return status;
162}
163
164/**
165 * isci_io_request_build() - This function builds the io request object.
166 * @isci_host: This parameter specifies the ISCI host object
167 * @request: This parameter points to the isci_request object allocated in the
168 * request construct function.
169 * @sci_device: This parameter is the handle for the sci core's remote device
170 * object that is the destination for this request.
171 *
172 * SCI_SUCCESS on successfull completion, or specific failure code.
173 */
174static enum sci_status isci_io_request_build(
175 struct isci_host *isci_host,
176 struct isci_request *request,
177 struct isci_remote_device *isci_device)
178{
179 struct smp_discover_response_protocols dev_protocols;
180 enum sci_status status = SCI_SUCCESS;
181 struct sas_task *task = isci_request_access_task(request);
182 struct scic_sds_remote_device *sci_device =
183 isci_device->sci_device_handle;
184
185 dev_dbg(&isci_host->pdev->dev,
186 "%s: isci_device = 0x%p; request = %p, "
187 "num_scatter = %d\n",
188 __func__,
189 isci_device,
190 request,
191 task->num_scatter);
192
193 /* map the sgl addresses, if present.
194 * libata does the mapping for sata devices
195 * before we get the request.
196 */
197 if (task->num_scatter &&
198 !sas_protocol_ata(task->task_proto) &&
199 !(SAS_PROTOCOL_SMP & task->task_proto)) {
200
201 request->num_sg_entries = dma_map_sg(
202 &isci_host->pdev->dev,
203 task->scatter,
204 task->num_scatter,
205 task->data_dir
206 );
207
208 if (request->num_sg_entries == 0)
209 return SCI_FAILURE_INSUFFICIENT_RESOURCES;
210 }
211
212 /* build the common request object. For now,
213 * we will let the core allocate the IO tag.
214 */
215 status = scic_io_request_construct(
216 isci_host->core_controller,
217 sci_device,
218 SCI_CONTROLLER_INVALID_IO_TAG,
219 request,
220 request->sci_request_mem_ptr,
221 (struct scic_sds_request **)&request->sci_request_handle
222 );
223
224 if (status != SCI_SUCCESS) {
225 dev_warn(&isci_host->pdev->dev,
226 "%s: failed request construct\n",
227 __func__);
228 return SCI_FAILURE;
229 }
230
231 sci_object_set_association(request->sci_request_handle, request);
232
233 /* Determine protocol and call the appropriate basic constructor */
234 scic_remote_device_get_protocols(sci_device, &dev_protocols);
235 if (dev_protocols.u.bits.attached_ssp_target)
236 status = isci_request_ssp_request_construct(request);
237 else if (dev_protocols.u.bits.attached_stp_target)
238 status = isci_request_stp_request_construct(request);
239 else if (dev_protocols.u.bits.attached_smp_target)
240 status = isci_smp_request_build(request);
241 else {
242 dev_warn(&isci_host->pdev->dev,
243 "%s: unknown protocol\n", __func__);
244 return SCI_FAILURE;
245 }
246
247 return SCI_SUCCESS;
248}
249
250
251/**
252 * isci_request_alloc_core() - This function gets the request object from the
253 * isci_host dma cache.
254 * @isci_host: This parameter specifies the ISCI host object
255 * @isci_request: This parameter will contain the pointer to the new
256 * isci_request object.
257 * @isci_device: This parameter is the pointer to the isci remote device object
258 * that is the destination for this request.
259 * @gfp_flags: This parameter specifies the os allocation flags.
260 *
261 * SCI_SUCCESS on successfull completion, or specific failure code.
262 */
263static int isci_request_alloc_core(
264 struct isci_host *isci_host,
265 struct isci_request **isci_request,
266 struct isci_remote_device *isci_device,
267 gfp_t gfp_flags)
268{
269 int ret = 0;
270 dma_addr_t handle;
271 struct isci_request *request;
272
273
274 /* get pointer to dma memory. This actually points
275 * to both the isci_remote_device object and the
276 * sci object. The isci object is at the beginning
277 * of the memory allocated here.
278 */
279 request = dma_pool_alloc(isci_host->dma_pool, gfp_flags, &handle);
280 if (!request) {
281 dev_warn(&isci_host->pdev->dev,
282 "%s: dma_pool_alloc returned NULL\n", __func__);
283 return -ENOMEM;
284 }
285
286 /* initialize the request object. */
287 spin_lock_init(&request->state_lock);
288 isci_request_change_state(request, allocated);
289 request->sci_request_mem_ptr = ((u8 *)request) +
290 sizeof(struct isci_request);
291 request->request_daddr = handle;
292 request->isci_host = isci_host;
293 request->isci_device = isci_device;
294 request->io_request_completion = NULL;
295
296 request->request_alloc_size = isci_host->dma_pool_alloc_size;
297 request->num_sg_entries = 0;
298
299 request->complete_in_target = false;
300
301 INIT_LIST_HEAD(&request->completed_node);
302 INIT_LIST_HEAD(&request->dev_node);
303
304 *isci_request = request;
305
306 return ret;
307}
308
309static int isci_request_alloc_io(
310 struct isci_host *isci_host,
311 struct sas_task *task,
312 struct isci_request **isci_request,
313 struct isci_remote_device *isci_device,
314 gfp_t gfp_flags)
315{
316 int retval = isci_request_alloc_core(isci_host, isci_request,
317 isci_device, gfp_flags);
318
319 if (!retval) {
320 (*isci_request)->ttype_ptr.io_task_ptr = task;
321 (*isci_request)->ttype = io_task;
322
323 task->lldd_task = *isci_request;
324 }
325 return retval;
326}
327
328/**
329 * isci_request_alloc_tmf() - This function gets the request object from the
330 * isci_host dma cache and initializes the relevant fields as a sas_task.
331 * @isci_host: This parameter specifies the ISCI host object
332 * @sas_task: This parameter is the task struct from the upper layer driver.
333 * @isci_request: This parameter will contain the pointer to the new
334 * isci_request object.
335 * @isci_device: This parameter is the pointer to the isci remote device object
336 * that is the destination for this request.
337 * @gfp_flags: This parameter specifies the os allocation flags.
338 *
339 * SCI_SUCCESS on successfull completion, or specific failure code.
340 */
341int isci_request_alloc_tmf(
342 struct isci_host *isci_host,
343 struct isci_tmf *isci_tmf,
344 struct isci_request **isci_request,
345 struct isci_remote_device *isci_device,
346 gfp_t gfp_flags)
347{
348 int retval = isci_request_alloc_core(isci_host, isci_request,
349 isci_device, gfp_flags);
350
351 if (!retval) {
352
353 (*isci_request)->ttype_ptr.tmf_task_ptr = isci_tmf;
354 (*isci_request)->ttype = tmf_task;
355 }
356 return retval;
357}
358
359/**
360 * isci_request_signal_device_reset() - This function will set the "device
361 * needs target reset" flag in the given sas_tasks' task_state_flags, and
362 * then cause the task to be added into the SCSI error handler queue which
363 * will eventually be escalated to a target reset.
364 *
365 *
366 */
367static void isci_request_signal_device_reset(
368 struct isci_request *isci_request)
369{
370 unsigned long flags;
371 struct sas_task *task = isci_request_access_task(isci_request);
372
373 dev_dbg(&isci_request->isci_host->pdev->dev,
374 "%s: request=%p, task=%p\n", __func__, isci_request, task);
375
376 spin_lock_irqsave(&task->task_state_lock, flags);
377 task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
378 spin_unlock_irqrestore(&task->task_state_lock, flags);
379
380 /* Cause this task to be scheduled in the SCSI error handler
381 * thread.
382 */
383 sas_task_abort(task);
384}
385
386/**
387 * isci_request_execute() - This function allocates the isci_request object,
388 * all fills in some common fields.
389 * @isci_host: This parameter specifies the ISCI host object
390 * @sas_task: This parameter is the task struct from the upper layer driver.
391 * @isci_request: This parameter will contain the pointer to the new
392 * isci_request object.
393 * @gfp_flags: This parameter specifies the os allocation flags.
394 *
395 * SCI_SUCCESS on successfull completion, or specific failure code.
396 */
397int isci_request_execute(
398 struct isci_host *isci_host,
399 struct sas_task *task,
400 struct isci_request **isci_request,
401 gfp_t gfp_flags)
402{
403 int ret = 0;
404 struct scic_sds_remote_device *sci_device;
405 enum sci_status status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
406 struct isci_remote_device *isci_device;
407 struct isci_request *request;
408 unsigned long flags;
409
410 isci_device = isci_dev_from_domain_dev(task->dev);
411 sci_device = isci_device->sci_device_handle;
412
413 /* do common allocation and init of request object. */
414 ret = isci_request_alloc_io(
415 isci_host,
416 task,
417 &request,
418 isci_device,
419 gfp_flags
420 );
421
422 if (ret)
423 goto out;
424
425 status = isci_io_request_build(isci_host, request, isci_device);
426 if (status == SCI_SUCCESS) {
427
428 spin_lock_irqsave(&isci_host->scic_lock, flags);
429
430 /* send the request, let the core assign the IO TAG. */
431 status = scic_controller_start_io(
432 isci_host->core_controller,
433 sci_device,
434 request->sci_request_handle,
435 SCI_CONTROLLER_INVALID_IO_TAG
436 );
437
438 if (status == SCI_SUCCESS ||
439 status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
440
441 /* Either I/O started OK, or the core has signaled that
442 * the device needs a target reset.
443 *
444 * In either case, hold onto the I/O for later.
445 *
446 * Update it's status and add it to the list in the
447 * remote device object.
448 */
449 isci_request_change_state(request, started);
450 list_add(&request->dev_node,
451 &isci_device->reqs_in_process);
452
453 if (status ==
454 SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
455 /* Signal libsas that we need the SCSI error
456 * handler thread to work on this I/O and that
457 * we want a device reset.
458 */
459 isci_request_signal_device_reset(request);
460
461 /* Change the status, since we are holding
462 * the I/O until it is managed by the SCSI
463 * error handler.
464 */
465 status = SCI_SUCCESS;
466 }
467 } else
468 dev_warn(&isci_host->pdev->dev,
469 "%s: failed request start\n",
470 __func__);
471
472 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
473
474 } else
475 dev_warn(&isci_host->pdev->dev,
476 "%s: request_construct failed - status = 0x%x\n",
477 __func__,
478 status);
479
480 out:
481 if (status != SCI_SUCCESS) {
482
483 /* release dma memory on failure. */
484 isci_request_free(isci_host, request);
485 request = NULL;
486 ret = SCI_FAILURE;
487 }
488
489 *isci_request = request;
490 return ret;
491}
492
493
494/**
495 * isci_request_process_response_iu() - This function sets the status and
496 * response iu, in the task struct, from the request object for the upper
497 * layer driver.
498 * @sas_task: This parameter is the task struct from the upper layer driver.
499 * @resp_iu: This parameter points to the response iu of the completed request.
500 * @dev: This parameter specifies the linux device struct.
501 *
502 * none.
503 */
504static void isci_request_process_response_iu(
505 struct sas_task *task,
506 struct ssp_response_iu *resp_iu,
507 struct device *dev)
508{
509 dev_dbg(dev,
510 "%s: resp_iu = %p "
511 "resp_iu->status = 0x%x,\nresp_iu->datapres = %d "
512 "resp_iu->response_data_len = %x, "
513 "resp_iu->sense_data_len = %x\nrepsonse data: ",
514 __func__,
515 resp_iu,
516 resp_iu->status,
517 resp_iu->datapres,
518 resp_iu->response_data_len,
519 resp_iu->sense_data_len);
520
521 task->task_status.stat = resp_iu->status;
522
523 /* libsas updates the task status fields based on the response iu. */
524 sas_ssp_task_response(dev, task, resp_iu);
525}
526
527/**
528 * isci_request_set_open_reject_status() - This function prepares the I/O
529 * completion for OPEN_REJECT conditions.
530 * @request: This parameter is the completed isci_request object.
531 * @response_ptr: This parameter specifies the service response for the I/O.
532 * @status_ptr: This parameter specifies the exec status for the I/O.
533 * @complete_to_host_ptr: This parameter specifies the action to be taken by
534 * the LLDD with respect to completing this request or forcing an abort
535 * condition on the I/O.
536 * @open_rej_reason: This parameter specifies the encoded reason for the
537 * abandon-class reject.
538 *
539 * none.
540 */
541static void isci_request_set_open_reject_status(
542 struct isci_request *request,
543 struct sas_task *task,
544 enum service_response *response_ptr,
545 enum exec_status *status_ptr,
546 enum isci_completion_selection *complete_to_host_ptr,
547 enum sas_open_rej_reason open_rej_reason)
548{
549 /* Task in the target is done. */
550 request->complete_in_target = true;
551 *response_ptr = SAS_TASK_UNDELIVERED;
552 *status_ptr = SAS_OPEN_REJECT;
553 *complete_to_host_ptr = isci_perform_normal_io_completion;
554 task->task_status.open_rej_reason = open_rej_reason;
555}
556
557/**
558 * isci_request_handle_controller_specific_errors() - This function decodes
559 * controller-specific I/O completion error conditions.
560 * @request: This parameter is the completed isci_request object.
561 * @response_ptr: This parameter specifies the service response for the I/O.
562 * @status_ptr: This parameter specifies the exec status for the I/O.
563 * @complete_to_host_ptr: This parameter specifies the action to be taken by
564 * the LLDD with respect to completing this request or forcing an abort
565 * condition on the I/O.
566 *
567 * none.
568 */
569static void isci_request_handle_controller_specific_errors(
570 struct isci_remote_device *isci_device,
571 struct isci_request *request,
572 struct sas_task *task,
573 enum service_response *response_ptr,
574 enum exec_status *status_ptr,
575 enum isci_completion_selection *complete_to_host_ptr)
576{
577 unsigned int cstatus;
578
579 cstatus = scic_request_get_controller_status(
580 request->sci_request_handle
581 );
582
583 dev_dbg(&request->isci_host->pdev->dev,
584 "%s: %p SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR "
585 "- controller status = 0x%x\n",
586 __func__, request, cstatus);
587
588 /* Decode the controller-specific errors; most
589 * important is to recognize those conditions in which
590 * the target may still have a task outstanding that
591 * must be aborted.
592 *
593 * Note that there are SCU completion codes being
594 * named in the decode below for which SCIC has already
595 * done work to handle them in a way other than as
596 * a controller-specific completion code; these are left
597 * in the decode below for completeness sake.
598 */
599 switch (cstatus) {
600 case SCU_TASK_DONE_DMASETUP_DIRERR:
601 /* Also SCU_TASK_DONE_SMP_FRM_TYPE_ERR: */
602 case SCU_TASK_DONE_XFERCNT_ERR:
603 /* Also SCU_TASK_DONE_SMP_UFI_ERR: */
604 if (task->task_proto == SAS_PROTOCOL_SMP) {
605 /* SCU_TASK_DONE_SMP_UFI_ERR == Task Done. */
606 *response_ptr = SAS_TASK_COMPLETE;
607
608 /* See if the device has been/is being stopped. Note
609 * that we ignore the quiesce state, since we are
610 * concerned about the actual device state.
611 */
612 if ((isci_device->status == isci_stopping) ||
613 (isci_device->status == isci_stopped))
614 *status_ptr = SAS_DEVICE_UNKNOWN;
615 else
616 *status_ptr = SAS_ABORTED_TASK;
617
618 request->complete_in_target = true;
619
620 *complete_to_host_ptr =
621 isci_perform_normal_io_completion;
622 } else {
623 /* Task in the target is not done. */
624 *response_ptr = SAS_TASK_UNDELIVERED;
625
626 if ((isci_device->status == isci_stopping) ||
627 (isci_device->status == isci_stopped))
628 *status_ptr = SAS_DEVICE_UNKNOWN;
629 else
630 *status_ptr = SAM_STAT_TASK_ABORTED;
631
632 request->complete_in_target = false;
633
634 *complete_to_host_ptr =
635 isci_perform_error_io_completion;
636 }
637
638 break;
639
640 case SCU_TASK_DONE_CRC_ERR:
641 case SCU_TASK_DONE_NAK_CMD_ERR:
642 case SCU_TASK_DONE_EXCESS_DATA:
643 case SCU_TASK_DONE_UNEXP_FIS:
644 /* Also SCU_TASK_DONE_UNEXP_RESP: */
645 case SCU_TASK_DONE_VIIT_ENTRY_NV: /* TODO - conditions? */
646 case SCU_TASK_DONE_IIT_ENTRY_NV: /* TODO - conditions? */
647 case SCU_TASK_DONE_RNCNV_OUTBOUND: /* TODO - conditions? */
648 /* These are conditions in which the target
649 * has completed the task, so that no cleanup
650 * is necessary.
651 */
652 *response_ptr = SAS_TASK_COMPLETE;
653
654 /* See if the device has been/is being stopped. Note
655 * that we ignore the quiesce state, since we are
656 * concerned about the actual device state.
657 */
658 if ((isci_device->status == isci_stopping) ||
659 (isci_device->status == isci_stopped))
660 *status_ptr = SAS_DEVICE_UNKNOWN;
661 else
662 *status_ptr = SAS_ABORTED_TASK;
663
664 request->complete_in_target = true;
665
666 *complete_to_host_ptr = isci_perform_normal_io_completion;
667 break;
668
669
670 /* Note that the only open reject completion codes seen here will be
671 * abandon-class codes; all others are automatically retried in the SCU.
672 */
673 case SCU_TASK_OPEN_REJECT_WRONG_DESTINATION:
674
675 isci_request_set_open_reject_status(
676 request, task, response_ptr, status_ptr,
677 complete_to_host_ptr, SAS_OREJ_WRONG_DEST);
678 break;
679
680 case SCU_TASK_OPEN_REJECT_ZONE_VIOLATION:
681
682 /* Note - the return of AB0 will change when
683 * libsas implements detection of zone violations.
684 */
685 isci_request_set_open_reject_status(
686 request, task, response_ptr, status_ptr,
687 complete_to_host_ptr, SAS_OREJ_RESV_AB0);
688 break;
689
690 case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1:
691
692 isci_request_set_open_reject_status(
693 request, task, response_ptr, status_ptr,
694 complete_to_host_ptr, SAS_OREJ_RESV_AB1);
695 break;
696
697 case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2:
698
699 isci_request_set_open_reject_status(
700 request, task, response_ptr, status_ptr,
701 complete_to_host_ptr, SAS_OREJ_RESV_AB2);
702 break;
703
704 case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3:
705
706 isci_request_set_open_reject_status(
707 request, task, response_ptr, status_ptr,
708 complete_to_host_ptr, SAS_OREJ_RESV_AB3);
709 break;
710
711 case SCU_TASK_OPEN_REJECT_BAD_DESTINATION:
712
713 isci_request_set_open_reject_status(
714 request, task, response_ptr, status_ptr,
715 complete_to_host_ptr, SAS_OREJ_BAD_DEST);
716 break;
717
718 case SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY:
719
720 isci_request_set_open_reject_status(
721 request, task, response_ptr, status_ptr,
722 complete_to_host_ptr, SAS_OREJ_STP_NORES);
723 break;
724
725 case SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED:
726
727 isci_request_set_open_reject_status(
728 request, task, response_ptr, status_ptr,
729 complete_to_host_ptr, SAS_OREJ_EPROTO);
730 break;
731
732 case SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED:
733
734 isci_request_set_open_reject_status(
735 request, task, response_ptr, status_ptr,
736 complete_to_host_ptr, SAS_OREJ_CONN_RATE);
737 break;
738
739 case SCU_TASK_DONE_LL_R_ERR:
740 /* Also SCU_TASK_DONE_ACK_NAK_TO: */
741 case SCU_TASK_DONE_LL_PERR:
742 case SCU_TASK_DONE_LL_SY_TERM:
743 /* Also SCU_TASK_DONE_NAK_ERR:*/
744 case SCU_TASK_DONE_LL_LF_TERM:
745 /* Also SCU_TASK_DONE_DATA_LEN_ERR: */
746 case SCU_TASK_DONE_LL_ABORT_ERR:
747 case SCU_TASK_DONE_SEQ_INV_TYPE:
748 /* Also SCU_TASK_DONE_UNEXP_XR: */
749 case SCU_TASK_DONE_XR_IU_LEN_ERR:
750 case SCU_TASK_DONE_INV_FIS_LEN:
751 /* Also SCU_TASK_DONE_XR_WD_LEN: */
752 case SCU_TASK_DONE_SDMA_ERR:
753 case SCU_TASK_DONE_OFFSET_ERR:
754 case SCU_TASK_DONE_MAX_PLD_ERR:
755 case SCU_TASK_DONE_LF_ERR:
756 case SCU_TASK_DONE_SMP_RESP_TO_ERR: /* Escalate to dev reset? */
757 case SCU_TASK_DONE_SMP_LL_RX_ERR:
758 case SCU_TASK_DONE_UNEXP_DATA:
759 case SCU_TASK_DONE_UNEXP_SDBFIS:
760 case SCU_TASK_DONE_REG_ERR:
761 case SCU_TASK_DONE_SDB_ERR:
762 case SCU_TASK_DONE_TASK_ABORT:
763 default:
764 /* Task in the target is not done. */
765 *response_ptr = SAS_TASK_UNDELIVERED;
766 *status_ptr = SAM_STAT_TASK_ABORTED;
767 request->complete_in_target = false;
768
769 *complete_to_host_ptr = isci_perform_error_io_completion;
770 break;
771 }
772}
773
774/**
775 * isci_task_save_for_upper_layer_completion() - This function saves the
776 * request for later completion to the upper layer driver.
777 * @host: This parameter is a pointer to the host on which the the request
778 * should be queued (either as an error or success).
779 * @request: This parameter is the completed request.
780 * @response: This parameter is the response code for the completed task.
781 * @status: This parameter is the status code for the completed task.
782 *
783 * none.
784 */
785static void isci_task_save_for_upper_layer_completion(
786 struct isci_host *host,
787 struct isci_request *request,
788 enum service_response response,
789 enum exec_status status,
790 enum isci_completion_selection task_notification_selection)
791{
792 struct sas_task *task = isci_request_access_task(request);
793
794 isci_task_set_completion_status(task, response, status,
795 task_notification_selection);
796
797
798 /* Tasks aborted specifically by a call to the lldd_abort_task
799 * function should not be completed to the host in the regular path.
800 */
801 switch (task_notification_selection) {
802
803 case isci_perform_normal_io_completion:
804
805 /* Normal notification (task_done) */
806 dev_dbg(&host->pdev->dev,
807 "%s: Normal - task = %p, response=%d, status=%d\n",
808 __func__,
809 task,
810 response,
811 status);
812 /* Add to the completed list. */
813 list_add(&request->completed_node,
814 &host->requests_to_complete);
815 break;
816
817 case isci_perform_aborted_io_completion:
818 /*
819 * No notification because this request is already
820 * in the abort path.
821 */
822 dev_warn(&host->pdev->dev,
823 "%s: Aborted - task = %p, response=%d, status=%d\n",
824 __func__,
825 task,
826 response,
827 status);
828 break;
829
830 case isci_perform_error_io_completion:
831 /* Use sas_task_abort */
832 dev_warn(&host->pdev->dev,
833 "%s: Error - task = %p, response=%d, status=%d\n",
834 __func__,
835 task,
836 response,
837 status);
838 /* Add to the aborted list. */
839 list_add(&request->completed_node,
840 &host->requests_to_abort);
841 break;
842
843 default:
844 dev_warn(&host->pdev->dev,
845 "%s: Unknown - task = %p, response=%d, status=%d\n",
846 __func__,
847 task,
848 response,
849 status);
850
851 /* Add to the aborted list. */
852 list_add(&request->completed_node,
853 &host->requests_to_abort);
854 break;
855 }
856}
857
858/**
859 * isci_request_io_request_complete() - This function is called by the sci core
860 * when an io request completes.
861 * @isci_host: This parameter specifies the ISCI host object
862 * @request: This parameter is the completed isci_request object.
863 * @completion_status: This parameter specifies the completion status from the
864 * sci core.
865 *
866 * none.
867 */
868void isci_request_io_request_complete(
869 struct isci_host *isci_host,
870 struct isci_request *request,
871 enum sci_io_status completion_status)
872{
873 struct sas_task *task = isci_request_access_task(request);
874 struct ssp_response_iu *resp_iu;
875 void *resp_buf;
876 unsigned long task_flags;
877 unsigned long state_flags;
878 struct completion *io_request_completion;
879 struct isci_remote_device *isci_device = request->isci_device;
880 enum service_response response = SAS_TASK_UNDELIVERED;
881 enum exec_status status = SAS_ABORTED_TASK;
882 enum isci_request_status request_status;
883 enum isci_completion_selection complete_to_host
884 = isci_perform_normal_io_completion;
885
886 dev_dbg(&isci_host->pdev->dev,
887 "%s: request = %p, task = %p,\n"
888 "task->data_dir = %d completion_status = 0x%x\n",
889 __func__,
890 request,
891 task,
892 task->data_dir,
893 completion_status);
894
895 spin_lock_irqsave(&request->state_lock, state_flags);
896 request_status = isci_request_get_state(request);
897 spin_unlock_irqrestore(&request->state_lock, state_flags);
898
899 /* Decode the request status. Note that if the request has been
900 * aborted by a task management function, we don't care
901 * what the status is.
902 */
903 switch (request_status) {
904
905 case aborted:
906 /* "aborted" indicates that the request was aborted by a task
907 * management function, since once a task management request is
908 * perfomed by the device, the request only completes because
909 * of the subsequent driver terminate.
910 *
911 * Aborted also means an external thread is explicitly managing
912 * this request, so that we do not complete it up the stack.
913 *
914 * The target is still there (since the TMF was successful).
915 */
916 request->complete_in_target = true;
917 response = SAS_TASK_COMPLETE;
918
919 /* See if the device has been/is being stopped. Note
920 * that we ignore the quiesce state, since we are
921 * concerned about the actual device state.
922 */
923 if ((isci_device->status == isci_stopping)
924 || (isci_device->status == isci_stopped)
925 )
926 status = SAS_DEVICE_UNKNOWN;
927 else
928 status = SAS_ABORTED_TASK;
929
930 complete_to_host = isci_perform_aborted_io_completion;
931 /* This was an aborted request. */
932 break;
933
934 case aborting:
935 /* aborting means that the task management function tried and
936 * failed to abort the request. We need to note the request
937 * as SAS_TASK_UNDELIVERED, so that the scsi mid layer marks the
938 * target as down.
939 *
940 * Aborting also means an external thread is explicitly managing
941 * this request, so that we do not complete it up the stack.
942 */
943 request->complete_in_target = true;
944 response = SAS_TASK_UNDELIVERED;
945
946 if ((isci_device->status == isci_stopping) ||
947 (isci_device->status == isci_stopped))
948 /* The device has been /is being stopped. Note that
949 * we ignore the quiesce state, since we are
950 * concerned about the actual device state.
951 */
952 status = SAS_DEVICE_UNKNOWN;
953 else
954 status = SAS_PHY_DOWN;
955
956 complete_to_host = isci_perform_aborted_io_completion;
957
958 /* This was an aborted request. */
959 break;
960
961 case terminating:
962
963 /* This was an terminated request. This happens when
964 * the I/O is being terminated because of an action on
965 * the device (reset, tear down, etc.), and the I/O needs
966 * to be completed up the stack.
967 */
968 request->complete_in_target = true;
969 response = SAS_TASK_UNDELIVERED;
970
971 /* See if the device has been/is being stopped. Note
972 * that we ignore the quiesce state, since we are
973 * concerned about the actual device state.
974 */
975 if ((isci_device->status == isci_stopping) ||
976 (isci_device->status == isci_stopped))
977 status = SAS_DEVICE_UNKNOWN;
978 else
979 status = SAS_ABORTED_TASK;
980
981 complete_to_host = isci_perform_normal_io_completion;
982
983 /* This was a terminated request. */
984 break;
985
986 default:
987
988 /* This is an active request being completed from the core. */
989 switch (completion_status) {
990
991 case SCI_IO_FAILURE_RESPONSE_VALID:
992 dev_dbg(&isci_host->pdev->dev,
993 "%s: SCI_IO_FAILURE_RESPONSE_VALID (%p/%p)\n",
994 __func__,
995 request,
996 task);
997
998 if (sas_protocol_ata(task->task_proto)) {
999 resp_buf
1000 = scic_stp_io_request_get_d2h_reg_address(
1001 request->sci_request_handle
1002 );
1003 isci_request_process_stp_response(task,
1004 resp_buf
1005 );
1006
1007 } else if (SAS_PROTOCOL_SSP == task->task_proto) {
1008
1009 /* crack the iu response buffer. */
1010 resp_iu
1011 = scic_io_request_get_response_iu_address(
1012 request->sci_request_handle
1013 );
1014
1015 isci_request_process_response_iu(task, resp_iu,
1016 &isci_host->pdev->dev
1017 );
1018
1019 } else if (SAS_PROTOCOL_SMP == task->task_proto) {
1020
1021 dev_err(&isci_host->pdev->dev,
1022 "%s: SCI_IO_FAILURE_RESPONSE_VALID: "
1023 "SAS_PROTOCOL_SMP protocol\n",
1024 __func__);
1025
1026 } else
1027 dev_err(&isci_host->pdev->dev,
1028 "%s: unknown protocol\n", __func__);
1029
1030 /* use the task status set in the task struct by the
1031 * isci_request_process_response_iu call.
1032 */
1033 request->complete_in_target = true;
1034 response = task->task_status.resp;
1035 status = task->task_status.stat;
1036 break;
1037
1038 case SCI_IO_SUCCESS:
1039 case SCI_IO_SUCCESS_IO_DONE_EARLY:
1040
1041 response = SAS_TASK_COMPLETE;
1042 status = SAM_STAT_GOOD;
1043 request->complete_in_target = true;
1044
1045 if (task->task_proto == SAS_PROTOCOL_SMP) {
1046
1047 u8 *command_iu_address
1048 = scic_io_request_get_command_iu_address(
1049 request->sci_request_handle
1050 );
1051
1052 dev_dbg(&isci_host->pdev->dev,
1053 "%s: SMP protocol completion\n",
1054 __func__);
1055
1056 sg_copy_from_buffer(
1057 &task->smp_task.smp_resp, 1,
1058 command_iu_address
1059 + sizeof(struct smp_request),
1060 sizeof(struct smp_resp)
1061 );
1062 } else if (completion_status
1063 == SCI_IO_SUCCESS_IO_DONE_EARLY) {
1064
1065 /* This was an SSP / STP / SATA transfer.
1066 * There is a possibility that less data than
1067 * the maximum was transferred.
1068 */
1069 u32 transferred_length
1070 = scic_io_request_get_number_of_bytes_transferred(
1071 request->sci_request_handle);
1072
1073 task->task_status.residual
1074 = task->total_xfer_len - transferred_length;
1075
1076 /* If there were residual bytes, call this an
1077 * underrun.
1078 */
1079 if (task->task_status.residual != 0)
1080 status = SAS_DATA_UNDERRUN;
1081
1082 dev_dbg(&isci_host->pdev->dev,
1083 "%s: SCI_IO_SUCCESS_IO_DONE_EARLY %d\n",
1084 __func__,
1085 status);
1086
1087 } else
1088 dev_dbg(&isci_host->pdev->dev,
1089 "%s: SCI_IO_SUCCESS\n",
1090 __func__);
1091
1092 break;
1093
1094 case SCI_IO_FAILURE_TERMINATED:
1095 dev_dbg(&isci_host->pdev->dev,
1096 "%s: SCI_IO_FAILURE_TERMINATED (%p/%p)\n",
1097 __func__,
1098 request,
1099 task);
1100
1101 /* The request was terminated explicitly. No handling
1102 * is needed in the SCSI error handler path.
1103 */
1104 request->complete_in_target = true;
1105 response = SAS_TASK_UNDELIVERED;
1106
1107 /* See if the device has been/is being stopped. Note
1108 * that we ignore the quiesce state, since we are
1109 * concerned about the actual device state.
1110 */
1111 if ((isci_device->status == isci_stopping) ||
1112 (isci_device->status == isci_stopped))
1113 status = SAS_DEVICE_UNKNOWN;
1114 else
1115 status = SAS_ABORTED_TASK;
1116
1117 complete_to_host = isci_perform_normal_io_completion;
1118 break;
1119
1120 case SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR:
1121
1122 isci_request_handle_controller_specific_errors(
1123 isci_device, request, task, &response, &status,
1124 &complete_to_host);
1125
1126 break;
1127
1128 case SCI_IO_FAILURE_REMOTE_DEVICE_RESET_REQUIRED:
1129 /* This is a special case, in that the I/O completion
1130 * is telling us that the device needs a reset.
1131 * In order for the device reset condition to be
1132 * noticed, the I/O has to be handled in the error
1133 * handler. Set the reset flag and cause the
1134 * SCSI error thread to be scheduled.
1135 */
1136 spin_lock_irqsave(&task->task_state_lock, task_flags);
1137 task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
1138 spin_unlock_irqrestore(&task->task_state_lock, task_flags);
1139
1140 complete_to_host = isci_perform_error_io_completion;
1141 request->complete_in_target = false;
1142 break;
1143
1144 default:
1145 /* Catch any otherwise unhandled error codes here. */
1146 dev_warn(&isci_host->pdev->dev,
1147 "%s: invalid completion code: 0x%x - "
1148 "isci_request = %p\n",
1149 __func__, completion_status, request);
1150
1151 response = SAS_TASK_UNDELIVERED;
1152
1153 /* See if the device has been/is being stopped. Note
1154 * that we ignore the quiesce state, since we are
1155 * concerned about the actual device state.
1156 */
1157 if ((isci_device->status == isci_stopping) ||
1158 (isci_device->status == isci_stopped))
1159 status = SAS_DEVICE_UNKNOWN;
1160 else
1161 status = SAS_ABORTED_TASK;
1162
1163 complete_to_host = isci_perform_error_io_completion;
1164 request->complete_in_target = false;
1165 break;
1166 }
1167 break;
1168 }
1169
1170 isci_request_unmap_sgl(request, isci_host->pdev);
1171
1172 /* Put the completed request on the correct list */
1173 isci_task_save_for_upper_layer_completion(isci_host, request, response,
1174 status, complete_to_host
1175 );
1176
1177 /* complete the io request to the core. */
1178 scic_controller_complete_io(
1179 isci_host->core_controller,
1180 isci_device->sci_device_handle,
1181 request->sci_request_handle
1182 );
1183 /* NULL the request handle so it cannot be completed or
1184 * terminated again, and to cause any calls into abort
1185 * task to recognize the already completed case.
1186 */
1187 request->sci_request_handle = NULL;
1188
1189 /* Only remove the request from the remote device list
1190 * of pending requests if we have not requested error
1191 * handling on this request.
1192 */
1193 if (complete_to_host != isci_perform_error_io_completion)
1194 list_del_init(&request->dev_node);
1195
1196
1197 /* Save possible completion ptr. */
1198 io_request_completion = request->io_request_completion;
1199
1200 if (io_request_completion) {
1201
1202 /* This is inherantly a regular I/O request,
1203 * since we are currently in the regular
1204 * I/O completion callback function.
1205 * Signal whoever is waiting that this
1206 * request is complete.
1207 */
1208 complete(io_request_completion);
1209 }
1210
1211 isci_host_can_dequeue(isci_host, 1);
1212}
1213
1214/**
1215 * isci_request_io_request_get_transfer_length() - This function is called by
1216 * the sci core to retrieve the transfer length for a given request.
1217 * @request: This parameter is the isci_request object.
1218 *
1219 * length of transfer for specified request.
1220 */
1221u32 isci_request_io_request_get_transfer_length(struct isci_request *request)
1222{
1223 struct sas_task *task = isci_request_access_task(request);
1224
1225 dev_dbg(&request->isci_host->pdev->dev,
1226 "%s: total_xfer_len: %d\n",
1227 __func__,
1228 task->total_xfer_len);
1229 return task->total_xfer_len;
1230}
1231
1232
1233/**
1234 * isci_request_io_request_get_data_direction() - This function is called by
1235 * the sci core to retrieve the data direction for a given request.
1236 * @request: This parameter is the isci_request object.
1237 *
1238 * data direction for specified request.
1239 */
1240SCI_IO_REQUEST_DATA_DIRECTION isci_request_io_request_get_data_direction(
1241 struct isci_request *request)
1242{
1243 struct sas_task *task = isci_request_access_task(request);
1244 SCI_IO_REQUEST_DATA_DIRECTION ret;
1245
1246 switch (task->data_dir) {
1247
1248 case DMA_FROM_DEVICE:
1249 ret = SCI_IO_REQUEST_DATA_IN;
1250 dev_dbg(&request->isci_host->pdev->dev,
1251 "%s: request=%p, FROM_DEVICE\n",
1252 __func__,
1253 request);
1254 break;
1255
1256 case DMA_TO_DEVICE:
1257 ret = SCI_IO_REQUEST_DATA_OUT;
1258 dev_dbg(&request->isci_host->pdev->dev,
1259 "%s: request=%p, TO_DEVICE\n",
1260 __func__,
1261 request);
1262 break;
1263
1264 case DMA_BIDIRECTIONAL:
1265 case DMA_NONE:
1266 default:
1267 ret = SCI_IO_REQUEST_NO_DATA;
1268 dev_dbg(&request->isci_host->pdev->dev,
1269 "%s: request=%p, unhandled direction case, "
1270 "data_dir=%d\n",
1271 __func__,
1272 request,
1273 task->data_dir);
1274 break;
1275
1276 }
1277 return ret;
1278}
1279
1280/**
1281 * isci_request_sge_get_address_field() - This function is called by the sci
1282 * core to retrieve the address field contents for a given sge.
1283 * @request: This parameter is the isci_request object.
1284 * @sge_address: This parameter is the sge.
1285 *
1286 * physical address in the specified sge.
1287 */
1288dma_addr_t isci_request_sge_get_address_field(
1289 struct isci_request *request,
1290 void *sge_address)
1291{
1292 struct sas_task *task = isci_request_access_task(request);
1293 dma_addr_t ret;
1294 struct isci_host *isci_host = isci_host_from_sas_ha(
1295 task->dev->port->ha);
1296
1297 dev_dbg(&isci_host->pdev->dev,
1298 "%s: request = %p, sge_address = %p\n",
1299 __func__,
1300 request,
1301 sge_address);
1302
1303 if (task->data_dir == PCI_DMA_NONE)
1304 return 0;
1305
1306 /* the case where num_scatter == 0 is special, in that
1307 * task->scatter is the actual buffer address, not an sgl.
1308 * so a map single is required here.
1309 */
1310 if ((task->num_scatter == 0) &&
1311 !sas_protocol_ata(task->task_proto)) {
1312 ret = dma_map_single(
1313 &isci_host->pdev->dev,
1314 task->scatter,
1315 task->total_xfer_len,
1316 task->data_dir
1317 );
1318 request->zero_scatter_daddr = ret;
1319 } else
1320 ret = sg_dma_address(((struct scatterlist *)sge_address));
1321
1322 dev_dbg(&isci_host->pdev->dev,
1323 "%s: bus address = %lx\n",
1324 __func__,
1325 (unsigned long)ret);
1326
1327 return ret;
1328}
1329
1330
1331/**
1332 * isci_request_sge_get_length_field() - This function is called by the sci
1333 * core to retrieve the length field contents for a given sge.
1334 * @request: This parameter is the isci_request object.
1335 * @sge_address: This parameter is the sge.
1336 *
1337 * length field value in the specified sge.
1338 */
1339u32 isci_request_sge_get_length_field(
1340 struct isci_request *request,
1341 void *sge_address)
1342{
1343 struct sas_task *task = isci_request_access_task(request);
1344 int ret;
1345
1346 dev_dbg(&request->isci_host->pdev->dev,
1347 "%s: request = %p, sge_address = %p\n",
1348 __func__,
1349 request,
1350 sge_address);
1351
1352 if (task->data_dir == PCI_DMA_NONE)
1353 return 0;
1354
1355 /* the case where num_scatter == 0 is special, in that
1356 * task->scatter is the actual buffer address, not an sgl.
1357 * so we return total_xfer_len here.
1358 */
1359 if (task->num_scatter == 0)
1360 ret = task->total_xfer_len;
1361 else
1362 ret = sg_dma_len((struct scatterlist *)sge_address);
1363
1364 dev_dbg(&request->isci_host->pdev->dev,
1365 "%s: len = %d\n",
1366 __func__,
1367 ret);
1368
1369 return ret;
1370}
1371
1372
1373/**
1374 * isci_request_ssp_io_request_get_cdb_address() - This function is called by
1375 * the sci core to retrieve the cdb address for a given request.
1376 * @request: This parameter is the isci_request object.
1377 *
1378 * cdb address for specified request.
1379 */
1380void *isci_request_ssp_io_request_get_cdb_address(
1381 struct isci_request *request)
1382{
1383 struct sas_task *task = isci_request_access_task(request);
1384
1385 dev_dbg(&request->isci_host->pdev->dev,
1386 "%s: request->task->ssp_task.cdb = %p\n",
1387 __func__,
1388 task->ssp_task.cdb);
1389 return task->ssp_task.cdb;
1390}
1391
1392
1393/**
1394 * isci_request_ssp_io_request_get_cdb_length() - This function is called by
1395 * the sci core to retrieve the cdb length for a given request.
1396 * @request: This parameter is the isci_request object.
1397 *
1398 * cdb length for specified request.
1399 */
1400u32 isci_request_ssp_io_request_get_cdb_length(
1401 struct isci_request *request)
1402{
1403 return 16;
1404}
1405
1406
1407/**
1408 * isci_request_ssp_io_request_get_lun() - This function is called by the sci
1409 * core to retrieve the lun for a given request.
1410 * @request: This parameter is the isci_request object.
1411 *
1412 * lun for specified request.
1413 */
1414u32 isci_request_ssp_io_request_get_lun(
1415 struct isci_request *request)
1416{
1417 struct sas_task *task = isci_request_access_task(request);
1418
1419#ifdef DEBUG
1420 int i;
1421
1422 for (i = 0; i < 8; i++)
1423 dev_dbg(&request->isci_host->pdev->dev,
1424 "%s: request->task->ssp_task.LUN[%d] = %x\n",
1425 __func__, i, request->task->ssp_task.LUN[i]);
1426
1427#endif
1428
1429 return task->ssp_task.LUN[0];
1430}
1431
1432
1433/**
1434 * isci_request_ssp_io_request_get_task_attribute() - This function is called
1435 * by the sci core to retrieve the task attribute for a given request.
1436 * @request: This parameter is the isci_request object.
1437 *
1438 * task attribute for specified request.
1439 */
1440u32 isci_request_ssp_io_request_get_task_attribute(
1441 struct isci_request *request)
1442{
1443 struct sas_task *task = isci_request_access_task(request);
1444
1445 dev_dbg(&request->isci_host->pdev->dev,
1446 "%s: request->task->ssp_task.task_attr = %x\n",
1447 __func__,
1448 task->ssp_task.task_attr);
1449
1450 return task->ssp_task.task_attr;
1451}
1452
1453
1454/**
1455 * isci_request_ssp_io_request_get_command_priority() - This function is called
1456 * by the sci core to retrieve the command priority for a given request.
1457 * @request: This parameter is the isci_request object.
1458 *
1459 * command priority for specified request.
1460 */
1461u32 isci_request_ssp_io_request_get_command_priority(
1462 struct isci_request *request)
1463{
1464 struct sas_task *task = isci_request_access_task(request);
1465
1466 dev_dbg(&request->isci_host->pdev->dev,
1467 "%s: request->task->ssp_task.task_prio = %x\n",
1468 __func__,
1469 task->ssp_task.task_prio);
1470
1471 return task->ssp_task.task_prio;
1472}
diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h
new file mode 100644
index 000000000000..5079d4a7c41b
--- /dev/null
+++ b/drivers/scsi/isci/request.h
@@ -0,0 +1,429 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#if !defined(_ISCI_REQUEST_H_)
57#define _ISCI_REQUEST_H_
58
59#include "isci.h"
60
61/**
62 * struct isci_request_status - This enum defines the possible states of an I/O
63 * request.
64 *
65 *
66 */
67enum isci_request_status {
68 unallocated = 0x00,
69 allocated = 0x01,
70 started = 0x02,
71 completed = 0x03,
72 aborting = 0x04,
73 aborted = 0x05,
74 terminating = 0x06
75};
76
77enum task_type {
78 io_task = 0,
79 tmf_task = 1
80};
81
82/**
83 * struct isci_request - This class represents the request object used to track
84 * IO, smp and TMF request internal. It wraps the SCIC request object.
85 *
86 *
87 */
88struct isci_request {
89
90 struct scic_sds_request *sci_request_handle;
91
92 enum isci_request_status status;
93 enum task_type ttype;
94 unsigned short io_tag;
95 bool complete_in_target;
96
97 union ttype_ptr_union {
98 struct sas_task *io_task_ptr; /* When ttype==io_task */
99 struct isci_tmf *tmf_task_ptr; /* When ttype==tmf_task */
100 } ttype_ptr;
101 struct isci_host *isci_host;
102 struct isci_remote_device *isci_device;
103 /* For use in the requests_to_{complete|abort} lists: */
104 struct list_head completed_node;
105 /* For use in the reqs_in_process list: */
106 struct list_head dev_node;
107 void *sci_request_mem_ptr;
108 spinlock_t state_lock;
109 dma_addr_t request_daddr;
110 dma_addr_t zero_scatter_daddr;
111
112 unsigned int num_sg_entries; /* returned by pci_alloc_sg */
113 unsigned int request_alloc_size; /* size of block from dma_pool_alloc */
114
115 /** Note: "io_request_completion" is completed in two different ways
116 * depending on whether this is a TMF or regular request.
117 * - TMF requests are completed in the thread that started them;
118 * - regular requests are completed in the request completion callback
119 * function.
120 * This difference in operation allows the aborter of a TMF request
121 * to be sure that once the TMF request completes, the I/O that the
122 * TMF was aborting is guaranteed to have completed.
123 */
124 struct completion *io_request_completion;
125};
126
127/**
128 * This function gets the status of the request object.
129 * @request: This parameter points to the isci_request object
130 *
131 * status of the object as a isci_request_status enum.
132 */
133static inline
134enum isci_request_status isci_request_get_state(
135 struct isci_request *isci_request)
136{
137 BUG_ON(isci_request == NULL);
138
139 /*probably a bad sign... */
140 if (isci_request->status == unallocated)
141 dev_warn(&isci_request->isci_host->pdev->dev,
142 "%s: isci_request->status == unallocated\n",
143 __func__);
144
145 return isci_request->status;
146}
147
148
149/**
150 * isci_request_change_state() - This function sets the status of the request
151 * object.
152 * @request: This parameter points to the isci_request object
153 * @status: This Parameter is the new status of the object
154 *
155 */
156static inline enum isci_request_status isci_request_change_state(
157 struct isci_request *isci_request,
158 enum isci_request_status status)
159{
160 enum isci_request_status old_state;
161 unsigned long flags;
162
163 dev_dbg(&isci_request->isci_host->pdev->dev,
164 "%s: isci_request = %p, state = 0x%x\n",
165 __func__,
166 isci_request,
167 status);
168
169 BUG_ON(isci_request == NULL);
170
171 spin_lock_irqsave(&isci_request->state_lock, flags);
172 old_state = isci_request->status;
173 isci_request->status = status;
174 spin_unlock_irqrestore(&isci_request->state_lock, flags);
175
176 return old_state;
177}
178
179/**
180 * isci_request_change_started_to_newstate() - This function sets the status of
181 * the request object.
182 * @request: This parameter points to the isci_request object
183 * @status: This Parameter is the new status of the object
184 *
185 * state previous to any change.
186 */
187static inline enum isci_request_status isci_request_change_started_to_newstate(
188 struct isci_request *isci_request,
189 struct completion *completion_ptr,
190 enum isci_request_status newstate)
191{
192 enum isci_request_status old_state;
193 unsigned long flags;
194
195 BUG_ON(isci_request == NULL);
196
197 spin_lock_irqsave(&isci_request->state_lock, flags);
198
199 old_state = isci_request->status;
200
201 if (old_state == started) {
202 BUG_ON(isci_request->io_request_completion != NULL);
203
204 isci_request->io_request_completion = completion_ptr;
205 isci_request->status = newstate;
206 }
207 spin_unlock_irqrestore(&isci_request->state_lock, flags);
208
209 dev_dbg(&isci_request->isci_host->pdev->dev,
210 "%s: isci_request = %p, old_state = 0x%x\n",
211 __func__,
212 isci_request,
213 old_state);
214
215 return old_state;
216}
217
218/**
219 * isci_request_change_started_to_aborted() - This function sets the status of
220 * the request object.
221 * @request: This parameter points to the isci_request object
222 * @completion_ptr: This parameter is saved as the kernel completion structure
223 * signalled when the old request completes.
224 *
225 * state previous to any change.
226 */
227static inline enum isci_request_status isci_request_change_started_to_aborted(
228 struct isci_request *isci_request,
229 struct completion *completion_ptr)
230{
231 return isci_request_change_started_to_newstate(
232 isci_request, completion_ptr, aborted
233 );
234}
235/**
236 * isci_request_free() - This function frees the request object.
237 * @isci_host: This parameter specifies the ISCI host object
238 * @isci_request: This parameter points to the isci_request object
239 *
240 */
241static inline void isci_request_free(
242 struct isci_host *isci_host,
243 struct isci_request *isci_request)
244{
245 BUG_ON(isci_request == NULL);
246
247 /* release the dma memory if we fail. */
248 dma_pool_free(isci_host->dma_pool, isci_request,
249 isci_request->request_daddr);
250}
251
252
253/* #define ISCI_REQUEST_VALIDATE_ACCESS
254 */
255
256#ifdef ISCI_REQUEST_VALIDATE_ACCESS
257
258static inline
259struct sas_task *isci_request_access_task(struct isci_request *isci_request)
260{
261 BUG_ON(isci_request->ttype != io_task);
262 return isci_request->ttype_ptr.io_task_ptr;
263}
264
265static inline
266struct isci_tmf *isci_request_access_tmf(struct isci_request *isci_request)
267{
268 BUG_ON(isci_request->ttype != tmf_task);
269 return isci_request->ttype_ptr.tmf_task_ptr;
270}
271
272#else /* not ISCI_REQUEST_VALIDATE_ACCESS */
273
274#define isci_request_access_task(RequestPtr) \
275 ((RequestPtr)->ttype_ptr.io_task_ptr)
276
277#define isci_request_access_tmf(RequestPtr) \
278 ((RequestPtr)->ttype_ptr.tmf_task_ptr)
279
280#endif /* not ISCI_REQUEST_VALIDATE_ACCESS */
281
282
283int isci_request_alloc_tmf(
284 struct isci_host *isci_host,
285 struct isci_tmf *isci_tmf,
286 struct isci_request **isci_request,
287 struct isci_remote_device *isci_device,
288 gfp_t gfp_flags);
289
290
291int isci_request_execute(
292 struct isci_host *isci_host,
293 struct sas_task *task,
294 struct isci_request **request,
295 gfp_t gfp_flags);
296
297/**
298 * isci_request_unmap_sgl() - This function unmaps the DMA address of a given
299 * sgl
300 * @request: This parameter points to the isci_request object
301 * @*pdev: This Parameter is the pci_device struct for the controller
302 *
303 */
304static inline void isci_request_unmap_sgl(
305 struct isci_request *request,
306 struct pci_dev *pdev)
307{
308 struct sas_task *task = isci_request_access_task(request);
309
310 dev_dbg(&request->isci_host->pdev->dev,
311 "%s: request = %p, task = %p,\n"
312 "task->data_dir = %d, is_sata = %d\n ",
313 __func__,
314 request,
315 task,
316 task->data_dir,
317 sas_protocol_ata(task->task_proto));
318
319 if ((task->data_dir != PCI_DMA_NONE) &&
320 !sas_protocol_ata(task->task_proto)) {
321 if (task->num_scatter == 0)
322 /* 0 indicates a single dma address */
323 dma_unmap_single(
324 &pdev->dev,
325 request->zero_scatter_daddr,
326 task->total_xfer_len,
327 task->data_dir
328 );
329
330 else /* unmap the sgl dma addresses */
331 dma_unmap_sg(
332 &pdev->dev,
333 task->scatter,
334 request->num_sg_entries,
335 task->data_dir
336 );
337 }
338}
339
340
341void isci_request_io_request_complete(
342 struct isci_host *isci_host,
343 struct isci_request *request,
344 enum sci_io_status completion_status);
345
346u32 isci_request_io_request_get_transfer_length(
347 struct isci_request *request);
348
349SCI_IO_REQUEST_DATA_DIRECTION isci_request_io_request_get_data_direction(
350 struct isci_request *request);
351
352/**
353 * isci_request_io_request_get_next_sge() - This function is called by the sci
354 * core to retrieve the next sge for a given request.
355 * @request: This parameter is the isci_request object.
356 * @current_sge_address: This parameter is the last sge retrieved by the sci
357 * core for this request.
358 *
359 * pointer to the next sge for specified request.
360 */
361static inline void *isci_request_io_request_get_next_sge(
362 struct isci_request *request,
363 void *current_sge_address)
364{
365 struct sas_task *task = isci_request_access_task(request);
366 void *ret = NULL;
367
368 dev_dbg(&request->isci_host->pdev->dev,
369 "%s: request = %p, "
370 "current_sge_address = %p, "
371 "num_scatter = %d\n",
372 __func__,
373 request,
374 current_sge_address,
375 task->num_scatter);
376
377 if (!current_sge_address) /* First time through.. */
378 ret = task->scatter; /* always task->scatter */
379 else if (task->num_scatter == 0) /* Next element, if num_scatter == 0 */
380 ret = NULL; /* there is only one element. */
381 else
382 ret = sg_next(current_sge_address); /* sg_next returns NULL
383 * for the last element
384 */
385
386 dev_dbg(&request->isci_host->pdev->dev,
387 "%s: next sge address = %p\n",
388 __func__,
389 ret);
390
391 return ret;
392}
393
394dma_addr_t isci_request_sge_get_address_field(
395 struct isci_request *request,
396 void *sge_address);
397
398u32 isci_request_sge_get_length_field(
399 struct isci_request *request,
400 void *sge_address);
401
402void *isci_request_ssp_io_request_get_cdb_address(
403 struct isci_request *request);
404
405u32 isci_request_ssp_io_request_get_cdb_length(
406 struct isci_request *request);
407
408u32 isci_request_ssp_io_request_get_lun(
409 struct isci_request *request);
410
411u32 isci_request_ssp_io_request_get_task_attribute(
412 struct isci_request *request);
413
414u32 isci_request_ssp_io_request_get_command_priority(
415 struct isci_request *request);
416
417
418
419
420
421void isci_terminate_pending_requests(
422 struct isci_host *isci_host,
423 struct isci_remote_device *isci_device,
424 enum isci_request_status new_request_state);
425
426
427
428
429#endif /* !defined(_ISCI_REQUEST_H_) */
diff --git a/drivers/scsi/isci/sata.c b/drivers/scsi/isci/sata.c
new file mode 100644
index 000000000000..19b0eea93ca7
--- /dev/null
+++ b/drivers/scsi/isci/sata.c
@@ -0,0 +1,356 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include "isci.h"
57#include "scic_remote_device.h"
58#include "scic_sds_remote_device.h"
59#include "scic_io_request.h"
60#include "scic_task_request.h"
61#include "task.h"
62#include "request.h"
63#include "sata.h"
64#include "intel_sat.h"
65#include "intel_ata.h"
66
67static u8 isci_sata_get_management_task_protocol(struct isci_tmf *tmf);
68
69
70/**
71 * isci_sata_task_to_fis_copy() - This function gets the host_to_dev_fis from
72 * the core and copies the fis from the task into it.
73 * @task: This parameter is a pointer to the task struct from libsas.
74 *
75 * pointer to the host_to_dev_fis from the core request object.
76 */
77struct host_to_dev_fis *isci_sata_task_to_fis_copy(struct sas_task *task)
78{
79 struct isci_request *request = task->lldd_task;
80 struct host_to_dev_fis *register_fis =
81 scic_stp_io_request_get_h2d_reg_address(
82 request->sci_request_handle
83 );
84
85 memcpy(
86 (u8 *)register_fis,
87 (u8 *)&task->ata_task.fis,
88 sizeof(struct host_to_dev_fis)
89 );
90
91 if (!task->ata_task.device_control_reg_update)
92 register_fis->flags |= 0x80;
93
94 register_fis->flags &= 0xF0;
95
96 return register_fis;
97}
98
99/**
100 * isci_sata_is_task_ncq() - This function determines if the given stp task is
101 * a ncq request.
102 * @task: This parameter is a pointer to the task struct from libsas.
103 *
104 * true if the task is ncq
105 */
106bool isci_sata_is_task_ncq(struct sas_task *task)
107{
108 struct ata_queued_cmd *qc = task->uldd_task;
109
110 bool ret = (qc &&
111 (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
112 qc->tf.command == ATA_CMD_FPDMA_READ));
113
114 return ret;
115}
116
117/**
118 * isci_sata_set_ncq_tag() - This function sets the ncq tag field in the
119 * host_to_dev_fis equal to the tag in the queue command in the task.
120 * @task: This parameter is a pointer to the task struct from libsas.
121 * @register_fis: This parameter is a pointer to the host_to_dev_fis from the
122 * core request object.
123 *
124 */
125void isci_sata_set_ncq_tag(
126 struct host_to_dev_fis *register_fis,
127 struct sas_task *task)
128{
129 struct ata_queued_cmd *qc = task->uldd_task;
130 struct isci_request *request = task->lldd_task;
131
132 register_fis->sector_count = qc->tag << 3;
133 scic_stp_io_request_set_ncq_tag(request->sci_request_handle, qc->tag);
134}
135
136/**
137 * isci_request_process_stp_response() - This function sets the status and
138 * response, in the task struct, from the request object for the upper layer
139 * driver.
140 * @sas_task: This parameter is the task struct from the upper layer driver.
141 * @response_buffer: This parameter points to the response of the completed
142 * request.
143 *
144 * none.
145 */
146void isci_request_process_stp_response(
147 struct sas_task *task,
148 void *response_buffer)
149{
150 struct sata_fis_reg_d2h *d2h_reg_fis = (struct sata_fis_reg_d2h *)response_buffer;
151 struct task_status_struct *ts = &task->task_status;
152 struct ata_task_resp *resp = (void *)&ts->buf[0];
153
154 resp->frame_len = le16_to_cpu(*(__le16 *)(response_buffer + 6));
155 memcpy(&resp->ending_fis[0], response_buffer + 16, 24);
156 ts->buf_valid_size = sizeof(*resp);
157
158 /**
159 * If the device fault bit is set in the status register, then
160 * set the sense data and return.
161 */
162 if (d2h_reg_fis->status & ATA_STATUS_REG_DEVICE_FAULT_BIT)
163 ts->stat = SAS_PROTO_RESPONSE;
164 else
165 ts->stat = SAM_STAT_GOOD;
166
167 ts->resp = SAS_TASK_COMPLETE;
168}
169
170/**
171 * isci_sata_get_sat_protocol() - retrieve the sat protocol for the request
172 * @isci_request: ata request
173 *
174 * Note: temporary implementation until expert mode removes the callback
175 *
176 */
177u8 isci_sata_get_sat_protocol(struct isci_request *isci_request)
178{
179 struct sas_task *task;
180 struct domain_device *dev;
181
182 dev_dbg(&isci_request->isci_host->pdev->dev,
183 "%s: isci_request = %p, ttype = %d\n",
184 __func__, isci_request, isci_request->ttype);
185
186 if (tmf_task == isci_request->ttype) {
187 struct isci_tmf *tmf = isci_request_access_tmf(isci_request);
188
189 return isci_sata_get_management_task_protocol(tmf);
190 }
191
192 task = isci_request_access_task(isci_request);
193 dev = task->dev;
194
195 if (!sas_protocol_ata(task->task_proto)) {
196 WARN(1, "unhandled task protocol\n");
197 return SAT_PROTOCOL_NON_DATA;
198 }
199
200 if (task->data_dir == DMA_NONE)
201 return SAT_PROTOCOL_NON_DATA;
202
203 /* the "_IN" protocol types are equivalent to their "_OUT"
204 * analogs as far as the core is concerned
205 */
206 if (dev->sata_dev.command_set == ATAPI_COMMAND_SET) {
207 if (task->ata_task.dma_xfer)
208 return SAT_PROTOCOL_PACKET_DMA_DATA_IN;
209 else
210 return SAT_PROTOCOL_PACKET_PIO_DATA_IN;
211 }
212
213 if (task->ata_task.use_ncq)
214 return SAT_PROTOCOL_FPDMA;
215
216 if (task->ata_task.dma_xfer)
217 return SAT_PROTOCOL_UDMA_DATA_IN;
218 else
219 return SAT_PROTOCOL_PIO_DATA_IN;
220}
221
222static u8 isci_sata_get_management_task_protocol(
223 struct isci_tmf *tmf)
224{
225 u8 ret = 0;
226
227 pr_warn("tmf = %p, func = %d\n", tmf, tmf->tmf_code);
228
229 if ((tmf->tmf_code == isci_tmf_sata_srst_high) ||
230 (tmf->tmf_code == isci_tmf_sata_srst_low)) {
231 pr_warn("%s: tmf->tmf_code == TMF_LU_RESET\n", __func__);
232 ret = SAT_PROTOCOL_SOFT_RESET;
233 }
234
235 return ret;
236}
237
238enum sci_status isci_sata_management_task_request_build(
239 struct isci_request *isci_request)
240{
241 struct isci_tmf *isci_tmf;
242 enum sci_status status;
243
244 if (tmf_task != isci_request->ttype)
245 return SCI_FAILURE;
246
247 isci_tmf = isci_request_access_tmf(isci_request);
248
249 switch (isci_tmf->tmf_code) {
250
251 case isci_tmf_sata_srst_high:
252 case isci_tmf_sata_srst_low:
253 {
254 struct host_to_dev_fis *register_fis =
255 scic_stp_io_request_get_h2d_reg_address(
256 isci_request->sci_request_handle
257 );
258
259 memset(register_fis, 0, sizeof(*register_fis));
260
261 register_fis->fis_type = 0x27;
262 register_fis->flags &= ~0x80;
263 register_fis->flags &= 0xF0;
264 if (isci_tmf->tmf_code == isci_tmf_sata_srst_high)
265 register_fis->control |= ATA_SRST;
266 else
267 register_fis->control &= ~ATA_SRST;
268 break;
269 }
270 /* other management commnd go here... */
271 default:
272 return SCI_FAILURE;
273 }
274
275 /* core builds the protocol specific request
276 * based on the h2d fis.
277 */
278 status = scic_task_request_construct_sata(
279 isci_request->sci_request_handle
280 );
281
282 return status;
283}
284
285/**
286 * isci_task_send_lu_reset_sata() - This function is called by of the SAS
287 * Domain Template functions. This is one of the Task Management functoins
288 * called by libsas, to reset the given SAS lun. Note the assumption that
289 * while this call is executing, no I/O will be sent by the host to the
290 * device.
291 * @lun: This parameter specifies the lun to be reset.
292 *
293 * status, zero indicates success.
294 */
295int isci_task_send_lu_reset_sata(
296 struct isci_host *isci_host,
297 struct isci_remote_device *isci_device,
298 u8 *lun)
299{
300 struct isci_tmf tmf;
301 int ret = TMF_RESP_FUNC_FAILED;
302 unsigned long flags;
303
304 /* Send the initial SRST to the target */
305 #define ISCI_SRST_TIMEOUT_MS 20 /* 20 ms timeout. */
306 isci_task_build_tmf(&tmf, isci_device, isci_tmf_sata_srst_high,
307 NULL, NULL
308 );
309
310 ret = isci_task_execute_tmf(isci_host, &tmf, ISCI_SRST_TIMEOUT_MS);
311
312 if (ret != TMF_RESP_FUNC_COMPLETE) {
313 dev_warn(&isci_host->pdev->dev,
314 "%s: Assert SRST failed (%p) = %x",
315 __func__,
316 isci_device,
317 ret);
318
319 /* Return the failure so that the LUN reset is escalated
320 * to a target reset.
321 */
322 goto out;
323 }
324
325 /* Leave SRST high for a bit. */
326 #define ISCI_SRST_ASSERT_DELAY 100 /* usecs */
327 scic_cb_stall_execution(ISCI_SRST_ASSERT_DELAY);
328
329 /* Deassert SRST. */
330 isci_task_build_tmf(&tmf, isci_device, isci_tmf_sata_srst_low,
331 NULL, NULL
332 );
333 ret = isci_task_execute_tmf(isci_host, &tmf, ISCI_SRST_TIMEOUT_MS);
334
335 if (ret == TMF_RESP_FUNC_COMPLETE)
336 dev_dbg(&isci_host->pdev->dev,
337 "%s: SATA LUN reset passed (%p)\n",
338 __func__,
339 isci_device);
340 else
341 dev_warn(&isci_host->pdev->dev,
342 "%s: Deassert SRST failed (%p)=%x\n",
343 __func__,
344 isci_device,
345 ret);
346
347 out:
348 spin_lock_irqsave(&isci_host->scic_lock, flags);
349
350 /* Resume the device. */
351 scic_sds_remote_device_resume(isci_device->sci_device_handle);
352
353 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
354
355 return ret;
356}
diff --git a/drivers/scsi/isci/sata.h b/drivers/scsi/isci/sata.h
new file mode 100644
index 000000000000..b6ba25b52d2c
--- /dev/null
+++ b/drivers/scsi/isci/sata.h
@@ -0,0 +1,83 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include "intel_sat.h"
57
58
59
60struct host_to_dev_fis *isci_sata_task_to_fis_copy(
61 struct sas_task *task);
62
63bool isci_sata_is_task_ncq(
64 struct sas_task *task);
65
66void isci_sata_set_ncq_tag(
67 struct host_to_dev_fis *register_fis,
68 struct sas_task *task);
69
70void isci_request_process_stp_response(
71 struct sas_task *task,
72 void *response_buffer);
73
74u8 isci_sata_get_sat_protocol(
75 struct isci_request *isci_request);
76
77enum sci_status isci_sata_management_task_request_build(
78 struct isci_request *isci_request);
79
80int isci_task_send_lu_reset_sata(
81 struct isci_host *isci_host,
82 struct isci_remote_device *isci_device,
83 u8 *lun);
diff --git a/drivers/scsi/isci/sci_environment.h b/drivers/scsi/isci/sci_environment.h
new file mode 100644
index 000000000000..e1020ee6c38e
--- /dev/null
+++ b/drivers/scsi/isci/sci_environment.h
@@ -0,0 +1,112 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#ifndef _SCI_ENVIRONMENT_H_
57#define _SCI_ENVIRONMENT_H_
58
59#include "isci.h"
60
61struct scic_sds_controller;
62struct scic_sds_phy;
63struct scic_sds_port;
64struct scic_sds_remote_device;
65
66static inline struct device *scic_to_dev(struct scic_sds_controller *scic)
67{
68 struct isci_host *isci_host = sci_object_get_association(scic);
69
70 return &isci_host->pdev->dev;
71}
72
73static inline struct device *sciphy_to_dev(struct scic_sds_phy *sci_phy)
74{
75 struct isci_phy *iphy = sci_object_get_association(sci_phy);
76
77 if (!iphy || !iphy->isci_port || !iphy->isci_port->isci_host)
78 return NULL;
79
80 return &iphy->isci_port->isci_host->pdev->dev;
81}
82
83static inline struct device *sciport_to_dev(struct scic_sds_port *sci_port)
84{
85 struct isci_port *iport = sci_object_get_association(sci_port);
86
87 if (!iport || !iport->isci_host)
88 return NULL;
89
90 return &iport->isci_host->pdev->dev;
91}
92
93static inline struct device *scirdev_to_dev(struct scic_sds_remote_device *sci_dev)
94{
95 struct isci_remote_device *idev = sci_object_get_association(sci_dev);
96
97 if (!idev || !idev->isci_port || !idev->isci_port->isci_host)
98 return NULL;
99
100 return &idev->isci_port->isci_host->pdev->dev;
101}
102
103enum {
104 ISCI_SI_REVA0,
105 ISCI_SI_REVA2,
106 ISCI_SI_REVB0,
107};
108
109extern int isci_si_rev;
110
111
112#endif
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c
new file mode 100644
index 000000000000..5e6f55863407
--- /dev/null
+++ b/drivers/scsi/isci/task.c
@@ -0,0 +1,1691 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include <linux/completion.h>
57#include "scic_task_request.h"
58#include "scic_remote_device.h"
59#include "scic_io_request.h"
60#include "scic_sds_remote_device.h"
61#include "scic_sds_remote_node_context.h"
62#include "isci.h"
63#include "request.h"
64#include "sata.h"
65#include "task.h"
66
67
68/**
69 * isci_task_execute_task() - This function is one of the SAS Domain Template
70 * functions. This function is called by libsas to send a task down to
71 * hardware.
72 * @task: This parameter specifies the SAS task to send.
73 * @num: This parameter specifies the number of tasks to queue.
74 * @gfp_flags: This parameter specifies the context of this call.
75 *
76 * status, zero indicates success.
77 */
78int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
79{
80 struct isci_host *isci_host;
81 struct isci_request *request = NULL;
82 struct isci_remote_device *device;
83 unsigned long flags;
84 unsigned long quiesce_flags = 0;
85 int ret;
86 enum sci_status status;
87
88
89 dev_dbg(task->dev->port->ha->dev, "%s: num=%d\n", __func__, num);
90
91 if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
92
93 isci_task_complete_for_upper_layer(
94 task,
95 SAS_TASK_UNDELIVERED,
96 SAM_STAT_TASK_ABORTED,
97 isci_perform_normal_io_completion
98 );
99
100 return 0; /* The I/O was accepted (and failed). */
101 }
102 if ((task->dev == NULL) || (task->dev->port == NULL)) {
103
104 /* Indicate SAS_TASK_UNDELIVERED, so that the scsi midlayer
105 * removes the target.
106 */
107 isci_task_complete_for_upper_layer(
108 task,
109 SAS_TASK_UNDELIVERED,
110 SAS_DEVICE_UNKNOWN,
111 isci_perform_normal_io_completion
112 );
113 return 0; /* The I/O was accepted (and failed). */
114 }
115 isci_host = isci_host_from_sas_ha(task->dev->port->ha);
116
117 /* Check if we have room for more tasks */
118 ret = isci_host_can_queue(isci_host, num);
119
120 if (ret) {
121 dev_warn(task->dev->port->ha->dev, "%s: queue full\n", __func__);
122 return ret;
123 }
124
125 do {
126 dev_dbg(task->dev->port->ha->dev,
127 "task = %p, num = %d; dev = %p; cmd = %p\n",
128 task, num, task->dev, task->uldd_task);
129
130 if ((task->dev == NULL) || (task->dev->port == NULL)) {
131 dev_warn(task->dev->port->ha->dev,
132 "%s: task %p's port or dev == NULL!\n",
133 __func__, task);
134
135 /* Indicate SAS_TASK_UNDELIVERED, so that the scsi
136 * midlayer removes the target.
137 */
138 isci_task_complete_for_upper_layer(
139 task,
140 SAS_TASK_UNDELIVERED,
141 SAS_DEVICE_UNKNOWN,
142 isci_perform_normal_io_completion
143 );
144 /* We don't have a valid host reference, so we
145 * can't control the host queueing condition.
146 */
147 continue;
148 }
149
150 device = isci_dev_from_domain_dev(task->dev);
151
152 isci_host = isci_host_from_sas_ha(task->dev->port->ha);
153
154 /* check if the controller hasn't started or if the device
155 * is ready but not accepting IO.
156 */
157 if (device) {
158
159 spin_lock_irqsave(&device->host_quiesce_lock,
160 quiesce_flags);
161 }
162 /* From this point onward, any process that needs to guarantee
163 * that there is no kernel I/O being started will have to wait
164 * for the quiesce spinlock.
165 */
166
167 if (isci_host_get_state(isci_host) == isci_starting ||
168 (device && ((isci_remote_device_get_state(device) == isci_ready) ||
169 (isci_remote_device_get_state(device) == isci_host_quiesce)))) {
170
171 /* Forces a retry from scsi mid layer. */
172 dev_warn(task->dev->port->ha->dev,
173 "%s: task %p: isci_host->status = %d, "
174 "device = %p\n",
175 __func__,
176 task,
177 isci_host_get_state(isci_host),
178 device);
179
180 if (device)
181 dev_dbg(task->dev->port->ha->dev,
182 "%s: device->status = 0x%x\n",
183 __func__,
184 isci_remote_device_get_state(device));
185
186 /* Indicate QUEUE_FULL so that the scsi midlayer
187 * retries.
188 */
189 isci_task_complete_for_upper_layer(
190 task,
191 SAS_TASK_COMPLETE,
192 SAS_QUEUE_FULL,
193 isci_perform_normal_io_completion
194 );
195 isci_host_can_dequeue(isci_host, 1);
196 }
197 /* the device is going down... */
198 else if (!device || (isci_ready_for_io != isci_remote_device_get_state(device))) {
199
200 dev_dbg(task->dev->port->ha->dev,
201 "%s: task %p: isci_host->status = %d, "
202 "device = %p\n",
203 __func__,
204 task,
205 isci_host_get_state(isci_host),
206 device);
207
208 if (device)
209 dev_dbg(task->dev->port->ha->dev,
210 "%s: device->status = 0x%x\n",
211 __func__,
212 isci_remote_device_get_state(device));
213
214 /* Indicate SAS_TASK_UNDELIVERED, so that the scsi
215 * midlayer removes the target.
216 */
217 isci_task_complete_for_upper_layer(
218 task,
219 SAS_TASK_UNDELIVERED,
220 SAS_DEVICE_UNKNOWN,
221 isci_perform_normal_io_completion
222 );
223 isci_host_can_dequeue(isci_host, 1);
224
225 } else {
226 /* build and send the request. */
227 status = isci_request_execute(isci_host, task, &request,
228 gfp_flags);
229
230 if (status == SCI_SUCCESS) {
231 spin_lock_irqsave(&task->task_state_lock, flags);
232 task->task_state_flags |= SAS_TASK_AT_INITIATOR;
233 spin_unlock_irqrestore(&task->task_state_lock, flags);
234 } else {
235 /* Indicate QUEUE_FULL so that the scsi
236 * midlayer retries. if the request
237 * failed for remote device reasons,
238 * it gets returned as
239 * SAS_TASK_UNDELIVERED next time
240 * through.
241 */
242 isci_task_complete_for_upper_layer(
243 task,
244 SAS_TASK_COMPLETE,
245 SAS_QUEUE_FULL,
246 isci_perform_normal_io_completion
247 );
248 isci_host_can_dequeue(isci_host, 1);
249 }
250 }
251 if (device) {
252 spin_unlock_irqrestore(&device->host_quiesce_lock,
253 quiesce_flags
254 );
255 }
256 task = list_entry(task->list.next, struct sas_task, list);
257 } while (--num > 0);
258 return 0;
259}
260
261
262
263/**
264 * isci_task_request_build() - This function builds the task request object.
265 * @isci_host: This parameter specifies the ISCI host object
266 * @request: This parameter points to the isci_request object allocated in the
267 * request construct function.
268 * @tmf: This parameter is the task management struct to be built
269 *
270 * SCI_SUCCESS on successfull completion, or specific failure code.
271 */
272static enum sci_status isci_task_request_build(
273 struct isci_host *isci_host,
274 struct isci_request **isci_request,
275 struct isci_tmf *isci_tmf)
276{
277 struct scic_sds_remote_device *sci_device;
278 enum sci_status status = SCI_FAILURE;
279 struct isci_request *request;
280 struct isci_remote_device *isci_device;
281/* struct sci_sas_identify_address_frame_protocols dev_protocols; */
282 struct smp_discover_response_protocols dev_protocols;
283
284
285 dev_dbg(&isci_host->pdev->dev,
286 "%s: isci_tmf = %p\n", __func__, isci_tmf);
287
288 isci_device = isci_tmf->device;
289 sci_device = isci_device->sci_device_handle;
290
291 /* do common allocation and init of request object. */
292 status = isci_request_alloc_tmf(
293 isci_host,
294 isci_tmf,
295 &request,
296 isci_device,
297 GFP_ATOMIC
298 );
299
300 if (status != SCI_SUCCESS)
301 goto out;
302
303 /* let the core do it's construct. */
304 status = scic_task_request_construct(
305 isci_host->core_controller,
306 sci_device,
307 SCI_CONTROLLER_INVALID_IO_TAG,
308 request,
309 request->sci_request_mem_ptr,
310 &request->sci_request_handle
311 );
312
313 if (status != SCI_SUCCESS) {
314 dev_warn(&isci_host->pdev->dev,
315 "%s: scic_task_request_construct failed - "
316 "status = 0x%x\n",
317 __func__,
318 status);
319 goto errout;
320 }
321
322 sci_object_set_association(
323 request->sci_request_handle,
324 request
325 );
326
327 scic_remote_device_get_protocols(
328 sci_device,
329 &dev_protocols
330 );
331
332 /* let the core do it's protocol
333 * specific construction.
334 */
335 if (dev_protocols.u.bits.attached_ssp_target) {
336
337 isci_tmf->proto = SAS_PROTOCOL_SSP;
338 status = scic_task_request_construct_ssp(
339 request->sci_request_handle
340 );
341 if (status != SCI_SUCCESS)
342 goto errout;
343 }
344
345 if (dev_protocols.u.bits.attached_stp_target) {
346
347 isci_tmf->proto = SAS_PROTOCOL_SATA;
348 status = isci_sata_management_task_request_build(request);
349
350 if (status != SCI_SUCCESS)
351 goto errout;
352 }
353
354 goto out;
355
356 errout:
357
358 /* release the dma memory if we fail. */
359 isci_request_free(isci_host, request);
360 request = NULL;
361
362 out:
363 *isci_request = request;
364 return status;
365}
366
367/**
368 * isci_tmf_timeout_cb() - This function is called as a kernel callback when
369 * the timeout period for the TMF has expired.
370 *
371 *
372 */
373static void isci_tmf_timeout_cb(void *tmf_request_arg)
374{
375 struct isci_request *request = (struct isci_request *)tmf_request_arg;
376 struct isci_tmf *tmf = isci_request_access_tmf(request);
377 enum sci_status status;
378
379 BUG_ON(request->ttype != tmf_task);
380
381 /* This task management request has timed-out. Terminate the request
382 * so that the request eventually completes to the requestor in the
383 * request completion callback path.
384 */
385 /* Note - the timer callback function itself has provided spinlock
386 * exclusion from the start and completion paths. No need to take
387 * the request->isci_host->scic_lock here.
388 */
389
390 if (tmf->timeout_timer != NULL) {
391 /* Call the users callback, if any. */
392 if (tmf->cb_state_func != NULL)
393 tmf->cb_state_func(isci_tmf_timed_out, tmf,
394 tmf->cb_data);
395
396 /* Terminate the TMF transmit request. */
397 status = scic_controller_terminate_request(
398 request->isci_host->core_controller,
399 request->isci_device->sci_device_handle,
400 request->sci_request_handle
401 );
402
403 dev_dbg(&request->isci_host->pdev->dev,
404 "%s: tmf_request = %p; tmf = %p; status = %d\n",
405 __func__, request, tmf, status);
406 } else
407 dev_dbg(&request->isci_host->pdev->dev,
408 "%s: timer already canceled! "
409 "tmf_request = %p; tmf = %p\n",
410 __func__, request, tmf);
411
412 /* No need to unlock since the caller to this callback is doing it for
413 * us.
414 * request->isci_host->scic_lock
415 */
416}
417
418/**
419 * isci_task_execute_tmf() - This function builds and sends a task request,
420 * then waits for the completion.
421 * @isci_host: This parameter specifies the ISCI host object
422 * @tmf: This parameter is the pointer to the task management structure for
423 * this request.
424 * @timeout_ms: This parameter specifies the timeout period for the task
425 * management request.
426 *
427 * TMF_RESP_FUNC_COMPLETE on successful completion of the TMF (this includes
428 * error conditions reported in the IU status), or TMF_RESP_FUNC_FAILED.
429 */
430int isci_task_execute_tmf(
431 struct isci_host *isci_host,
432 struct isci_tmf *tmf,
433 unsigned long timeout_ms)
434{
435 DECLARE_COMPLETION_ONSTACK(completion);
436 enum sci_status status = SCI_FAILURE;
437 struct scic_sds_remote_device *sci_device;
438 struct isci_remote_device *isci_device = tmf->device;
439 struct isci_request *request;
440 int ret = TMF_RESP_FUNC_FAILED;
441 unsigned long flags;
442
443 /* sanity check, return TMF_RESP_FUNC_FAILED
444 * if the device is not there and ready.
445 */
446 if (!isci_device ||
447 ((isci_ready_for_io != isci_remote_device_get_state(isci_device)) &&
448 (isci_host_quiesce != isci_remote_device_get_state(isci_device)))) {
449 dev_dbg(&isci_host->pdev->dev,
450 "%s: isci_device = %p not ready (%d)\n",
451 __func__,
452 isci_device,
453 isci_remote_device_get_state(isci_device));
454 return TMF_RESP_FUNC_FAILED;
455 } else
456 dev_dbg(&isci_host->pdev->dev,
457 "%s: isci_device = %p\n",
458 __func__, isci_device);
459
460 sci_device = isci_device->sci_device_handle;
461
462 /* Assign the pointer to the TMF's completion kernel wait structure. */
463 tmf->complete = &completion;
464
465 isci_task_request_build(
466 isci_host,
467 &request,
468 tmf
469 );
470
471 if (!request) {
472 dev_warn(&isci_host->pdev->dev,
473 "%s: isci_task_request_build failed\n",
474 __func__);
475 return TMF_RESP_FUNC_FAILED;
476 }
477
478 /* Allocate the TMF timeout timer. */
479 tmf->timeout_timer = isci_timer_create(
480 &isci_host->timer_list_struct,
481 isci_host,
482 request,
483 isci_tmf_timeout_cb
484 );
485
486 spin_lock_irqsave(&isci_host->scic_lock, flags);
487
488 /* Start the timer. */
489 if (tmf->timeout_timer)
490 isci_timer_start(tmf->timeout_timer, timeout_ms);
491 else
492 dev_warn(&isci_host->pdev->dev,
493 "%s: isci_timer_create failed!!!!\n",
494 __func__);
495
496 /* start the TMF io. */
497 status = scic_controller_start_task(
498 isci_host->core_controller,
499 sci_device,
500 request->sci_request_handle,
501 SCI_CONTROLLER_INVALID_IO_TAG
502 );
503
504 if (status != SCI_SUCCESS) {
505 dev_warn(&isci_host->pdev->dev,
506 "%s: start_io failed - status = 0x%x, request = %p\n",
507 __func__,
508 status,
509 request);
510 goto cleanup_request;
511 }
512
513 /* Call the users callback, if any. */
514 if (tmf->cb_state_func != NULL)
515 tmf->cb_state_func(isci_tmf_started, tmf, tmf->cb_data);
516
517 /* Change the state of the TMF-bearing request to "started". */
518 isci_request_change_state(request, started);
519
520 /* add the request to the remote device request list. */
521 list_add(&request->dev_node, &isci_device->reqs_in_process);
522
523 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
524
525 /* Wait for the TMF to complete, or a timeout. */
526 wait_for_completion(&completion);
527
528 isci_print_tmf(tmf);
529
530 if (tmf->status == SCI_SUCCESS)
531 ret = TMF_RESP_FUNC_COMPLETE;
532 else if (tmf->status == SCI_FAILURE_IO_RESPONSE_VALID) {
533 dev_dbg(&isci_host->pdev->dev,
534 "%s: tmf.status == "
535 "SCI_FAILURE_IO_RESPONSE_VALID\n",
536 __func__);
537 ret = TMF_RESP_FUNC_COMPLETE;
538 }
539 /* Else - leave the default "failed" status alone. */
540
541 dev_dbg(&isci_host->pdev->dev,
542 "%s: completed request = %p\n",
543 __func__,
544 request);
545
546 if (request->io_request_completion != NULL) {
547
548 /* The fact that this is non-NULL for a TMF request
549 * means there is a thread waiting for this TMF to
550 * finish.
551 */
552 complete(request->io_request_completion);
553 }
554
555 spin_lock_irqsave(&isci_host->scic_lock, flags);
556
557 cleanup_request:
558
559 /* Clean up the timer if needed. */
560 if (tmf->timeout_timer) {
561 isci_timer_stop(tmf->timeout_timer);
562 isci_timer_free(&isci_host->timer_list_struct,
563 tmf->timeout_timer);
564 tmf->timeout_timer = NULL;
565 }
566
567 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
568
569 isci_request_free(isci_host, request);
570
571 return ret;
572}
573
574void isci_task_build_tmf(
575 struct isci_tmf *tmf,
576 struct isci_remote_device *isci_device,
577 enum isci_tmf_function_codes code,
578 void (*tmf_sent_cb)(enum isci_tmf_cb_state,
579 struct isci_tmf *,
580 void *),
581 void *cb_data)
582{
583 dev_dbg(&isci_device->isci_port->isci_host->pdev->dev,
584 "%s: isci_device = %p\n", __func__, isci_device);
585
586 memset(tmf, 0, sizeof(*tmf));
587
588 tmf->device = isci_device;
589 tmf->tmf_code = code;
590 tmf->timeout_timer = NULL;
591 tmf->cb_state_func = tmf_sent_cb;
592 tmf->cb_data = cb_data;
593}
594
595static struct isci_request *isci_task_get_request_from_task(
596 struct sas_task *task,
597 struct isci_host **isci_host,
598 struct isci_remote_device **isci_device)
599{
600
601 struct isci_request *request = NULL;
602 unsigned long flags;
603
604 spin_lock_irqsave(&task->task_state_lock, flags);
605
606 request = task->lldd_task;
607
608 /* If task is already done, the request isn't valid */
609 if (!(task->task_state_flags & SAS_TASK_STATE_DONE) &&
610 (task->task_state_flags & SAS_TASK_AT_INITIATOR) &&
611 (request != NULL)) {
612
613 if (isci_host != NULL)
614 *isci_host = request->isci_host;
615
616 if (isci_device != NULL)
617 *isci_device = request->isci_device;
618 }
619
620 spin_unlock_irqrestore(&task->task_state_lock, flags);
621
622 return request;
623}
624
625/**
626 * isci_task_validate_request_to_abort() - This function checks the given I/O
627 * against the "started" state. If the request is still "started", it's
628 * state is changed to aborted. NOTE: isci_host->scic_lock MUST BE HELD
629 * BEFORE CALLING THIS FUNCTION.
630 * @isci_request: This parameter specifies the request object to control.
631 * @isci_host: This parameter specifies the ISCI host object
632 * @isci_device: This is the device to which the request is pending.
633 * @aborted_io_completion: This is a completion structure that will be added to
634 * the request in case it is changed to aborting; this completion is
635 * triggered when the request is fully completed.
636 *
637 * Either "started" on successful change of the task status to "aborted", or
638 * "unallocated" if the task cannot be controlled.
639 */
640static enum isci_request_status isci_task_validate_request_to_abort(
641 struct isci_request *isci_request,
642 struct isci_host *isci_host,
643 struct isci_remote_device *isci_device,
644 struct completion *aborted_io_completion)
645{
646 enum isci_request_status old_state = unallocated;
647
648 /* Only abort the task if it's in the
649 * device's request_in_process list
650 */
651 if (isci_request && !list_empty(&isci_request->dev_node)) {
652 old_state = isci_request_change_started_to_aborted(
653 isci_request, aborted_io_completion);
654
655 /* Only abort requests in the started state. */
656 if (old_state != started)
657 old_state = unallocated;
658 }
659
660 return old_state;
661}
662
663static void isci_request_cleanup_completed_loiterer(
664 struct isci_host *isci_host,
665 struct isci_remote_device *isci_device,
666 struct isci_request *isci_request)
667{
668 struct sas_task *task = isci_request_access_task(isci_request);
669 unsigned long flags;
670
671 dev_dbg(&isci_host->pdev->dev,
672 "%s: isci_device=%p, request=%p, task=%p\n",
673 __func__, isci_device, isci_request,
674 isci_request->ttype_ptr.io_task_ptr);
675
676 spin_lock_irqsave(&isci_host->scic_lock, flags);
677 list_del_init(&isci_request->dev_node);
678 if (task != NULL)
679 task->lldd_task = NULL;
680 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
681
682 isci_request_free(isci_host, isci_request);
683}
684/**
685 * isci_terminate_request_core() - This function will terminate the given
686 * request, and wait for it to complete. This function must only be called
687 * from a thread that can wait. Note that the request is terminated and
688 * completed (back to the host, if started there).
689 * @isci_host: This SCU.
690 * @isci_device: The target.
691 * @isci_request: The I/O request to be terminated.
692 *
693 *
694 */
695static void isci_terminate_request_core(
696 struct isci_host *isci_host,
697 struct isci_remote_device *isci_device,
698 struct isci_request *isci_request,
699 struct completion *request_completion)
700{
701 enum sci_status status = SCI_SUCCESS;
702 bool was_terminated = false;
703 bool needs_cleanup_handling = false;
704 enum isci_request_status request_status;
705 unsigned long flags;
706
707 dev_dbg(&isci_host->pdev->dev,
708 "%s: device = %p; request = %p\n",
709 __func__, isci_device, isci_request);
710
711 /* Peek at the current status of the request. This will tell
712 * us if there was special handling on the request such that it
713 * needs to be detached and freed here.
714 */
715 spin_lock_irqsave(&isci_request->state_lock, flags);
716 request_status = isci_request_get_state(isci_request);
717
718 /* TMFs are in their own thread */
719 if ((isci_request->ttype == io_task) &&
720 ((request_status == aborted) ||
721 (request_status == aborting) ||
722 (request_status == terminating)))
723 /* The completion routine won't free a request in
724 * the aborted/aborting/terminating state, so we do
725 * it here.
726 */
727 needs_cleanup_handling = true;
728
729 spin_unlock_irqrestore(&isci_request->state_lock, flags);
730
731 spin_lock_irqsave(&isci_host->scic_lock, flags);
732 /* Make sure the request wasn't just sitting around signalling
733 * device condition (if the request handle is NULL, then the
734 * request completed but needed additional handling here).
735 */
736 if (isci_request->sci_request_handle != NULL) {
737 was_terminated = true;
738 status = scic_controller_terminate_request(
739 isci_host->core_controller,
740 isci_device->sci_device_handle,
741 isci_request->sci_request_handle
742 );
743 }
744 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
745
746 /*
747 * The only time the request to terminate will
748 * fail is when the io request is completed and
749 * being aborted.
750 */
751 if (status != SCI_SUCCESS)
752 dev_err(&isci_host->pdev->dev,
753 "%s: scic_controller_terminate_request"
754 " returned = 0x%x\n",
755 __func__,
756 status);
757 else {
758 if (was_terminated) {
759 dev_dbg(&isci_host->pdev->dev,
760 "%s: before completion wait (%p)\n",
761 __func__,
762 request_completion);
763
764 /* Wait here for the request to complete. */
765 wait_for_completion(request_completion);
766
767 dev_dbg(&isci_host->pdev->dev,
768 "%s: after completion wait (%p)\n",
769 __func__,
770 request_completion);
771 }
772
773 if (needs_cleanup_handling)
774 isci_request_cleanup_completed_loiterer(
775 isci_host, isci_device, isci_request
776 );
777 }
778}
779static void isci_terminate_request(
780 struct isci_host *isci_host,
781 struct isci_remote_device *isci_device,
782 struct isci_request *isci_request,
783 enum isci_request_status new_request_state)
784{
785 enum isci_request_status old_state;
786
787 DECLARE_COMPLETION_ONSTACK(request_completion);
788 unsigned long flags;
789
790 spin_lock_irqsave(&isci_host->scic_lock, flags);
791
792 /* Change state to "new_request_state" if it is currently "started" */
793 old_state = isci_request_change_started_to_newstate(
794 isci_request,
795 &request_completion,
796 new_request_state
797 );
798
799 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
800
801 if (old_state == started)
802 /* This request was not already being aborted. If it had been,
803 * then the aborting I/O (ie. the TMF request) would not be in
804 * the aborting state, and thus would be terminated here. Note
805 * that since the TMF completion's call to the kernel function
806 * "complete()" does not happen until the pending I/O request
807 * terminate fully completes, we do not have to implement a
808 * special wait here for already aborting requests - the
809 * termination of the TMF request will force the request
810 * to finish it's already started terminate.
811 */
812 isci_terminate_request_core(isci_host, isci_device,
813 isci_request, &request_completion);
814}
815
816/**
817 * isci_terminate_pending_requests() - This function will change the all of the
818 * requests on the given device's state to "aborting", will terminate the
819 * requests, and wait for them to complete. This function must only be
820 * called from a thread that can wait. Note that the requests are all
821 * terminated and completed (back to the host, if started there).
822 * @isci_host: This parameter specifies SCU.
823 * @isci_device: This parameter specifies the target.
824 *
825 *
826 */
827void isci_terminate_pending_requests(
828 struct isci_host *isci_host,
829 struct isci_remote_device *isci_device,
830 enum isci_request_status new_request_state)
831{
832 struct isci_request *isci_request;
833 struct sas_task *task;
834 bool done = false;
835 unsigned long flags;
836
837 dev_dbg(&isci_host->pdev->dev,
838 "%s: isci_device = %p (new request state = %d)\n",
839 __func__, isci_device, new_request_state);
840
841 #define ISCI_TERMINATE_SHOW_PENDING_REQUESTS
842 #ifdef ISCI_TERMINATE_SHOW_PENDING_REQUESTS
843 {
844 struct isci_request *request;
845
846 /* Only abort the task if it's in the
847 * device's request_in_process list
848 */
849 list_for_each_entry(request,
850 &isci_device->reqs_in_process,
851 dev_node)
852 dev_dbg(&isci_host->pdev->dev,
853 "%s: isci_device = %p; request is on "
854 "reqs_in_process list: %p\n",
855 __func__, isci_device, request);
856 }
857 #endif /* ISCI_TERMINATE_SHOW_PENDING_REQUESTS */
858
859 /* Clean up all pending requests. */
860 do {
861 spin_lock_irqsave(&isci_host->scic_lock, flags);
862
863 if (list_empty(&isci_device->reqs_in_process)) {
864
865 done = true;
866 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
867
868 dev_dbg(&isci_host->pdev->dev,
869 "%s: isci_device = %p; done.\n",
870 __func__, isci_device);
871 } else {
872 /* The list was not empty - grab the first request. */
873 isci_request = list_first_entry(
874 &isci_device->reqs_in_process,
875 struct isci_request, dev_node
876 );
877 /* Note that we are not expecting to have to control
878 * the target to abort the request.
879 */
880 isci_request->complete_in_target = true;
881
882 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
883
884 /* Get the libsas task reference. */
885 task = isci_request_access_task(isci_request);
886
887 dev_dbg(&isci_host->pdev->dev,
888 "%s: isci_device=%p request=%p; task=%p\n",
889 __func__, isci_device, isci_request, task);
890
891 /* Mark all still pending I/O with the selected next
892 * state.
893 */
894 isci_terminate_request(isci_host, isci_device,
895 isci_request, new_request_state
896 );
897
898 /* Set the 'done' state on the task. */
899 if (task)
900 isci_task_all_done(task);
901 }
902 } while (!done);
903}
904
905/**
906 * isci_task_send_lu_reset_sas() - This function is called by of the SAS Domain
907 * Template functions.
908 * @lun: This parameter specifies the lun to be reset.
909 *
910 * status, zero indicates success.
911 */
912static int isci_task_send_lu_reset_sas(
913 struct isci_host *isci_host,
914 struct isci_remote_device *isci_device,
915 u8 *lun)
916{
917 struct isci_tmf tmf;
918 int ret = TMF_RESP_FUNC_FAILED;
919
920 dev_dbg(&isci_host->pdev->dev,
921 "%s: isci_host = %p, isci_device = %p\n",
922 __func__, isci_host, isci_device);
923 /* Send the LUN reset to the target. By the time the call returns,
924 * the TMF has fully exected in the target (in which case the return
925 * value is "TMF_RESP_FUNC_COMPLETE", or the request timed-out (or
926 * was otherwise unable to be executed ("TMF_RESP_FUNC_FAILED").
927 */
928 isci_task_build_tmf(&tmf, isci_device, isci_tmf_ssp_lun_reset, NULL,
929 NULL);
930
931 #define ISCI_LU_RESET_TIMEOUT_MS 2000 /* 2 second timeout. */
932 ret = isci_task_execute_tmf(isci_host, &tmf, ISCI_LU_RESET_TIMEOUT_MS);
933
934 if (ret == TMF_RESP_FUNC_COMPLETE)
935 dev_dbg(&isci_host->pdev->dev,
936 "%s: %p: TMF_LU_RESET passed\n",
937 __func__, isci_device);
938 else
939 dev_dbg(&isci_host->pdev->dev,
940 "%s: %p: TMF_LU_RESET failed (%x)\n",
941 __func__, isci_device, ret);
942
943 return ret;
944}
945
946/**
947 * isci_task_lu_reset() - This function is one of the SAS Domain Template
948 * functions. This is one of the Task Management functoins called by libsas,
949 * to reset the given lun. Note the assumption that while this call is
950 * executing, no I/O will be sent by the host to the device.
951 * @lun: This parameter specifies the lun to be reset.
952 *
953 * status, zero indicates success.
954 */
955int isci_task_lu_reset(
956 struct domain_device *domain_device,
957 u8 *lun)
958{
959 struct isci_host *isci_host = NULL;
960 struct isci_remote_device *isci_device = NULL;
961 int ret;
962 bool device_stopping = false;
963
964 if (domain_device == NULL) {
965 pr_warn("%s: domain_device == NULL\n", __func__);
966 return TMF_RESP_FUNC_FAILED;
967 }
968
969 isci_device = isci_dev_from_domain_dev(domain_device);
970
971 if (domain_device->port != NULL)
972 isci_host = isci_host_from_sas_ha(domain_device->port->ha);
973
974 pr_debug("%s: domain_device=%p, isci_host=%p; isci_device=%p\n",
975 __func__, domain_device, isci_host, isci_device);
976
977 if (isci_device != NULL)
978 device_stopping = (isci_device->status == isci_stopping)
979 || (isci_device->status == isci_stopped);
980
981 /* If there is a device reset pending on any request in the
982 * device's list, fail this LUN reset request in order to
983 * escalate to the device reset.
984 */
985 if ((isci_device == NULL) ||
986 (isci_host == NULL) ||
987 ((isci_host != NULL) &&
988 (isci_device != NULL) &&
989 (device_stopping ||
990 (isci_device_is_reset_pending(isci_host, isci_device))))) {
991 dev_warn(&isci_host->pdev->dev,
992 "%s: No dev (%p), no host (%p), or "
993 "RESET PENDING: domain_device=%p\n",
994 __func__, isci_device, isci_host, domain_device);
995 return TMF_RESP_FUNC_FAILED;
996 }
997
998 /* Stop I/O to the remote device. */
999 isci_device_set_host_quiesce_lock_state(isci_device, true);
1000
1001 /* Send the task management part of the reset. */
1002 if (sas_protocol_ata(domain_device->tproto)) {
1003 ret = isci_task_send_lu_reset_sata(
1004 isci_host, isci_device, lun
1005 );
1006 } else
1007 ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun);
1008
1009 /* If the LUN reset worked, all the I/O can now be terminated. */
1010 if (ret == TMF_RESP_FUNC_COMPLETE)
1011 /* Terminate all I/O now. */
1012 isci_terminate_pending_requests(isci_host,
1013 isci_device,
1014 terminating);
1015
1016 /* Resume I/O to the remote device. */
1017 isci_device_set_host_quiesce_lock_state(isci_device, false);
1018
1019 return ret;
1020}
1021
1022
1023/* int (*lldd_clear_nexus_port)(struct asd_sas_port *); */
1024int isci_task_clear_nexus_port(struct asd_sas_port *port)
1025{
1026 return TMF_RESP_FUNC_FAILED;
1027}
1028
1029
1030
1031int isci_task_clear_nexus_ha(struct sas_ha_struct *ha)
1032{
1033 return TMF_RESP_FUNC_FAILED;
1034}
1035
1036int isci_task_I_T_nexus_reset(struct domain_device *dev)
1037{
1038 return TMF_RESP_FUNC_FAILED;
1039}
1040
1041
1042/* Task Management Functions. Must be called from process context. */
1043
1044/**
1045 * isci_abort_task_process_cb() - This is a helper function for the abort task
1046 * TMF command. It manages the request state with respect to the successful
1047 * transmission / completion of the abort task request.
1048 * @cb_state: This parameter specifies when this function was called - after
1049 * the TMF request has been started and after it has timed-out.
1050 * @tmf: This parameter specifies the TMF in progress.
1051 *
1052 *
1053 */
1054static void isci_abort_task_process_cb(
1055 enum isci_tmf_cb_state cb_state,
1056 struct isci_tmf *tmf,
1057 void *cb_data)
1058{
1059 struct isci_request *old_request;
1060
1061 old_request = (struct isci_request *)cb_data;
1062
1063 dev_dbg(&old_request->isci_host->pdev->dev,
1064 "%s: tmf=%p, old_request=%p\n",
1065 __func__, tmf, old_request);
1066
1067 switch (cb_state) {
1068
1069 case isci_tmf_started:
1070 /* The TMF has been started. Nothing to do here, since the
1071 * request state was already set to "aborted" by the abort
1072 * task function.
1073 */
1074 BUG_ON(old_request->status != aborted);
1075 break;
1076
1077 case isci_tmf_timed_out:
1078
1079 /* Set the task's state to "aborting", since the abort task
1080 * function thread set it to "aborted" (above) in anticipation
1081 * of the task management request working correctly. Since the
1082 * timeout has now fired, the TMF request failed. We set the
1083 * state such that the request completion will indicate the
1084 * device is no longer present.
1085 */
1086 isci_request_change_state(old_request, aborting);
1087 break;
1088
1089 default:
1090 dev_err(&old_request->isci_host->pdev->dev,
1091 "%s: Bad cb_state (%d): tmf=%p, old_request=%p\n",
1092 __func__, cb_state, tmf, old_request);
1093 break;
1094 }
1095}
1096
1097/**
1098 * isci_task_abort_task() - This function is one of the SAS Domain Template
1099 * functions. This function is called by libsas to abort a specified task.
1100 * @task: This parameter specifies the SAS task to abort.
1101 *
1102 * status, zero indicates success.
1103 */
1104int isci_task_abort_task(struct sas_task *task)
1105{
1106 DECLARE_COMPLETION_ONSTACK(aborted_io_completion);
1107 struct isci_request *old_request = NULL;
1108 struct isci_remote_device *isci_device = NULL;
1109 struct isci_host *isci_host = NULL;
1110 struct isci_tmf tmf;
1111 int ret = TMF_RESP_FUNC_FAILED;
1112 unsigned long flags;
1113 bool any_dev_reset, device_stopping;
1114
1115 /* Get the isci_request reference from the task. Note that
1116 * this check does not depend on the pending request list
1117 * in the device, because tasks driving resets may land here
1118 * after completion in the core.
1119 */
1120 old_request = isci_task_get_request_from_task(task, &isci_host,
1121 &isci_device);
1122
1123 dev_dbg(&isci_host->pdev->dev,
1124 "%s: task = %p\n", __func__, task);
1125
1126 /* Check if the device has been / is currently being removed.
1127 * If so, no task management will be done, and the I/O will
1128 * be terminated.
1129 */
1130 device_stopping = (isci_device->status == isci_stopping)
1131 || (isci_device->status == isci_stopped);
1132
1133#ifdef NOMORE
1134 /* This abort task function is the first stop of the libsas error
1135 * handler thread. Since libsas is executing in a thread with a
1136 * referernce to the "task" parameter, that task cannot be completed
1137 * directly back to the upper layers. In order to make sure that
1138 * the task is managed correctly if this abort task fails, set the
1139 * "SAS_TASK_STATE_ABORTED" bit now such that completions up the
1140 * stack will be intercepted and only allowed to happen in the
1141 * libsas SCSI error handler thread.
1142 */
1143 spin_lock_irqsave(&task->task_state_lock, flags);
1144 task->task_state_flags |= SAS_TASK_STATE_ABORTED;
1145 spin_unlock_irqrestore(&task->task_state_lock, flags);
1146#endif /* NOMORE */
1147
1148 /* This version of the driver will fail abort requests for
1149 * SATA/STP. Failing the abort request this way will cause the
1150 * SCSI error handler thread to escalate to LUN reset
1151 */
1152 if (sas_protocol_ata(task->task_proto) && !device_stopping) {
1153 dev_warn(&isci_host->pdev->dev,
1154 " task %p is for a STP/SATA device;"
1155 " returning TMF_RESP_FUNC_FAILED\n"
1156 " to cause a LUN reset...\n", task);
1157 return TMF_RESP_FUNC_FAILED;
1158 }
1159
1160 dev_dbg(&isci_host->pdev->dev,
1161 "%s: old_request == %p\n", __func__, old_request);
1162
1163 spin_lock_irqsave(&task->task_state_lock, flags);
1164
1165 /* Don't do resets to stopping devices. */
1166 if (device_stopping)
1167 task->task_state_flags &= ~SAS_TASK_NEED_DEV_RESET;
1168
1169 /* See if there is a pending device reset for this device. */
1170 any_dev_reset = task->task_state_flags & SAS_TASK_NEED_DEV_RESET;
1171
1172 spin_unlock_irqrestore(&task->task_state_lock, flags);
1173
1174 if ((isci_device != NULL) && !device_stopping)
1175 any_dev_reset = any_dev_reset
1176 || isci_device_is_reset_pending(isci_host,
1177 isci_device
1178 );
1179
1180 /* If the extraction of the request reference from the task
1181 * failed, then the request has been completed (or if there is a
1182 * pending reset then this abort request function must be failed
1183 * in order to escalate to the target reset).
1184 */
1185 if ((old_request == NULL) ||
1186 ((old_request != NULL) &&
1187 (old_request->sci_request_handle == NULL) &&
1188 (old_request->complete_in_target)) ||
1189 any_dev_reset) {
1190
1191 spin_lock_irqsave(&task->task_state_lock, flags);
1192
1193 /* If the device reset task flag is set, fail the task
1194 * management request. Otherwise, the original request
1195 * has completed.
1196 */
1197 if (any_dev_reset) {
1198
1199 /* Turn off the task's DONE to make sure this
1200 * task is escalated to a target reset.
1201 */
1202 task->task_state_flags &= ~SAS_TASK_STATE_DONE;
1203
1204 /* Fail the task management request in order to
1205 * escalate to the target reset.
1206 */
1207 ret = TMF_RESP_FUNC_FAILED;
1208
1209 dev_dbg(&isci_host->pdev->dev,
1210 "%s: Failing task abort in order to "
1211 "escalate to target reset because\n"
1212 "SAS_TASK_NEED_DEV_RESET is set for "
1213 "task %p on dev %p\n",
1214 __func__, task, isci_device);
1215
1216 } else {
1217 ret = TMF_RESP_FUNC_COMPLETE;
1218
1219 dev_dbg(&isci_host->pdev->dev,
1220 "%s: abort task not needed for %p\n",
1221 __func__, task);
1222
1223 /* The request has already completed and there
1224 * is nothing to do here other than to set the task
1225 * done bit, and indicate that the task abort function
1226 * was sucessful.
1227 */
1228 isci_set_task_doneflags(task);
1229
1230 /* Set the abort bit to make sure that libsas sticks the
1231 * task in the completed task queue.
1232 */
1233/* task->task_state_flags |= SAS_TASK_STATE_ABORTED; */
1234
1235 /* Check for the situation where the request was
1236 * left around on the device list but the
1237 * request already completed.
1238 */
1239 if (old_request && !old_request->sci_request_handle) {
1240
1241 isci_request_cleanup_completed_loiterer(
1242 isci_host, isci_device, old_request
1243 );
1244 }
1245 }
1246 spin_unlock_irqrestore(&task->task_state_lock, flags);
1247
1248 return ret;
1249 }
1250
1251 spin_lock_irqsave(&isci_host->scic_lock, flags);
1252
1253 /* Sanity check the request status, and set the I/O kernel completion
1254 * struct that will be triggered when the request completes.
1255 */
1256 if (isci_task_validate_request_to_abort(
1257 old_request,
1258 isci_host,
1259 isci_device,
1260 &aborted_io_completion)
1261 == unallocated) {
1262 dev_dbg(&isci_host->pdev->dev,
1263 "%s: old_request not valid for device = %p\n",
1264 __func__,
1265 isci_device);
1266 old_request = NULL;
1267 }
1268
1269 if (!old_request) {
1270
1271 /* There is no isci_request attached to the sas_task.
1272 * It must have been completed and detached.
1273 */
1274 dev_dbg(&isci_host->pdev->dev,
1275 "%s: old_request == NULL\n",
1276 __func__);
1277
1278 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1279
1280 /* Set the state on the task. */
1281 isci_task_all_done(task);
1282
1283 return TMF_RESP_FUNC_COMPLETE;
1284 }
1285 if (task->task_proto == SAS_PROTOCOL_SMP || device_stopping) {
1286
1287 if (device_stopping)
1288 dev_dbg(&isci_host->pdev->dev,
1289 "%s: device is stopping, thus no TMF\n",
1290 __func__);
1291 else
1292 dev_dbg(&isci_host->pdev->dev,
1293 "%s: request is SMP, thus no TMF\n",
1294 __func__);
1295
1296 old_request->complete_in_target = true;
1297
1298 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1299
1300 /* Set the state on the task. */
1301 isci_task_all_done(task);
1302
1303 ret = TMF_RESP_FUNC_COMPLETE;
1304
1305 /* Stopping and SMP devices are not sent a TMF, and are not
1306 * reset, but the outstanding I/O request is terminated here.
1307 *
1308 * Clean up the request on our side, and wait for the aborted
1309 * I/O to complete.
1310 */
1311 isci_terminate_request_core(isci_host, isci_device, old_request,
1312 &aborted_io_completion);
1313 } else {
1314 /* Fill in the tmf stucture */
1315 isci_task_build_tmf(&tmf, isci_device, isci_tmf_ssp_task_abort,
1316 isci_abort_task_process_cb, old_request);
1317
1318 tmf.io_tag = scic_io_request_get_io_tag(
1319 old_request->sci_request_handle
1320 );
1321
1322 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1323
1324 #define ISCI_ABORT_TASK_TIMEOUT_MS 500 /* half second timeout. */
1325 ret = isci_task_execute_tmf(isci_host, &tmf,
1326 ISCI_ABORT_TASK_TIMEOUT_MS);
1327
1328 if (ret == TMF_RESP_FUNC_COMPLETE) {
1329 old_request->complete_in_target = true;
1330
1331 /* Clean up the request on our side, and wait for the aborted I/O to
1332 * complete.
1333 */
1334 isci_terminate_request_core(isci_host, isci_device, old_request,
1335 &aborted_io_completion);
1336
1337 /* Set the state on the task. */
1338 isci_task_all_done(task);
1339 } else
1340 dev_err(&isci_host->pdev->dev,
1341 "%s: isci_task_send_tmf failed\n",
1342 __func__);
1343 }
1344
1345 return ret;
1346}
1347
1348/**
1349 * isci_task_abort_task_set() - This function is one of the SAS Domain Template
1350 * functions. This is one of the Task Management functoins called by libsas,
1351 * to abort all task for the given lun.
1352 * @d_device: This parameter specifies the domain device associated with this
1353 * request.
1354 * @lun: This parameter specifies the lun associated with this request.
1355 *
1356 * status, zero indicates success.
1357 */
1358int isci_task_abort_task_set(
1359 struct domain_device *d_device,
1360 u8 *lun)
1361{
1362 return TMF_RESP_FUNC_FAILED;
1363}
1364
1365
1366/**
1367 * isci_task_clear_aca() - This function is one of the SAS Domain Template
1368 * functions. This is one of the Task Management functoins called by libsas.
1369 * @d_device: This parameter specifies the domain device associated with this
1370 * request.
1371 * @lun: This parameter specifies the lun associated with this request.
1372 *
1373 * status, zero indicates success.
1374 */
1375int isci_task_clear_aca(
1376 struct domain_device *d_device,
1377 u8 *lun)
1378{
1379 return TMF_RESP_FUNC_FAILED;
1380}
1381
1382
1383
1384/**
1385 * isci_task_clear_task_set() - This function is one of the SAS Domain Template
1386 * functions. This is one of the Task Management functoins called by libsas.
1387 * @d_device: This parameter specifies the domain device associated with this
1388 * request.
1389 * @lun: This parameter specifies the lun associated with this request.
1390 *
1391 * status, zero indicates success.
1392 */
1393int isci_task_clear_task_set(
1394 struct domain_device *d_device,
1395 u8 *lun)
1396{
1397 return TMF_RESP_FUNC_FAILED;
1398}
1399
1400
1401/**
1402 * isci_task_query_task() - This function is implemented to cause libsas to
1403 * correctly escalate the failed abort to a LUN or target reset (this is
1404 * because sas_scsi_find_task libsas function does not correctly interpret
1405 * all return codes from the abort task call). When TMF_RESP_FUNC_SUCC is
1406 * returned, libsas turns this into a LUN reset; when FUNC_FAILED is
1407 * returned, libsas will turn this into a target reset
1408 * @task: This parameter specifies the sas task being queried.
1409 * @lun: This parameter specifies the lun associated with this request.
1410 *
1411 * status, zero indicates success.
1412 */
1413int isci_task_query_task(
1414 struct sas_task *task)
1415{
1416 /* See if there is a pending device reset for this device. */
1417 if (task->task_state_flags & SAS_TASK_NEED_DEV_RESET)
1418 return TMF_RESP_FUNC_FAILED;
1419 else
1420 return TMF_RESP_FUNC_SUCC;
1421}
1422
1423/**
1424 * isci_task_request_complete() - This function is called by the sci core when
1425 * an task request completes.
1426 * @isci_host: This parameter specifies the ISCI host object
1427 * @request: This parameter is the completed isci_request object.
1428 * @completion_status: This parameter specifies the completion status from the
1429 * sci core.
1430 *
1431 * none.
1432 */
1433void isci_task_request_complete(
1434 struct isci_host *isci_host,
1435 struct isci_request *request,
1436 enum sci_task_status completion_status)
1437{
1438 struct isci_remote_device *isci_device = request->isci_device;
1439 enum isci_request_status old_state;
1440 struct isci_tmf *tmf = isci_request_access_tmf(request);
1441 struct completion *tmf_complete;
1442
1443 dev_dbg(&isci_host->pdev->dev,
1444 "%s: request = %p, status=%d\n",
1445 __func__, request, completion_status);
1446
1447 old_state = isci_request_change_state(request, completed);
1448
1449 tmf->status = completion_status;
1450 request->complete_in_target = true;
1451
1452 if (SAS_PROTOCOL_SSP == tmf->proto) {
1453
1454 memcpy(&tmf->resp.resp_iu,
1455 scic_io_request_get_response_iu_address(
1456 request->sci_request_handle
1457 ),
1458 sizeof(struct sci_ssp_response_iu));
1459
1460 } else if (SAS_PROTOCOL_SATA == tmf->proto) {
1461
1462 memcpy(&tmf->resp.d2h_fis,
1463 scic_stp_io_request_get_d2h_reg_address(
1464 request->sci_request_handle
1465 ),
1466 sizeof(struct sata_fis_reg_d2h)
1467 );
1468 }
1469
1470 /* Manage the timer if it is still running. */
1471 if (tmf->timeout_timer) {
1472
1473 isci_timer_stop(tmf->timeout_timer);
1474 isci_timer_free(&isci_host->timer_list_struct,
1475 tmf->timeout_timer);
1476 tmf->timeout_timer = NULL;
1477 }
1478
1479 /* PRINT_TMF( ((struct isci_tmf *)request->task)); */
1480 tmf_complete = tmf->complete;
1481
1482 scic_controller_complete_task(
1483 isci_host->core_controller,
1484 isci_device->sci_device_handle,
1485 request->sci_request_handle
1486 );
1487 /* NULL the request handle to make sure it cannot be terminated
1488 * or completed again.
1489 */
1490 request->sci_request_handle = NULL;
1491
1492 isci_request_change_state(request, unallocated);
1493 list_del_init(&request->dev_node);
1494
1495 /* The task management part completes last. */
1496 complete(tmf_complete);
1497}
1498
1499
1500/**
1501 * isci_task_ssp_request_get_lun() - This function is called by the sci core to
1502 * retrieve the lun for a given task request.
1503 * @request: This parameter is the isci_request object.
1504 *
1505 * lun for specified task request.
1506 */
1507u32 isci_task_ssp_request_get_lun(struct isci_request *request)
1508{
1509 struct isci_tmf *isci_tmf = isci_request_access_tmf(request);
1510
1511 dev_dbg(&request->isci_host->pdev->dev,
1512 "%s: lun = %d\n", __func__, isci_tmf->lun[0]);
1513/* @todo: build lun from array of bytes to 32 bit */
1514 return isci_tmf->lun[0];
1515}
1516
1517/**
1518 * isci_task_ssp_request_get_function() - This function is called by the sci
1519 * core to retrieve the function for a given task request.
1520 * @request: This parameter is the isci_request object.
1521 *
1522 * function code for specified task request.
1523 */
1524u8 isci_task_ssp_request_get_function(struct isci_request *request)
1525{
1526 struct isci_tmf *isci_tmf = isci_request_access_tmf(request);
1527
1528 dev_dbg(&request->isci_host->pdev->dev,
1529 "%s: func = %d\n", __func__, isci_tmf->tmf_code);
1530
1531 return isci_tmf->tmf_code;
1532}
1533
1534/**
1535 * isci_task_ssp_request_get_io_tag_to_manage() - This function is called by
1536 * the sci core to retrieve the io tag for a given task request.
1537 * @request: This parameter is the isci_request object.
1538 *
1539 * io tag for specified task request.
1540 */
1541u16 isci_task_ssp_request_get_io_tag_to_manage(struct isci_request *request)
1542{
1543 u16 io_tag = SCI_CONTROLLER_INVALID_IO_TAG;
1544
1545 if (tmf_task == request->ttype) {
1546 struct isci_tmf *tmf = isci_request_access_tmf(request);
1547 io_tag = tmf->io_tag;
1548 }
1549
1550 dev_dbg(&request->isci_host->pdev->dev,
1551 "%s: request = %p, io_tag = %d\n",
1552 __func__, request, io_tag);
1553
1554 return io_tag;
1555}
1556
1557/**
1558 * isci_task_ssp_request_get_response_data_address() - This function is called
1559 * by the sci core to retrieve the response data address for a given task
1560 * request.
1561 * @request: This parameter is the isci_request object.
1562 *
1563 * response data address for specified task request.
1564 */
1565void *isci_task_ssp_request_get_response_data_address(
1566 struct isci_request *request)
1567{
1568 struct isci_tmf *isci_tmf = isci_request_access_tmf(request);
1569
1570 return &isci_tmf->resp.resp_iu;
1571}
1572
1573/**
1574 * isci_task_ssp_request_get_response_data_length() - This function is called
1575 * by the sci core to retrieve the response data length for a given task
1576 * request.
1577 * @request: This parameter is the isci_request object.
1578 *
1579 * response data length for specified task request.
1580 */
1581u32 isci_task_ssp_request_get_response_data_length(
1582 struct isci_request *request)
1583{
1584 struct isci_tmf *isci_tmf = isci_request_access_tmf(request);
1585
1586 return sizeof(isci_tmf->resp.resp_iu);
1587}
1588
1589/**
1590 * isci_bus_reset_handler() - This function performs a target reset of the
1591 * device referenced by "cmd'. This function is exported through the
1592 * "struct scsi_host_template" structure such that it is called when an I/O
1593 * recovery process has escalated to a target reset. Note that this function
1594 * is called from the scsi error handler event thread, so may block on calls.
1595 * @scsi_cmd: This parameter specifies the target to be reset.
1596 *
1597 * SUCCESS if the reset process was successful, else FAILED.
1598 */
1599int isci_bus_reset_handler(struct scsi_cmnd *cmd)
1600{
1601 unsigned long flags = 0;
1602 struct isci_host *isci_host = NULL;
1603 enum sci_status status;
1604 int base_status;
1605 struct isci_remote_device *isci_dev
1606 = isci_dev_from_domain_dev(
1607 sdev_to_domain_dev(cmd->device));
1608
1609 dev_dbg(&cmd->device->sdev_gendev,
1610 "%s: cmd %p, isci_dev %p\n",
1611 __func__, cmd, isci_dev);
1612
1613 if (!isci_dev) {
1614 dev_warn(&cmd->device->sdev_gendev,
1615 "%s: isci_dev is GONE!\n",
1616 __func__);
1617
1618 return TMF_RESP_FUNC_COMPLETE; /* Nothing to reset. */
1619 }
1620
1621 if (isci_dev->isci_port != NULL)
1622 isci_host = isci_dev->isci_port->isci_host;
1623
1624 if (isci_host != NULL)
1625 spin_lock_irqsave(&isci_host->scic_lock, flags);
1626
1627 status = scic_remote_device_reset(isci_dev->sci_device_handle);
1628 if (status != SCI_SUCCESS) {
1629
1630 if (isci_host != NULL)
1631 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1632
1633 scmd_printk(KERN_WARNING, cmd,
1634 "%s: scic_remote_device_reset(%p) returned %d!\n",
1635 __func__, isci_dev, status);
1636
1637 return TMF_RESP_FUNC_FAILED;
1638 }
1639 if (isci_host != NULL)
1640 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1641
1642 /* Stop I/O to the remote device. */
1643 isci_device_set_host_quiesce_lock_state(isci_dev, true);
1644
1645 /* Make sure all pending requests are able to be fully terminated. */
1646 isci_device_clear_reset_pending(isci_dev);
1647
1648 /* Terminate in-progress I/O now. */
1649 isci_remote_device_nuke_requests(isci_dev);
1650
1651 /* Call into the libsas default handler (which calls sas_phy_reset). */
1652 base_status = sas_eh_bus_reset_handler(cmd);
1653
1654 if (base_status != SUCCESS) {
1655
1656 /* There can be cases where the resets to individual devices
1657 * behind an expander will fail because of an unplug of the
1658 * expander itself.
1659 */
1660 scmd_printk(KERN_WARNING, cmd,
1661 "%s: sas_eh_bus_reset_handler(%p) returned %d!\n",
1662 __func__, cmd, base_status);
1663 }
1664
1665 /* WHAT TO DO HERE IF sas_phy_reset FAILS? */
1666
1667 if (isci_host != NULL)
1668 spin_lock_irqsave(&isci_host->scic_lock, flags);
1669 status
1670 = scic_remote_device_reset_complete(isci_dev->sci_device_handle);
1671
1672 if (isci_host != NULL)
1673 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1674
1675 if (status != SCI_SUCCESS) {
1676 scmd_printk(KERN_WARNING, cmd,
1677 "%s: scic_remote_device_reset_complete(%p) "
1678 "returned %d!\n",
1679 __func__, isci_dev, status);
1680 }
1681 /* WHAT TO DO HERE IF scic_remote_device_reset_complete FAILS? */
1682
1683 dev_dbg(&cmd->device->sdev_gendev,
1684 "%s: cmd %p, isci_dev %p complete.\n",
1685 __func__, cmd, isci_dev);
1686
1687 /* Resume I/O to the remote device. */
1688 isci_device_set_host_quiesce_lock_state(isci_dev, false);
1689
1690 return TMF_RESP_FUNC_COMPLETE;
1691}
diff --git a/drivers/scsi/isci/task.h b/drivers/scsi/isci/task.h
new file mode 100644
index 000000000000..ced6a8be1b31
--- /dev/null
+++ b/drivers/scsi/isci/task.h
@@ -0,0 +1,368 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#if !defined(_ISCI_TASK_H_)
57#define _ISCI_TASK_H_
58
59struct isci_request;
60struct isci_host;
61
62/**
63 * enum isci_tmf_cb_state - This enum defines the possible states in which the
64 * TMF callback function is invoked during the TMF execution process.
65 *
66 *
67 */
68enum isci_tmf_cb_state {
69
70 isci_tmf_init_state = 0,
71 isci_tmf_started,
72 isci_tmf_timed_out
73};
74
75/**
76 * enum isci_tmf_function_codes - This enum defines the possible preparations
77 * of task management requests.
78 *
79 *
80 */
81enum isci_tmf_function_codes {
82
83 isci_tmf_func_none = 0,
84 isci_tmf_ssp_task_abort = TMF_ABORT_TASK,
85 isci_tmf_ssp_lun_reset = TMF_LU_RESET,
86 isci_tmf_sata_srst_high = TMF_LU_RESET + 0x100, /* Non SCSI */
87 isci_tmf_sata_srst_low = TMF_LU_RESET + 0x101 /* Non SCSI */
88};
89/**
90 * struct isci_tmf - This class represents the task management object which
91 * acts as an interface to libsas for processing task management requests
92 *
93 *
94 */
95struct isci_tmf {
96
97 struct completion *complete;
98 enum sas_protocol proto;
99 union {
100 struct sci_ssp_response_iu resp_iu;
101 struct dev_to_host_fis d2h_fis;
102 } resp;
103 unsigned char lun[8];
104 u16 io_tag;
105 struct isci_remote_device *device;
106 enum isci_tmf_function_codes tmf_code;
107 int status;
108
109 struct isci_timer *timeout_timer;
110
111 /* The optional callback function allows the user process to
112 * track the TMF transmit / timeout conditions.
113 */
114 void (*cb_state_func)(
115 enum isci_tmf_cb_state,
116 struct isci_tmf *, void *);
117 void *cb_data;
118
119};
120
121static inline void isci_print_tmf(
122 struct isci_tmf *tmf)
123{
124 if (SAS_PROTOCOL_SATA == tmf->proto)
125 dev_dbg(&tmf->device->isci_port->isci_host->pdev->dev,
126 "%s: status = %x\n"
127 "tmf->resp.d2h_fis.status = %x\n"
128 "tmf->resp.d2h_fis.error = %x\n",
129 __func__,
130 tmf->status,
131 tmf->resp.d2h_fis.status,
132 tmf->resp.d2h_fis.error);
133 else
134 dev_dbg(&tmf->device->isci_port->isci_host->pdev->dev,
135 "%s: status = %x\n"
136 "tmf->resp.resp_iu.data_present = %x\n"
137 "tmf->resp.resp_iu.status = %x\n"
138 "tmf->resp.resp_iu.data_length = %x\n"
139 "tmf->resp.resp_iu.data[0] = %x\n"
140 "tmf->resp.resp_iu.data[1] = %x\n"
141 "tmf->resp.resp_iu.data[2] = %x\n"
142 "tmf->resp.resp_iu.data[3] = %x\n",
143 __func__,
144 tmf->status,
145 tmf->resp.resp_iu.data_present,
146 tmf->resp.resp_iu.status,
147 (tmf->resp.resp_iu.response_data_length[0] << 24) +
148 (tmf->resp.resp_iu.response_data_length[1] << 16) +
149 (tmf->resp.resp_iu.response_data_length[2] << 8) +
150 tmf->resp.resp_iu.response_data_length[3],
151 tmf->resp.resp_iu.data[0],
152 tmf->resp.resp_iu.data[1],
153 tmf->resp.resp_iu.data[2],
154 tmf->resp.resp_iu.data[3]);
155}
156
157
158int isci_task_execute_task(
159 struct sas_task *task,
160 int num,
161 gfp_t gfp_flags);
162
163int isci_task_abort_task(
164 struct sas_task *task);
165
166int isci_task_abort_task_set(
167 struct domain_device *d_device,
168 u8 *lun);
169
170int isci_task_clear_aca(
171 struct domain_device *d_device,
172 u8 *lun);
173
174int isci_task_clear_task_set(
175 struct domain_device *d_device,
176 u8 *lun);
177
178int isci_task_query_task(
179 struct sas_task *task);
180
181int isci_task_lu_reset(
182 struct domain_device *d_device,
183 u8 *lun);
184
185int isci_task_clear_nexus_port(
186 struct asd_sas_port *port);
187
188int isci_task_clear_nexus_ha(
189 struct sas_ha_struct *ha);
190
191int isci_task_I_T_nexus_reset(
192 struct domain_device *d_device);
193
194void isci_task_request_complete(
195 struct isci_host *isci_host,
196 struct isci_request *request,
197 enum sci_task_status completion_status);
198
199u16 isci_task_ssp_request_get_io_tag_to_manage(
200 struct isci_request *request);
201
202u8 isci_task_ssp_request_get_function(
203 struct isci_request *request);
204
205u32 isci_task_ssp_request_get_lun(
206 struct isci_request *request);
207
208void *isci_task_ssp_request_get_response_data_address(
209 struct isci_request *request);
210
211u32 isci_task_ssp_request_get_response_data_length(
212 struct isci_request *request);
213
214int isci_queuecommand(
215 struct scsi_cmnd *scsi_cmd,
216 void (*donefunc)(struct scsi_cmnd *));
217
218int isci_bus_reset_handler(struct scsi_cmnd *cmd);
219
220void isci_task_build_tmf(
221 struct isci_tmf *tmf,
222 struct isci_remote_device *isci_device,
223 enum isci_tmf_function_codes code,
224 void (*tmf_sent_cb)(
225 enum isci_tmf_cb_state,
226 struct isci_tmf *, void *),
227 void *cb_data);
228
229int isci_task_execute_tmf(
230 struct isci_host *isci_host,
231 struct isci_tmf *tmf,
232 unsigned long timeout_ms);
233
234/**
235 * enum isci_completion_selection - This enum defines the possible actions to
236 * take with respect to a given request's notification back to libsas.
237 *
238 *
239 */
240enum isci_completion_selection {
241
242 isci_perform_normal_io_completion, /* Normal notify (task_done) */
243 isci_perform_aborted_io_completion, /* No notification. */
244 isci_perform_error_io_completion /* Use sas_task_abort */
245};
246
247static inline void isci_set_task_doneflags(
248 struct sas_task *task)
249{
250 /* Since no futher action will be taken on this task,
251 * make sure to mark it complete from the lldd perspective.
252 */
253 task->task_state_flags |= SAS_TASK_STATE_DONE;
254 task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
255 task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
256}
257/**
258 * isci_task_all_done() - This function clears the task bits to indicate the
259 * LLDD is done with the task.
260 *
261 *
262 */
263static inline void isci_task_all_done(
264 struct sas_task *task)
265{
266 unsigned long flags;
267
268 /* Since no futher action will be taken on this task,
269 * make sure to mark it complete from the lldd perspective.
270 */
271 spin_lock_irqsave(&task->task_state_lock, flags);
272 isci_set_task_doneflags(task);
273 spin_unlock_irqrestore(&task->task_state_lock, flags);
274}
275
276/**
277 * isci_task_set_completion_status() - This function sets the completion status
278 * for the request.
279 * @task: This parameter is the completed request.
280 * @response: This parameter is the response code for the completed task.
281 * @status: This parameter is the status code for the completed task.
282 *
283 * none.
284 */
285static inline void isci_task_set_completion_status(
286 struct sas_task *task,
287 enum service_response response,
288 enum exec_status status,
289 enum isci_completion_selection task_notification_selection)
290{
291 unsigned long flags;
292
293 spin_lock_irqsave(&task->task_state_lock, flags);
294
295 task->task_status.resp = response;
296 task->task_status.stat = status;
297
298 /* Don't set DONE (or clear AT_INITIATOR) for any task going into the
299 * error path, because the EH interprets that as a handled error condition.
300 * Also don't take action if there is a reset pending.
301 */
302 if ((task_notification_selection != isci_perform_error_io_completion)
303 && !(task->task_state_flags & SAS_TASK_NEED_DEV_RESET))
304 isci_set_task_doneflags(task);
305
306 spin_unlock_irqrestore(&task->task_state_lock, flags);
307}
308/**
309 * isci_task_complete_for_upper_layer() - This function completes the request
310 * to the upper layer driver.
311 * @host: This parameter is a pointer to the host on which the the request
312 * should be queued (either as an error or success).
313 * @request: This parameter is the completed request.
314 * @response: This parameter is the response code for the completed task.
315 * @status: This parameter is the status code for the completed task.
316 *
317 * none.
318 */
319static inline void isci_task_complete_for_upper_layer(
320 struct sas_task *task,
321 enum service_response response,
322 enum exec_status status,
323 enum isci_completion_selection task_notification_selection)
324{
325 isci_task_set_completion_status(task, response, status,
326 task_notification_selection);
327
328
329 /* Tasks aborted specifically by a call to the lldd_abort_task
330 * function should not be completed to the host in the regular path.
331 */
332 switch (task_notification_selection) {
333 case isci_perform_normal_io_completion:
334 /* Normal notification (task_done) */
335 dev_dbg(task->dev->port->ha->dev,
336 "%s: Normal - task = %p, response=%d, status=%d\n",
337 __func__, task, response, status);
338 task->task_done(task);
339 task->lldd_task = NULL;
340 break;
341
342 case isci_perform_aborted_io_completion:
343 /* No notification because this request is already in the
344 * abort path.
345 */
346 dev_warn(task->dev->port->ha->dev,
347 "%s: Aborted - task = %p, response=%d, status=%d\n",
348 __func__, task, response, status);
349 break;
350
351 case isci_perform_error_io_completion:
352 /* Use sas_task_abort */
353 dev_warn(task->dev->port->ha->dev,
354 "%s: Error - task = %p, response=%d, status=%d\n",
355 __func__, task, response, status);
356 sas_task_abort(task);
357 break;
358
359 default:
360 dev_warn(task->dev->port->ha->dev,
361 "%s: isci task notification default case!",
362 __func__);
363 sas_task_abort(task);
364 break;
365 }
366}
367
368#endif /* !defined(_SCI_TASK_H_) */
diff --git a/drivers/scsi/isci/timers.c b/drivers/scsi/isci/timers.c
new file mode 100644
index 000000000000..ca723089ee88
--- /dev/null
+++ b/drivers/scsi/isci/timers.c
@@ -0,0 +1,319 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include "isci.h"
57#include "timers.h"
58
59
60/**
61 * isci_timer_list_construct() - This method contrucst the SCI Timer List
62 * object used by the SCI Module class. The construction process involves
63 * creating isci_timer objects and adding them to the SCI Timer List
64 * object's list member. The number of isci_timer objects is determined by
65 * the timer_list_size parameter.
66 * @isci_timer_list: This parameter points to the SCI Timer List object being
67 * constructed. The calling routine is responsible for allocating the memory
68 * for isci_timer_list and initializing the timer list_head member of
69 * isci_timer_list.
70 * @timer_list_size: This parameter specifies the number of isci_timer objects
71 * contained by the SCI Timer List. which this timer is to be associated.
72 *
73 * This method returns an error code indicating sucess or failure. The user
74 * should check for possible memory allocation error return otherwise, a zero
75 * indicates success.
76 */
77int isci_timer_list_construct(
78 struct isci_timer_list *isci_timer_list,
79 int timer_list_size)
80{
81 struct isci_timer *isci_timer;
82 int i;
83 int err = 0;
84
85
86 for (i = 0; i < timer_list_size; i++) {
87
88 isci_timer = kzalloc(sizeof(*isci_timer), GFP_KERNEL);
89
90 if (!isci_timer) {
91
92 err = -ENOMEM;
93 break;
94 }
95 isci_timer->used = 0;
96 isci_timer->stopped = 1;
97 isci_timer->parent = isci_timer_list;
98 list_add(&isci_timer->node, &isci_timer_list->timers);
99 }
100
101 return 0;
102
103}
104
105
106/**
107 * isci_timer_list_destroy() - This method destroys the SCI Timer List object
108 * used by the SCI Module class. The destruction process involves freeing
109 * memory allocated for isci_timer objects on the SCI Timer List object's
110 * timers list_head member. If any isci_timer objects are mark as "in use",
111 * they are not freed and the function returns an error code of -EBUSY.
112 * @isci_timer_list: This parameter points to the SCI Timer List object being
113 * destroyed.
114 *
115 * This method returns an error code indicating sucess or failure. The user
116 * should check for possible -EBUSY error return, in the event of one or more
117 * isci_timers still "in use", otherwise, a zero indicates success.
118 */
119int isci_timer_list_destroy(
120 struct isci_timer_list *isci_timer_list)
121{
122 struct isci_timer *timer, *tmp;
123
124 list_for_each_entry_safe(timer, tmp, &isci_timer_list->timers, node) {
125 isci_timer_free(isci_timer_list, timer);
126 list_del(&timer->node);
127 kfree(timer);
128 }
129 return 0;
130}
131
132
133
134static void isci_timer_restart(struct isci_timer *isci_timer)
135{
136 struct timer_list *timer =
137 &isci_timer->timer;
138 unsigned long timeout;
139
140 dev_dbg(&isci_timer->isci_host->pdev->dev,
141 "%s: isci_timer = %p\n", __func__, isci_timer);
142
143 isci_timer->restart = 0;
144 isci_timer->stopped = 0;
145 timeout = isci_timer->timeout_value;
146 timeout = (timeout * HZ) / 1000;
147 timeout = timeout ? timeout : 1;
148 mod_timer(timer, jiffies + timeout);
149}
150
151/**
152 * This method pulls an isci_timer object off of the list for the SCI Timer
153 * List object specified, marks the isci_timer as "in use" and initializes
154 * it with user callback function and cookie data. The timer is not start at
155 * this time, just reserved for the user.
156 * @isci_timer_list: This parameter points to the SCI Timer List from which the
157 * timer is reserved.
158 * @cookie: This parameter specifies a piece of information that the user must
159 * retain. This cookie is to be supplied by the user anytime a timeout
160 * occurs for the created timer.
161 * @timer_callback: This parameter specifies the callback method to be invoked
162 * whenever the timer expires.
163 *
164 * This method returns a pointer to an isci_timer object reserved from the SCI
165 * Timer List. The pointer will be utilized for all further interactions
166 * relating to this timer.
167 */
168
169static void timer_function(unsigned long data)
170{
171
172 struct isci_timer *timer = (struct isci_timer *)data;
173 struct isci_host *isci_host = timer->isci_host;
174 unsigned long flags;
175
176 dev_dbg(&isci_host->pdev->dev,
177 "%s: isci_timer = %p\n", __func__, timer);
178
179 if (isci_stopped == isci_host_get_state(isci_host)) {
180 timer->stopped = 1;
181 return;
182 }
183
184 spin_lock_irqsave(&isci_host->scic_lock, flags);
185
186 if (!timer->stopped) {
187 timer->stopped = 1;
188 timer->timer_callback(timer->cookie);
189
190 if (timer->restart)
191 isci_timer_restart(timer);
192 }
193
194 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
195}
196
197
198struct isci_timer *isci_timer_create(
199 struct isci_timer_list *isci_timer_list,
200 struct isci_host *isci_host,
201 void *cookie,
202 void (*timer_callback)(void *))
203{
204
205 struct timer_list *timer;
206 struct isci_timer *isci_timer;
207 struct list_head *timer_list =
208 &isci_timer_list->timers;
209 unsigned long flags;
210
211 spin_lock_irqsave(&isci_host->scic_lock, flags);
212
213 if (list_empty(timer_list)) {
214 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
215 return NULL;
216 }
217
218 isci_timer = list_entry(timer_list->next, struct isci_timer, node);
219
220 if (isci_timer->used) {
221 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
222 return NULL;
223 }
224 isci_timer->used = 1;
225 isci_timer->stopped = 1;
226 list_move_tail(&isci_timer->node, timer_list);
227
228 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
229
230 timer = &isci_timer->timer;
231 timer->data = (unsigned long)isci_timer;
232 timer->function = timer_function;
233 isci_timer->cookie = cookie;
234 isci_timer->timer_callback = timer_callback;
235 isci_timer->isci_host = isci_host;
236
237 dev_dbg(&isci_host->pdev->dev,
238 "%s: isci_timer = %p\n", __func__, isci_timer);
239
240 return isci_timer;
241}
242
243/**
244 * isci_timer_free() - This method frees the isci_timer, marking it "free to
245 * use", then places its back at the head of the timers list for the SCI
246 * Timer List object specified.
247 * @isci_timer_list: This parameter points to the SCI Timer List from which the
248 * timer is reserved.
249 * @isci_timer: This parameter specifies the timer to be freed.
250 *
251 */
252void isci_timer_free(
253 struct isci_timer_list *isci_timer_list,
254 struct isci_timer *isci_timer)
255{
256 struct list_head *timer_list = &isci_timer_list->timers;
257
258 dev_dbg(&isci_timer->isci_host->pdev->dev,
259 "%s: isci_timer = %p\n", __func__, isci_timer);
260
261 if (list_empty(timer_list))
262 return;
263
264 isci_timer->used = 0;
265 list_move(&isci_timer->node, timer_list);
266
267 if (!isci_timer->stopped) {
268 del_timer(&isci_timer->timer);
269 isci_timer->stopped = 1;
270 }
271}
272
273/**
274 * isci_timer_start() - This method starts the specified isci_timer, with the
275 * specified timeout value.
276 * @isci_timer: This parameter specifies the timer to be started.
277 * @timeout: This parameter specifies the timeout, in milliseconds, after which
278 * the associated callback function will be called.
279 *
280 */
281void isci_timer_start(
282 struct isci_timer *isci_timer,
283 unsigned long timeout)
284{
285 struct timer_list *timer = &isci_timer->timer;
286
287 dev_dbg(&isci_timer->isci_host->pdev->dev,
288 "%s: isci_timer = %p\n", __func__, isci_timer);
289
290 isci_timer->timeout_value = timeout;
291 init_timer(timer);
292 timeout = (timeout * HZ) / 1000;
293 timeout = timeout ? timeout : 1;
294
295 timer->expires = jiffies + timeout;
296 timer->data = (unsigned long)isci_timer;
297 timer->function = timer_function;
298 isci_timer->stopped = 0;
299 isci_timer->restart = 0;
300 add_timer(timer);
301}
302
303/**
304 * isci_timer_stop() - This method stops the supplied isci_timer.
305 * @isci_timer: This parameter specifies the isci_timer to be stopped.
306 *
307 */
308void isci_timer_stop(struct isci_timer *isci_timer)
309{
310 dev_dbg(&isci_timer->isci_host->pdev->dev,
311 "%s: isci_timer = %p\n", __func__, isci_timer);
312
313 if (isci_timer->stopped)
314 return;
315
316 isci_timer->stopped = 1;
317
318 del_timer(&isci_timer->timer);
319}
diff --git a/drivers/scsi/isci/timers.h b/drivers/scsi/isci/timers.h
new file mode 100644
index 000000000000..ca5c2159a1c2
--- /dev/null
+++ b/drivers/scsi/isci/timers.h
@@ -0,0 +1,126 @@
1/*
2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 * * Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * * Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in
37 * the documentation and/or other materials provided with the
38 * distribution.
39 * * Neither the name of Intel Corporation nor the names of its
40 * contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#if !defined(_SCI_TIMER_H_)
57#define _SCI_TIMER_H_
58
59#include <linux/timer.h>
60#include <linux/types.h>
61
62/***************************************************
63 * isci_timer
64 ***************************************************
65 */
66/**
67 * struct isci_timer_list - This class is the container for all isci_timer
68 * objects
69 *
70 *
71 */
72struct isci_timer_list {
73
74 struct list_head timers;
75};
76
77/**
78 * struct isci_timer - This class represents the timer object used by SCIC. It
79 * wraps the Linux timer_list object.
80 *
81 *
82 */
83struct isci_timer {
84 int used;
85 int stopped;
86 int restart;
87 int timeout_value;
88 void *cookie;
89 void (*timer_callback)(void *);
90 struct list_head node;
91 struct timer_list timer;
92 struct isci_timer_list *parent;
93 struct isci_host *isci_host;
94};
95
96#define to_isci_timer(t) \
97 container_of(t, struct isci_timer, timer);
98
99int isci_timer_list_construct(
100 struct isci_timer_list *isci_timer_list,
101 int timer_list_size);
102
103
104int isci_timer_list_destroy(
105 struct isci_timer_list *isci_timer_list);
106
107struct isci_timer *isci_timer_create(
108 struct isci_timer_list *isci_timer_list,
109 struct isci_host *isci_host,
110 void *cookie,
111 void (*timer_callback)(void *));
112
113void isci_timer_free(
114 struct isci_timer_list *isci_timer_list,
115 struct isci_timer *isci_timer);
116
117void isci_timer_start(
118 struct isci_timer *isci_timer,
119 unsigned long timeout);
120
121void isci_timer_stop(
122 struct isci_timer *isci_timer);
123
124
125#endif /* !defined (_SCI_TIMER_H_) */
126
diff --git a/firmware/Makefile b/firmware/Makefile
index 0d15a3d113a2..5f43bfba3c7a 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -82,6 +82,7 @@ fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis \
82fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin 82fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin
83fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \ 83fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \
84 advansys/3550.bin advansys/38C0800.bin 84 advansys/3550.bin advansys/38C0800.bin
85fw-shipped-$(CONFIG_SCSI_ISCI) += isci/isci_firmware.bin
85fw-shipped-$(CONFIG_SCSI_QLOGIC_1280) += qlogic/1040.bin qlogic/1280.bin \ 86fw-shipped-$(CONFIG_SCSI_QLOGIC_1280) += qlogic/1040.bin qlogic/1280.bin \
86 qlogic/12160.bin 87 qlogic/12160.bin
87fw-shipped-$(CONFIG_SCSI_QLOGICPTI) += qlogic/isp1000.bin 88fw-shipped-$(CONFIG_SCSI_QLOGICPTI) += qlogic/isp1000.bin
diff --git a/firmware/isci/isci_firmware.bin.ihex b/firmware/isci/isci_firmware.bin.ihex
new file mode 100644
index 000000000000..9fc9e60f399c
--- /dev/null
+++ b/firmware/isci/isci_firmware.bin.ihex
@@ -0,0 +1,11 @@
1:1000000023534355204D4147494323000100010834
2:1000100001000000020000000400000008000000D1
3:1000200001000000020000000400000008000000C1
4:1000300002080300000003000000030000000300AA
5:1000400000000300000003000000030000000300A4
6:1000500000000308000000F0FFFFCF5F000000F188
7:10006000FFFFCF5F000000F2FFFFCF5F000000F353
8:10007000FFFFCF5F000000F4FFFFCF5F000000F53F
9:10008000FFFFCF5F000000F6FFFFCF5F000000F72B
10:05009000FFFFCF5FFF40
11:00000001FF