diff options
author | Markus Lidel <Markus.Lidel@shadowconnect.com> | 2005-06-24 01:02:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-24 03:05:28 -0400 |
commit | 61fbfa8129c1771061a0e9f47747854293081c5b (patch) | |
tree | 03fe14c41e2a49d3841ae6820a2dd43a91fddee9 /drivers/message/i2o/pci.c | |
parent | 34d6e07570ef74b965131452a862b13dfa779188 (diff) |
[PATCH] I2O: bugfixes and compability enhancements
Changes:
- Fixed sysfs bug where user and parent links where added to the I2O
device itself
- Fixed bug when calculating TID for the event handler and cleaned up the
workflow of i2o_driver_dispatch()
- Fixed oops when no I2O device could be found for an event delivered to
Exec-OSM
- Fixed initialization of spinlock in Exec-OSM
- Fixed memory leak in i2o_cfg_passthru() and i2o_cfg_passthru()
- Removed MTRR support
- Added PCI ID of Promise SX6000 with firmware >= 1.20.x.x
- Turn of caching for ioremapped memory of in_queue
- Added initialization sequence for Promise controllers
- Moved definition of u8 / u16 / u32 for raidutils before first use
Signed-off-by: Markus Lidel <Markus.Lidel@shadowconnect.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/message/i2o/pci.c')
-rw-r--r-- | drivers/message/i2o/pci.c | 93 |
1 files changed, 31 insertions, 62 deletions
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c index e772752f056d..579a8b7a2120 100644 --- a/drivers/message/i2o/pci.c +++ b/drivers/message/i2o/pci.c | |||
@@ -31,10 +31,6 @@ | |||
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | #include <linux/i2o.h> | 32 | #include <linux/i2o.h> |
33 | 33 | ||
34 | #ifdef CONFIG_MTRR | ||
35 | #include <asm/mtrr.h> | ||
36 | #endif // CONFIG_MTRR | ||
37 | |||
38 | /* Module internal functions from other sources */ | 34 | /* Module internal functions from other sources */ |
39 | extern struct i2o_controller *i2o_iop_alloc(void); | 35 | extern struct i2o_controller *i2o_iop_alloc(void); |
40 | extern void i2o_iop_free(struct i2o_controller *); | 36 | extern void i2o_iop_free(struct i2o_controller *); |
@@ -49,6 +45,8 @@ extern int i2o_driver_dispatch(struct i2o_controller *, u32, | |||
49 | static struct pci_device_id __devinitdata i2o_pci_ids[] = { | 45 | static struct pci_device_id __devinitdata i2o_pci_ids[] = { |
50 | {PCI_DEVICE_CLASS(PCI_CLASS_INTELLIGENT_I2O << 8, 0xffff00)}, | 46 | {PCI_DEVICE_CLASS(PCI_CLASS_INTELLIGENT_I2O << 8, 0xffff00)}, |
51 | {PCI_DEVICE(PCI_VENDOR_ID_DPT, 0xa511)}, | 47 | {PCI_DEVICE(PCI_VENDOR_ID_DPT, 0xa511)}, |
48 | {.vendor = PCI_VENDOR_ID_INTEL,.device = 0x1962, | ||
49 | .subvendor = PCI_VENDOR_ID_PROMISE,.subdevice = PCI_ANY_ID}, | ||
52 | {0} | 50 | {0} |
53 | }; | 51 | }; |
54 | 52 | ||
@@ -97,13 +95,6 @@ static void i2o_pci_free(struct i2o_controller *c) | |||
97 | i2o_dma_free(dev, &c->hrt); | 95 | i2o_dma_free(dev, &c->hrt); |
98 | i2o_dma_free(dev, &c->status); | 96 | i2o_dma_free(dev, &c->status); |
99 | 97 | ||
100 | #ifdef CONFIG_MTRR | ||
101 | if (c->mtrr_reg0 >= 0) | ||
102 | mtrr_del(c->mtrr_reg0, 0, 0); | ||
103 | if (c->mtrr_reg1 >= 0) | ||
104 | mtrr_del(c->mtrr_reg1, 0, 0); | ||
105 | #endif | ||
106 | |||
107 | if (c->raptor && c->in_queue.virt) | 98 | if (c->raptor && c->in_queue.virt) |
108 | iounmap(c->in_queue.virt); | 99 | iounmap(c->in_queue.virt); |
109 | 100 | ||
@@ -178,14 +169,15 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c) | |||
178 | c->name, (unsigned long)c->base.phys, | 169 | c->name, (unsigned long)c->base.phys, |
179 | (unsigned long)c->base.len); | 170 | (unsigned long)c->base.len); |
180 | 171 | ||
181 | c->base.virt = ioremap(c->base.phys, c->base.len); | 172 | c->base.virt = ioremap_nocache(c->base.phys, c->base.len); |
182 | if (!c->base.virt) { | 173 | if (!c->base.virt) { |
183 | printk(KERN_ERR "%s: Unable to map controller.\n", c->name); | 174 | printk(KERN_ERR "%s: Unable to map controller.\n", c->name); |
184 | return -ENOMEM; | 175 | return -ENOMEM; |
185 | } | 176 | } |
186 | 177 | ||
187 | if (c->raptor) { | 178 | if (c->raptor) { |
188 | c->in_queue.virt = ioremap(c->in_queue.phys, c->in_queue.len); | 179 | c->in_queue.virt = |
180 | ioremap_nocache(c->in_queue.phys, c->in_queue.len); | ||
189 | if (!c->in_queue.virt) { | 181 | if (!c->in_queue.virt) { |
190 | printk(KERN_ERR "%s: Unable to map controller.\n", | 182 | printk(KERN_ERR "%s: Unable to map controller.\n", |
191 | c->name); | 183 | c->name); |
@@ -199,40 +191,6 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c) | |||
199 | c->post_port = c->base.virt + 0x40; | 191 | c->post_port = c->base.virt + 0x40; |
200 | c->reply_port = c->base.virt + 0x44; | 192 | c->reply_port = c->base.virt + 0x44; |
201 | 193 | ||
202 | #ifdef CONFIG_MTRR | ||
203 | /* Enable Write Combining MTRR for IOP's memory region */ | ||
204 | c->mtrr_reg0 = mtrr_add(c->in_queue.phys, c->in_queue.len, | ||
205 | MTRR_TYPE_WRCOMB, 1); | ||
206 | c->mtrr_reg1 = -1; | ||
207 | |||
208 | if (c->mtrr_reg0 < 0) | ||
209 | printk(KERN_WARNING "%s: could not enable write combining " | ||
210 | "MTRR\n", c->name); | ||
211 | else | ||
212 | printk(KERN_INFO "%s: using write combining MTRR\n", c->name); | ||
213 | |||
214 | /* | ||
215 | * If it is an INTEL i960 I/O processor then set the first 64K to | ||
216 | * Uncacheable since the region contains the messaging unit which | ||
217 | * shouldn't be cached. | ||
218 | */ | ||
219 | if ((pdev->vendor == PCI_VENDOR_ID_INTEL || | ||
220 | pdev->vendor == PCI_VENDOR_ID_DPT) && !c->raptor) { | ||
221 | printk(KERN_INFO "%s: MTRR workaround for Intel i960 processor" | ||
222 | "\n", c->name); | ||
223 | c->mtrr_reg1 = mtrr_add(c->base.phys, 0x10000, | ||
224 | MTRR_TYPE_UNCACHABLE, 1); | ||
225 | |||
226 | if (c->mtrr_reg1 < 0) { | ||
227 | printk(KERN_WARNING "%s: Error in setting " | ||
228 | "MTRR_TYPE_UNCACHABLE\n", c->name); | ||
229 | mtrr_del(c->mtrr_reg0, c->in_queue.phys, | ||
230 | c->in_queue.len); | ||
231 | c->mtrr_reg0 = -1; | ||
232 | } | ||
233 | } | ||
234 | #endif | ||
235 | |||
236 | if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) { | 194 | if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) { |
237 | i2o_pci_free(c); | 195 | i2o_pci_free(c); |
238 | return -ENOMEM; | 196 | return -ENOMEM; |
@@ -385,28 +343,25 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, | |||
385 | { | 343 | { |
386 | struct i2o_controller *c; | 344 | struct i2o_controller *c; |
387 | int rc; | 345 | int rc; |
346 | struct pci_dev *i960 = NULL; | ||
388 | 347 | ||
389 | printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n"); | 348 | printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n"); |
390 | 349 | ||
391 | if ((pdev->class & 0xff) > 1) { | 350 | if ((pdev->class & 0xff) > 1) { |
392 | printk(KERN_WARNING "i2o: I2O controller found but does not " | 351 | printk(KERN_WARNING "i2o: %s does not support I2O 1.5 " |
393 | "support I2O 1.5 (skipping).\n"); | 352 | "(skipping).\n", pci_name(pdev)); |
394 | return -ENODEV; | 353 | return -ENODEV; |
395 | } | 354 | } |
396 | 355 | ||
397 | if ((rc = pci_enable_device(pdev))) { | 356 | if ((rc = pci_enable_device(pdev))) { |
398 | printk(KERN_WARNING "i2o: I2O controller found but could not be" | 357 | printk(KERN_WARNING "i2o: couldn't enable device %s\n", |
399 | " enabled.\n"); | 358 | pci_name(pdev)); |
400 | return rc; | 359 | return rc; |
401 | } | 360 | } |
402 | 361 | ||
403 | printk(KERN_INFO "i2o: I2O controller found on bus %d at %d.\n", | ||
404 | pdev->bus->number, pdev->devfn); | ||
405 | |||
406 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { | 362 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { |
407 | printk(KERN_WARNING "i2o: I2O controller on bus %d at %d: No " | 363 | printk(KERN_WARNING "i2o: no suitable DMA found for %s\n", |
408 | "suitable DMA available!\n", pdev->bus->number, | 364 | pci_name(pdev)); |
409 | pdev->devfn); | ||
410 | rc = -ENODEV; | 365 | rc = -ENODEV; |
411 | goto disable; | 366 | goto disable; |
412 | } | 367 | } |
@@ -415,11 +370,13 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, | |||
415 | 370 | ||
416 | c = i2o_iop_alloc(); | 371 | c = i2o_iop_alloc(); |
417 | if (IS_ERR(c)) { | 372 | if (IS_ERR(c)) { |
418 | printk(KERN_ERR "i2o: memory for I2O controller could not be " | 373 | printk(KERN_ERR "i2o: couldn't allocate memory for %s\n", |
419 | "allocated\n"); | 374 | pci_name(pdev)); |
420 | rc = PTR_ERR(c); | 375 | rc = PTR_ERR(c); |
421 | goto disable; | 376 | goto disable; |
422 | } | 377 | } else |
378 | printk(KERN_INFO "%s: controller found (%s)\n", c->name, | ||
379 | pci_name(pdev)); | ||
423 | 380 | ||
424 | c->pdev = pdev; | 381 | c->pdev = pdev; |
425 | c->device = pdev->dev; | 382 | c->device = pdev->dev; |
@@ -432,9 +389,18 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, | |||
432 | } | 389 | } |
433 | 390 | ||
434 | if (pdev->subsystem_vendor == PCI_VENDOR_ID_PROMISE) { | 391 | if (pdev->subsystem_vendor == PCI_VENDOR_ID_PROMISE) { |
392 | /* | ||
393 | * Expose the ship behind i960 for initialization, or it will | ||
394 | * failed | ||
395 | */ | ||
396 | i960 = | ||
397 | pci_find_slot(c->pdev->bus->number, | ||
398 | PCI_DEVFN(PCI_SLOT(c->pdev->devfn), 0)); | ||
399 | |||
400 | if (i960) | ||
401 | pci_write_config_word(i960, 0x42, 0); | ||
402 | |||
435 | c->promise = 1; | 403 | c->promise = 1; |
436 | printk(KERN_INFO "%s: Promise workarounds activated.\n", | ||
437 | c->name); | ||
438 | } | 404 | } |
439 | 405 | ||
440 | /* Cards that go bananas if you quiesce them before you reset them. */ | 406 | /* Cards that go bananas if you quiesce them before you reset them. */ |
@@ -459,6 +425,9 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, | |||
459 | if ((rc = i2o_iop_add(c))) | 425 | if ((rc = i2o_iop_add(c))) |
460 | goto uninstall; | 426 | goto uninstall; |
461 | 427 | ||
428 | if (i960) | ||
429 | pci_write_config_word(i960, 0x42, 0x03ff); | ||
430 | |||
462 | return 0; | 431 | return 0; |
463 | 432 | ||
464 | uninstall: | 433 | uninstall: |