diff options
| -rw-r--r-- | drivers/block/cciss.c | 74 |
1 files changed, 34 insertions, 40 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 52f53c134c5b..6399e5090df4 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
| @@ -68,6 +68,12 @@ MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" | |||
| 68 | MODULE_VERSION("3.6.20"); | 68 | MODULE_VERSION("3.6.20"); |
| 69 | MODULE_LICENSE("GPL"); | 69 | MODULE_LICENSE("GPL"); |
| 70 | 70 | ||
| 71 | static int cciss_allow_hpsa; | ||
| 72 | module_param(cciss_allow_hpsa, int, S_IRUGO|S_IWUSR); | ||
| 73 | MODULE_PARM_DESC(cciss_allow_hpsa, | ||
| 74 | "Prevent cciss driver from accessing hardware known to be " | ||
| 75 | " supported by the hpsa driver"); | ||
| 76 | |||
| 71 | #include "cciss_cmd.h" | 77 | #include "cciss_cmd.h" |
| 72 | #include "cciss.h" | 78 | #include "cciss.h" |
| 73 | #include <linux/cciss_ioctl.h> | 79 | #include <linux/cciss_ioctl.h> |
| @@ -101,8 +107,6 @@ static const struct pci_device_id cciss_pci_device_id[] = { | |||
| 101 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, | 107 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, |
| 102 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A}, | 108 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A}, |
| 103 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B}, | 109 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B}, |
| 104 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
| 105 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, | ||
| 106 | {0,} | 110 | {0,} |
| 107 | }; | 111 | }; |
| 108 | 112 | ||
| @@ -123,8 +127,6 @@ static struct board_type products[] = { | |||
| 123 | {0x409D0E11, "Smart Array 6400 EM", &SA5_access}, | 127 | {0x409D0E11, "Smart Array 6400 EM", &SA5_access}, |
| 124 | {0x40910E11, "Smart Array 6i", &SA5_access}, | 128 | {0x40910E11, "Smart Array 6i", &SA5_access}, |
| 125 | {0x3225103C, "Smart Array P600", &SA5_access}, | 129 | {0x3225103C, "Smart Array P600", &SA5_access}, |
| 126 | {0x3223103C, "Smart Array P800", &SA5_access}, | ||
| 127 | {0x3234103C, "Smart Array P400", &SA5_access}, | ||
| 128 | {0x3235103C, "Smart Array P400i", &SA5_access}, | 130 | {0x3235103C, "Smart Array P400i", &SA5_access}, |
| 129 | {0x3211103C, "Smart Array E200i", &SA5_access}, | 131 | {0x3211103C, "Smart Array E200i", &SA5_access}, |
| 130 | {0x3212103C, "Smart Array E200", &SA5_access}, | 132 | {0x3212103C, "Smart Array E200", &SA5_access}, |
| @@ -132,6 +134,10 @@ static struct board_type products[] = { | |||
| 132 | {0x3214103C, "Smart Array E200i", &SA5_access}, | 134 | {0x3214103C, "Smart Array E200i", &SA5_access}, |
| 133 | {0x3215103C, "Smart Array E200i", &SA5_access}, | 135 | {0x3215103C, "Smart Array E200i", &SA5_access}, |
| 134 | {0x3237103C, "Smart Array E500", &SA5_access}, | 136 | {0x3237103C, "Smart Array E500", &SA5_access}, |
| 137 | /* controllers below this line are also supported by the hpsa driver. */ | ||
| 138 | #define HPSA_BOUNDARY 0x3223103C | ||
| 139 | {0x3223103C, "Smart Array P800", &SA5_access}, | ||
| 140 | {0x3234103C, "Smart Array P400", &SA5_access}, | ||
| 135 | {0x323D103C, "Smart Array P700m", &SA5_access}, | 141 | {0x323D103C, "Smart Array P700m", &SA5_access}, |
| 136 | {0x3241103C, "Smart Array P212", &SA5_access}, | 142 | {0x3241103C, "Smart Array P212", &SA5_access}, |
| 137 | {0x3243103C, "Smart Array P410", &SA5_access}, | 143 | {0x3243103C, "Smart Array P410", &SA5_access}, |
| @@ -140,7 +146,6 @@ static struct board_type products[] = { | |||
| 140 | {0x3249103C, "Smart Array P812", &SA5_access}, | 146 | {0x3249103C, "Smart Array P812", &SA5_access}, |
| 141 | {0x324A103C, "Smart Array P712m", &SA5_access}, | 147 | {0x324A103C, "Smart Array P712m", &SA5_access}, |
| 142 | {0x324B103C, "Smart Array P711m", &SA5_access}, | 148 | {0x324B103C, "Smart Array P711m", &SA5_access}, |
| 143 | {0xFFFF103C, "Unknown Smart Array", &SA5_access}, | ||
| 144 | }; | 149 | }; |
| 145 | 150 | ||
| 146 | /* How long to wait (in milliseconds) for board to go into simple mode */ | 151 | /* How long to wait (in milliseconds) for board to go into simple mode */ |
| @@ -3754,7 +3759,27 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
| 3754 | __u64 cfg_offset; | 3759 | __u64 cfg_offset; |
| 3755 | __u32 cfg_base_addr; | 3760 | __u32 cfg_base_addr; |
| 3756 | __u64 cfg_base_addr_index; | 3761 | __u64 cfg_base_addr_index; |
| 3757 | int i, err; | 3762 | int i, prod_index, err; |
| 3763 | |||
| 3764 | subsystem_vendor_id = pdev->subsystem_vendor; | ||
| 3765 | subsystem_device_id = pdev->subsystem_device; | ||
| 3766 | board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) | | ||
| 3767 | subsystem_vendor_id); | ||
| 3768 | |||
| 3769 | for (i = 0; i < ARRAY_SIZE(products); i++) { | ||
| 3770 | /* Stand aside for hpsa driver on request */ | ||
| 3771 | if (cciss_allow_hpsa && products[i].board_id == HPSA_BOUNDARY) | ||
| 3772 | return -ENODEV; | ||
| 3773 | if (board_id == products[i].board_id) | ||
| 3774 | break; | ||
| 3775 | } | ||
| 3776 | prod_index = i; | ||
| 3777 | if (prod_index == ARRAY_SIZE(products)) { | ||
| 3778 | dev_warn(&pdev->dev, | ||
| 3779 | "unrecognized board ID: 0x%08lx, ignoring.\n", | ||
| 3780 | (unsigned long) board_id); | ||
| 3781 | return -ENODEV; | ||
| 3782 | } | ||
| 3758 | 3783 | ||
| 3759 | /* check to see if controller has been disabled */ | 3784 | /* check to see if controller has been disabled */ |
| 3760 | /* BEFORE trying to enable it */ | 3785 | /* BEFORE trying to enable it */ |
| @@ -3778,11 +3803,6 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
| 3778 | return err; | 3803 | return err; |
| 3779 | } | 3804 | } |
| 3780 | 3805 | ||
| 3781 | subsystem_vendor_id = pdev->subsystem_vendor; | ||
| 3782 | subsystem_device_id = pdev->subsystem_device; | ||
| 3783 | board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) | | ||
| 3784 | subsystem_vendor_id); | ||
| 3785 | |||
| 3786 | #ifdef CCISS_DEBUG | 3806 | #ifdef CCISS_DEBUG |
| 3787 | printk("command = %x\n", command); | 3807 | printk("command = %x\n", command); |
| 3788 | printk("irq = %x\n", pdev->irq); | 3808 | printk("irq = %x\n", pdev->irq); |
| @@ -3868,14 +3888,9 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
| 3868 | * leave a little room for ioctl calls. | 3888 | * leave a little room for ioctl calls. |
| 3869 | */ | 3889 | */ |
| 3870 | c->max_commands = readl(&(c->cfgtable->CmdsOutMax)); | 3890 | c->max_commands = readl(&(c->cfgtable->CmdsOutMax)); |
| 3871 | for (i = 0; i < ARRAY_SIZE(products); i++) { | 3891 | c->product_name = products[prod_index].product_name; |
| 3872 | if (board_id == products[i].board_id) { | 3892 | c->access = *(products[prod_index].access); |
| 3873 | c->product_name = products[i].product_name; | 3893 | c->nr_cmds = c->max_commands - 4; |
| 3874 | c->access = *(products[i].access); | ||
| 3875 | c->nr_cmds = c->max_commands - 4; | ||
| 3876 | break; | ||
| 3877 | } | ||
| 3878 | } | ||
| 3879 | if ((readb(&c->cfgtable->Signature[0]) != 'C') || | 3894 | if ((readb(&c->cfgtable->Signature[0]) != 'C') || |
| 3880 | (readb(&c->cfgtable->Signature[1]) != 'I') || | 3895 | (readb(&c->cfgtable->Signature[1]) != 'I') || |
| 3881 | (readb(&c->cfgtable->Signature[2]) != 'S') || | 3896 | (readb(&c->cfgtable->Signature[2]) != 'S') || |
| @@ -3884,27 +3899,6 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
| 3884 | err = -ENODEV; | 3899 | err = -ENODEV; |
| 3885 | goto err_out_free_res; | 3900 | goto err_out_free_res; |
| 3886 | } | 3901 | } |
| 3887 | /* We didn't find the controller in our list. We know the | ||
| 3888 | * signature is valid. If it's an HP device let's try to | ||
| 3889 | * bind to the device and fire it up. Otherwise we bail. | ||
| 3890 | */ | ||
| 3891 | if (i == ARRAY_SIZE(products)) { | ||
| 3892 | if (subsystem_vendor_id == PCI_VENDOR_ID_HP) { | ||
| 3893 | c->product_name = products[i-1].product_name; | ||
| 3894 | c->access = *(products[i-1].access); | ||
| 3895 | c->nr_cmds = c->max_commands - 4; | ||
| 3896 | printk(KERN_WARNING "cciss: This is an unknown " | ||
| 3897 | "Smart Array controller.\n" | ||
| 3898 | "cciss: Please update to the latest driver " | ||
| 3899 | "available from www.hp.com.\n"); | ||
| 3900 | } else { | ||
| 3901 | printk(KERN_WARNING "cciss: Sorry, I don't know how" | ||
| 3902 | " to access the Smart Array controller %08lx\n" | ||
| 3903 | , (unsigned long)board_id); | ||
| 3904 | err = -ENODEV; | ||
| 3905 | goto err_out_free_res; | ||
| 3906 | } | ||
| 3907 | } | ||
| 3908 | #ifdef CONFIG_X86 | 3902 | #ifdef CONFIG_X86 |
| 3909 | { | 3903 | { |
| 3910 | /* Need to enable prefetch in the SCSI core for 6400 in x86 */ | 3904 | /* Need to enable prefetch in the SCSI core for 6400 in x86 */ |
