aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-04-02 08:15:04 -0400
committerDan Williams <dan.j.williams@intel.com>2011-07-03 07:00:37 -0400
commitbc5c96748a5f2067193faa8131b2aa5f9775d309 (patch)
tree509dc1a4e1cd2859f9c521af6c41b0a955226bc2
parent524b5f723be8a1d966c1285d69810bc461f181c2 (diff)
isci: simplify dma coherent allocation
Remove the insane infrastructure for preallocating coheren DMA regions, and just allocate the memory where needed. This also gets rid of the aligment adjustments given that Documentation/DMA-API-HOWTO.txt sais: "The cpu return address and the DMA bus master address are both guaranteed to be aligned to the smallest PAGE_SIZE order which is greater than or equal to the requested size. This invariant exists (for example) to guarantee that if you allocate a chunk which is smaller than or equal to 64 kilobytes, the extent of the buffer you receive will not cross a 64K boundary." Signed-off-by: Christoph Hellwig <hch@lst.de> [djbw: moved allocation from start to init, re-add memset] Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/scsi/isci/Makefile1
-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.h153
-rw-r--r--drivers/scsi/isci/core/sci_memory_descriptor_list.h168
-rw-r--r--drivers/scsi/isci/core/scic_controller.h1
-rw-r--r--drivers/scsi/isci/core/scic_sds_controller.c291
-rw-r--r--drivers/scsi/isci/core/scic_sds_controller.h49
-rw-r--r--drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.c66
-rw-r--r--drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.h22
-rw-r--r--drivers/scsi/isci/host.c95
-rw-r--r--drivers/scsi/isci/host.h9
11 files changed, 111 insertions, 903 deletions
diff --git a/drivers/scsi/isci/Makefile b/drivers/scsi/isci/Makefile
index a65c0ae9d2c4..522e7a7c062e 100644
--- a/drivers/scsi/isci/Makefile
+++ b/drivers/scsi/isci/Makefile
@@ -25,6 +25,5 @@ isci-objs := init.o phy.o request.o sata.o \
25 core/scic_sds_smp_remote_device.o \ 25 core/scic_sds_smp_remote_device.o \
26 core/scic_sds_remote_node_table.o \ 26 core/scic_sds_remote_node_table.o \
27 core/scic_sds_unsolicited_frame_control.o \ 27 core/scic_sds_unsolicited_frame_control.o \
28 core/sci_base_memory_descriptor_list.o \
29 core/sci_base_state_machine.o \ 28 core/sci_base_state_machine.o \
30 core/sci_util.o 29 core/sci_util.o
diff --git a/drivers/scsi/isci/core/sci_base_memory_descriptor_list.c b/drivers/scsi/isci/core/sci_base_memory_descriptor_list.c
deleted file mode 100644
index 2d785b518a06..000000000000
--- a/drivers/scsi/isci/core/sci_base_memory_descriptor_list.c
+++ /dev/null
@@ -1,159 +0,0 @@
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 != NULL)
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 != NULL)
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 != NULL)
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
deleted file mode 100644
index b58d4e86e7b9..000000000000
--- a/drivers/scsi/isci/core/sci_base_memory_descriptor_list.h
+++ /dev/null
@@ -1,153 +0,0 @@
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_memory_descriptor_list.h"
68
69
70/**
71 * struct sci_base_memory_descriptor_list - This structure contains all of the
72 * fields necessary to implement a simple stack for managing the list of
73 * available controller indices.
74 *
75 *
76 */
77struct sci_base_memory_descriptor_list {
78 /**
79 * This field indicates the length of the memory descriptor entry array.
80 */
81 u32 length;
82
83 /**
84 * This field is utilized to provide iterator pattern functionality.
85 * It indicates the index of the next memory descriptor in the iteration.
86 */
87 u32 next_index;
88
89 /**
90 * This field will point to the list of memory descriptors.
91 */
92 struct sci_physical_memory_descriptor *mde_array;
93
94 /**
95 * This field simply allows a user to chain memory descriptor lists
96 * together if desired. This field will be initialized to NULL.
97 */
98 struct sci_base_memory_descriptor_list *next_mdl;
99
100};
101
102/**
103 * sci_base_mdl_construct() - This method is invoked to construct an memory
104 * descriptor list. It initializes the fields of the MDL.
105 * @mdl: This parameter specifies the memory descriptor list to be constructed.
106 * @mde_array: This parameter specifies the array of memory descriptor entries
107 * to be managed by this list.
108 * @mde_array_length: This parameter specifies the size of the array of entries.
109 * @next_mdl: This parameter specifies a subsequent MDL object to be managed by
110 * this MDL object.
111 *
112 * none.
113 */
114void sci_base_mdl_construct(
115 struct sci_base_memory_descriptor_list *mdl,
116 struct sci_physical_memory_descriptor *mde_array,
117 u32 mde_array_length,
118 struct sci_base_memory_descriptor_list *next_mdl);
119
120/**
121 * sci_base_mde_construct() -
122 *
123 * This macro constructs an memory descriptor entry with the given alignment
124 * and size
125 */
126#define sci_base_mde_construct(mde, alignment, size, attributes) \
127 { \
128 (mde)->constant_memory_alignment = (alignment); \
129 (mde)->constant_memory_size = (size); \
130 (mde)->constant_memory_attributes = (attributes); \
131 }
132
133/**
134 * sci_base_mde_is_valid() - This method validates that the memory descriptor
135 * is correctly filled out by the SCI User
136 * @mde: This parameter is the mde entry to validate
137 * @alignment: This parameter specifies the expected alignment of the memory
138 * for the mde.
139 * @size: This parameter specifies the memory size expected for the mde its
140 * value should not have been changed by the SCI User.
141 * @attributes: This parameter specifies the attributes for the memory
142 * descriptor provided.
143 *
144 * bool This method returns an indication as to whether the supplied MDE is
145 * valid or not. true The MDE is valid. false The MDE is not valid.
146 */
147bool sci_base_mde_is_valid(
148 struct sci_physical_memory_descriptor *mde,
149 u32 alignment,
150 u32 size,
151 u16 attributes);
152
153#endif /* _SCI_BASE_MEMORY_DESCRIPTOR_LIST_H_ */
diff --git a/drivers/scsi/isci/core/sci_memory_descriptor_list.h b/drivers/scsi/isci/core/sci_memory_descriptor_list.h
deleted file mode 100644
index a039998d01c6..000000000000
--- a/drivers/scsi/isci/core/sci_memory_descriptor_list.h
+++ /dev/null
@@ -1,168 +0,0 @@
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
68struct sci_base_memory_descriptor_list;
69
70/**
71 *
72 *
73 * SCI_MDE_ATTRIBUTES These constants depict memory attributes for the Memory
74 * Descriptor Entries (MDEs) contained in the MDL.
75 */
76#define SCI_MDE_ATTRIBUTE_CACHEABLE 0x0001
77#define SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS 0x0002
78
79/**
80 * struct sci_physical_memory_descriptor - This structure defines a description
81 * of a memory location for the SCI implementation.
82 *
83 *
84 */
85struct sci_physical_memory_descriptor {
86 /**
87 * This field contains the virtual address associated with this descriptor
88 * element. This field shall be zero when the descriptor is retrieved from
89 * the SCI implementation. The user shall set this field prior
90 * sci_controller_start()
91 */
92 void *virtual_address;
93
94 /**
95 * This field contains the physical address associated with this desciptor
96 * element. This field shall be zero when the descriptor is retrieved from
97 * the SCI implementation. The user shall set this field prior
98 * sci_controller_start()
99 */
100 dma_addr_t physical_address;
101
102 /**
103 * This field contains the size requirement for this memory descriptor.
104 * A value of zero for this field indicates the end of the descriptor
105 * list. The value should be treated as read only for an SCI user.
106 */
107 u32 constant_memory_size;
108
109 /**
110 * This field contains the alignment requirement for this memory
111 * descriptor. A value of zero for this field indicates the end of the
112 * descriptor list. All other values indicate the number of bytes to
113 * achieve the necessary alignment. The value should be treated as
114 * read only for an SCI user.
115 */
116 u32 constant_memory_alignment;
117
118 /**
119 * This field contains an indication regarding the desired memory
120 * attributes for this memory descriptor entry.
121 * Notes:
122 * - If the cacheable attribute is set, the user can allocate
123 * memory that is backed by cache for better performance. It
124 * is not required that the memory be backed by cache.
125 * - If the physically contiguous attribute is set, then the
126 * entire memory must be physically contiguous across all
127 * page boundaries.
128 */
129 u16 constant_memory_attributes;
130
131};
132
133/**
134 * sci_mdl_first_entry() - This method simply rewinds the MDL iterator back to
135 * the first memory descriptor entry in the list.
136 * @mdl: This parameter specifies the memory descriptor list that is to be
137 * rewound.
138 *
139 */
140void sci_mdl_first_entry(
141 struct sci_base_memory_descriptor_list *mdl);
142
143/**
144 * sci_mdl_next_entry() - This method simply updates the "current" pointer to
145 * the next sequential memory descriptor.
146 * @mdl: This parameter specifies the memory descriptor list for which to
147 * return the next memory descriptor entry in the list.
148 *
149 * none.
150 */
151void sci_mdl_next_entry(
152 struct sci_base_memory_descriptor_list *mdl);
153
154/**
155 * sci_mdl_get_current_entry() - This method simply returns the current memory
156 * descriptor entry.
157 * @mdl: This parameter specifies the memory descriptor list for which to
158 * return the current memory descriptor entry.
159 *
160 * This method returns a pointer to the current physical memory descriptor in
161 * the MDL. NULL This value is returned if there are no descriptors in the list.
162 */
163struct sci_physical_memory_descriptor *sci_mdl_get_current_entry(
164 struct sci_base_memory_descriptor_list *mdl);
165
166
167#endif /* _SCI_MEMORY_DESCRIPTOR_LIST_H_ */
168
diff --git a/drivers/scsi/isci/core/scic_controller.h b/drivers/scsi/isci/core/scic_controller.h
index 236c583162ec..649b61ac5d6d 100644
--- a/drivers/scsi/isci/core/scic_controller.h
+++ b/drivers/scsi/isci/core/scic_controller.h
@@ -144,4 +144,5 @@ enum sci_status scic_controller_free_io_tag(
144 144
145struct device; 145struct device;
146struct scic_sds_controller *scic_controller_alloc(struct device *dev); 146struct scic_sds_controller *scic_controller_alloc(struct device *dev);
147int scic_controller_mem_init(struct scic_sds_controller *scic);
147#endif /* _SCIC_CONTROLLER_H_ */ 148#endif /* _SCIC_CONTROLLER_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_controller.c b/drivers/scsi/isci/core/scic_sds_controller.c
index 7ead6f381550..4aae7b6361a7 100644
--- a/drivers/scsi/isci/core/scic_sds_controller.c
+++ b/drivers/scsi/isci/core/scic_sds_controller.c
@@ -226,171 +226,66 @@ static void scic_sds_controller_initialize_power_control(struct scic_sds_control
226 scic->power_control.phys_granted_power = 0; 226 scic->power_control.phys_granted_power = 0;
227} 227}
228 228
229#define SCU_REMOTE_NODE_CONTEXT_ALIGNMENT (32) 229int scic_controller_mem_init(struct scic_sds_controller *scic)
230#define SCU_TASK_CONTEXT_ALIGNMENT (256)
231#define SCU_UNSOLICITED_FRAME_ADDRESS_ALIGNMENT (64)
232#define SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT (1024)
233#define SCU_UNSOLICITED_FRAME_HEADER_ALIGNMENT (64)
234
235/**
236 * This method builds the memory descriptor table for this controller.
237 * @this_controller: This parameter specifies the controller object for which
238 * to build the memory table.
239 *
240 */
241static void scic_sds_controller_build_memory_descriptor_table(
242 struct scic_sds_controller *this_controller)
243{ 230{
244 sci_base_mde_construct( 231 struct device *dev = scic_to_dev(scic);
245 &this_controller->memory_descriptors[SCU_MDE_COMPLETION_QUEUE], 232 dma_addr_t dma_handle;
246 SCU_COMPLETION_RAM_ALIGNMENT, 233 enum sci_status result;
247 (sizeof(u32) * this_controller->completion_queue_entries),
248 (SCI_MDE_ATTRIBUTE_CACHEABLE | SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS)
249 );
250
251 sci_base_mde_construct(
252 &this_controller->memory_descriptors[SCU_MDE_REMOTE_NODE_CONTEXT],
253 SCU_REMOTE_NODE_CONTEXT_ALIGNMENT,
254 this_controller->remote_node_entries * sizeof(union scu_remote_node_context),
255 SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
256 );
257
258 sci_base_mde_construct(
259 &this_controller->memory_descriptors[SCU_MDE_TASK_CONTEXT],
260 SCU_TASK_CONTEXT_ALIGNMENT,
261 this_controller->task_context_entries * sizeof(struct scu_task_context),
262 SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
263 );
264
265 /*
266 * The UF buffer address table size must be programmed to a power
267 * of 2. Find the first power of 2 that is equal to or greater then
268 * the number of unsolicited frame buffers to be utilized. */
269 scic_sds_unsolicited_frame_control_set_address_table_count(
270 &this_controller->uf_control
271 );
272
273 sci_base_mde_construct(
274 &this_controller->memory_descriptors[SCU_MDE_UF_BUFFER],
275 SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT,
276 scic_sds_unsolicited_frame_control_get_mde_size(this_controller->uf_control),
277 SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
278 );
279}
280
281/**
282 * This method validates the driver supplied memory descriptor table.
283 * @this_controller:
284 *
285 * enum sci_status
286 */
287static enum sci_status scic_sds_controller_validate_memory_descriptor_table(
288 struct scic_sds_controller *this_controller)
289{
290 bool mde_list_valid;
291
292 mde_list_valid = sci_base_mde_is_valid(
293 &this_controller->memory_descriptors[SCU_MDE_COMPLETION_QUEUE],
294 SCU_COMPLETION_RAM_ALIGNMENT,
295 (sizeof(u32) * this_controller->completion_queue_entries),
296 (SCI_MDE_ATTRIBUTE_CACHEABLE | SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS)
297 );
298
299 if (mde_list_valid == false)
300 return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD;
301
302 mde_list_valid = sci_base_mde_is_valid(
303 &this_controller->memory_descriptors[SCU_MDE_REMOTE_NODE_CONTEXT],
304 SCU_REMOTE_NODE_CONTEXT_ALIGNMENT,
305 this_controller->remote_node_entries * sizeof(union scu_remote_node_context),
306 SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
307 );
308
309 if (mde_list_valid == false)
310 return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD;
311
312 mde_list_valid = sci_base_mde_is_valid(
313 &this_controller->memory_descriptors[SCU_MDE_TASK_CONTEXT],
314 SCU_TASK_CONTEXT_ALIGNMENT,
315 this_controller->task_context_entries * sizeof(struct scu_task_context),
316 SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
317 );
318
319 if (mde_list_valid == false)
320 return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD;
321
322 mde_list_valid = sci_base_mde_is_valid(
323 &this_controller->memory_descriptors[SCU_MDE_UF_BUFFER],
324 SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT,
325 scic_sds_unsolicited_frame_control_get_mde_size(this_controller->uf_control),
326 SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
327 );
328
329 if (mde_list_valid == false)
330 return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD;
331
332 return SCI_SUCCESS;
333}
334
335/**
336 * This method initializes the controller with the physical memory addresses
337 * that are used to communicate with the driver.
338 * @this_controller:
339 *
340 */
341static void scic_sds_controller_ram_initialization(
342 struct scic_sds_controller *this_controller)
343{
344 struct sci_physical_memory_descriptor *mde;
345 234
346 /* 235 scic->completion_queue = dmam_alloc_coherent(dev,
347 * The completion queue is actually placed in cacheable memory 236 scic->completion_queue_entries * sizeof(u32),
348 * Therefore it no longer comes out of memory in the MDL. */ 237 &dma_handle, GFP_KERNEL);
349 mde = &this_controller->memory_descriptors[SCU_MDE_COMPLETION_QUEUE]; 238 if (!scic->completion_queue)
350 this_controller->completion_queue = (u32 *)mde->virtual_address; 239 return -ENOMEM;
351 writel(lower_32_bits(mde->physical_address), \ 240
352 &this_controller->smu_registers->completion_queue_lower); 241 writel(lower_32_bits(dma_handle),
353 writel(upper_32_bits(mde->physical_address), 242 &scic->smu_registers->completion_queue_lower);
354 &this_controller->smu_registers->completion_queue_upper); 243 writel(upper_32_bits(dma_handle),
355 244 &scic->smu_registers->completion_queue_upper);
356 /* 245
357 * Program the location of the Remote Node Context table 246 scic->remote_node_context_table = dmam_alloc_coherent(dev,
358 * into the SCU. */ 247 scic->remote_node_entries *
359 mde = &this_controller->memory_descriptors[SCU_MDE_REMOTE_NODE_CONTEXT]; 248 sizeof(union scu_remote_node_context),
360 this_controller->remote_node_context_table = (union scu_remote_node_context *) 249 &dma_handle, GFP_KERNEL);
361 mde->virtual_address; 250 if (!scic->remote_node_context_table)
362 writel(lower_32_bits(mde->physical_address), 251 return -ENOMEM;
363 &this_controller->smu_registers->remote_node_context_lower); 252
364 writel(upper_32_bits(mde->physical_address), 253 writel(lower_32_bits(dma_handle),
365 &this_controller->smu_registers->remote_node_context_upper); 254 &scic->smu_registers->remote_node_context_lower);
366 255 writel(upper_32_bits(dma_handle),
367 /* Program the location of the Task Context table into the SCU. */ 256 &scic->smu_registers->remote_node_context_upper);
368 mde = &this_controller->memory_descriptors[SCU_MDE_TASK_CONTEXT]; 257
369 this_controller->task_context_table = (struct scu_task_context *) 258 scic->task_context_table = dmam_alloc_coherent(dev,
370 mde->virtual_address; 259 scic->task_context_entries *
371 writel(lower_32_bits(mde->physical_address), 260 sizeof(struct scu_task_context),
372 &this_controller->smu_registers->host_task_table_lower); 261 &dma_handle, GFP_KERNEL);
373 writel(upper_32_bits(mde->physical_address), 262 if (!scic->task_context_table)
374 &this_controller->smu_registers->host_task_table_upper); 263 return -ENOMEM;
375 264
376 mde = &this_controller->memory_descriptors[SCU_MDE_UF_BUFFER]; 265 writel(lower_32_bits(dma_handle),
377 scic_sds_unsolicited_frame_control_construct( 266 &scic->smu_registers->host_task_table_lower);
378 &this_controller->uf_control, mde, this_controller 267 writel(upper_32_bits(dma_handle),
379 ); 268 &scic->smu_registers->host_task_table_upper);
269
270 result = scic_sds_unsolicited_frame_control_construct(scic);
271 if (result)
272 return result;
380 273
381 /* 274 /*
382 * Inform the silicon as to the location of the UF headers and 275 * Inform the silicon as to the location of the UF headers and
383 * address table. 276 * address table.
384 */ 277 */
385 writel(lower_32_bits(this_controller->uf_control.headers.physical_address), 278 writel(lower_32_bits(scic->uf_control.headers.physical_address),
386 &this_controller->scu_registers->sdma.uf_header_base_address_lower); 279 &scic->scu_registers->sdma.uf_header_base_address_lower);
387 writel(upper_32_bits(this_controller->uf_control.headers.physical_address), 280 writel(upper_32_bits(scic->uf_control.headers.physical_address),
388 &this_controller->scu_registers->sdma.uf_header_base_address_upper); 281 &scic->scu_registers->sdma.uf_header_base_address_upper);
282
283 writel(lower_32_bits(scic->uf_control.address_table.physical_address),
284 &scic->scu_registers->sdma.uf_address_table_lower);
285 writel(upper_32_bits(scic->uf_control.address_table.physical_address),
286 &scic->scu_registers->sdma.uf_address_table_upper);
389 287
390 writel(lower_32_bits(this_controller->uf_control.address_table.physical_address), 288 return 0;
391 &this_controller->scu_registers->sdma.uf_address_table_lower);
392 writel(upper_32_bits(this_controller->uf_control.address_table.physical_address),
393 &this_controller->scu_registers->sdma.uf_address_table_upper);
394} 289}
395 290
396/** 291/**
@@ -2525,7 +2420,6 @@ static enum sci_status scic_controller_set_mode(
2525 scic->completion_event_entries = SCU_EVENT_COUNT; 2420 scic->completion_event_entries = SCU_EVENT_COUNT;
2526 scic->completion_queue_entries = 2421 scic->completion_queue_entries =
2527 SCU_COMPLETION_QUEUE_COUNT; 2422 SCU_COMPLETION_QUEUE_COUNT;
2528 scic_sds_controller_build_memory_descriptor_table(scic);
2529 break; 2423 break;
2530 2424
2531 case SCI_MODE_SIZE: 2425 case SCI_MODE_SIZE:
@@ -2536,7 +2430,6 @@ static enum sci_status scic_controller_set_mode(
2536 scic->completion_event_entries = SCU_MIN_EVENTS; 2430 scic->completion_event_entries = SCU_MIN_EVENTS;
2537 scic->completion_queue_entries = 2431 scic->completion_queue_entries =
2538 SCU_MIN_COMPLETION_QUEUE_ENTRIES; 2432 SCU_MIN_COMPLETION_QUEUE_ENTRIES;
2539 scic_sds_controller_build_memory_descriptor_table(scic);
2540 break; 2433 break;
2541 2434
2542 default: 2435 default:
@@ -3040,72 +2933,52 @@ static enum sci_status scic_sds_controller_initialized_state_start_handler(
3040 u16 index; 2933 u16 index;
3041 enum sci_status result; 2934 enum sci_status result;
3042 2935
3043 /* 2936 /* Build the TCi free pool */
3044 * Make sure that the SCI User filled in the memory descriptor 2937 sci_pool_initialize(scic->tci_pool);
3045 * table correctly 2938 for (index = 0; index < scic->task_context_entries; index++)
3046 */ 2939 sci_pool_put(scic->tci_pool, index);
3047 result = scic_sds_controller_validate_memory_descriptor_table(scic);
3048
3049 if (result == SCI_SUCCESS) {
3050 /*
3051 * The memory descriptor list looks good so program the
3052 * hardware
3053 */
3054 scic_sds_controller_ram_initialization(scic);
3055 }
3056
3057 if (result == SCI_SUCCESS) {
3058 /* Build the TCi free pool */
3059 sci_pool_initialize(scic->tci_pool);
3060 for (index = 0; index < scic->task_context_entries; index++)
3061 sci_pool_put(scic->tci_pool, index);
3062 2940
3063 /* Build the RNi free pool */ 2941 /* Build the RNi free pool */
3064 scic_sds_remote_node_table_initialize( 2942 scic_sds_remote_node_table_initialize(
3065 &scic->available_remote_nodes, 2943 &scic->available_remote_nodes,
3066 scic->remote_node_entries); 2944 scic->remote_node_entries);
3067 }
3068 2945
3069 if (result == SCI_SUCCESS) { 2946 /*
3070 /* 2947 * Before anything else lets make sure we will not be
3071 * Before anything else lets make sure we will not be 2948 * interrupted by the hardware.
3072 * interrupted by the hardware. 2949 */
3073 */ 2950 scic_controller_disable_interrupts(scic);
3074 scic_controller_disable_interrupts(scic);
3075 2951
3076 /* Enable the port task scheduler */ 2952 /* Enable the port task scheduler */
3077 scic_sds_controller_enable_port_task_scheduler(scic); 2953 scic_sds_controller_enable_port_task_scheduler(scic);
3078 2954
3079 /* Assign all the task entries to scic physical function */ 2955 /* Assign all the task entries to scic physical function */
3080 scic_sds_controller_assign_task_entries(scic); 2956 scic_sds_controller_assign_task_entries(scic);
3081 2957
3082 /* Now initialze the completion queue */ 2958 /* Now initialze the completion queue */
3083 scic_sds_controller_initialize_completion_queue(scic); 2959 scic_sds_controller_initialize_completion_queue(scic);
3084 2960
3085 /* Initialize the unsolicited frame queue for use */ 2961 /* Initialize the unsolicited frame queue for use */
3086 scic_sds_controller_initialize_unsolicited_frame_queue(scic); 2962 scic_sds_controller_initialize_unsolicited_frame_queue(scic);
3087 }
3088 2963
3089 /* Start all of the ports on this controller */ 2964 /* Start all of the ports on this controller */
3090 for (index = 0; 2965 for (index = 0; index < scic->logical_port_entries; index++) {
3091 (index < scic->logical_port_entries) && (result == SCI_SUCCESS);
3092 index++) {
3093 struct scic_sds_port *sci_port = &scic->port_table[index]; 2966 struct scic_sds_port *sci_port = &scic->port_table[index];
3094 2967
3095 result = sci_port->state_handlers->parent.start_handler( 2968 result = sci_port->state_handlers->parent.start_handler(
3096 &sci_port->parent); 2969 &sci_port->parent);
2970 if (result)
2971 return result;
3097 } 2972 }
3098 2973
3099 if (result == SCI_SUCCESS) { 2974 scic_sds_controller_start_next_phy(scic);
3100 scic_sds_controller_start_next_phy(scic);
3101 2975
3102 isci_timer_start(scic->timeout_timer, timeout); 2976 isci_timer_start(scic->timeout_timer, timeout);
3103 2977
3104 sci_base_state_machine_change_state(&scic->state_machine, 2978 sci_base_state_machine_change_state(&scic->state_machine,
3105 SCI_BASE_CONTROLLER_STATE_STARTING); 2979 SCI_BASE_CONTROLLER_STATE_STARTING);
3106 }
3107 2980
3108 return result; 2981 return SCI_SUCCESS;
3109} 2982}
3110 2983
3111/* 2984/*
@@ -3658,8 +3531,6 @@ enum sci_status scic_controller_construct(struct scic_sds_controller *scic,
3658 &scic->parent, scic_sds_controller_state_table, 3531 &scic->parent, scic_sds_controller_state_table,
3659 SCI_BASE_CONTROLLER_STATE_INITIAL); 3532 SCI_BASE_CONTROLLER_STATE_INITIAL);
3660 3533
3661 sci_base_mdl_construct(&scic->mdl, scic->memory_descriptors,
3662 ARRAY_SIZE(scic->memory_descriptors), NULL);
3663 sci_base_state_machine_start(&scic->state_machine); 3534 sci_base_state_machine_start(&scic->state_machine);
3664 3535
3665 scic->scu_registers = scu_base; 3536 scic->scu_registers = scu_base;
diff --git a/drivers/scsi/isci/core/scic_sds_controller.h b/drivers/scsi/isci/core/scic_sds_controller.h
index 5cff8066a0ef..163a9e11576a 100644
--- a/drivers/scsi/isci/core/scic_sds_controller.h
+++ b/drivers/scsi/isci/core/scic_sds_controller.h
@@ -68,10 +68,8 @@
68 68
69#include "sci_pool.h" 69#include "sci_pool.h"
70#include "sci_controller_constants.h" 70#include "sci_controller_constants.h"
71#include "sci_memory_descriptor_list.h"
72#include "sci_base_state.h" 71#include "sci_base_state.h"
73#include "sci_base_state_machine.h" 72#include "sci_base_state_machine.h"
74#include "sci_base_memory_descriptor_list.h"
75#include "scic_config_parameters.h" 73#include "scic_config_parameters.h"
76#include "scic_sds_port.h" 74#include "scic_sds_port.h"
77#include "scic_sds_phy.h" 75#include "scic_sds_phy.h"
@@ -89,40 +87,6 @@ struct scic_sds_remote_device;
89struct scic_sds_request; 87struct scic_sds_request;
90struct scic_sds_controller; 88struct scic_sds_controller;
91 89
92#define SCU_COMPLETION_RAM_ALIGNMENT (64)
93
94/**
95 * enum scic_sds_controller_memory_descriptors -
96 *
97 * This enumeration depects the types of MDEs that are going to be created for
98 * the controller object.
99 */
100enum scic_sds_controller_memory_descriptors {
101 /**
102 * Completion queue MDE entry
103 */
104 SCU_MDE_COMPLETION_QUEUE,
105
106 /**
107 * Remote node context MDE entry
108 */
109 SCU_MDE_REMOTE_NODE_CONTEXT,
110
111 /**
112 * Task context MDE entry
113 */
114 SCU_MDE_TASK_CONTEXT,
115
116 /**
117 * Unsolicited frame buffer MDE entrys this is the start of the unsolicited
118 * frame buffer entries.
119 */
120 SCU_MDE_UF_BUFFER,
121
122 SCU_MAX_MDES
123};
124
125
126/** 90/**
127 * struct scic_power_control - 91 * struct scic_power_control -
128 * 92 *
@@ -174,13 +138,6 @@ struct scic_sds_controller {
174 struct sci_base_object parent; 138 struct sci_base_object parent;
175 139
176 /** 140 /**
177 * This field points to the memory descriptor list associated with this
178 * controller. The MDL indicates the memory requirements necessary for
179 * this controller object.
180 */
181 struct sci_base_memory_descriptor_list mdl;
182
183 /**
184 * This field contains the information for the base controller state 141 * This field contains the information for the base controller state
185 * machine. 142 * machine.
186 */ 143 */
@@ -285,12 +242,6 @@ struct scic_sds_controller {
285 union scu_remote_node_context *remote_node_context_table; 242 union scu_remote_node_context *remote_node_context_table;
286 243
287 /** 244 /**
288 * This field is the array of physical memory requiremets for this controller
289 * object.
290 */
291 struct sci_physical_memory_descriptor memory_descriptors[SCU_MAX_MDES];
292
293 /**
294 * This field is a pointer to the completion queue. This memory is 245 * This field is a pointer to the completion queue. This memory is
295 * written to by the hardware and read by the software. 246 * written to by the hardware and read by the software.
296 */ 247 */
diff --git a/drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.c b/drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.c
index 31a3516ddebe..9e393e5df8ec 100644
--- a/drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.c
+++ b/drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.c
@@ -68,26 +68,6 @@
68#include "sci_environment.h" 68#include "sci_environment.h"
69 69
70/** 70/**
71 * The UF buffer address table size must be programmed to a power of 2. Find
72 * the first power of 2 that is equal to or greater then the number of
73 * unsolicited frame buffers to be utilized.
74 * @uf_control: This parameter specifies the UF control object for which to
75 * update the address table count.
76 *
77 */
78void scic_sds_unsolicited_frame_control_set_address_table_count(
79 struct scic_sds_unsolicited_frame_control *uf_control)
80{
81 uf_control->address_table.count = SCU_MIN_UF_TABLE_ENTRIES;
82 while (
83 (uf_control->address_table.count < uf_control->buffers.count)
84 && (uf_control->address_table.count < SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES)
85 ) {
86 uf_control->address_table.count <<= 1;
87 }
88}
89
90/**
91 * This method will program the unsolicited frames (UFs) into the UF address 71 * This method will program the unsolicited frames (UFs) into the UF address
92 * table and construct the UF frame structure being modeled in the core. It 72 * table and construct the UF frame structure being modeled in the core. It
93 * will handle the case where some of the UFs are not being used and thus 73 * will handle the case where some of the UFs are not being used and thus
@@ -155,23 +135,9 @@ static void scic_sds_unsolicited_frame_control_construct_frames(
155 } 135 }
156} 136}
157 137
158/** 138int scic_sds_unsolicited_frame_control_construct(struct scic_sds_controller *scic)
159 * This method constructs the various members of the unsolicted frame control
160 * object (buffers, headers, address, table, etc).
161 * @uf_control: This parameter specifies the unsolicited frame control object
162 * to construct.
163 * @mde: This parameter specifies the memory descriptor from which to derive
164 * all of the address information needed to get the unsolicited frame
165 * functionality working.
166 * @controller: This parameter specifies the controller object associated with
167 * the uf_control being constructed.
168 *
169 */
170void scic_sds_unsolicited_frame_control_construct(
171 struct scic_sds_unsolicited_frame_control *uf_control,
172 struct sci_physical_memory_descriptor *mde,
173 struct scic_sds_controller *controller)
174{ 139{
140 struct scic_sds_unsolicited_frame_control *uf_control = &scic->uf_control;
175 u32 unused_uf_header_entries; 141 u32 unused_uf_header_entries;
176 u32 used_uf_header_entries; 142 u32 used_uf_header_entries;
177 u32 used_uf_buffer_bytes; 143 u32 used_uf_buffer_bytes;
@@ -179,10 +145,22 @@ void scic_sds_unsolicited_frame_control_construct(
179 u32 used_uf_header_bytes; 145 u32 used_uf_header_bytes;
180 dma_addr_t uf_buffer_phys_address; 146 dma_addr_t uf_buffer_phys_address;
181 void *uf_buffer_virt_address; 147 void *uf_buffer_virt_address;
148 size_t size;
149
150 /*
151 * The UF buffer address table size must be programmed to a power
152 * of 2. Find the first power of 2 that is equal to or greater then
153 * the number of unsolicited frame buffers to be utilized.
154 */
155 uf_control->address_table.count = SCU_MIN_UF_TABLE_ENTRIES;
156 while (uf_control->address_table.count < uf_control->buffers.count &&
157 uf_control->address_table.count < SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES)
158 uf_control->address_table.count <<= 1;
182 159
183 /* 160 /*
184 * Prepare all of the memory sizes for the UF headers, UF address 161 * Prepare all of the memory sizes for the UF headers, UF address
185 * table, and UF buffers themselves. */ 162 * table, and UF buffers themselves.
163 */
186 used_uf_buffer_bytes = uf_control->buffers.count 164 used_uf_buffer_bytes = uf_control->buffers.count
187 * SCU_UNSOLICITED_FRAME_BUFFER_SIZE; 165 * SCU_UNSOLICITED_FRAME_BUFFER_SIZE;
188 unused_uf_header_entries = uf_control->address_table.count 166 unused_uf_header_entries = uf_control->address_table.count
@@ -193,13 +171,19 @@ void scic_sds_unsolicited_frame_control_construct(
193 used_uf_header_bytes = used_uf_header_entries 171 used_uf_header_bytes = used_uf_header_entries
194 * sizeof(struct scu_unsolicited_frame_header); 172 * sizeof(struct scu_unsolicited_frame_header);
195 173
174 size = used_uf_buffer_bytes + used_uf_header_bytes +
175 uf_control->address_table.count * sizeof(dma_addr_t);
176
177
196 /* 178 /*
197 * The Unsolicited Frame buffers are set at the start of the UF 179 * The Unsolicited Frame buffers are set at the start of the UF
198 * memory descriptor entry. The headers and address table will be 180 * memory descriptor entry. The headers and address table will be
199 * placed after the buffers. 181 * placed after the buffers.
200 */ 182 */
201 uf_buffer_phys_address = mde->physical_address; 183 uf_buffer_virt_address = dmam_alloc_coherent(scic_to_dev(scic), size,
202 uf_buffer_virt_address = mde->virtual_address; 184 &uf_buffer_phys_address, GFP_KERNEL);
185 if (!uf_buffer_virt_address)
186 return -ENOMEM;
203 187
204 /* 188 /*
205 * Program the location of the UF header table into the SCU. 189 * Program the location of the UF header table into the SCU.
@@ -254,10 +238,12 @@ void scic_sds_unsolicited_frame_control_construct(
254 scic_sds_unsolicited_frame_control_construct_frames( 238 scic_sds_unsolicited_frame_control_construct_frames(
255 uf_control, 239 uf_control,
256 uf_buffer_phys_address, 240 uf_buffer_phys_address,
257 mde->virtual_address, 241 uf_buffer_virt_address,
258 unused_uf_header_entries, 242 unused_uf_header_entries,
259 used_uf_header_entries 243 used_uf_header_entries
260 ); 244 );
245
246 return 0;
261} 247}
262 248
263/** 249/**
diff --git a/drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.h b/drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.h
index a0204aa7128a..4eb244c06cfc 100644
--- a/drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.h
+++ b/drivers/scsi/isci/core/scic_sds_unsolicited_frame_control.h
@@ -64,7 +64,6 @@
64#define _SCIC_SDS_UNSOLICITED_FRAME_CONTROL_H_ 64#define _SCIC_SDS_UNSOLICITED_FRAME_CONTROL_H_
65 65
66#include "scu_unsolicited_frame.h" 66#include "scu_unsolicited_frame.h"
67#include "sci_memory_descriptor_list.h"
68#include "scu_constants.h" 67#include "scu_constants.h"
69#include "sci_status.h" 68#include "sci_status.h"
70 69
@@ -248,14 +247,9 @@ struct scic_sds_unsolicited_frame_control {
248 247
249}; 248};
250 249
251void scic_sds_unsolicited_frame_control_set_address_table_count(
252 struct scic_sds_unsolicited_frame_control *uf_control);
253
254struct scic_sds_controller; 250struct scic_sds_controller;
255void scic_sds_unsolicited_frame_control_construct( 251
256 struct scic_sds_unsolicited_frame_control *uf_control, 252int scic_sds_unsolicited_frame_control_construct(struct scic_sds_controller *scic);
257 struct sci_physical_memory_descriptor *mde,
258 struct scic_sds_controller *this_controller);
259 253
260enum sci_status scic_sds_unsolicited_frame_control_get_header( 254enum sci_status scic_sds_unsolicited_frame_control_get_header(
261 struct scic_sds_unsolicited_frame_control *uf_control, 255 struct scic_sds_unsolicited_frame_control *uf_control,
@@ -271,16 +265,4 @@ bool scic_sds_unsolicited_frame_control_release_frame(
271 struct scic_sds_unsolicited_frame_control *uf_control, 265 struct scic_sds_unsolicited_frame_control *uf_control,
272 u32 frame_index); 266 u32 frame_index);
273 267
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_ */ 268#endif /* _SCIC_SDS_UNSOLICITED_FRAME_CONTROL_H_ */
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index adfc2452d216..927f08892ad6 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -170,96 +170,6 @@ void isci_host_stop_complete(struct isci_host *ihost, enum sci_status completion
170 wake_up(&ihost->eventq); 170 wake_up(&ihost->eventq);
171} 171}
172 172
173static struct coherent_memory_info *isci_host_alloc_mdl_struct(
174 struct isci_host *isci_host,
175 u32 size)
176{
177 struct coherent_memory_info *mdl_struct;
178 void *uncached_address = NULL;
179
180
181 mdl_struct = devm_kzalloc(&isci_host->pdev->dev,
182 sizeof(*mdl_struct),
183 GFP_KERNEL);
184 if (!mdl_struct)
185 return NULL;
186
187 INIT_LIST_HEAD(&mdl_struct->node);
188
189 uncached_address = dmam_alloc_coherent(&isci_host->pdev->dev,
190 size,
191 &mdl_struct->dma_handle,
192 GFP_KERNEL);
193 if (!uncached_address)
194 return NULL;
195
196 /* memset the whole memory area. */
197 memset((char *)uncached_address, 0, size);
198 mdl_struct->vaddr = uncached_address;
199 mdl_struct->size = (size_t)size;
200
201 return mdl_struct;
202}
203
204static void isci_host_build_mde(
205 struct sci_physical_memory_descriptor *mde_struct,
206 struct coherent_memory_info *mdl_struct)
207{
208 unsigned long address = 0;
209 dma_addr_t dma_addr = 0;
210
211 address = (unsigned long)mdl_struct->vaddr;
212 dma_addr = mdl_struct->dma_handle;
213
214 /* to satisfy the alignment. */
215 if ((address % mde_struct->constant_memory_alignment) != 0) {
216 int align_offset
217 = (mde_struct->constant_memory_alignment
218 - (address % mde_struct->constant_memory_alignment));
219 address += align_offset;
220 dma_addr += align_offset;
221 }
222
223 mde_struct->virtual_address = (void *)address;
224 mde_struct->physical_address = dma_addr;
225 mdl_struct->mde = mde_struct;
226}
227
228static int isci_host_mdl_allocate_coherent(
229 struct isci_host *isci_host)
230{
231 struct sci_physical_memory_descriptor *current_mde;
232 struct coherent_memory_info *mdl_struct;
233 u32 size = 0;
234
235 struct sci_base_memory_descriptor_list *mdl_handle =
236 &isci_host->core_controller->mdl;
237
238 sci_mdl_first_entry(mdl_handle);
239
240 current_mde = sci_mdl_get_current_entry(mdl_handle);
241
242 while (current_mde != NULL) {
243
244 size = (current_mde->constant_memory_size
245 + current_mde->constant_memory_alignment);
246
247 mdl_struct = isci_host_alloc_mdl_struct(isci_host, size);
248 if (!mdl_struct)
249 return -ENOMEM;
250
251 list_add_tail(&mdl_struct->node, &isci_host->mdl_struct_list);
252
253 isci_host_build_mde(current_mde, mdl_struct);
254
255 sci_mdl_next_entry(mdl_handle);
256 current_mde = sci_mdl_get_current_entry(mdl_handle);
257 }
258
259 return 0;
260}
261
262
263/** 173/**
264 * isci_host_completion_routine() - This function is the delayed service 174 * isci_host_completion_routine() - This function is the delayed service
265 * routine that calls the sci core library's completion handler. It's 175 * routine that calls the sci core library's completion handler. It's
@@ -523,8 +433,6 @@ int isci_host_init(struct isci_host *isci_host)
523 tasklet_init(&isci_host->completion_tasklet, 433 tasklet_init(&isci_host->completion_tasklet,
524 isci_host_completion_routine, (unsigned long)isci_host); 434 isci_host_completion_routine, (unsigned long)isci_host);
525 435
526 INIT_LIST_HEAD(&(isci_host->mdl_struct_list));
527
528 INIT_LIST_HEAD(&isci_host->requests_to_complete); 436 INIT_LIST_HEAD(&isci_host->requests_to_complete);
529 INIT_LIST_HEAD(&isci_host->requests_to_errorback); 437 INIT_LIST_HEAD(&isci_host->requests_to_errorback);
530 438
@@ -539,8 +447,7 @@ int isci_host_init(struct isci_host *isci_host)
539 return -ENODEV; 447 return -ENODEV;
540 } 448 }
541 449
542 /* populate mdl with dma memory. scu_mdl_allocate_coherent() */ 450 err = scic_controller_mem_init(isci_host->core_controller);
543 err = isci_host_mdl_allocate_coherent(isci_host);
544 if (err) 451 if (err)
545 return err; 452 return err;
546 453
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
index 8372094ef5ad..6e660744d8d4 100644
--- a/drivers/scsi/isci/host.h
+++ b/drivers/scsi/isci/host.h
@@ -75,14 +75,6 @@
75#define ISCI_CAN_QUEUE_VAL 250 /* < SCI_MAX_IO_REQUESTS ? */ 75#define ISCI_CAN_QUEUE_VAL 250 /* < SCI_MAX_IO_REQUESTS ? */
76#define SCIC_CONTROLLER_STOP_TIMEOUT 5000 76#define SCIC_CONTROLLER_STOP_TIMEOUT 5000
77 77
78struct coherent_memory_info {
79 struct list_head node;
80 dma_addr_t dma_handle;
81 void *vaddr;
82 size_t size;
83 struct sci_physical_memory_descriptor *mde;
84};
85
86struct isci_host { 78struct isci_host {
87 struct scic_sds_controller *core_controller; 79 struct scic_sds_controller *core_controller;
88 union scic_oem_parameters oem_parameters; 80 union scic_oem_parameters oem_parameters;
@@ -114,7 +106,6 @@ struct isci_host {
114 wait_queue_head_t eventq; 106 wait_queue_head_t eventq;
115 struct Scsi_Host *shost; 107 struct Scsi_Host *shost;
116 struct tasklet_struct completion_tasklet; 108 struct tasklet_struct completion_tasklet;
117 struct list_head mdl_struct_list;
118 struct list_head requests_to_complete; 109 struct list_head requests_to_complete;
119 struct list_head requests_to_errorback; 110 struct list_head requests_to_errorback;
120 spinlock_t scic_lock; 111 spinlock_t scic_lock;