aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/host.c
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 /drivers/scsi/isci/host.c
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>
Diffstat (limited to 'drivers/scsi/isci/host.c')
-rw-r--r--drivers/scsi/isci/host.c95
1 files changed, 1 insertions, 94 deletions
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