aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mvsas/mv_init.c
diff options
context:
space:
mode:
authorXiangliang Yu <yuxiangl@marvell.com>2011-04-26 09:36:51 -0400
committerJames Bottomley <James.Bottomley@suse.de>2011-05-01 13:08:03 -0400
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 0123c6b6db96..90b636611cde 100644
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright 2007 Red Hat, Inc. 4 * Copyright 2007 Red Hat, Inc.
5 * Copyright 2008 Marvell. <kewei@marvell.com> 5 * Copyright 2008 Marvell. <kewei@marvell.com>
6 * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
6 * 7 *
7 * This file is licensed under GPLv2. 8 * This file is licensed under GPLv2.
8 * 9 *
@@ -25,7 +26,16 @@
25 26
26#include "mv_sas.h" 27#include "mv_sas.h"
27 28
29static int lldd_max_execute_num = 1;
30module_param_named(collector, lldd_max_execute_num, int, S_IRUGO);
31MODULE_PARM_DESC(collector, "\n"
32 "\tIf greater than one, tells the SAS Layer to run in Task Collector\n"
33 "\tMode. If 1 or 0, tells the SAS Layer to run in Direct Mode.\n"
34 "\tThe mvsas SAS LLDD supports both modes.\n"
35 "\tDefault: 1 (Direct Mode).\n");
36
28static struct scsi_transport_template *mvs_stt; 37static struct scsi_transport_template *mvs_stt;
38struct kmem_cache *mvs_task_list_cache;
29static const struct mvs_chip_info mvs_chips[] = { 39static const struct mvs_chip_info mvs_chips[] = {
30 [chip_6320] = { 1, 2, 0x400, 17, 16, 9, &mvs_64xx_dispatch, }, 40 [chip_6320] = { 1, 2, 0x400, 17, 16, 9, &mvs_64xx_dispatch, },
31 [chip_6440] = { 1, 4, 0x400, 17, 16, 9, &mvs_64xx_dispatch, }, 41 [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)
109 119
110static void mvs_free(struct mvs_info *mvi) 120static void mvs_free(struct mvs_info *mvi)
111{ 121{
112 int i;
113 struct mvs_wq *mwq; 122 struct mvs_wq *mwq;
114 int slot_nr; 123 int slot_nr;
115 124
@@ -121,12 +130,8 @@ static void mvs_free(struct mvs_info *mvi)
121 else 130 else
122 slot_nr = MVS_SLOTS; 131 slot_nr = MVS_SLOTS;
123 132
124 for (i = 0; i < mvi->tags_num; i++) { 133 if (mvi->dma_pool)
125 struct mvs_slot_info *slot = &mvi->slot_info[i]; 134 pci_pool_destroy(mvi->dma_pool);
126 if (slot->buf)
127 dma_free_coherent(mvi->dev, MVS_SLOT_BUF_SZ,
128 slot->buf, slot->buf_dma);
129 }
130 135
131 if (mvi->tx) 136 if (mvi->tx)
132 dma_free_coherent(mvi->dev, 137 dma_free_coherent(mvi->dev,
@@ -215,6 +220,7 @@ static irqreturn_t mvs_interrupt(int irq, void *opaque)
215static int __devinit mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost) 220static int __devinit mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost)
216{ 221{
217 int i = 0, slot_nr; 222 int i = 0, slot_nr;
223 char pool_name[32];
218 224
219 if (mvi->flags & MVF_FLAG_SOC) 225 if (mvi->flags & MVF_FLAG_SOC)
220 slot_nr = MVS_SOC_SLOTS; 226 slot_nr = MVS_SOC_SLOTS;
@@ -274,18 +280,14 @@ static int __devinit mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost)
274 if (!mvi->bulk_buffer) 280 if (!mvi->bulk_buffer)
275 goto err_out; 281 goto err_out;
276#endif 282#endif
277 for (i = 0; i < slot_nr; i++) { 283 sprintf(pool_name, "%s%d", "mvs_dma_pool", mvi->id);
278 struct mvs_slot_info *slot = &mvi->slot_info[i]; 284 mvi->dma_pool = pci_pool_create(pool_name, mvi->pdev, MVS_SLOT_BUF_SZ, 16, 0);
279 285 if (!mvi->dma_pool) {
280 slot->buf = dma_alloc_coherent(mvi->dev, MVS_SLOT_BUF_SZ, 286 printk(KERN_DEBUG "failed to create dma pool %s.\n", pool_name);
281 &slot->buf_dma, GFP_KERNEL);
282 if (!slot->buf) {
283 printk(KERN_DEBUG"failed to allocate slot->buf.\n");
284 goto err_out; 287 goto err_out;
285 }
286 memset(slot->buf, 0, MVS_SLOT_BUF_SZ);
287 ++mvi->tags_num;
288 } 288 }
289 mvi->tags_num = slot_nr;
290
289 /* Initialize tags */ 291 /* Initialize tags */
290 mvs_tag_init(mvi); 292 mvs_tag_init(mvi);
291 return 0; 293 return 0;
@@ -486,7 +488,7 @@ static void __devinit mvs_post_sas_ha_init(struct Scsi_Host *shost,
486 488
487 sha->num_phys = nr_core * chip_info->n_phy; 489 sha->num_phys = nr_core * chip_info->n_phy;
488 490
489 sha->lldd_max_execute_num = 1; 491 sha->lldd_max_execute_num = lldd_max_execute_num;
490 492
491 if (mvi->flags & MVF_FLAG_SOC) 493 if (mvi->flags & MVF_FLAG_SOC)
492 can_queue = MVS_SOC_CAN_QUEUE; 494 can_queue = MVS_SOC_CAN_QUEUE;
@@ -710,6 +712,14 @@ static int __init mvs_init(void)
710 if (!mvs_stt) 712 if (!mvs_stt)
711 return -ENOMEM; 713 return -ENOMEM;
712 714
715 mvs_task_list_cache = kmem_cache_create("mvs_task_list", sizeof(struct mvs_task_list),
716 0, SLAB_HWCACHE_ALIGN, NULL);
717 if (!mvs_task_list_cache) {
718 rc = -ENOMEM;
719 mv_printk("%s: mvs_task_list_cache alloc failed! \n", __func__);
720 goto err_out;
721 }
722
713 rc = pci_register_driver(&mvs_pci_driver); 723 rc = pci_register_driver(&mvs_pci_driver);
714 724
715 if (rc) 725 if (rc)
@@ -726,6 +736,7 @@ static void __exit mvs_exit(void)
726{ 736{
727 pci_unregister_driver(&mvs_pci_driver); 737 pci_unregister_driver(&mvs_pci_driver);
728 sas_release_transport(mvs_stt); 738 sas_release_transport(mvs_stt);
739 kmem_cache_destroy(mvs_task_list_cache);
729} 740}
730 741
731module_init(mvs_init); 742module_init(mvs_init);