Skip to contentSkip to conversation

Add Marvell UMI driver

PATCH Superseded Li Jianyun 4 participants 6 messages Apr 20, 2011

Subsystems (2)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Li Jianyun

author
#0 lore raw

PATCH 1/1 Add Marvell UMI driver

The Marvell Universal Message Interface (UMI) defines a messaging
interface between host and Marvell products. It considers situations of limited system resource and optimized system performance.
UMI driver translates host request to message and sends message to
FW via UMI, FW receives message and processes it, then sends response to UMI driver.
FW generates an interrupt when it needs to send information or
responseto UMI driver.

---
 drivers/scsi/Kconfig    |    9 +
 drivers/scsi/Makefile   |    1 +
 drivers/scsi/mvumi.c    | 2245 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/scsi/mvumi.h    |  610 +++++++++++++
 include/linux/pci_ids.h |    2 +
 5 files changed, 2867 insertions(+), 0 deletions(-)
 create mode 100644 drivers/scsi/mvumi.c
 create mode 100644 drivers/scsi/mvumi.h
drivers/scsi/Kconfig +9 -0
index 4a1f029..181ea6c 100644
@@ -559,6 +559,15 @@ source "drivers/scsi/aic7xxx/Kconfig.aic79xx"
 source "drivers/scsi/aic94xx/Kconfig"
 source "drivers/scsi/mvsas/Kconfig"
 
+config SCSI_MVUMI
+	tristate "Marvell UMI driver"
+	depends on SCSI && PCI
+	help
+	  Module for Marvell Universal Message Interface(UMI) driver
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called mvumi.
+
 config SCSI_DPT_I2O
 	tristate "Adaptec I2O RAID support "
 	depends on SCSI && PCI && VIRT_TO_BUS
drivers/scsi/Makefile +1 -0
index 7ad0b8a..bce1609 100644
@@ -133,6 +133,7 @@ obj-$(CONFIG_SCSI_IBMVFC)	+= ibmvscsi/
 obj-$(CONFIG_SCSI_HPTIOP)	+= hptiop.o
 obj-$(CONFIG_SCSI_STEX)		+= stex.o
 obj-$(CONFIG_SCSI_MVSAS)	+= mvsas/
+obj-$(CONFIG_SCSI_MVUMI)	+= mvumi.o
 obj-$(CONFIG_PS3_ROM)		+= ps3rom.o
 obj-$(CONFIG_SCSI_CXGB3_ISCSI)	+= libiscsi.o libiscsi_tcp.o cxgbi/
 obj-$(CONFIG_SCSI_CXGB4_ISCSI)	+= libiscsi.o libiscsi_tcp.o cxgbi/
drivers/scsi/mvumi.c new file +2245 -0

2,245 lines not on this page · raw message

drivers/scsi/mvumi.h new file +610 -0

610 lines not on this page · raw message

include/linux/pci_ids.h +2 -0
index 4e2c915..2a72ed8 100644
@@ -1569,10 +1569,12 @@
 #define PCI_SUBDEVICE_ID_KEYSPAN_SX2	0x5334
 
 #define PCI_VENDOR_ID_MARVELL		0x11ab
+#define PCI_VENDOR_ID_MARVELL_2		0x1b4b
 #define PCI_DEVICE_ID_MARVELL_GT64111	0x4146
 #define PCI_DEVICE_ID_MARVELL_GT64260	0x6430
 #define PCI_DEVICE_ID_MARVELL_MV64360	0x6460
 #define PCI_DEVICE_ID_MARVELL_MV64460	0x6480
+#define PCI_DEVICE_ID_MARVELL_MV9143	0x9143
 #define PCI_DEVICE_ID_MARVELL_88ALP01_NAND	0x4100
 #define PCI_DEVICE_ID_MARVELL_88ALP01_SD	0x4101
 #define PCI_DEVICE_ID_MARVELL_88ALP01_CCIC	0x4102

--
1.7.1

#1 lore raw
Quoted 11 lines · Li Jianyun

The Marvell Universal Message Interface (UMI) defines a messaging
interface between host and Marvell products. It considers situations of limited system resource and optimized system performance.
UMI driver translates host request to message and sends message to
FW via UMI, FW receives message and processes it, then sends response to UMI driver.
FW generates an interrupt when it needs to send information or
responseto UMI driver.

