summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mvsas/mv_init.c
diff options
context:
space:
mode:
authorXiangliang Yu <yuxiangl@marvell.com>2011-04-26 06:36:51 -0700
committerJames Bottomley <James.Bottomley@suse.de>2011-05-01 12:08:03 -0500
commit0b15fb1fdfd403726542cb6111bc916b7a9f7fad (patch)
tree3f3d2d7516aad34f7ce68cbb317781e7aa7fd41a /drivers/scsi/mvsas/mv_init.c
parent8214028344b4a38aabf73d95347e1e35538c75f6 (diff)
[SCSI] mvsas: add support for Task collector mode and fixed relative bugs
1. Add support for Task collector mode. 2. Fixed relative collector mode bug: - I/O failed when disks is on two ports - system hang when hotplug disk - system hang when unplug disk during run IO 3. Unlock ap->lock within .lldd_execute_task for direct mode to improve performance Signed-off-by: Xiangliang Yu <yuxiangl@marvell.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/mvsas/mv_init.c')
-rw-r--r--drivers/scsi/mvsas/mv_init.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
index 0123c6b6db9..90b636611cd 100644
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -3,6 +3,7 @@
*
* Copyright 2007 Red Hat, Inc.
* Copyright 2008 Marvell. <kewei@marvell.com>
+ * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
*
* This file is licensed under GPLv2.
*
@@ -25,7 +26,16 @@
#include "mv_sas.h"
+static int lldd_max_execute_num = 1;
+module_param_named(collector, lldd_max_execute_num, int, S_IRUGO);
+MODULE_PARM_DESC(collector, "\n"
+ "\tIf greater than one, tells the SAS Layer to run in Task Collector\n"
+ "\tMode. If 1 or 0, tells the SAS Layer to run in Direct Mode.\n"
+ "\tThe mvsas SAS LLDD supports both modes.\n"
+ "\tDefault: 1 (Direct Mode).\n");
+
static struct scsi_transport_template *mvs_stt;
+struct kmem_cache *mvs_task_list_cache;
static const struct mvs_chip_info mvs_chips[] = {
[chip_6320] = { 1, 2, 0x400, 17, 16, 9, &mvs_64xx_dispatch, },
[chip_6440] = { 1, 4, 0x400, 17, 16, 9, &mvs_64xx_dispatch, },
@@ -109,7 +119,6 @@ static void __devinit mvs_phy_init(struct mvs_info *mvi, int phy_id)
static void mvs_free(struct mvs_info *mvi)
{
- int i;
struct mvs_wq *mwq;
int slot_nr;
@@ -121,12 +130,8 @@ static void mvs_free(struct mvs_info *mvi)
else
slot_nr = MVS_SLOTS;
- for (i = 0; i < mvi->tags_num; i++) {
- struct mvs_slot_info *slot = &mvi->slot_info[i];
- if (slot->buf)
- dma_free_coherent(mvi->dev, MVS_SLOT_BUF_SZ,
- slot->buf, slot->buf_dma);
- }
+ if (mvi->dma_pool)
+ pci_pool_destroy(mvi->dma_pool);
if (mvi->tx)
dma_free_coherent(mvi->dev,
@@ -215,6 +220,7 @@ static irqreturn_t mvs_interrupt(int irq, void *opaque)
static int __devinit mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost)
{
int i = 0, slot_nr;
+ char pool_name[32];
if (mvi->flags & MVF_FLAG_SOC)
slot_nr = MVS_SOC_SLOTS;
@@ -274,18 +280,14 @@ static int __devinit mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost)
if (!mvi->bulk_buffer)
goto err_out;
#endif
- for (i = 0; i < slot_nr; i++) {
- struct mvs_slot_info *slot = &mvi->slot_info[i];
-
- slot->buf = dma_alloc_coherent(mvi->dev, MVS_SLOT_BUF_SZ,
- &slot->buf_dma, GFP_KERNEL);
- if (!slot->buf) {
- printk(KERN_DEBUG"failed to allocate slot->buf.\n");
+ sprintf(pool_name, "%s%d", "mvs_dma_pool", mvi->id);
+ mvi->dma_pool = pci_pool_create(pool_name, mvi->pdev, MVS_SLOT_BUF_SZ, 16, 0);
+ if (!mvi->dma_pool) {
+ printk(KERN_DEBUG "failed to create dma pool %s.\n", pool_name);
goto err_out;
- }
- memset(slot->buf, 0, MVS_SLOT_BUF_SZ);
- ++mvi->tags_num;
}
+ mvi->tags_num = slot_nr;
+
/* Initialize tags */
mvs_tag_init(mvi);
return 0;
@@ -486,7 +488,7 @@ static void __devinit mvs_post_sas_ha_init(struct Scsi_Host *shost,
sha->num_phys = nr_core * chip_info->n_phy;
- sha->lldd_max_execute_num = 1;
+ sha->lldd_max_execute_num = lldd_max_execute_num;
if (mvi->flags & MVF_FLAG_SOC)
can_queue = MVS_SOC_CAN_QUEUE;
@@ -710,6 +712,14 @@ static int __init mvs_init(void)
if (!mvs_stt)
return -ENOMEM;
+ mvs_task_list_cache = kmem_cache_create("mvs_task_list", sizeof(struct mvs_task_list),
+ 0, SLAB_HWCACHE_ALIGN, NULL);
+ if (!mvs_task_list_cache) {
+ rc = -ENOMEM;
+ mv_printk("%s: mvs_task_list_cache alloc failed! \n", __func__);
+ goto err_out;
+ }
+
rc = pci_register_driver(&mvs_pci_driver);
if (rc)
@@ -726,6 +736,7 @@ static void __exit mvs_exit(void)
{
pci_unregister_driver(&mvs_pci_driver);
sas_release_transport(mvs_stt);
+ kmem_cache_destroy(mvs_task_list_cache);
}
module_init(mvs_init);