diff options
Diffstat (limited to 'drivers/scsi/mac_esp.c')
-rw-r--r-- | drivers/scsi/mac_esp.c | 152 |
1 files changed, 54 insertions, 98 deletions
diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c index c24e86f07804..4a90eaf7cb63 100644 --- a/drivers/scsi/mac_esp.c +++ b/drivers/scsi/mac_esp.c | |||
@@ -22,7 +22,6 @@ | |||
22 | 22 | ||
23 | #include <asm/irq.h> | 23 | #include <asm/irq.h> |
24 | #include <asm/dma.h> | 24 | #include <asm/dma.h> |
25 | |||
26 | #include <asm/macints.h> | 25 | #include <asm/macints.h> |
27 | #include <asm/macintosh.h> | 26 | #include <asm/macintosh.h> |
28 | 27 | ||
@@ -53,7 +52,6 @@ struct mac_esp_priv { | |||
53 | void __iomem *pdma_io; | 52 | void __iomem *pdma_io; |
54 | int error; | 53 | int error; |
55 | }; | 54 | }; |
56 | static struct platform_device *internal_pdev, *external_pdev; | ||
57 | static struct esp *esp_chips[2]; | 55 | static struct esp *esp_chips[2]; |
58 | 56 | ||
59 | #define MAC_ESP_GET_PRIV(esp) ((struct mac_esp_priv *) \ | 57 | #define MAC_ESP_GET_PRIV(esp) ((struct mac_esp_priv *) \ |
@@ -279,24 +277,27 @@ static void mac_esp_send_pdma_cmd(struct esp *esp, u32 addr, u32 esp_count, | |||
279 | * Programmed IO routines follow. | 277 | * Programmed IO routines follow. |
280 | */ | 278 | */ |
281 | 279 | ||
282 | static inline int mac_esp_wait_for_fifo(struct esp *esp) | 280 | static inline unsigned int mac_esp_wait_for_fifo(struct esp *esp) |
283 | { | 281 | { |
284 | int i = 500000; | 282 | int i = 500000; |
285 | 283 | ||
286 | do { | 284 | do { |
287 | if (esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES) | 285 | unsigned int fbytes = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES; |
288 | return 0; | 286 | |
287 | if (fbytes) | ||
288 | return fbytes; | ||
289 | 289 | ||
290 | udelay(2); | 290 | udelay(2); |
291 | } while (--i); | 291 | } while (--i); |
292 | 292 | ||
293 | printk(KERN_ERR PFX "FIFO is empty (sreg %02x)\n", | 293 | printk(KERN_ERR PFX "FIFO is empty (sreg %02x)\n", |
294 | esp_read8(ESP_STATUS)); | 294 | esp_read8(ESP_STATUS)); |
295 | return 1; | 295 | return 0; |
296 | } | 296 | } |
297 | 297 | ||
298 | static inline int mac_esp_wait_for_intr(struct esp *esp) | 298 | static inline int mac_esp_wait_for_intr(struct esp *esp) |
299 | { | 299 | { |
300 | struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp); | ||
300 | int i = 500000; | 301 | int i = 500000; |
301 | 302 | ||
302 | do { | 303 | do { |
@@ -308,6 +309,7 @@ static inline int mac_esp_wait_for_intr(struct esp *esp) | |||
308 | } while (--i); | 309 | } while (--i); |
309 | 310 | ||
310 | printk(KERN_ERR PFX "IRQ timeout (sreg %02x)\n", esp->sreg); | 311 | printk(KERN_ERR PFX "IRQ timeout (sreg %02x)\n", esp->sreg); |
312 | mep->error = 1; | ||
311 | return 1; | 313 | return 1; |
312 | } | 314 | } |
313 | 315 | ||
@@ -347,11 +349,10 @@ static inline int mac_esp_wait_for_intr(struct esp *esp) | |||
347 | static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count, | 349 | static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count, |
348 | u32 dma_count, int write, u8 cmd) | 350 | u32 dma_count, int write, u8 cmd) |
349 | { | 351 | { |
350 | unsigned long flags; | ||
351 | struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp); | 352 | struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp); |
352 | u8 *fifo = esp->regs + ESP_FDATA * 16; | 353 | u8 *fifo = esp->regs + ESP_FDATA * 16; |
353 | 354 | ||
354 | local_irq_save(flags); | 355 | disable_irq(esp->host->irq); |
355 | 356 | ||
356 | cmd &= ~ESP_CMD_DMA; | 357 | cmd &= ~ESP_CMD_DMA; |
357 | mep->error = 0; | 358 | mep->error = 0; |
@@ -359,11 +360,35 @@ static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count, | |||
359 | if (write) { | 360 | if (write) { |
360 | scsi_esp_cmd(esp, cmd); | 361 | scsi_esp_cmd(esp, cmd); |
361 | 362 | ||
362 | if (!mac_esp_wait_for_intr(esp)) { | 363 | while (1) { |
363 | if (mac_esp_wait_for_fifo(esp)) | 364 | unsigned int n; |
364 | esp_count = 0; | 365 | |
365 | } else { | 366 | n = mac_esp_wait_for_fifo(esp); |
366 | esp_count = 0; | 367 | if (!n) |
368 | break; | ||
369 | |||
370 | if (n > esp_count) | ||
371 | n = esp_count; | ||
372 | esp_count -= n; | ||
373 | |||
374 | MAC_ESP_PIO_LOOP("%2@,%0@+", n); | ||
375 | |||
376 | if (!esp_count) | ||
377 | break; | ||
378 | |||
379 | if (mac_esp_wait_for_intr(esp)) | ||
380 | break; | ||
381 | |||
382 | if (((esp->sreg & ESP_STAT_PMASK) != ESP_DIP) && | ||
383 | ((esp->sreg & ESP_STAT_PMASK) != ESP_MIP)) | ||
384 | break; | ||
385 | |||
386 | esp->ireg = esp_read8(ESP_INTRPT); | ||
387 | if ((esp->ireg & (ESP_INTR_DC | ESP_INTR_BSERV)) != | ||
388 | ESP_INTR_BSERV) | ||
389 | break; | ||
390 | |||
391 | scsi_esp_cmd(esp, ESP_CMD_TI); | ||
367 | } | 392 | } |
368 | } else { | 393 | } else { |
369 | scsi_esp_cmd(esp, ESP_CMD_FLUSH); | 394 | scsi_esp_cmd(esp, ESP_CMD_FLUSH); |
@@ -374,47 +399,24 @@ static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count, | |||
374 | MAC_ESP_PIO_LOOP("%0@+,%2@", esp_count); | 399 | MAC_ESP_PIO_LOOP("%0@+,%2@", esp_count); |
375 | 400 | ||
376 | scsi_esp_cmd(esp, cmd); | 401 | scsi_esp_cmd(esp, cmd); |
377 | } | ||
378 | |||
379 | while (esp_count) { | ||
380 | unsigned int n; | ||
381 | 402 | ||
382 | if (mac_esp_wait_for_intr(esp)) { | 403 | while (esp_count) { |
383 | mep->error = 1; | 404 | unsigned int n; |
384 | break; | ||
385 | } | ||
386 | |||
387 | if (esp->sreg & ESP_STAT_SPAM) { | ||
388 | printk(KERN_ERR PFX "gross error\n"); | ||
389 | mep->error = 1; | ||
390 | break; | ||
391 | } | ||
392 | |||
393 | n = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES; | ||
394 | |||
395 | if (write) { | ||
396 | if (n > esp_count) | ||
397 | n = esp_count; | ||
398 | esp_count -= n; | ||
399 | |||
400 | MAC_ESP_PIO_LOOP("%2@,%0@+", n); | ||
401 | 405 | ||
402 | if ((esp->sreg & ESP_STAT_PMASK) == ESP_STATP) | 406 | if (mac_esp_wait_for_intr(esp)) |
403 | break; | 407 | break; |
404 | 408 | ||
405 | if (esp_count) { | 409 | if (((esp->sreg & ESP_STAT_PMASK) != ESP_DOP) && |
406 | esp->ireg = esp_read8(ESP_INTRPT); | 410 | ((esp->sreg & ESP_STAT_PMASK) != ESP_MOP)) |
407 | if (esp->ireg & ESP_INTR_DC) | 411 | break; |
408 | break; | ||
409 | 412 | ||
410 | scsi_esp_cmd(esp, ESP_CMD_TI); | ||
411 | } | ||
412 | } else { | ||
413 | esp->ireg = esp_read8(ESP_INTRPT); | 413 | esp->ireg = esp_read8(ESP_INTRPT); |
414 | if (esp->ireg & ESP_INTR_DC) | 414 | if ((esp->ireg & (ESP_INTR_DC | ESP_INTR_BSERV)) != |
415 | ESP_INTR_BSERV) | ||
415 | break; | 416 | break; |
416 | 417 | ||
417 | n = MAC_ESP_FIFO_SIZE - n; | 418 | n = MAC_ESP_FIFO_SIZE - |
419 | (esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES); | ||
418 | if (n > esp_count) | 420 | if (n > esp_count) |
419 | n = esp_count; | 421 | n = esp_count; |
420 | 422 | ||
@@ -429,7 +431,7 @@ static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count, | |||
429 | } | 431 | } |
430 | } | 432 | } |
431 | 433 | ||
432 | local_irq_restore(flags); | 434 | enable_irq(esp->host->irq); |
433 | } | 435 | } |
434 | 436 | ||
435 | static int mac_esp_irq_pending(struct esp *esp) | 437 | static int mac_esp_irq_pending(struct esp *esp) |
@@ -492,29 +494,12 @@ static int __devinit esp_mac_probe(struct platform_device *dev) | |||
492 | struct Scsi_Host *host; | 494 | struct Scsi_Host *host; |
493 | struct esp *esp; | 495 | struct esp *esp; |
494 | int err; | 496 | int err; |
495 | int chips_present; | ||
496 | struct mac_esp_priv *mep; | 497 | struct mac_esp_priv *mep; |
497 | 498 | ||
498 | if (!MACH_IS_MAC) | 499 | if (!MACH_IS_MAC) |
499 | return -ENODEV; | 500 | return -ENODEV; |
500 | 501 | ||
501 | switch (macintosh_config->scsi_type) { | 502 | if (dev->id > 1) |
502 | case MAC_SCSI_QUADRA: | ||
503 | case MAC_SCSI_QUADRA3: | ||
504 | chips_present = 1; | ||
505 | break; | ||
506 | case MAC_SCSI_QUADRA2: | ||
507 | if ((macintosh_config->ident == MAC_MODEL_Q900) || | ||
508 | (macintosh_config->ident == MAC_MODEL_Q950)) | ||
509 | chips_present = 2; | ||
510 | else | ||
511 | chips_present = 1; | ||
512 | break; | ||
513 | default: | ||
514 | chips_present = 0; | ||
515 | } | ||
516 | |||
517 | if (dev->id + 1 > chips_present) | ||
518 | return -ENODEV; | 503 | return -ENODEV; |
519 | 504 | ||
520 | host = scsi_host_alloc(tpnt, sizeof(struct esp)); | 505 | host = scsi_host_alloc(tpnt, sizeof(struct esp)); |
@@ -639,55 +624,26 @@ static struct platform_driver esp_mac_driver = { | |||
639 | .probe = esp_mac_probe, | 624 | .probe = esp_mac_probe, |
640 | .remove = __devexit_p(esp_mac_remove), | 625 | .remove = __devexit_p(esp_mac_remove), |
641 | .driver = { | 626 | .driver = { |
642 | .name = DRV_MODULE_NAME, | 627 | .name = DRV_MODULE_NAME, |
628 | .owner = THIS_MODULE, | ||
643 | }, | 629 | }, |
644 | }; | 630 | }; |
645 | 631 | ||
646 | static int __init mac_esp_init(void) | 632 | static int __init mac_esp_init(void) |
647 | { | 633 | { |
648 | int err; | 634 | return platform_driver_register(&esp_mac_driver); |
649 | |||
650 | err = platform_driver_register(&esp_mac_driver); | ||
651 | if (err) | ||
652 | return err; | ||
653 | |||
654 | internal_pdev = platform_device_alloc(DRV_MODULE_NAME, 0); | ||
655 | if (internal_pdev && platform_device_add(internal_pdev)) { | ||
656 | platform_device_put(internal_pdev); | ||
657 | internal_pdev = NULL; | ||
658 | } | ||
659 | external_pdev = platform_device_alloc(DRV_MODULE_NAME, 1); | ||
660 | if (external_pdev && platform_device_add(external_pdev)) { | ||
661 | platform_device_put(external_pdev); | ||
662 | external_pdev = NULL; | ||
663 | } | ||
664 | |||
665 | if (internal_pdev || external_pdev) { | ||
666 | return 0; | ||
667 | } else { | ||
668 | platform_driver_unregister(&esp_mac_driver); | ||
669 | return -ENOMEM; | ||
670 | } | ||
671 | } | 635 | } |
672 | 636 | ||
673 | static void __exit mac_esp_exit(void) | 637 | static void __exit mac_esp_exit(void) |
674 | { | 638 | { |
675 | platform_driver_unregister(&esp_mac_driver); | 639 | platform_driver_unregister(&esp_mac_driver); |
676 | |||
677 | if (internal_pdev) { | ||
678 | platform_device_unregister(internal_pdev); | ||
679 | internal_pdev = NULL; | ||
680 | } | ||
681 | if (external_pdev) { | ||
682 | platform_device_unregister(external_pdev); | ||
683 | external_pdev = NULL; | ||
684 | } | ||
685 | } | 640 | } |
686 | 641 | ||
687 | MODULE_DESCRIPTION("Mac ESP SCSI driver"); | 642 | MODULE_DESCRIPTION("Mac ESP SCSI driver"); |
688 | MODULE_AUTHOR("Finn Thain <fthain@telegraphics.com.au>"); | 643 | MODULE_AUTHOR("Finn Thain <fthain@telegraphics.com.au>"); |
689 | MODULE_LICENSE("GPL v2"); | 644 | MODULE_LICENSE("GPL v2"); |
690 | MODULE_VERSION(DRV_VERSION); | 645 | MODULE_VERSION(DRV_VERSION); |
646 | MODULE_ALIAS("platform:" DRV_MODULE_NAME); | ||
691 | 647 | ||
692 | module_init(mac_esp_init); | 648 | module_init(mac_esp_init); |
693 | module_exit(mac_esp_exit); | 649 | module_exit(mac_esp_exit); |