Why not sign off using your marvell.com email address?

Quoted 13 lines

+++ b/drivers/scsi/mvumi.c

drivers/scsi/mvumi.c new file +11 -0
@@ -0,0 +1,2245 @@
+/*
+ * Marvell UMI driver
+ *
+ * Copyright 2011 Marvell. <[email protected]>
+ *
+ * This file is licensed under GPLv2.
+ *
+ * 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; version 2 of the
+ * License.

drivers/scsi/mvumi.c line 21

Quoted 10 lines
drivers/scsi/mvumi.c new file +10 -0
+ *
+ * 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.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA

Unless you are willing to track the office location of the FSF for the next 40 years, and send patches updating it here, just drop this paragraph, it's pointless, as the person _did_ get a copy with the kernel.

thanks,

greg k-h

author
#2 lore raw

Hi Grep KH
thanks for your remind,I am a beginner,and don't know how to
send patch to kernel.
I will update the Signed-off-by. Do I need update the subject to "[PATCH][RESEND] Add Marvell UMI driver" when I resend this patch?
thanks for your patient.

2011/4/20 Greg KH <[email protected]>:

Quoted 44 lines · Li Jianyun
Quoted 11 lines

The Marvell Universal Message Interface (UMI) defines a messaging
interface between host and Marvell products. It considers situations of limited system resource and optimized system performance.
UMI driver translates host request to message and sends message to
FW via UMI, FW receives message and processes it, then sends response to UMI driver.
FW generates an interrupt when it needs to send information or
responseto UMI driver.

Why not sign off using your marvell.com email address?

Quoted 13 lines

+++ b/drivers/scsi/mvumi.c

drivers/scsi/mvumi.c new file +11 -0
@@ -0,0 +1,2245 @@
+/*
+ * Marvell UMI driver
+ *
+ * Copyright 2011 Marvell. <[email protected]>
+ *
+ * This file is licensed under GPLv2.
+ *
+ * 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; version 2 of the
+ * License.

drivers/scsi/mvumi.c line 21

Quoted 10 lines
drivers/scsi/mvumi.c new file +10 -0
+ *
+ * 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.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA

Unless you are willing to track the office location of the FSF for the next 40 years, and send patches updating it here, just drop this paragraph, it's pointless, as the person _did_ get a copy with the kernel.

Quoted 4 lines

thanks,

greg k-h

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#3 lore raw
Quoted 6 lines · li jianyun

Hi Grep KH
thanks for your remind,I am a beginner,and don't know how to
send patch to kernel.
I will update the Signed-off-by. Do I need update the subject to "[PATCH][RESEND] Add Marvell UMI driver" when I resend this patch?
thanks for your patient.

No, just do:

	[patch v2]

as git will strip out the first set of [] markings, but not the second when applying the patch.

thanks,

greg k-h

#4 lore raw
In reply to Li Jianyun
Quoted 1 line

+#include <asm/uaccess.h>

linux/uaccess.h

[scripts/checkpatch.pl --file whatever is your friend]

drivers/scsi/mvumi.c line 128

Quoted 13 lines
drivers/scsi/mvumi.c new file +13 -0
+static int mvumi_map_pci_addr(struct pci_dev *dev, void **addr_array)
+{
+	int i;
+	unsigned long addr, range;
+
+	for (i = 0; i < MAX_BASE_ADDRESS; i++) {
+		addr = pci_resource_start(dev, i);
+		range = pci_resource_len(dev, i);
+
+		if (pci_resource_flags(dev, i) & IORESOURCE_MEM) {
+			addr_array[i] = (void *) ioremap_nocache(addr, range);
+			if (!addr_array[i]) {
+				dev_printk(KERN_ERR, &dev->dev,

dev_err is a bit easier

drivers/scsi/mvumi.c line 139

Quoted 11 lines
drivers/scsi/mvumi.c new file +11 -0
+					"Failed to map IO mem\n");
+				return -1;
+			}
+		} else
+			addr_array[i] = (void *) addr;
+
+		dev_printk(KERN_INFO, &dev->dev,
+			"BAR %d : %p.\n", i, addr_array[i]);
+	}
+	return 0;
+}

See pci_iomap/ioread32/iowrite32/etc you appear to be reinventing the wheel.

drivers/scsi/mvumi.c line 154

Quoted 5 lines
drivers/scsi/mvumi.c new file +5 -0
+static struct mvumi_res_mgnt *mvumi_alloc_mem_resource(struct mvumi_hba *mhba,
+				enum resource_type type, unsigned int size)
+{
+	struct mvumi_res_mgnt *res_mgnt =
+			vmalloc(sizeof(struct mvumi_res_mgnt));

Unless it's a very large object (> 2 pages) use kmalloc - on 32bit machines kmalloc resources are much more freely available

This whole abstraction appears to be overkill though. You know what sort of resource you allocated anyway so this seems to be excessive and confusing

drivers/scsi/mvumi.c line 334

Quoted 12 lines
drivers/scsi/mvumi.c new file +12 -0
+static struct mvumi_cmd *mvumi_create_internal_cmd(struct mvumi_hba *mhba,
+				unsigned int buf_size)
+{
+	struct mvumi_cmd *cmd;
+
+	cmd = kmalloc(sizeof(struct mvumi_cmd), GFP_KERNEL);
+	if (cmd == NULL) {
+		dev_printk(KERN_ERR, &mhba->pdev->dev,
+			"failed to create a internal cmd\n");
+		return NULL;
+	}
+	memset(cmd, 0, sizeof(struct mvumi_cmd));

kzalloc

drivers/scsi/mvumi.c line 560

Quoted 4 lines
drivers/scsi/mvumi.c new file +4 -0
+static unsigned char mvumi_send_ib_list_entry(struct mvumi_hba *mhba)
+{
+	void *regs = mhba->mmio;
+	writel((unsigned int) 0xfff, mhba->ib_shadow);

Don't think you need some of these casts either

drivers/scsi/mvumi.c line 1100

Quoted 1 line
drivers/scsi/mvumi.c new file +1 -0
+	dev_printk(KERN_INFO, &mhba->pdev->dev, "start firmware handshake.\n");

dev_info etc as well as dev_err

drivers/scsi/mvumi.c line 1139

Quoted 9 lines
drivers/scsi/mvumi.c new file +9 -0
+	dev_printk(KERN_INFO, &mhba->pdev->dev, "CLA_INB_LIST_BASEL=0x%x.\n",
+					mvumi_mr32(CLA_INB_LIST_BASEL));
+	dev_printk(KERN_INFO, &mhba->pdev->dev, "CLA_INB_LIST_BASEH=0x%x.\n",
+					mvumi_mr32(CLA_INB_LIST_BASEH));
+	dev_printk(KERN_INFO, &mhba->pdev->dev, "CLA_OUTB_LIST_BASEL=0x%x.\n",
+					mvumi_mr32(CLA_OUTB_LIST_BASEL));
+	dev_printk(KERN_INFO, &mhba->pdev->dev, "CLA_OUTB_LIST_BASEH=0x%x.\n",
+					mvumi_mr32(CLA_OUTB_LIST_BASEH));
+	dev_printk(KERN_INFO, &mhba->pdev->dev, "firmware handshake ok.\n");

A lot of this looks like it should be dev_dbg()

drivers/scsi/mvumi.c line 1552

Quoted 10 lines
drivers/scsi/mvumi.c new file +10 -0
+static void dwordcpy(void *to, const void *from, size_t n)
+{
+	unsigned int *p_dst = (unsigned int *) to;
+	unsigned int *p_src = (unsigned int *) from;
+
+	WARN_ON(n & 0x3);
+	n >>= 2;
+	while (n--)
+		*p_dst++ = *p_src++;
+}

Why not use memcpy ?

drivers/scsi/mvumi.c line 1554

Quoted 2 lines
drivers/scsi/mvumi.c new file +2 -0
+static enum MV_QUEUE_COMMAND_RESULT mvumi_send_command(struct mvumi_hba *mhba,
+						struct mvumi_cmd *cmd)

Please dont use CAPITAL_LETTER_SIZED_GIANT_TYPE_NAMING, Linux reserves shouting for defines in general

drivers/scsi/mvumi.c line 2015

Quoted 1 line
drivers/scsi/mvumi.c new file +1 -0
+	pci_read_config_word(pdev, 0x0A,  &class_code);

The class is available in the pci_dev already is it not ?

drivers/scsi/mvumi.c line 2023

Quoted 8 lines
drivers/scsi/mvumi.c new file +8 -0
+	dev_printk(KERN_INFO, &pdev->dev,
+			" %#4.04x:%#4.04x:%#4.04x:%#4.04x: ",
+			pdev->vendor, pdev->device, pdev->subsystem_vendor,
+			pdev->subsystem_device);
+	dev_printk(KERN_INFO, &pdev->dev,
+			"bus %d:slot %d:func %d:class_code:%#4.04x\n",
+			pdev->bus->number, PCI_SLOT(pdev->devfn),
+			PCI_FUNC(pdev->devfn), class_code);

Like most of the printk stuff this should be debug level

drivers/scsi/mvumi.h line 214

Quoted 6 lines
drivers/scsi/mvumi.h new file +6 -0
+struct mv_sgl {
+	unsigned int	baseaddr_l;
+	unsigned int	baseaddr_h;
+	unsigned int	flags;
+	unsigned int	size;
+};

In general if you want these to be a given size (ie they are shared) use u32/u64/u8/u16 etc and make it explicit.

drivers/scsi/mvumi.h line 227

Quoted 13 lines
drivers/scsi/mvumi.h new file +13 -0
+
+#define sgd_getsz(sgd, sz)  do {	\
+	(sz) = (sgd)->size;		\
+} while (0)
+
+#define sgd_setsz(sgd, sz) do {			\
+	(sgd)->size = (sz);			\
+} while (0)
+
+
+#define sgd_inc(sgd) do {					\
+	sgd = (struct mv_sgl *) (((unsigned char *) (sgd)) + 16);\
+} while (0)

These really shouldn't be magic macros, and all the casting actually makes them messier than just using C pointer increment rules like normal drivers.

If struct foo is 16 bytes then ++ moves a struct foo * on to the next struct so you don't need all the gunge anyway

Quoted 1 line

+static inline struct list_head *list_get_first(struct list_head *head)

I'm not sure hiding your only subtly different list handling in a header is going to help everyone understand the code either !

drivers/scsi/mvumi.h

Quoted 8 lines
drivers/scsi/mvumi.h new file +7 -0
+#define list_get_first_entry(head, type, member)	\
+	list_entry(list_get_first(head), type, member)
+
+#define list_get_last_entry(head, type, member)	\
+	list_entry(list_get_last(head), type, member)
+
 
+extern struct timezone sys_tz;

Umm why ???

#5 lore raw
In reply to Li Jianyun
Quoted 20 lines · Li Jianyun
drivers/scsi/mvumi.c new file +20 -0
+/**
+ * mvumi_init_data -	Initialize requested date for FW
+ * @mhba:			Adapter soft state
+ */
+static int mvumi_init_data(struct mvumi_hba *mhba)
+{
+	struct mv_ob_data_pool *ob_pool;
+	struct mvumi_res_mgnt *res_mgnt;
+	unsigned int tmp_size, offset, i;
+	void *virmem, *v;
+	dma_addr_t p;
+
+	if (mhba->fw_flag & MVUMI_FW_ALLOC)
+		return 0;
+	tmp_size = 128 + mhba->ib_max_entry_size_bytes * mhba->max_io + 16
+							+ sizeof(unsigned int);
+	tmp_size += 8 + mhba->ob_max_entry_size_bytes * mhba->max_io + 4;
+	res_mgnt = mvumi_alloc_mem_resource(mhba,
+			RESOURCE_UNCACHED_MEMORY, tmp_size);
+	if (!res_mgnt) {

drivers/scsi/mvumi.c line 1459

Quoted 10 lines
drivers/scsi/mvumi.c new file +10 -0
+		dev_printk(KERN_ERR, &mhba->pdev->dev,
+			"failed to allocate memory for inbound list\n");
+		goto fail_alloc_dma_buf;
+	}
+
+	p = res_mgnt->bus_addr;
+	v = res_mgnt->virt_addr;
+	offset = (unsigned int)(round_up(res_mgnt->bus_addr, 128) -
+							res_mgnt->bus_addr);
+	p += offset;

p now has offset again, no? Is this intentional?

Review

Quoted 1 line
(quoted diff) +1 -0
+	v = (unsigned char *) v + offset;

I don't think you need the cast. The kernel relies on the gcc extension that "void* += n" moves up n bytes.

Quoted 13 lines
drivers/scsi/mvumi.c new file +13 -0
+	mhba->ib_list = v;
+	mhba->ib_list_phys = p;
+
+	v = (unsigned char *) v + mhba->ib_max_entry_size_bytes * mhba->max_io;
+	p += mhba->ib_max_entry_size_bytes * mhba->max_io;
+
+	offset = (unsigned int)(round_up(p, 8) - p);
+	p += offset;
+	v = (unsigned char *) v + offset;
+	mhba->ib_shadow = v;
+	mhba->ib_shadow_phys = p;
+
+	p += sizeof(unsigned int);

drivers/scsi/mvumi.c line 1483

Quoted 10 lines
drivers/scsi/mvumi.c new file +10 -0
+	v = (unsigned char *) v + sizeof(unsigned int);
+
+	offset = round_up(p, 8) - p;
+	p += offset;
+	v = (unsigned char *) v + offset;
+	mhba->ob_shadow = v;
+	mhba->ob_shadow_phys = p;
+	p += 8;
+	v = (unsigned char *) v + 8;
+	offset = (unsigned int) (round_up(p, 128) - p);

Sometimes you cast the result of round_up() to unsigned int and sometimes not. So I guess you just need to never cast. Since the result will be in range 8..128 anyway I think the casting can just go away completely.

drivers/scsi/mvumi.c line 384

Quoted 4 lines
drivers/scsi/mvumi.c new file +4 -0
+
+	return 0;
+}
+/**

Newline missing here.

Quoted 13 lines

+ * mvumi_probe_one - PCI hotplug entry point
+ * @pdev: PCI device structure
+ * @id: PCI ids of supported hotplugged adapter
+ */

