diff options
author | Xiangliang Yu <yuxiangl@marvell.com> | 2011-04-26 09:36:51 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2011-05-01 13:08:03 -0400 |
commit | 0b15fb1fdfd403726542cb6111bc916b7a9f7fad (patch) | |
tree | 3f3d2d7516aad34f7ce68cbb317781e7aa7fd41a /drivers/scsi/mvsas/mv_init.c | |
parent | 8214028344b4a38aabf73d95347e1e35538c75f6 (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.c | 47 |
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 | ||
29 | static int lldd_max_execute_num = 1; | ||
30 | module_param_named(collector, lldd_max_execute_num, int, S_IRUGO); | ||
31 | MODULE_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 | |||
28 | static struct scsi_transport_template *mvs_stt; | 37 | static struct scsi_transport_template *mvs_stt; |
38 | struct kmem_cache *mvs_task_list_cache; | ||
29 | static const struct mvs_chip_info mvs_chips[] = { | 39 | static 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 | ||
110 | static void mvs_free(struct mvs_info *mvi) | 120 | static 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) | |||
215 | static int __devinit mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost) | 220 | static 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 | ||
731 | module_init(mvs_init); | 742 | module_init(mvs_init); |