diff options
author | Xiangliang Yu <yuxiangl@marvell.com> | 2011-04-26 06:36:51 -0700 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2011-05-01 12:08:03 -0500 |
commit | 0b15fb1fdfd403726542cb6111bc916b7a9f7fad (patch) | |
tree | 3f3d2d7516aad34f7ce68cbb317781e7aa7fd41a /drivers/scsi/mvsas/mv_init.c | |
parent | 8214028344b4a38aabf73d95347e1e35538c75f6 (diff) | |
download | op-kernel-dev-0b15fb1fdfd403726542cb6111bc916b7a9f7fad.zip op-kernel-dev-0b15fb1fdfd403726542cb6111bc916b7a9f7fad.tar.gz |
[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 0123c6b..90b6366 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); |