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 \ core/scic_sds_smp_remote_device.o \ core/scic_sds_remote_node_table.o \ core/scic_sds_unsolicited_frame_control.o \ - core/sci_base_memory_descriptor_list.o \ core/sci_base_state_machine.o \ 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 @@ -/* - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * BSD LICENSE - * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * This file contains the base implementation for the memory descriptor list. - * This is currently comprised of MDL iterator methods. - * - * - */ - -#include "sci_environment.h" -#include "sci_base_memory_descriptor_list.h" - -/* - * ****************************************************************************** - * * P U B L I C M E T H O D S - * ****************************************************************************** */ - -void sci_mdl_first_entry( - struct sci_base_memory_descriptor_list *base_mdl) -{ - base_mdl->next_index = 0; - - /* - * If this MDL is managing another MDL, then recursively rewind that MDL - * object as well. */ - if (base_mdl->next_mdl != NULL) - sci_mdl_first_entry(base_mdl->next_mdl); -} - - -void sci_mdl_next_entry( - struct sci_base_memory_descriptor_list *base_mdl) -{ - /* - * If there is at least one more entry left in the array, then change - * the next pointer to it. */ - if (base_mdl->next_index < base_mdl->length) - base_mdl->next_index++; - else if (base_mdl->next_index == base_mdl->length) { - /* - * This MDL has exhausted it's set of entries. If this MDL is managing - * another MDL, then start iterating through that MDL. */ - if (base_mdl->next_mdl != NULL) - sci_mdl_next_entry(base_mdl->next_mdl); - } -} - - -struct sci_physical_memory_descriptor *sci_mdl_get_current_entry( - struct sci_base_memory_descriptor_list *base_mdl) -{ - if (base_mdl->next_index < base_mdl->length) - return &base_mdl->mde_array[base_mdl->next_index]; - else if (base_mdl->next_index == base_mdl->length) { - /* - * This MDL has exhausted it's set of entries. If this MDL is managing - * another MDL, then return it's current entry. */ - if (base_mdl->next_mdl != NULL) - return sci_mdl_get_current_entry(base_mdl->next_mdl); - } - - return NULL; -} - -/* - * ****************************************************************************** - * * P R O T E C T E D M E T H O D S - * ****************************************************************************** */ - -void sci_base_mdl_construct( - struct sci_base_memory_descriptor_list *mdl, - struct sci_physical_memory_descriptor *mde_array, - u32 mde_array_length, - struct sci_base_memory_descriptor_list *next_mdl) -{ - mdl->length = mde_array_length; - mdl->mde_array = mde_array; - mdl->next_index = 0; - mdl->next_mdl = next_mdl; -} - -/* --------------------------------------------------------------------------- */ - -bool sci_base_mde_is_valid( - struct sci_physical_memory_descriptor *mde, - u32 alignment, - u32 size, - u16 attributes) -{ - /* Only need the lower 32 bits to ensure alignment is met. */ - u32 physical_address = lower_32_bits(mde->physical_address); - - if ( - ((((unsigned long)mde->virtual_address) & (alignment - 1)) != 0) - || ((physical_address & (alignment - 1)) != 0) - || (mde->constant_memory_alignment != alignment) - || (mde->constant_memory_size != size) - || (mde->virtual_address == NULL) - || (mde->constant_memory_attributes != attributes) - ) { - return false; - } - - return true; -} - 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 @@ -/* - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * BSD LICENSE - * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _SCI_BASE_MEMORY_DESCRIPTOR_LIST_H_ -#define _SCI_BASE_MEMORY_DESCRIPTOR_LIST_H_ - -/** - * This file contains the protected interface structures, constants and - * interface methods for the struct sci_base_memory_descriptor_list object. - * - * - */ - - -#include "sci_memory_descriptor_list.h" - - -/** - * struct sci_base_memory_descriptor_list - This structure contains all of the - * fields necessary to implement a simple stack for managing the list of - * available controller indices. - * - * - */ -struct sci_base_memory_descriptor_list { - /** - * This field indicates the length of the memory descriptor entry array. - */ - u32 length; - - /** - * This field is utilized to provide iterator pattern functionality. - * It indicates the index of the next memory descriptor in the iteration. - */ - u32 next_index; - - /** - * This field will point to the list of memory descriptors. - */ - struct sci_physical_memory_descriptor *mde_array; - - /** - * This field simply allows a user to chain memory descriptor lists - * together if desired. This field will be initialized to NULL. - */ - struct sci_base_memory_descriptor_list *next_mdl; - -}; - -/** - * sci_base_mdl_construct() - This method is invoked to construct an memory - * descriptor list. It initializes the fields of the MDL. - * @mdl: This parameter specifies the memory descriptor list to be constructed. - * @mde_array: This parameter specifies the array of memory descriptor entries - * to be managed by this list. - * @mde_array_length: This parameter specifies the size of the array of entries. - * @next_mdl: This parameter specifies a subsequent MDL object to be managed by - * this MDL object. - * - * none. - */ -void sci_base_mdl_construct( - struct sci_base_memory_descriptor_list *mdl, - struct sci_physical_memory_descriptor *mde_array, - u32 mde_array_length, - struct sci_base_memory_descriptor_list *next_mdl); - -/** - * sci_base_mde_construct() - - * - * This macro constructs an memory descriptor entry with the given alignment - * and size - */ -#define sci_base_mde_construct(mde, alignment, size, attributes) \ - { \ - (mde)->constant_memory_alignment = (alignment); \ - (mde)->constant_memory_size = (size); \ - (mde)->constant_memory_attributes = (attributes); \ - } - -/** - * sci_base_mde_is_valid() - This method validates that the memory descriptor - * is correctly filled out by the SCI User - * @mde: This parameter is the mde entry to validate - * @alignment: This parameter specifies the expected alignment of the memory - * for the mde. - * @size: This parameter specifies the memory size expected for the mde its - * value should not have been changed by the SCI User. - * @attributes: This parameter specifies the attributes for the memory - * descriptor provided. - * - * bool This method returns an indication as to whether the supplied MDE is - * valid or not. true The MDE is valid. false The MDE is not valid. - */ -bool sci_base_mde_is_valid( - struct sci_physical_memory_descriptor *mde, - u32 alignment, - u32 size, - u16 attributes); - -#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 @@ -/* - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * BSD LICENSE - * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _SCI_MEMORY_DESCRIPTOR_LIST_H_ -#define _SCI_MEMORY_DESCRIPTOR_LIST_H_ - -/** - * This file contains all of the basic data types utilized by an SCI user or - * implementor. - * - * - */ - - - -struct sci_base_memory_descriptor_list; - -/** - * - * - * SCI_MDE_ATTRIBUTES These constants depict memory attributes for the Memory - * Descriptor Entries (MDEs) contained in the MDL. - */ -#define SCI_MDE_ATTRIBUTE_CACHEABLE 0x0001 -#define SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS 0x0002 - -/** - * struct sci_physical_memory_descriptor - This structure defines a description - * of a memory location for the SCI implementation. - * - * - */ -struct sci_physical_memory_descriptor { - /** - * This field contains the virtual address associated with this descriptor - * element. This field shall be zero when the descriptor is retrieved from - * the SCI implementation. The user shall set this field prior - * sci_controller_start() - */ - void *virtual_address; - - /** - * This field contains the physical address associated with this desciptor - * element. This field shall be zero when the descriptor is retrieved from - * the SCI implementation. The user shall set this field prior - * sci_controller_start() - */ - dma_addr_t physical_address; - - /** - * This field contains the size requirement for this memory descriptor. - * A value of zero for this field indicates the end of the descriptor - * list. The value should be treated as read only for an SCI user. - */ - u32 constant_memory_size; - - /** - * This field contains the alignment requirement for this memory - * descriptor. A value of zero for this field indicates the end of the - * descriptor list. All other values indicate the number of bytes to - * achieve the necessary alignment. The value should be treated as - * read only for an SCI user. - */ - u32 constant_memory_alignment; - - /** - * This field contains an indication regarding the desired memory - * attributes for this memory descriptor entry. - * Notes: - * - If the cacheable attribute is set, the user can allocate - * memory that is backed by cache for better performance. It - * is not required that the memory be backed by cache. - * - If the physically contiguous attribute is set, then the - * entire memory must be physically contiguous across all - * page boundaries. - */ - u16 constant_memory_attributes; - -}; - -/** - * sci_mdl_first_entry() - This method simply rewinds the MDL iterator back to - * the first memory descriptor entry in the list. - * @mdl: This parameter specifies the memory descriptor list that is to be - * rewound. - * - */ -void sci_mdl_first_entry( - struct sci_base_memory_descriptor_list *mdl); - -/** - * sci_mdl_next_entry() - This method simply updates the "current" pointer to - * the next sequential memory descriptor. - * @mdl: This parameter specifies the memory descriptor list for which to - * return the next memory descriptor entry in the list. - * - * none. - */ -void sci_mdl_next_entry( - struct sci_base_memory_descriptor_list *mdl); - -/** - * sci_mdl_get_current_entry() - This method simply returns the current memory - * descriptor entry. - * @mdl: This parameter specifies the memory descriptor list for which to - * return the current memory descriptor entry. - * - * This method returns a pointer to the current physical memory descriptor in - * the MDL. NULL This value is returned if there are no descriptors in the list. - */ -struct sci_physical_memory_descriptor *sci_mdl_get_current_entry( - struct sci_base_memory_descriptor_list *mdl); - - -#endif /* _SCI_MEMORY_DESCRIPTOR_LIST_H_ */ - 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( struct device; struct scic_sds_controller *scic_controller_alloc(struct device *dev); +int scic_controller_mem_init(struct scic_sds_controller *scic); #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 scic->power_control.phys_granted_power = 0; } -#define SCU_REMOTE_NODE_CONTEXT_ALIGNMENT (32) -#define SCU_TASK_CONTEXT_ALIGNMENT (256) -#define SCU_UNSOLICITED_FRAME_ADDRESS_ALIGNMENT (64) -#define SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT (1024) -#define SCU_UNSOLICITED_FRAME_HEADER_ALIGNMENT (64) - -/** - * This method builds the memory descriptor table for this controller. - * @this_controller: This parameter specifies the controller object for which - * to build the memory table. - * - */ -static void scic_sds_controller_build_memory_descriptor_table( - struct scic_sds_controller *this_controller) +int scic_controller_mem_init(struct scic_sds_controller *scic) { - sci_base_mde_construct( - &this_controller->memory_descriptors[SCU_MDE_COMPLETION_QUEUE], - SCU_COMPLETION_RAM_ALIGNMENT, - (sizeof(u32) * this_controller->completion_queue_entries), - (SCI_MDE_ATTRIBUTE_CACHEABLE | SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS) - ); + struct device *dev = scic_to_dev(scic); + dma_addr_t dma_handle; + enum sci_status result; - sci_base_mde_construct( - &this_controller->memory_descriptors[SCU_MDE_REMOTE_NODE_CONTEXT], - SCU_REMOTE_NODE_CONTEXT_ALIGNMENT, - this_controller->remote_node_entries * sizeof(union scu_remote_node_context), - SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS - ); + scic->completion_queue = dmam_alloc_coherent(dev, + scic->completion_queue_entries * sizeof(u32), + &dma_handle, GFP_KERNEL); + if (!scic->completion_queue) + return -ENOMEM; - sci_base_mde_construct( - &this_controller->memory_descriptors[SCU_MDE_TASK_CONTEXT], - SCU_TASK_CONTEXT_ALIGNMENT, - this_controller->task_context_entries * sizeof(struct scu_task_context), - SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS - ); + writel(lower_32_bits(dma_handle), + &scic->smu_registers->completion_queue_lower); + writel(upper_32_bits(dma_handle), + &scic->smu_registers->completion_queue_upper); - /* - * The UF buffer address table size must be programmed to a power - * of 2. Find the first power of 2 that is equal to or greater then - * the number of unsolicited frame buffers to be utilized. */ - scic_sds_unsolicited_frame_control_set_address_table_count( - &this_controller->uf_control - ); + scic->remote_node_context_table = dmam_alloc_coherent(dev, + scic->remote_node_entries * + sizeof(union scu_remote_node_context), + &dma_handle, GFP_KERNEL); + if (!scic->remote_node_context_table) + return -ENOMEM; - sci_base_mde_construct( - &this_controller->memory_descriptors[SCU_MDE_UF_BUFFER], - SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT, - scic_sds_unsolicited_frame_control_get_mde_size(this_controller->uf_control), - SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS - ); -} + writel(lower_32_bits(dma_handle), + &scic->smu_registers->remote_node_context_lower); + writel(upper_32_bits(dma_handle), + &scic->smu_registers->remote_node_context_upper); -/** - * This method validates the driver supplied memory descriptor table. - * @this_controller: - * - * enum sci_status - */ -static enum sci_status scic_sds_controller_validate_memory_descriptor_table( - struct scic_sds_controller *this_controller) -{ - bool mde_list_valid; + scic->task_context_table = dmam_alloc_coherent(dev, + scic->task_context_entries * + sizeof(struct scu_task_context), + &dma_handle, GFP_KERNEL); + if (!scic->task_context_table) + return -ENOMEM; - mde_list_valid = sci_base_mde_is_valid( - &this_controller->memory_descriptors[SCU_MDE_COMPLETION_QUEUE], - SCU_COMPLETION_RAM_ALIGNMENT, - (sizeof(u32) * this_controller->completion_queue_entries), - (SCI_MDE_ATTRIBUTE_CACHEABLE | SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS) - ); + writel(lower_32_bits(dma_handle), + &scic->smu_registers->host_task_table_lower); + writel(upper_32_bits(dma_handle), + &scic->smu_registers->host_task_table_upper); - if (mde_list_valid == false) - return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD; - - mde_list_valid = sci_base_mde_is_valid( - &this_controller->memory_descriptors[SCU_MDE_REMOTE_NODE_CONTEXT], - SCU_REMOTE_NODE_CONTEXT_ALIGNMENT, - this_controller->remote_node_entries * sizeof(union scu_remote_node_context), - SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS - ); - - if (mde_list_valid == false) - return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD; - - mde_list_valid = sci_base_mde_is_valid( - &this_controller->memory_descriptors[SCU_MDE_TASK_CONTEXT], - SCU_TASK_CONTEXT_ALIGNMENT, - this_controller->task_context_entries * sizeof(struct scu_task_context), - SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS - ); - - if (mde_list_valid == false) - return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD; - - mde_list_valid = sci_base_mde_is_valid( - &this_controller->memory_descriptors[SCU_MDE_UF_BUFFER], - SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT, - scic_sds_unsolicited_frame_control_get_mde_size(this_controller->uf_control), - SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS - ); - - if (mde_list_valid == false) - return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD; - - return SCI_SUCCESS; -} - -/** - * This method initializes the controller with the physical memory addresses - * that are used to communicate with the driver. - * @this_controller: - * - */ -static void scic_sds_controller_ram_initialization( - struct scic_sds_controller *this_controller) -{ - struct sci_physical_memory_descriptor *mde; - - /* - * The completion queue is actually placed in cacheable memory - * Therefore it no longer comes out of memory in the MDL. */ - mde = &this_controller->memory_descriptors[SCU_MDE_COMPLETION_QUEUE]; - this_controller->completion_queue = (u32 *)mde->virtual_address; - writel(lower_32_bits(mde->physical_address), \ - &this_controller->smu_registers->completion_queue_lower); - writel(upper_32_bits(mde->physical_address), - &this_controller->smu_registers->completion_queue_upper); - - /* - * Program the location of the Remote Node Context table - * into the SCU. */ - mde = &this_controller->memory_descriptors[SCU_MDE_REMOTE_NODE_CONTEXT]; - this_controller->remote_node_context_table = (union scu_remote_node_context *) - mde->virtual_address; - writel(lower_32_bits(mde->physical_address), - &this_controller->smu_registers->remote_node_context_lower); - writel(upper_32_bits(mde->physical_address), - &this_controller->smu_registers->remote_node_context_upper); - - /* Program the location of the Task Context table into the SCU. */ - mde = &this_controller->memory_descriptors[SCU_MDE_TASK_CONTEXT]; - this_controller->task_context_table = (struct scu_task_context *) - mde->virtual_address; - writel(lower_32_bits(mde->physical_address), - &this_controller->smu_registers->host_task_table_lower); - writel(upper_32_bits(mde->physical_address), - &this_controller->smu_registers->host_task_table_upper); - - mde = &this_controller->memory_descriptors[SCU_MDE_UF_BUFFER]; - scic_sds_unsolicited_frame_control_construct( - &this_controller->uf_control, mde, this_controller - ); + result = scic_sds_unsolicited_frame_control_construct(scic); + if (result) + return result; /* * Inform the silicon as to the location of the UF headers and * address table. */ - writel(lower_32_bits(this_controller->uf_control.headers.physical_address), - &this_controller->scu_registers->sdma.uf_header_base_address_lower); - writel(upper_32_bits(this_controller->uf_control.headers.physical_address), - &this_controller->scu_registers->sdma.uf_header_base_address_upper); + writel(lower_32_bits(scic->uf_control.headers.physical_address), + &scic->scu_registers->sdma.uf_header_base_address_lower); + writel(upper_32_bits(scic->uf_control.headers.physical_address), + &scic->scu_registers->sdma.uf_header_base_address_upper); - writel(lower_32_bits(this_controller->uf_control.address_table.physical_address), - &this_controller->scu_registers->sdma.uf_address_table_lower); - writel(upper_32_bits(this_controller->uf_control.address_table.physical_address), - &this_controller->scu_registers->sdma.uf_address_table_upper); + writel(lower_32_bits(scic->uf_control.address_table.physical_address), + &scic->scu_registers->sdma.uf_address_table_lower); + writel(upper_32_bits(scic->uf_control.address_table.physical_address), + &scic->scu_registers->sdma.uf_address_table_upper); + + return 0; } /** @@ -2525,7 +2420,6 @@ static enum sci_status scic_controller_set_mode( scic->completion_event_entries = SCU_EVENT_COUNT; scic->completion_queue_entries = SCU_COMPLETION_QUEUE_COUNT; - scic_sds_controller_build_memory_descriptor_table(scic); break; case SCI_MODE_SIZE: @@ -2536,7 +2430,6 @@ static enum sci_status scic_controller_set_mode( scic->completion_event_entries = SCU_MIN_EVENTS; scic->completion_queue_entries = SCU_MIN_COMPLETION_QUEUE_ENTRIES; - scic_sds_controller_build_memory_descriptor_table(scic); break; default: @@ -3040,72 +2933,52 @@ static enum sci_status scic_sds_controller_initialized_state_start_handler( u16 index; enum sci_status result; + /* Build the TCi free pool */ + sci_pool_initialize(scic->tci_pool); + for (index = 0; index < scic->task_context_entries; index++) + sci_pool_put(scic->tci_pool, index); + + /* Build the RNi free pool */ + scic_sds_remote_node_table_initialize( + &scic->available_remote_nodes, + scic->remote_node_entries); + /* - * Make sure that the SCI User filled in the memory descriptor - * table correctly + * Before anything else lets make sure we will not be + * interrupted by the hardware. */ - result = scic_sds_controller_validate_memory_descriptor_table(scic); + scic_controller_disable_interrupts(scic); - if (result == SCI_SUCCESS) { - /* - * The memory descriptor list looks good so program the - * hardware - */ - scic_sds_controller_ram_initialization(scic); - } + /* Enable the port task scheduler */ + scic_sds_controller_enable_port_task_scheduler(scic); - if (result == SCI_SUCCESS) { - /* Build the TCi free pool */ - sci_pool_initialize(scic->tci_pool); - for (index = 0; index < scic->task_context_entries; index++) - sci_pool_put(scic->tci_pool, index); + /* Assign all the task entries to scic physical function */ + scic_sds_controller_assign_task_entries(scic); - /* Build the RNi free pool */ - scic_sds_remote_node_table_initialize( - &scic->available_remote_nodes, - scic->remote_node_entries); - } + /* Now initialze the completion queue */ + scic_sds_controller_initialize_completion_queue(scic); - if (result == SCI_SUCCESS) { - /* - * Before anything else lets make sure we will not be - * interrupted by the hardware. - */ - scic_controller_disable_interrupts(scic); - - /* Enable the port task scheduler */ - scic_sds_controller_enable_port_task_scheduler(scic); - - /* Assign all the task entries to scic physical function */ - scic_sds_controller_assign_task_entries(scic); - - /* Now initialze the completion queue */ - scic_sds_controller_initialize_completion_queue(scic); - - /* Initialize the unsolicited frame queue for use */ - scic_sds_controller_initialize_unsolicited_frame_queue(scic); - } + /* Initialize the unsolicited frame queue for use */ + scic_sds_controller_initialize_unsolicited_frame_queue(scic); /* Start all of the ports on this controller */ - for (index = 0; - (index < scic->logical_port_entries) && (result == SCI_SUCCESS); - index++) { + for (index = 0; index < scic->logical_port_entries; index++) { struct scic_sds_port *sci_port = &scic->port_table[index]; result = sci_port->state_handlers->parent.start_handler( &sci_port->parent); + if (result) + return result; } - if (result == SCI_SUCCESS) { - scic_sds_controller_start_next_phy(scic); + scic_sds_controller_start_next_phy(scic); - isci_timer_start(scic->timeout_timer, timeout); + isci_timer_start(scic->timeout_timer, timeout); - sci_base_state_machine_change_state(&scic->state_machine, - SCI_BASE_CONTROLLER_STATE_STARTING); - } + sci_base_state_machine_change_state(&scic->state_machine, + SCI_BASE_CONTROLLER_STATE_STARTING); - return result; + return SCI_SUCCESS; } /* @@ -3658,8 +3531,6 @@ enum sci_status scic_controller_construct(struct scic_sds_controller *scic, &scic->parent, scic_sds_controller_state_table, SCI_BASE_CONTROLLER_STATE_INITIAL); - sci_base_mdl_construct(&scic->mdl, scic->memory_descriptors, - ARRAY_SIZE(scic->memory_descriptors), NULL); sci_base_state_machine_start(&scic->state_machine); 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 @@ #include "sci_pool.h" #include "sci_controller_constants.h" -#include "sci_memory_descriptor_list.h" #include "sci_base_state.h" #include "sci_base_state_machine.h" -#include "sci_base_memory_descriptor_list.h" #include "scic_config_parameters.h" #include "scic_sds_port.h" #include "scic_sds_phy.h" @@ -89,40 +87,6 @@ struct scic_sds_remote_device; struct scic_sds_request; struct scic_sds_controller; -#define SCU_COMPLETION_RAM_ALIGNMENT (64) - -/** - * enum scic_sds_controller_memory_descriptors - - * - * This enumeration depects the types of MDEs that are going to be created for - * the controller object. - */ -enum scic_sds_controller_memory_descriptors { - /** - * Completion queue MDE entry - */ - SCU_MDE_COMPLETION_QUEUE, - - /** - * Remote node context MDE entry - */ - SCU_MDE_REMOTE_NODE_CONTEXT, - - /** - * Task context MDE entry - */ - SCU_MDE_TASK_CONTEXT, - - /** - * Unsolicited frame buffer MDE entrys this is the start of the unsolicited - * frame buffer entries. - */ - SCU_MDE_UF_BUFFER, - - SCU_MAX_MDES -}; - - /** * struct scic_power_control - * @@ -173,13 +137,6 @@ struct scic_sds_controller { */ struct sci_base_object parent; - /** - * This field points to the memory descriptor list associated with this - * controller. The MDL indicates the memory requirements necessary for - * this controller object. - */ - struct sci_base_memory_descriptor_list mdl; - /** * This field contains the information for the base controller state * machine. @@ -284,12 +241,6 @@ struct scic_sds_controller { */ union scu_remote_node_context *remote_node_context_table; - /** - * This field is the array of physical memory requiremets for this controller - * object. - */ - struct sci_physical_memory_descriptor memory_descriptors[SCU_MAX_MDES]; - /** * This field is a pointer to the completion queue. This memory is * written to by the hardware and read by the software. 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 @@ -67,26 +67,6 @@ #include "sci_util.h" #include "sci_environment.h" -/** - * The UF buffer address table size must be programmed to a power of 2. Find - * the first power of 2 that is equal to or greater then the number of - * unsolicited frame buffers to be utilized. - * @uf_control: This parameter specifies the UF control object for which to - * update the address table count. - * - */ -void scic_sds_unsolicited_frame_control_set_address_table_count( - struct scic_sds_unsolicited_frame_control *uf_control) -{ - uf_control->address_table.count = SCU_MIN_UF_TABLE_ENTRIES; - while ( - (uf_control->address_table.count < uf_control->buffers.count) - && (uf_control->address_table.count < SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES) - ) { - uf_control->address_table.count <<= 1; - } -} - /** * This method will program the unsolicited frames (UFs) into the UF address * table and construct the UF frame structure being modeled in the core. It @@ -155,23 +135,9 @@ static void scic_sds_unsolicited_frame_control_construct_frames( } } -/** - * This method constructs the various members of the unsolicted frame control - * object (buffers, headers, address, table, etc). - * @uf_control: This parameter specifies the unsolicited frame control object - * to construct. - * @mde: This parameter specifies the memory descriptor from which to derive - * all of the address information needed to get the unsolicited frame - * functionality working. - * @controller: This parameter specifies the controller object associated with - * the uf_control being constructed. - * - */ -void scic_sds_unsolicited_frame_control_construct( - struct scic_sds_unsolicited_frame_control *uf_control, - struct sci_physical_memory_descriptor *mde, - struct scic_sds_controller *controller) +int scic_sds_unsolicited_frame_control_construct(struct scic_sds_controller *scic) { + struct scic_sds_unsolicited_frame_control *uf_control = &scic->uf_control; u32 unused_uf_header_entries; u32 used_uf_header_entries; u32 used_uf_buffer_bytes; @@ -179,10 +145,22 @@ void scic_sds_unsolicited_frame_control_construct( u32 used_uf_header_bytes; dma_addr_t uf_buffer_phys_address; void *uf_buffer_virt_address; + size_t size; + + /* + * The UF buffer address table size must be programmed to a power + * of 2. Find the first power of 2 that is equal to or greater then + * the number of unsolicited frame buffers to be utilized. + */ + uf_control->address_table.count = SCU_MIN_UF_TABLE_ENTRIES; + while (uf_control->address_table.count < uf_control->buffers.count && + uf_control->address_table.count < SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES) + uf_control->address_table.count <<= 1; /* * Prepare all of the memory sizes for the UF headers, UF address - * table, and UF buffers themselves. */ + * table, and UF buffers themselves. + */ used_uf_buffer_bytes = uf_control->buffers.count * SCU_UNSOLICITED_FRAME_BUFFER_SIZE; unused_uf_header_entries = uf_control->address_table.count @@ -193,13 +171,19 @@ void scic_sds_unsolicited_frame_control_construct( used_uf_header_bytes = used_uf_header_entries * sizeof(struct scu_unsolicited_frame_header); + size = used_uf_buffer_bytes + used_uf_header_bytes + + uf_control->address_table.count * sizeof(dma_addr_t); + + /* * The Unsolicited Frame buffers are set at the start of the UF * memory descriptor entry. The headers and address table will be * placed after the buffers. */ - uf_buffer_phys_address = mde->physical_address; - uf_buffer_virt_address = mde->virtual_address; + uf_buffer_virt_address = dmam_alloc_coherent(scic_to_dev(scic), size, + &uf_buffer_phys_address, GFP_KERNEL); + if (!uf_buffer_virt_address) + return -ENOMEM; /* * Program the location of the UF header table into the SCU. @@ -254,10 +238,12 @@ void scic_sds_unsolicited_frame_control_construct( scic_sds_unsolicited_frame_control_construct_frames( uf_control, uf_buffer_phys_address, - mde->virtual_address, + uf_buffer_virt_address, unused_uf_header_entries, used_uf_header_entries ); + + return 0; } /** 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 @@ #define _SCIC_SDS_UNSOLICITED_FRAME_CONTROL_H_ #include "scu_unsolicited_frame.h" -#include "sci_memory_descriptor_list.h" #include "scu_constants.h" #include "sci_status.h" @@ -248,14 +247,9 @@ struct scic_sds_unsolicited_frame_control { }; -void scic_sds_unsolicited_frame_control_set_address_table_count( - struct scic_sds_unsolicited_frame_control *uf_control); - struct scic_sds_controller; -void scic_sds_unsolicited_frame_control_construct( - struct scic_sds_unsolicited_frame_control *uf_control, - struct sci_physical_memory_descriptor *mde, - struct scic_sds_controller *this_controller); + +int scic_sds_unsolicited_frame_control_construct(struct scic_sds_controller *scic); enum sci_status scic_sds_unsolicited_frame_control_get_header( struct scic_sds_unsolicited_frame_control *uf_control, @@ -271,16 +265,4 @@ bool scic_sds_unsolicited_frame_control_release_frame( struct scic_sds_unsolicited_frame_control *uf_control, u32 frame_index); -/** - * scic_sds_unsolicited_frame_control_get_mde_size() - - * - * This macro simply calculates the size of the memory descriptor entry that - * relates to unsolicited frames and the surrounding silicon memory required to - * utilize it. - */ -#define scic_sds_unsolicited_frame_control_get_mde_size(uf_control) \ - (((uf_control).buffers.count * SCU_UNSOLICITED_FRAME_BUFFER_SIZE) \ - + ((uf_control).address_table.count * sizeof(dma_addr_t)) \ - + ((uf_control).buffers.count * sizeof(struct scu_unsolicited_frame_header))) - #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 wake_up(&ihost->eventq); } -static struct coherent_memory_info *isci_host_alloc_mdl_struct( - struct isci_host *isci_host, - u32 size) -{ - struct coherent_memory_info *mdl_struct; - void *uncached_address = NULL; - - - mdl_struct = devm_kzalloc(&isci_host->pdev->dev, - sizeof(*mdl_struct), - GFP_KERNEL); - if (!mdl_struct) - return NULL; - - INIT_LIST_HEAD(&mdl_struct->node); - - uncached_address = dmam_alloc_coherent(&isci_host->pdev->dev, - size, - &mdl_struct->dma_handle, - GFP_KERNEL); - if (!uncached_address) - return NULL; - - /* memset the whole memory area. */ - memset((char *)uncached_address, 0, size); - mdl_struct->vaddr = uncached_address; - mdl_struct->size = (size_t)size; - - return mdl_struct; -} - -static void isci_host_build_mde( - struct sci_physical_memory_descriptor *mde_struct, - struct coherent_memory_info *mdl_struct) -{ - unsigned long address = 0; - dma_addr_t dma_addr = 0; - - address = (unsigned long)mdl_struct->vaddr; - dma_addr = mdl_struct->dma_handle; - - /* to satisfy the alignment. */ - if ((address % mde_struct->constant_memory_alignment) != 0) { - int align_offset - = (mde_struct->constant_memory_alignment - - (address % mde_struct->constant_memory_alignment)); - address += align_offset; - dma_addr += align_offset; - } - - mde_struct->virtual_address = (void *)address; - mde_struct->physical_address = dma_addr; - mdl_struct->mde = mde_struct; -} - -static int isci_host_mdl_allocate_coherent( - struct isci_host *isci_host) -{ - struct sci_physical_memory_descriptor *current_mde; - struct coherent_memory_info *mdl_struct; - u32 size = 0; - - struct sci_base_memory_descriptor_list *mdl_handle = - &isci_host->core_controller->mdl; - - sci_mdl_first_entry(mdl_handle); - - current_mde = sci_mdl_get_current_entry(mdl_handle); - - while (current_mde != NULL) { - - size = (current_mde->constant_memory_size - + current_mde->constant_memory_alignment); - - mdl_struct = isci_host_alloc_mdl_struct(isci_host, size); - if (!mdl_struct) - return -ENOMEM; - - list_add_tail(&mdl_struct->node, &isci_host->mdl_struct_list); - - isci_host_build_mde(current_mde, mdl_struct); - - sci_mdl_next_entry(mdl_handle); - current_mde = sci_mdl_get_current_entry(mdl_handle); - } - - return 0; -} - - /** * isci_host_completion_routine() - This function is the delayed service * 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) tasklet_init(&isci_host->completion_tasklet, isci_host_completion_routine, (unsigned long)isci_host); - INIT_LIST_HEAD(&(isci_host->mdl_struct_list)); - INIT_LIST_HEAD(&isci_host->requests_to_complete); INIT_LIST_HEAD(&isci_host->requests_to_errorback); @@ -539,8 +447,7 @@ int isci_host_init(struct isci_host *isci_host) return -ENODEV; } - /* populate mdl with dma memory. scu_mdl_allocate_coherent() */ - err = isci_host_mdl_allocate_coherent(isci_host); + err = scic_controller_mem_init(isci_host->core_controller); if (err) return err; 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 @@ #define ISCI_CAN_QUEUE_VAL 250 /* < SCI_MAX_IO_REQUESTS ? */ #define SCIC_CONTROLLER_STOP_TIMEOUT 5000 -struct coherent_memory_info { - struct list_head node; - dma_addr_t dma_handle; - void *vaddr; - size_t size; - struct sci_physical_memory_descriptor *mde; -}; - struct isci_host { struct scic_sds_controller *core_controller; union scic_oem_parameters oem_parameters; @@ -114,7 +106,6 @@ struct isci_host { wait_queue_head_t eventq; struct Scsi_Host *shost; struct tasklet_struct completion_tasklet; - struct list_head mdl_struct_list; struct list_head requests_to_complete; struct list_head requests_to_errorback; spinlock_t scic_lock;