X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fmessage%2Fi2o%2Fpci.c;h=25d6f234198367cd1f70895fc7ab7f030f7262e0;hb=f1b11e505463fd597ab7963df26dd1f446dcceae;hp=ee7075fa1ec3e5ad31e5c3de88b295b2dea4663a;hpb=87d47d0547631e059c308b392cd2423fe9248c93;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c index ee7075f..25d6f23 100644 --- a/drivers/message/i2o/pci.c +++ b/drivers/message/i2o/pci.c @@ -15,11 +15,11 @@ * * Fixes/additions: * Philipp Rumpf - * Juha Sievänen - * Auvo Häkkinen + * Juha Sievänen + * Auvo Häkkinen * Deepak Saxena * Boji T Kannanthanam - * Alan Cox : + * Alan Cox : * Ported to Linux 2.5. * Markus Lidel : * Minor fixes for 2.6. @@ -168,31 +168,47 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c) c->in_port = c->base.virt + I2O_IN_PORT; c->out_port = c->base.virt + I2O_OUT_PORT; - if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) { + /* Motorola/Freescale chip does not follow spec */ + if (pdev->vendor == PCI_VENDOR_ID_MOTOROLA && pdev->device == 0x18c0) { + /* Check if CPU is enabled */ + if (be32_to_cpu(readl(c->base.virt + 0x10000)) & 0x10000000) { + printk(KERN_INFO "%s: MPC82XX needs CPU running to " + "service I2O.\n", c->name); + i2o_pci_free(c); + return -ENODEV; + } else { + c->irq_status += I2O_MOTOROLA_PORT_OFFSET; + c->irq_mask += I2O_MOTOROLA_PORT_OFFSET; + c->in_port += I2O_MOTOROLA_PORT_OFFSET; + c->out_port += I2O_MOTOROLA_PORT_OFFSET; + printk(KERN_INFO "%s: MPC82XX workarounds activated.\n", + c->name); + } + } + + if (i2o_dma_alloc(dev, &c->status, 8)) { i2o_pci_free(c); return -ENOMEM; } - if (i2o_dma_alloc(dev, &c->hrt, sizeof(i2o_hrt), GFP_KERNEL)) { + if (i2o_dma_alloc(dev, &c->hrt, sizeof(i2o_hrt))) { i2o_pci_free(c); return -ENOMEM; } - if (i2o_dma_alloc(dev, &c->dlct, 8192, GFP_KERNEL)) { + if (i2o_dma_alloc(dev, &c->dlct, 8192)) { i2o_pci_free(c); return -ENOMEM; } - if (i2o_dma_alloc(dev, &c->status_block, sizeof(i2o_status_block), - GFP_KERNEL)) { + if (i2o_dma_alloc(dev, &c->status_block, sizeof(i2o_status_block))) { i2o_pci_free(c); return -ENOMEM; } - if (i2o_dma_alloc - (dev, &c->out_queue, - I2O_MAX_OUTBOUND_MSG_FRAMES * I2O_OUTBOUND_MSG_FRAME_SIZE * - sizeof(u32), GFP_KERNEL)) { + if (i2o_dma_alloc(dev, &c->out_queue, + I2O_MAX_OUTBOUND_MSG_FRAMES * I2O_OUTBOUND_MSG_FRAME_SIZE * + sizeof(u32))) { i2o_pci_free(c); return -ENOMEM; } @@ -206,12 +222,11 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c) * i2o_pci_interrupt - Interrupt handler for I2O controller * @irq: interrupt line * @dev_id: pointer to the I2O controller - * @r: pointer to registers * * Handle an interrupt from a PCI based I2O controller. This turns out * to be rather simple. We keep the controller pointer in the cookie. */ -static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r) +static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id) { struct i2o_controller *c = dev_id; u32 m; @@ -242,6 +257,7 @@ static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r) /** * i2o_pci_irq_enable - Allocate interrupt for I2O controller + * @c: i2o_controller that the request is for * * Allocate an interrupt for the I2O controller, and activate interrupts * on the I2O controller. @@ -256,7 +272,7 @@ static int i2o_pci_irq_enable(struct i2o_controller *c) writel(0xffffffff, c->irq_mask); if (pdev->irq) { - rc = request_irq(pdev->irq, i2o_pci_interrupt, SA_SHIRQ, + rc = request_irq(pdev->irq, i2o_pci_interrupt, IRQF_SHARED, c->name, c); if (rc < 0) { printk(KERN_ERR "%s: unable to allocate interrupt %d." @@ -288,7 +304,7 @@ static void i2o_pci_irq_disable(struct i2o_controller *c) /** * i2o_pci_probe - Probe the PCI device for an I2O controller - * @dev: PCI device to test + * @pdev: PCI device to test * @id: id which matched with the PCI device id table * * Probe the PCI device for any device which is a memory of the @@ -303,7 +319,6 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, struct i2o_controller *c; int rc; struct pci_dev *i960 = NULL; - int pci_dev_busy = 0; printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n"); @@ -339,7 +354,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, pci_name(pdev)); c->pdev = pdev; - c->device.parent = get_device(&pdev->dev); + c->device.parent = &pdev->dev; /* Cards that fall apart if you hit them with large I/O loads... */ if (pdev->vendor == PCI_VENDOR_ID_NCR && pdev->device == 0x0630) { @@ -353,12 +368,13 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, * Expose the ship behind i960 for initialization, or it will * failed */ - i960 = - pci_find_slot(c->pdev->bus->number, + i960 = pci_get_slot(c->pdev->bus, PCI_DEVFN(PCI_SLOT(c->pdev->devfn), 0)); - if (i960) + if (i960) { pci_write_config_word(i960, 0x42, 0); + pci_dev_put(i960); + } c->promise = 1; c->limit_sectors = 1; @@ -395,9 +411,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, if ((rc = i2o_pci_alloc(c))) { printk(KERN_ERR "%s: DMA / IO allocation for I2O controller " - " failed\n", c->name); - if (rc == -ENODEV) - pci_dev_busy = 1; + "failed\n", c->name); goto free_controller; } @@ -410,8 +424,6 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, if ((rc = i2o_iop_add(c))) goto uninstall; - get_device(&c->device); - if (i960) pci_write_config_word(i960, 0x42, 0x03ff); @@ -424,19 +436,17 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, i2o_pci_free(c); free_controller: - put_device(c->device.parent); i2o_iop_free(c); disable: - if (!pci_dev_busy) - pci_disable_device(pdev); + pci_disable_device(pdev); return rc; } /** * i2o_pci_remove - Removes a I2O controller from the system - * pdev: I2O controller which should be removed + * @pdev: I2O controller which should be removed * * Reset the I2O controller, disable interrupts and remove all allocated * resources. @@ -454,7 +464,6 @@ static void __devexit i2o_pci_remove(struct pci_dev *pdev) printk(KERN_INFO "%s: Controller removed.\n", c->name); - put_device(c->device.parent); put_device(&c->device); }; @@ -483,4 +492,5 @@ void __exit i2o_pci_exit(void) { pci_unregister_driver(&i2o_pci_driver); }; + MODULE_DEVICE_TABLE(pci, i2o_pci_ids);