drivers/scsi/mvumi.c new file +9 -0
+static int __devinit mvumi_probe_one(struct pci_dev *pdev,
+					const struct pci_device_id *id)
+{
+	int ret;
+	struct Scsi_Host *host;
+	struct mvumi_hba *mhba;
+	unsigned short class_code = 0xFFFF;
+
+	pci_read_config_word(pdev, 0x0A,  &class_code);

drivers/scsi/mvumi.c line 2025

Quoted 10 lines
drivers/scsi/mvumi.c new file +10 -0
+	dev_printk(KERN_INFO, &pdev->dev,
+			" %#4.04x:%#4.04x:%#4.04x:%#4.04x: ",
+			pdev->vendor, pdev->device, pdev->subsystem_vendor,
+			pdev->subsystem_device);
+	dev_printk(KERN_INFO, &pdev->dev,
+			"bus %d:slot %d:func %d:class_code:%#4.04x\n",
+			pdev->bus->number, PCI_SLOT(pdev->devfn),
+			PCI_FUNC(pdev->devfn), class_code);
+
+	ret = pci_enable_device(pdev);

You may want to use pcim_enable_device(). Look at Documentation/driver- model/devres.txt. This would take care of some of your error handling for free.

Quoted 4 lines
drivers/scsi/mvumi.c new file +4 -0
+	if (ret)
+		return ret;
+
+	pci_set_master(pdev);

drivers/scsi/mvumi.c line 2039

Quoted 10 lines
drivers/scsi/mvumi.c new file +10 -0
+
+	if (IS_DMA64) {
+		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
+			if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
+				goto fail_set_dma_mask;
+		}
+	} else {
+		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)
+			goto fail_set_dma_mask;
+	}

