diff options
Diffstat (limited to 'drivers/message/i2o/pci.c')
-rw-r--r-- | drivers/message/i2o/pci.c | 67 |
1 files changed, 30 insertions, 37 deletions
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c index 579a8b7a2120..f33fd81f77a4 100644 --- a/drivers/message/i2o/pci.c +++ b/drivers/message/i2o/pci.c | |||
@@ -38,8 +38,7 @@ extern void i2o_iop_free(struct i2o_controller *); | |||
38 | extern int i2o_iop_add(struct i2o_controller *); | 38 | extern int i2o_iop_add(struct i2o_controller *); |
39 | extern void i2o_iop_remove(struct i2o_controller *); | 39 | extern void i2o_iop_remove(struct i2o_controller *); |
40 | 40 | ||
41 | extern int i2o_driver_dispatch(struct i2o_controller *, u32, | 41 | extern int i2o_driver_dispatch(struct i2o_controller *, u32); |
42 | struct i2o_message *); | ||
43 | 42 | ||
44 | /* PCI device id table for all I2O controllers */ | 43 | /* PCI device id table for all I2O controllers */ |
45 | static struct pci_device_id __devinitdata i2o_pci_ids[] = { | 44 | static struct pci_device_id __devinitdata i2o_pci_ids[] = { |
@@ -89,8 +88,7 @@ static void i2o_pci_free(struct i2o_controller *c) | |||
89 | 88 | ||
90 | i2o_dma_free(dev, &c->out_queue); | 89 | i2o_dma_free(dev, &c->out_queue); |
91 | i2o_dma_free(dev, &c->status_block); | 90 | i2o_dma_free(dev, &c->status_block); |
92 | if (c->lct) | 91 | kfree(c->lct); |
93 | kfree(c->lct); | ||
94 | i2o_dma_free(dev, &c->dlct); | 92 | i2o_dma_free(dev, &c->dlct); |
95 | i2o_dma_free(dev, &c->hrt); | 93 | i2o_dma_free(dev, &c->hrt); |
96 | i2o_dma_free(dev, &c->status); | 94 | i2o_dma_free(dev, &c->status); |
@@ -187,9 +185,9 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c) | |||
187 | } else | 185 | } else |
188 | c->in_queue = c->base; | 186 | c->in_queue = c->base; |
189 | 187 | ||
190 | c->irq_mask = c->base.virt + 0x34; | 188 | c->irq_mask = c->base.virt + I2O_IRQ_MASK; |
191 | c->post_port = c->base.virt + 0x40; | 189 | c->in_port = c->base.virt + I2O_IN_PORT; |
192 | c->reply_port = c->base.virt + 0x44; | 190 | c->out_port = c->base.virt + I2O_OUT_PORT; |
193 | 191 | ||
194 | if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) { | 192 | if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) { |
195 | i2o_pci_free(c); | 193 | i2o_pci_free(c); |
@@ -235,49 +233,34 @@ static irqreturn_t i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r) | |||
235 | { | 233 | { |
236 | struct i2o_controller *c = dev_id; | 234 | struct i2o_controller *c = dev_id; |
237 | struct device *dev = &c->pdev->dev; | 235 | struct device *dev = &c->pdev->dev; |
238 | struct i2o_message *m; | 236 | u32 mv = readl(c->out_port); |
239 | u32 mv; | ||
240 | 237 | ||
241 | /* | 238 | /* |
242 | * Old 960 steppings had a bug in the I2O unit that caused | 239 | * Old 960 steppings had a bug in the I2O unit that caused |
243 | * the queue to appear empty when it wasn't. | 240 | * the queue to appear empty when it wasn't. |
244 | */ | 241 | */ |
245 | mv = I2O_REPLY_READ32(c); | ||
246 | if (mv == I2O_QUEUE_EMPTY) { | 242 | if (mv == I2O_QUEUE_EMPTY) { |
247 | mv = I2O_REPLY_READ32(c); | 243 | mv = readl(c->out_port); |
248 | if (unlikely(mv == I2O_QUEUE_EMPTY)) { | 244 | if (unlikely(mv == I2O_QUEUE_EMPTY)) |
249 | return IRQ_NONE; | 245 | return IRQ_NONE; |
250 | } else | 246 | else |
251 | pr_debug("%s: 960 bug detected\n", c->name); | 247 | pr_debug("%s: 960 bug detected\n", c->name); |
252 | } | 248 | } |
253 | 249 | ||
254 | while (mv != I2O_QUEUE_EMPTY) { | 250 | while (mv != I2O_QUEUE_EMPTY) { |
255 | /* | ||
256 | * Map the message from the page frame map to kernel virtual. | ||
257 | * Because bus_to_virt is deprecated, we have calculate the | ||
258 | * location by ourself! | ||
259 | */ | ||
260 | m = i2o_msg_out_to_virt(c, mv); | ||
261 | |||
262 | /* | ||
263 | * Ensure this message is seen coherently but cachably by | ||
264 | * the processor | ||
265 | */ | ||
266 | dma_sync_single_for_cpu(dev, mv, MSG_FRAME_SIZE * 4, | ||
267 | PCI_DMA_FROMDEVICE); | ||
268 | |||
269 | /* dispatch it */ | 251 | /* dispatch it */ |
270 | if (i2o_driver_dispatch(c, mv, m)) | 252 | if (i2o_driver_dispatch(c, mv)) |
271 | /* flush it if result != 0 */ | 253 | /* flush it if result != 0 */ |
272 | i2o_flush_reply(c, mv); | 254 | i2o_flush_reply(c, mv); |
273 | 255 | ||
274 | /* | 256 | /* |
275 | * That 960 bug again... | 257 | * That 960 bug again... |
276 | */ | 258 | */ |
277 | mv = I2O_REPLY_READ32(c); | 259 | mv = readl(c->out_port); |
278 | if (mv == I2O_QUEUE_EMPTY) | 260 | if (mv == I2O_QUEUE_EMPTY) |
279 | mv = I2O_REPLY_READ32(c); | 261 | mv = readl(c->out_port); |
280 | } | 262 | } |
263 | |||
281 | return IRQ_HANDLED; | 264 | return IRQ_HANDLED; |
282 | } | 265 | } |
283 | 266 | ||
@@ -294,7 +277,9 @@ static int i2o_pci_irq_enable(struct i2o_controller *c) | |||
294 | struct pci_dev *pdev = c->pdev; | 277 | struct pci_dev *pdev = c->pdev; |
295 | int rc; | 278 | int rc; |
296 | 279 | ||
297 | I2O_IRQ_WRITE32(c, 0xffffffff); | 280 | wmb(); |
281 | writel(0xffffffff, c->irq_mask); | ||
282 | wmb(); | ||
298 | 283 | ||
299 | if (pdev->irq) { | 284 | if (pdev->irq) { |
300 | rc = request_irq(pdev->irq, i2o_pci_interrupt, SA_SHIRQ, | 285 | rc = request_irq(pdev->irq, i2o_pci_interrupt, SA_SHIRQ, |
@@ -306,7 +291,8 @@ static int i2o_pci_irq_enable(struct i2o_controller *c) | |||
306 | } | 291 | } |
307 | } | 292 | } |
308 | 293 | ||
309 | I2O_IRQ_WRITE32(c, 0x00000000); | 294 | writel(0x00000000, c->irq_mask); |
295 | wmb(); | ||
310 | 296 | ||
311 | printk(KERN_INFO "%s: Installed at IRQ %d\n", c->name, pdev->irq); | 297 | printk(KERN_INFO "%s: Installed at IRQ %d\n", c->name, pdev->irq); |
312 | 298 | ||
@@ -321,7 +307,9 @@ static int i2o_pci_irq_enable(struct i2o_controller *c) | |||
321 | */ | 307 | */ |
322 | static void i2o_pci_irq_disable(struct i2o_controller *c) | 308 | static void i2o_pci_irq_disable(struct i2o_controller *c) |
323 | { | 309 | { |
324 | I2O_IRQ_WRITE32(c, 0xffffffff); | 310 | wmb(); |
311 | writel(0xffffffff, c->irq_mask); | ||
312 | wmb(); | ||
325 | 313 | ||
326 | if (c->pdev->irq > 0) | 314 | if (c->pdev->irq > 0) |
327 | free_irq(c->pdev->irq, c); | 315 | free_irq(c->pdev->irq, c); |
@@ -379,7 +367,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, | |||
379 | pci_name(pdev)); | 367 | pci_name(pdev)); |
380 | 368 | ||
381 | c->pdev = pdev; | 369 | c->pdev = pdev; |
382 | c->device = pdev->dev; | 370 | c->device.parent = get_device(&pdev->dev); |
383 | 371 | ||
384 | /* Cards that fall apart if you hit them with large I/O loads... */ | 372 | /* Cards that fall apart if you hit them with large I/O loads... */ |
385 | if (pdev->vendor == PCI_VENDOR_ID_NCR && pdev->device == 0x0630) { | 373 | if (pdev->vendor == PCI_VENDOR_ID_NCR && pdev->device == 0x0630) { |
@@ -428,6 +416,8 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, | |||
428 | if (i960) | 416 | if (i960) |
429 | pci_write_config_word(i960, 0x42, 0x03ff); | 417 | pci_write_config_word(i960, 0x42, 0x03ff); |
430 | 418 | ||
419 | get_device(&c->device); | ||
420 | |||
431 | return 0; | 421 | return 0; |
432 | 422 | ||
433 | uninstall: | 423 | uninstall: |
@@ -438,6 +428,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, | |||
438 | 428 | ||
439 | free_controller: | 429 | free_controller: |
440 | i2o_iop_free(c); | 430 | i2o_iop_free(c); |
431 | put_device(c->device.parent); | ||
441 | 432 | ||
442 | disable: | 433 | disable: |
443 | pci_disable_device(pdev); | 434 | pci_disable_device(pdev); |
@@ -461,15 +452,17 @@ static void __devexit i2o_pci_remove(struct pci_dev *pdev) | |||
461 | i2o_pci_irq_disable(c); | 452 | i2o_pci_irq_disable(c); |
462 | i2o_pci_free(c); | 453 | i2o_pci_free(c); |
463 | 454 | ||
455 | pci_disable_device(pdev); | ||
456 | |||
464 | printk(KERN_INFO "%s: Controller removed.\n", c->name); | 457 | printk(KERN_INFO "%s: Controller removed.\n", c->name); |
465 | 458 | ||
466 | i2o_iop_free(c); | 459 | put_device(c->device.parent); |
467 | pci_disable_device(pdev); | 460 | put_device(&c->device); |
468 | }; | 461 | }; |
469 | 462 | ||
470 | /* PCI driver for I2O controller */ | 463 | /* PCI driver for I2O controller */ |
471 | static struct pci_driver i2o_pci_driver = { | 464 | static struct pci_driver i2o_pci_driver = { |
472 | .name = "I2O controller", | 465 | .name = "PCI_I2O", |
473 | .id_table = i2o_pci_ids, | 466 | .id_table = i2o_pci_ids, |
474 | .probe = i2o_pci_probe, | 467 | .probe = i2o_pci_probe, |
475 | .remove = __devexit_p(i2o_pci_remove), | 468 | .remove = __devexit_p(i2o_pci_remove), |