lkml.org 
[lkml]   [2012]   [Jul]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH V3 2/4] [SCSI] drivers/scsi/ufs: Separate PCI code into glue driver
    Date
    This patch separates PCI code from ufshcd.c and makes it as a
    core driver module and adds a new file ufshcd-pci.c as PCI glue
    driver.

    Reviewed-by: Namjae Jeon <linkinjeon@gmail.com>
    Signed-off-by: Vinayak Holikatti <vinholikatti@gmail.com>
    Signed-off-by: Santosh Yaraganavi <santoshsy@gmail.com>
    ---
    drivers/scsi/ufs/Kconfig | 26 ++-
    drivers/scsi/ufs/Makefile | 1 +
    drivers/scsi/ufs/ufshcd-pci.c | 228 ++++++++++++++++++++++++++
    drivers/scsi/ufs/ufshcd.c | 329 ++------------------------------------
    drivers/scsi/ufs/ufshcd.h | 206 ++++++++++++++++++++++++
    drivers/scsi/ufs/ufshcd_common.h | 53 ++++++
    6 files changed, 521 insertions(+), 322 deletions(-)
    create mode 100644 drivers/scsi/ufs/ufshcd-pci.c
    create mode 100644 drivers/scsi/ufs/ufshcd.h
    create mode 100644 drivers/scsi/ufs/ufshcd_common.h

    diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
    index 8f27f9d..265a8c8 100644
    --- a/drivers/scsi/ufs/Kconfig
    +++ b/drivers/scsi/ufs/Kconfig
    @@ -43,7 +43,27 @@
    # USA.

    config SCSI_UFSHCD
    - tristate "Universal Flash Storage host controller driver"
    - depends on PCI && SCSI
    + tristate "Universal Flash Storage Controller Driver Core"
    + depends on SCSI
    ---help---
    - This is a generic driver which supports PCIe UFS Host controllers.
    + This selects the support for UFS devices in Linux, say Y and make
    + sure that you know the name of your UFS host adapter (the card
    + inside your computer that "speaks" the UFS protocol, also
    + called UFS Host Controller), because you will be asked for it.
    + The module will be called ufshcd.
    +
    + To compile this driver as a module, choose M here and read
    + <file:Documentation/scsi/ufs.txt>.
    + However, do not compile this as a module if your root file system
    + (the one containing the directory /) is located on a UFS device.
    +
    +config SCSI_UFSHCD_PCI
    + tristate "PCI bus based UFS Controller support"
    + depends on SCSI_UFSHCD && PCI
    + ---help---
    + This selects the PCI UFS Host Controller Interface.
    + Most controllers found today are PCI devices.
    +
    + If you have a controller with this interface, say Y or M here.
    +
    + If unsure, say N.
    diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
    index adf7895..9eda0df 100644
    --- a/drivers/scsi/ufs/Makefile
    +++ b/drivers/scsi/ufs/Makefile
    @@ -1,2 +1,3 @@
    # UFSHCD makefile
    obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o
    +obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
    diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c
    new file mode 100644
    index 0000000..d078744
    --- /dev/null
    +++ b/drivers/scsi/ufs/ufshcd-pci.c
    @@ -0,0 +1,228 @@
    +/*
    + * Universal Flash Storage Host controller driver
    + *
    + * This code is based on drivers/scsi/ufs/ufshcd-pci.c
    + * Copyright (C) 2011-2012 Samsung India Software Operations
    + *
    + * Santosh Yaraganavi <santosh.sy@samsung.com>
    + * Vinayak Holikatti <h.vinayak@samsung.com>
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * as published by the Free Software Foundation; either version 2
    + * of the License, or (at your option) any later version.
    + *
    + * 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.
    + *
    + * NO WARRANTY
    + * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
    + * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
    + * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
    + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
    + * solely responsible for determining the appropriateness of using and
    + * distributing the Program and assumes all risks associated with its
    + * exercise of rights under this Agreement, including but not limited to
    + * the risks and costs of program errors, damage to or loss of data,
    + * programs or equipment, and unavailability or interruption of operations.
    +
    + * DISCLAIMER OF LIABILITY
    + * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
    + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    + * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
    + * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
    +
    + * 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 Street, Fifth Floor, Boston, MA 02110-1301,
    + * USA.
    + */
    +
    +#include "ufshcd.h"
    +#include "ufshcd_common.h"
    +#include <linux/pci.h>
    +
    +#ifdef CONFIG_PM
    +/**
    + * ufshcd_pci_suspend - suspend power management function
    + * @pdev: pointer to PCI device handle
    + * @state: power state
    + *
    + * Returns -ENOSYS
    + */
    +static int ufshcd_pci_suspend(struct pci_dev *pdev, pm_message_t state)
    +{
    + /*
    + * TODO:
    + * 1. Block SCSI requests from SCSI midlayer
    + * 2. Change the internal driver state to non operational
    + * 3. Set UTRLRSR and UTMRLRSR bits to zero
    + * 4. Wait until outstanding commands are completed
    + * 5. Set HCE to zero to send the UFS host controller to reset state
    + */
    +
    + return -ENOSYS;
    +}
    +
    +/**
    + * ufshcd_pci_resume - resume power management function
    + * @pdev: pointer to PCI device handle
    + *
    + * Returns -ENOSYS
    + */
    +static int ufshcd_pci_resume(struct pci_dev *pdev)
    +{
    + /*
    + * TODO:
    + * 1. Set HCE to 1, to start the UFS host controller
    + * initialization process
    + * 2. Set UTRLRSR and UTMRLRSR bits to 1
    + * 3. Change the internal driver state to operational
    + * 4. Unblock SCSI requests from SCSI midlayer
    + */
    +
    + return -ENOSYS;
    +}
    +#endif /* CONFIG_PM */
    +
    +/**
    + * ufshcd_pci_shutdown - main function to put the controller in reset state
    + * @pdev: pointer to PCI device handle
    + */
    +static void ufshcd_pci_shutdown(struct pci_dev *pdev)
    +{
    + ufshcd_hba_stop((struct ufs_hba *)pci_get_drvdata(pdev));
    +}
    +
    +/**
    + * ufshcd_pci_remove - de-allocate PCI/SCSI host and host memory space
    + * data structure memory
    + * @pdev - pointer to PCI handle
    + */
    +static void ufshcd_pci_remove(struct pci_dev *pdev)
    +{
    + struct ufs_hba *hba = pci_get_drvdata(pdev);
    +
    + free_irq(pdev->irq, hba);
    + ufshcd_remove(hba);
    + pci_release_regions(pdev);
    + pci_set_drvdata(pdev, NULL);
    + pci_clear_master(pdev);
    + pci_disable_device(pdev);
    +}
    +
    +/**
    + * ufshcd_set_dma_mask - Set dma mask based on the controller
    + * addressing capability
    + * @pdev: PCI device structure
    + *
    + * Returns 0 for success, non-zero for failure
    + */
    +static int ufshcd_set_dma_mask(struct pci_dev *pdev)
    +{
    + int err;
    +
    + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
    + && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
    + return 0;
    + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
    + if (!err)
    + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
    + return err;
    +}
    +
    +/**
    + * ufshcd_pci_probe - probe routine of the driver
    + * @pdev: pointer to PCI device handle
    + * @id: PCI device id
    + *
    + * Returns 0 on success, non-zero value on failure
    + */
    +static int __devinit
    +ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
    +{
    + struct ufs_hba *hba;
    + void __iomem *mmio_base;
    + int err;
    +
    + err = pci_enable_device(pdev);
    + if (err) {
    + dev_err(&pdev->dev, "pci_enable_device failed\n");
    + goto out_error;
    + }
    +
    + pci_set_master(pdev);
    +
    +
    + err = pci_request_regions(pdev, UFSHCD);
    + if (err < 0) {
    + dev_err(&pdev->dev, "request regions failed\n");
    + goto out_disable;
    + }
    +
    + mmio_base = pci_ioremap_bar(pdev, 0);
    + if (!mmio_base) {
    + dev_err(&pdev->dev, "memory map failed\n");
    + err = -ENOMEM;
    + goto out_release_regions;
    + }
    +
    + err = ufshcd_set_dma_mask(pdev);
    + if (err) {
    + dev_err(&pdev->dev, "set dma mask failed\n");
    + goto out_iounmap;
    + }
    +
    + err = ufshcd_init(&pdev->dev, &hba, mmio_base, pdev->irq);
    + if (err) {
    + dev_err(&pdev->dev, "%s:%d %sInitialization failed\n",
    + __FILE__, __LINE__, __func__);
    + goto out_iounmap;
    + }
    +
    + pci_set_drvdata(pdev, hba);
    +
    + return 0;
    +
    +out_iounmap:
    + iounmap(mmio_base);
    +out_release_regions:
    + pci_release_regions(pdev);
    +out_disable:
    + pci_clear_master(pdev);
    + pci_disable_device(pdev);
    +out_error:
    + return err;
    +}
    +
    +static DEFINE_PCI_DEVICE_TABLE(ufshcd_pci_tbl) = {
    + { PCI_VENDOR_ID_SAMSUNG, 0xC00C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
    + { } /* terminate list */
    +};
    +
    +MODULE_DEVICE_TABLE(pci, ufshcd_pci_tbl);
    +
    +static struct pci_driver ufshcd_pci_driver = {
    + .name = UFSHCD,
    + .id_table = ufshcd_pci_tbl,
    + .probe = ufshcd_pci_probe,
    + .remove = __devexit_p(ufshcd_pci_remove),
    + .shutdown = ufshcd_pci_shutdown,
    +#ifdef CONFIG_PM
    + .suspend = ufshcd_pci_suspend,
    + .resume = ufshcd_pci_resume,
    +#endif
    +};
    +
    +module_pci_driver(ufshcd_pci_driver);
    +
    +MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");
    +MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>");
    +MODULE_DESCRIPTION("PCI based UFS host controller driver");
    +MODULE_LICENSE("GPL");
    +MODULE_VERSION(UFSHCD_DRIVER_VERSION);
    diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
    index c7b8f4b..dfc3e85 100644
    --- a/drivers/scsi/ufs/ufshcd.c
    +++ b/drivers/scsi/ufs/ufshcd.c
    @@ -43,35 +43,7 @@
    * USA.
    */

    -#include <linux/module.h>
    -#include <linux/kernel.h>
    -#include <linux/init.h>
    -#include <linux/pci.h>
    -#include <linux/interrupt.h>
    -#include <linux/io.h>
    -#include <linux/delay.h>
    -#include <linux/slab.h>
    -#include <linux/spinlock.h>
    -#include <linux/workqueue.h>
    -#include <linux/errno.h>
    -#include <linux/types.h>
    -#include <linux/wait.h>
    -#include <linux/bitops.h>
    -
    -#include <asm/irq.h>
    -#include <asm/byteorder.h>
    -#include <scsi/scsi.h>
    -#include <scsi/scsi_cmnd.h>
    -#include <scsi/scsi_host.h>
    -#include <scsi/scsi_tcq.h>
    -#include <scsi/scsi_dbg.h>
    -#include <scsi/scsi_eh.h>
    -
    -#include "ufs.h"
    -#include "ufshci.h"
    -
    -#define UFSHCD "ufshcd"
    -#define UFSHCD_DRIVER_VERSION "0.1"
    +#include "ufshcd.h"

    enum {
    UFSHCD_MAX_CHANNEL = 0,
    @@ -102,121 +74,6 @@ enum {
    };

    /**
    - * struct uic_command - UIC command structure
    - * @command: UIC command
    - * @argument1: UIC command argument 1
    - * @argument2: UIC command argument 2
    - * @argument3: UIC command argument 3
    - * @cmd_active: Indicate if UIC command is outstanding
    - * @result: UIC command result
    - */
    -struct uic_command {
    - u32 command;
    - u32 argument1;
    - u32 argument2;
    - u32 argument3;
    - int cmd_active;
    - int result;
    -};
    -
    -/**
    - * struct ufs_hba - per adapter private structure
    - * @mmio_base: UFSHCI base register address
    - * @ucdl_base_addr: UFS Command Descriptor base address
    - * @utrdl_base_addr: UTP Transfer Request Descriptor base address
    - * @utmrdl_base_addr: UTP Task Management Descriptor base address
    - * @ucdl_dma_addr: UFS Command Descriptor DMA address
    - * @utrdl_dma_addr: UTRDL DMA address
    - * @utmrdl_dma_addr: UTMRDL DMA address
    - * @host: Scsi_Host instance of the driver
    - * @dev: device handle
    - * @lrb: local reference block
    - * @outstanding_tasks: Bits representing outstanding task requests
    - * @outstanding_reqs: Bits representing outstanding transfer requests
    - * @capabilities: UFS Controller Capabilities
    - * @nutrs: Transfer Request Queue depth supported by controller
    - * @nutmrs: Task Management Queue depth supported by controller
    - * @active_uic_cmd: handle of active UIC command
    - * @ufshcd_tm_wait_queue: wait queue for task management
    - * @tm_condition: condition variable for task management
    - * @ufshcd_state: UFSHCD states
    - * @int_enable_mask: Interrupt Mask Bits
    - * @uic_workq: Work queue for UIC completion handling
    - * @feh_workq: Work queue for fatal controller error handling
    - * @errors: HBA errors
    - */
    -struct ufs_hba {
    - void __iomem *mmio_base;
    -
    - /* Virtual memory reference */
    - struct utp_transfer_cmd_desc *ucdl_base_addr;
    - struct utp_transfer_req_desc *utrdl_base_addr;
    - struct utp_task_req_desc *utmrdl_base_addr;
    -
    - /* DMA memory reference */
    - dma_addr_t ucdl_dma_addr;
    - dma_addr_t utrdl_dma_addr;
    - dma_addr_t utmrdl_dma_addr;
    -
    - struct Scsi_Host *host;
    - struct device *dev;
    -
    - struct ufshcd_lrb *lrb;
    -
    - unsigned long outstanding_tasks;
    - unsigned long outstanding_reqs;
    -
    - u32 capabilities;
    - int nutrs;
    - int nutmrs;
    - u32 ufs_version;
    -
    - struct uic_command active_uic_cmd;
    - wait_queue_head_t ufshcd_tm_wait_queue;
    - unsigned long tm_condition;
    -
    - u32 ufshcd_state;
    - u32 int_enable_mask;
    -
    - /* Work Queues */
    - struct work_struct uic_workq;
    - struct work_struct feh_workq;
    -
    - /* HBA Errors */
    - u32 errors;
    -};
    -
    -/**
    - * struct ufshcd_lrb - local reference block
    - * @utr_descriptor_ptr: UTRD address of the command
    - * @ucd_cmd_ptr: UCD address of the command
    - * @ucd_rsp_ptr: Response UPIU address for this command
    - * @ucd_prdt_ptr: PRDT address of the command
    - * @cmd: pointer to SCSI command
    - * @sense_buffer: pointer to sense buffer address of the SCSI command
    - * @sense_bufflen: Length of the sense buffer
    - * @scsi_status: SCSI status of the command
    - * @command_type: SCSI, UFS, Query.
    - * @task_tag: Task tag of the command
    - * @lun: LUN of the command
    - */
    -struct ufshcd_lrb {
    - struct utp_transfer_req_desc *utr_descriptor_ptr;
    - struct utp_upiu_cmd *ucd_cmd_ptr;
    - struct utp_upiu_rsp *ucd_rsp_ptr;
    - struct ufshcd_sg_entry *ucd_prdt_ptr;
    -
    - struct scsi_cmnd *cmd;
    - u8 *sense_buffer;
    - unsigned int sense_bufflen;
    - int scsi_status;
    -
    - int command_type;
    - int task_tag;
    - unsigned int lun;
    -};
    -
    -/**
    * ufshcd_get_ufs_version - Get the UFS version supported by the HBA
    * @hba - Pointer to adapter instance
    *
    @@ -429,15 +286,6 @@ static void ufshcd_enable_run_stop_reg(struct ufs_hba *hba)
    }

    /**
    - * ufshcd_hba_stop - Send controller to reset state
    - * @hba: per adapter instance
    - */
    -static inline void ufshcd_hba_stop(struct ufs_hba *hba)
    -{
    - writel(CONTROLLER_DISABLE, (hba->mmio_base + REG_CONTROLLER_ENABLE));
    -}
    -
    -/**
    * ufshcd_hba_start - Start controller initialization sequence
    * @hba: per adapter instance
    */
    @@ -1685,57 +1533,6 @@ static struct scsi_host_template ufshcd_driver_template = {
    .can_queue = UFSHCD_CAN_QUEUE,
    };

    -/**
    - * ufshcd_pci_shutdown - main function to put the controller in reset state
    - * @pdev: pointer to PCI device handle
    - */
    -static void ufshcd_pci_shutdown(struct pci_dev *pdev)
    -{
    - ufshcd_hba_stop((struct ufs_hba *)pci_get_drvdata(pdev));
    -}
    -
    -#ifdef CONFIG_PM
    -/**
    - * ufshcd_pci_suspend - suspend power management function
    - * @pdev: pointer to PCI device handle
    - * @state: power state
    - *
    - * Returns -ENOSYS
    - */
    -static int ufshcd_pci_suspend(struct pci_dev *pdev, pm_message_t state)
    -{
    - /*
    - * TODO:
    - * 1. Block SCSI requests from SCSI midlayer
    - * 2. Change the internal driver state to non operational
    - * 3. Set UTRLRSR and UTMRLRSR bits to zero
    - * 4. Wait until outstanding commands are completed
    - * 5. Set HCE to zero to send the UFS host controller to reset state
    - */
    -
    - return -ENOSYS;
    -}
    -
    -/**
    - * ufshcd_pci_resume - resume power management function
    - * @pdev: pointer to PCI device handle
    - *
    - * Returns -ENOSYS
    - */
    -static int ufshcd_pci_resume(struct pci_dev *pdev)
    -{
    - /*
    - * TODO:
    - * 1. Set HCE to 1, to start the UFS host controller
    - * initialization process
    - * 2. Set UTRLRSR and UTMRLRSR bits to 1
    - * 3. Change the internal driver state to operational
    - * 4. Unblock SCSI requests from SCSI midlayer
    - */
    -
    - return -ENOSYS;
    -}
    -#endif /* CONFIG_PM */

    /**
    * ufshcd_hba_free - free allocated memory for
    @@ -1767,43 +1564,6 @@ void ufshcd_remove(struct ufs_hba *hba)
    EXPORT_SYMBOL(ufshcd_remove);

    /**
    - * ufshcd_pci_remove - de-allocate PCI/SCSI host and host memory space
    - * data structure memory
    - * @pdev - pointer to PCI handle
    - */
    -static void ufshcd_pci_remove(struct pci_dev *pdev)
    -{
    - struct ufs_hba *hba = pci_get_drvdata(pdev);
    -
    - free_irq(pdev->irq, hba);
    - ufshcd_remove(hba);
    - pci_release_regions(pdev);
    - pci_set_drvdata(pdev, NULL);
    - pci_clear_master(pdev);
    - pci_disable_device(pdev);
    -}
    -
    -/**
    - * ufshcd_set_dma_mask - Set dma mask based on the controller
    - * addressing capability
    - * @pdev: PCI device structure
    - *
    - * Returns 0 for success, non-zero for failure
    - */
    -static int ufshcd_set_dma_mask(struct pci_dev *pdev)
    -{
    - int err;
    -
    - if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
    - && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)))
    - return 0;
    - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
    - if (!err)
    - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
    - return err;
    -}
    -
    -/**
    * ufshcd_init - Driver initialization routine
    * @dev: pointer to device handle
    * @hba_handle: driver private handle
    @@ -1911,92 +1671,23 @@ out_error:
    }
    EXPORT_SYMBOL(ufshcd_init);

    -/**
    - * ufshcd_pci_probe - probe routine of the driver
    - * @pdev: pointer to PCI device handle
    - * @id: PCI device id
    - *
    - * Returns 0 on success, non-zero value on failure
    - */
    -static int __devinit
    -ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
    +static int __init ufshcd_module_init(void)
    {
    - struct ufs_hba *hba;
    - void __iomem *mmio_base;
    - int err;
    -
    - err = pci_enable_device(pdev);
    - if (err) {
    - dev_err(&pdev->dev, "pci_enable_device failed\n");
    - goto out_error;
    - }
    -
    - pci_set_master(pdev);
    -
    - err = pci_request_regions(pdev, UFSHCD);
    - if (err < 0) {
    - dev_err(&pdev->dev, "request regions failed\n");
    - goto out_disable;
    - }
    -
    - mmio_base = pci_ioremap_bar(pdev, 0);
    - if (!mmio_base) {
    - dev_err(&pdev->dev, "memory map failed\n");
    - err = -ENOMEM;
    - goto out_release_regions;
    - }
    -
    - err = ufshcd_set_dma_mask(pdev);
    - if (err) {
    - dev_err(&pdev->dev, "set dma mask failed\n");
    - goto out_iounmap;
    - }
    -
    - err = ufshcd_init(&pdev->dev, &hba, mmio_base, pdev->irq);
    - if (err) {
    - dev_err(&pdev->dev, "%s:%d %sInitialization failed\n",
    - __FILE__, __LINE__, __func__);
    - goto out_iounmap;
    - }
    -
    - pci_set_drvdata(pdev, hba);
    -
    + pr_info("UFS Host Driver Core loaded\n");
    return 0;
    -
    -out_iounmap:
    - iounmap(mmio_base);
    -out_release_regions:
    - pci_release_regions(pdev);
    -out_disable:
    - pci_clear_master(pdev);
    - pci_disable_device(pdev);
    -out_error:
    - return err;
    }

    -static DEFINE_PCI_DEVICE_TABLE(ufshcd_pci_tbl) = {
    - { PCI_VENDOR_ID_SAMSUNG, 0xC00C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
    - { } /* terminate list */
    -};
    +static void __exit ufshcd_module_exit(void)
    +{
    + pr_info("UFS Host Driver Core unloaded\n");
    +}

    -MODULE_DEVICE_TABLE(pci, ufshcd_pci_tbl);
    -
    -static struct pci_driver ufshcd_pci_driver = {
    - .name = UFSHCD,
    - .id_table = ufshcd_pci_tbl,
    - .probe = ufshcd_pci_probe,
    - .remove = __devexit_p(ufshcd_pci_remove),
    - .shutdown = ufshcd_pci_shutdown,
    -#ifdef CONFIG_PM
    - .suspend = ufshcd_pci_suspend,
    - .resume = ufshcd_pci_resume,
    -#endif
    -};
    +module_init(ufshcd_module_init);
    +module_exit(ufshcd_module_exit);

    -module_pci_driver(ufshcd_pci_driver);

    MODULE_AUTHOR("Santosh Yaragnavi <santosh.sy@samsung.com>");
    MODULE_AUTHOR("Vinayak Holikatti <h.vinayak@samsung.com>");
    -MODULE_DESCRIPTION("Generic UFS host controller driver");
    +MODULE_DESCRIPTION("Generic Core UFS host controller driver");
    MODULE_LICENSE("GPL");
    MODULE_VERSION(UFSHCD_DRIVER_VERSION);
    diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
    new file mode 100644
    index 0000000..40cb1f7
    --- /dev/null
    +++ b/drivers/scsi/ufs/ufshcd.h
    @@ -0,0 +1,206 @@
    +/*
    + * Universal Flash Storage Host controller driver
    + *
    + * This code is based on drivers/scsi/ufs/ufshcd.h
    + * Copyright (C) 2011-2012 Samsung India Software Operations
    + *
    + * Santosh Yaraganavi <santosh.sy@samsung.com>
    + * Vinayak Holikatti <h.vinayak@samsung.com>
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * as published by the Free Software Foundation; either version 2
    + * of the License, or (at your option) any later version.
    + *
    + * 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.
    + *
    + * NO WARRANTY
    + * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
    + * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
    + * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
    + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
    + * solely responsible for determining the appropriateness of using and
    + * distributing the Program and assumes all risks associated with its
    + * exercise of rights under this Agreement, including but not limited to
    + * the risks and costs of program errors, damage to or loss of data,
    + * programs or equipment, and unavailability or interruption of operations.
    +
    + * DISCLAIMER OF LIABILITY
    + * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
    + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    + * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
    + * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
    +
    + * 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 Street, Fifth Floor, Boston, MA 02110-1301,
    + * USA.
    + */
    +
    +#ifndef _UFSHCD_H
    +#define _UFSHCD_H
    +
    +#include <linux/module.h>
    +#include <linux/kernel.h>
    +#include <linux/init.h>
    +#include <linux/interrupt.h>
    +#include <linux/io.h>
    +#include <linux/delay.h>
    +#include <linux/slab.h>
    +#include <linux/spinlock.h>
    +#include <linux/workqueue.h>
    +#include <linux/errno.h>
    +#include <linux/types.h>
    +#include <linux/wait.h>
    +#include <linux/bitops.h>
    +#include <linux/pm_runtime.h>
    +#include <linux/clk.h>
    +
    +#include <asm/irq.h>
    +#include <asm/byteorder.h>
    +#include <scsi/scsi.h>
    +#include <scsi/scsi_cmnd.h>
    +#include <scsi/scsi_host.h>
    +#include <scsi/scsi_tcq.h>
    +#include <scsi/scsi_dbg.h>
    +#include <scsi/scsi_eh.h>
    +
    +#include "ufs.h"
    +#include "ufshci.h"
    +
    +#define UFSHCD "ufshcd"
    +#define UFSHCD_DRIVER_VERSION "0.2"
    +
    +/**
    + * struct uic_command - UIC command structure
    + * @command: UIC command
    + * @argument1: UIC command argument 1
    + * @argument2: UIC command argument 2
    + * @argument3: UIC command argument 3
    + * @cmd_active: Indicate if UIC command is outstanding
    + * @result: UIC command result
    + */
    +struct uic_command {
    + u32 command;
    + u32 argument1;
    + u32 argument2;
    + u32 argument3;
    + int cmd_active;
    + int result;
    +};
    +
    +/**
    + * struct ufshcd_lrb - local reference block
    + * @utr_descriptor_ptr: UTRD address of the command
    + * @ucd_cmd_ptr: UCD address of the command
    + * @ucd_rsp_ptr: Response UPIU address for this command
    + * @ucd_prdt_ptr: PRDT address of the command
    + * @cmd: pointer to SCSI command
    + * @sense_buffer: pointer to sense buffer address of the SCSI command
    + * @sense_bufflen: Length of the sense buffer
    + * @scsi_status: SCSI status of the command
    + * @command_type: SCSI, UFS, Query.
    + * @task_tag: Task tag of the command
    + * @lun: LUN of the command
    + */
    +struct ufshcd_lrb {
    + struct utp_transfer_req_desc *utr_descriptor_ptr;
    + struct utp_upiu_cmd *ucd_cmd_ptr;
    + struct utp_upiu_rsp *ucd_rsp_ptr;
    + struct ufshcd_sg_entry *ucd_prdt_ptr;
    +
    + struct scsi_cmnd *cmd;
    + u8 *sense_buffer;
    + unsigned int sense_bufflen;
    + int scsi_status;
    +
    + int command_type;
    + int task_tag;
    + unsigned int lun;
    +};
    +
    +
    +/**
    + * struct ufs_hba - per adapter private structure
    + * @mmio_base: UFSHCI base register address
    + * @ucdl_base_addr: UFS Command Descriptor base address
    + * @utrdl_base_addr: UTP Transfer Request Descriptor base address
    + * @utmrdl_base_addr: UTP Task Management Descriptor base address
    + * @ucdl_dma_addr: UFS Command Descriptor DMA address
    + * @utrdl_dma_addr: UTRDL DMA address
    + * @utmrdl_dma_addr: UTMRDL DMA address
    + * @host: Scsi_Host instance of the driver
    + * @dev: device handle
    + * @lrb: local reference block
    + * @outstanding_tasks: Bits representing outstanding task requests
    + * @outstanding_reqs: Bits representing outstanding transfer requests
    + * @capabilities: UFS Controller Capabilities
    + * @nutrs: Transfer Request Queue depth supported by controller
    + * @nutmrs: Task Management Queue depth supported by controller
    + * @active_uic_cmd: handle of active UIC command
    + * @ufshcd_tm_wait_queue: wait queue for task management
    + * @tm_condition: condition variable for task management
    + * @ufshcd_state: UFSHCD states
    + * @int_enable_mask: Interrupt Mask Bits
    + * @uic_workq: Work queue for UIC completion handling
    + * @feh_workq: Work queue for fatal controller error handling
    + * @errors: HBA errors
    + */
    +struct ufs_hba {
    + void __iomem *mmio_base;
    +
    + /* Virtual memory reference */
    + struct utp_transfer_cmd_desc *ucdl_base_addr;
    + struct utp_transfer_req_desc *utrdl_base_addr;
    + struct utp_task_req_desc *utmrdl_base_addr;
    +
    + /* DMA memory reference */
    + dma_addr_t ucdl_dma_addr;
    + dma_addr_t utrdl_dma_addr;
    + dma_addr_t utmrdl_dma_addr;
    +
    + struct Scsi_Host *host;
    + struct device *dev;
    +
    + struct ufshcd_lrb *lrb;
    +
    + unsigned long outstanding_tasks;
    + unsigned long outstanding_reqs;
    +
    + u32 capabilities;
    + int nutrs;
    + int nutmrs;
    + unsigned int irq;
    + u32 ufs_version;
    +
    + struct uic_command active_uic_cmd;
    + wait_queue_head_t ufshcd_tm_wait_queue;
    + unsigned long tm_condition;
    +
    + u32 ufshcd_state;
    + u32 int_enable_mask;
    +
    + /* Work Queues */
    + struct work_struct uic_workq;
    + struct work_struct feh_workq;
    +
    + /* HBA Errors */
    + u32 errors;
    +};
    +
    +/**
    + * ufshcd_hba_stop - Send controller to reset state
    + * @hba: per adapter instance
    + */
    +static inline void ufshcd_hba_stop(struct ufs_hba *hba)
    +{
    + writel(CONTROLLER_DISABLE, (hba->mmio_base + REG_CONTROLLER_ENABLE));
    +}
    +
    +#endif /* End of Header */
    diff --git a/drivers/scsi/ufs/ufshcd_common.h b/drivers/scsi/ufs/ufshcd_common.h
    new file mode 100644
    index 0000000..e027727
    --- /dev/null
    +++ b/drivers/scsi/ufs/ufshcd_common.h
    @@ -0,0 +1,53 @@
    +/*
    + * Universal Flash Storage Host controller driver
    + *
    + * This code is based on drivers/scsi/ufs/ufshcd_common.h
    + * Copyright (C) 2011-2012 Samsung India Software Operations
    + *
    + * Santosh Yaraganavi <santosh.sy@samsung.com>
    + * Vinayak Holikatti <h.vinayak@samsung.com>
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * as published by the Free Software Foundation; either version 2
    + * of the License, or (at your option) any later version.
    + *
    + * 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.
    + *
    + * NO WARRANTY
    + * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
    + * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
    + * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
    + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
    + * solely responsible for determining the appropriateness of using and
    + * distributing the Program and assumes all risks associated with its
    + * exercise of rights under this Agreement, including but not limited to
    + * the risks and costs of program errors, damage to or loss of data,
    + * programs or equipment, and unavailability or interruption of operations.
    +
    + * DISCLAIMER OF LIABILITY
    + * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
    + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    + * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), 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 OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
    + * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
    +
    + * 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 Street, Fifth Floor, Boston, MA 02110-1301,
    + * USA.
    + */
    +
    +#ifndef _UFSHCD_COMMON_H
    +#define _UFSHCD_COMMON_H
    +
    +extern int ufshcd_init(struct device *, struct ufs_hba ** , void __iomem * ,
    + int);
    +extern int ufshcd_remove(struct ufs_hba *);
    +
    +#endif /* END of Header */
    --
    1.7.9.5


    \
     
     \ /
      Last update: 2012-07-26 11:21    [W:2.534 / U:0.104 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site