I don't like that you lose the error code of pci_set_dma_mask() here.

drivers/scsi/mvumi.c line 2046

Quoted 6 lines
drivers/scsi/mvumi.c new file +6 -0
+	host = scsi_host_alloc(&mvumi_template, sizeof(struct mvumi_hba));
+	if (!host) {
+		dev_printk(KERN_ERR, &pdev->dev, "scsi_host_alloc failed\n");
+		goto fail_alloc_instance;
+	}
+	mhba = (struct mvumi_hba *) host->hostdata;

mhba = shost_priv(host);

Quoted 10 lines
drivers/scsi/mvumi.c new file +10 -0
+	memset(mhba, 0, sizeof(*mhba));
+
+	INIT_LIST_HEAD(&mhba->cmd_pool);
+	INIT_LIST_HEAD(&mhba->ob_data_pool_list);
+	INIT_LIST_HEAD(&mhba->free_ob_list);
+	INIT_LIST_HEAD(&mhba->res_list);
+	INIT_LIST_HEAD(&mhba->waiting_req_list);
+	atomic_set(&mhba->fw_outstanding, 0);
+
+	init_waitqueue_head(&mhba->int_cmd_wait_q);

drivers/scsi/mvumi.c line 2066

Quoted 10 lines
drivers/scsi/mvumi.c new file +10 -0
+
+	spin_lock_init(&mhba->cmd_pool_lock);
+	spin_lock_init(&mhba->tag_lock);
+
+	mhba->pdev = pdev;
+	mhba->shost = host;
+	mhba->unique_id = pdev->bus->number << 8 | pdev->devfn;
+
+	if (mvumi_init_fw(mhba))
+		goto fail_init_fw;

