Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aeab3fd7 authored by Noriyuki Fujii's avatar Noriyuki Fujii Committed by James Bottomley
Browse files

[SCSI] megaraid_sas: make driver PCI legacy I/O port free driver



On the large servers, I/O port resource may not be assigned to all
the PCI devices since it is limited (to 64KB on Intel Architecture[1])
and it may also be fragmented (I/O base register of PCI-to-PCI bridge
will usually be aligned to a 4KB boundary[2]).
If no I/O port resource is assigned to devices, those devices do not
work.

[1] Some machines support 64KB I/O port space per PCI segment.
[2] Some P2P bridges support optional 1KB aligned I/O base.

Therefore, I made a patch for MegaRAID SAS driver to make PCI legacy
I/O port free.  I have also tested the patch and it had no problem.

The way to make PCI legacy I/O port free is the same as Fusion-MPT
driver's and it has been merged into 2.6.30.4.

This has already been fixed in e1000 and lpfc.

As a result of the above, the driver can handle its device even when
there are a huge number of PCI devices being used on the system and no
I/O port region assigned to the device.

Signed-off-by: default avatarNoriyuki Fujii <n-fujii@np.css.fujitsu.com>
Acked-by: default avatar"Yang, Bo" <Bo.Yang@lsi.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent d8705f11
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -2501,7 +2501,9 @@ static int megasas_init_mfi(struct megasas_instance *instance)
		instance->base_addr = pci_resource_start(instance->pdev, 0);
	}

	if (pci_request_regions(instance->pdev, "megasas: LSI")) {
	if (pci_request_selected_regions(instance->pdev,
		pci_select_bars(instance->pdev, IORESOURCE_MEM),
		"megasas: LSI")) {
		printk(KERN_DEBUG "megasas: IO memory region busy!\n");
		return -EBUSY;
	}
@@ -2642,7 +2644,8 @@ static int megasas_init_mfi(struct megasas_instance *instance)
	iounmap(instance->reg_set);

      fail_ioremap:
	pci_release_regions(instance->pdev);
	pci_release_selected_regions(instance->pdev,
		pci_select_bars(instance->pdev, IORESOURCE_MEM));

	return -EINVAL;
}
@@ -2662,7 +2665,8 @@ static void megasas_release_mfi(struct megasas_instance *instance)

	iounmap(instance->reg_set);

	pci_release_regions(instance->pdev);
	pci_release_selected_regions(instance->pdev,
		pci_select_bars(instance->pdev, IORESOURCE_MEM));
}

/**
@@ -2971,7 +2975,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
	/*
	 * PCI prepping: enable device set bus mastering and dma mask
	 */
	rval = pci_enable_device(pdev);
	rval = pci_enable_device_mem(pdev);

	if (rval) {
		return rval;
@@ -3276,7 +3280,7 @@ megasas_resume(struct pci_dev *pdev)
	/*
	 * PCI prepping: enable device set bus mastering and dma mask
	 */
	rval = pci_enable_device(pdev);
	rval = pci_enable_device_mem(pdev);

	if (rval) {
		printk(KERN_ERR "megasas: Enable device failed\n");