You are once again loosing an error code here.

Quoted 4 lines
drivers/scsi/mvumi.c new file +4 -0
+	ret = request_irq(mhba->pdev->irq, mvumi_isr_handler, IRQF_SHARED,
+				"mvumi", mhba);
+	if (ret) {
+		dev_printk(KERN_ERR, &pdev->dev, "failed to register IRQ\n");

drivers/scsi/mvumi.c line 2080

Quoted 10 lines
drivers/scsi/mvumi.c new file +10 -0
+		goto fail_init_irq;
+	}
+
+	mhba->instancet->enable_intr(mhba->mmio);
+	pci_set_drvdata(pdev, mhba);
+
+	if (mvumi_io_attach(mhba))
+		goto fail_io_attach;
+	dev_printk(KERN_INFO, &pdev->dev, "probe mvumi driver successfully.\n");
+	return 0;

I don't know if the ordering is correct here. Once you have registered the IRQ handler you must be prepared to get interrupts. In fact with IRQ debugging enabled your IRQ handler will be called immediately in request_irq(). So when you set up other stuff here that is needed in the IRQ handler this can do all sort of things wrong.

Quoted 5 lines
drivers/scsi/mvumi.c new file +5 -0
+fail_io_attach:
+	pci_set_drvdata(pdev, NULL);
+	mhba->instancet->disable_intr(mhba->mmio);
+	free_irq(mhba->pdev->irq, mhba);
+fail_init_irq:

drivers/scsi/mvumi.c line 2096

Quoted 10 lines
drivers/scsi/mvumi.c new file +10 -0
+	mvumi_release_fw(mhba);
+fail_init_fw:
+	scsi_host_put(host);
+
+fail_alloc_instance:
+fail_set_dma_mask:
+	pci_disable_device(pdev);
+
+	return -ENODEV;
+}

You always lose the error codes of anything in your probe function. I don't think this is a good idea.

drivers/scsi/mvumi.c line 2109

Quoted 13 lines
drivers/scsi/mvumi.c new file +13 -0
+
+static void mvumi_detach_one(struct pci_dev *pdev)
+{
+	struct Scsi_Host *host;
+	struct mvumi_hba *mhba;
+
+	mhba = pci_get_drvdata(pdev);
+	host = mhba->shost;
+	scsi_remove_host(mhba->shost);
+	mvumi_flush_cache(mhba);
+
+	mhba->instancet->disable_intr(mhba->mmio);
+	free_irq(mhba->pdev->irq, mhba);

Same as above here: you may still get an IRQ until this point. So be careful with what you free first.

drivers/scsi/mvumi.c line 2115

Quoted 6 lines
drivers/scsi/mvumi.c new file +6 -0
+	mvumi_release_fw(mhba);
+	scsi_host_put(host);
+	pci_set_drvdata(pdev, NULL);
+	pci_disable_device(pdev);
+	dev_printk(KERN_INFO, &pdev->dev, "driver is removed!\n");
+}

Greetings,

Eike