Merge branch 'oprofile-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / drivers / scsi / mac_esp.c
index c24e86f..4a90eaf 100644 (file)
@@ -22,7 +22,6 @@
 
 #include <asm/irq.h>
 #include <asm/dma.h>
-
 #include <asm/macints.h>
 #include <asm/macintosh.h>
 
@@ -53,7 +52,6 @@ struct mac_esp_priv {
        void __iomem *pdma_io;
        int error;
 };
-static struct platform_device *internal_pdev, *external_pdev;
 static struct esp *esp_chips[2];
 
 #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,
  * Programmed IO routines follow.
  */
 
-static inline int mac_esp_wait_for_fifo(struct esp *esp)
+static inline unsigned int mac_esp_wait_for_fifo(struct esp *esp)
 {
        int i = 500000;
 
        do {
-               if (esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES)
-                       return 0;
+               unsigned int fbytes = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES;
+
+               if (fbytes)
+                       return fbytes;
 
                udelay(2);
        } while (--i);
 
        printk(KERN_ERR PFX "FIFO is empty (sreg %02x)\n",
               esp_read8(ESP_STATUS));
-       return 1;
+       return 0;
 }
 
 static inline int mac_esp_wait_for_intr(struct esp *esp)
 {
+       struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp);
        int i = 500000;
 
        do {
@@ -308,6 +309,7 @@ static inline int mac_esp_wait_for_intr(struct esp *esp)
        } while (--i);
 
        printk(KERN_ERR PFX "IRQ timeout (sreg %02x)\n", esp->sreg);
+       mep->error = 1;
        return 1;
 }
 
@@ -347,11 +349,10 @@ static inline int mac_esp_wait_for_intr(struct esp *esp)
 static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,
                                 u32 dma_count, int write, u8 cmd)
 {
-       unsigned long flags;
        struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp);
        u8 *fifo = esp->regs + ESP_FDATA * 16;
 
-       local_irq_save(flags);
+       disable_irq(esp->host->irq);
 
        cmd &= ~ESP_CMD_DMA;
        mep->error = 0;
@@ -359,11 +360,35 @@ static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,
        if (write) {
                scsi_esp_cmd(esp, cmd);
 
-               if (!mac_esp_wait_for_intr(esp)) {
-                       if (mac_esp_wait_for_fifo(esp))
-                               esp_count = 0;
-               } else {
-                       esp_count = 0;
+               while (1) {
+                       unsigned int n;
+
+                       n = mac_esp_wait_for_fifo(esp);
+                       if (!n)
+                               break;
+
+                       if (n > esp_count)
+                               n = esp_count;
+                       esp_count -= n;
+
+                       MAC_ESP_PIO_LOOP("%2@,%0@+", n);
+
+                       if (!esp_count)
+                               break;
+
+                       if (mac_esp_wait_for_intr(esp))
+                               break;
+
+                       if (((esp->sreg & ESP_STAT_PMASK) != ESP_DIP) &&
+                           ((esp->sreg & ESP_STAT_PMASK) != ESP_MIP))
+                               break;
+
+                       esp->ireg = esp_read8(ESP_INTRPT);
+                       if ((esp->ireg & (ESP_INTR_DC | ESP_INTR_BSERV)) !=
+                           ESP_INTR_BSERV)
+                               break;
+
+                       scsi_esp_cmd(esp, ESP_CMD_TI);
                }
        } else {
                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,
                        MAC_ESP_PIO_LOOP("%0@+,%2@", esp_count);
 
                scsi_esp_cmd(esp, cmd);
-       }
-
-       while (esp_count) {
-               unsigned int n;
 
-               if (mac_esp_wait_for_intr(esp)) {
-                       mep->error = 1;
-                       break;
-               }
-
-               if (esp->sreg & ESP_STAT_SPAM) {
-                       printk(KERN_ERR PFX "gross error\n");
-                       mep->error = 1;
-                       break;
-               }
-
-               n = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES;
-
-               if (write) {
-                       if (n > esp_count)
-                               n = esp_count;
-                       esp_count -= n;
-
-                       MAC_ESP_PIO_LOOP("%2@,%0@+", n);
+               while (esp_count) {
+                       unsigned int n;
 
-                       if ((esp->sreg & ESP_STAT_PMASK) == ESP_STATP)
+                       if (mac_esp_wait_for_intr(esp))
                                break;
 
-                       if (esp_count) {
-                               esp->ireg = esp_read8(ESP_INTRPT);
-                               if (esp->ireg & ESP_INTR_DC)
-                                       break;
+                       if (((esp->sreg & ESP_STAT_PMASK) != ESP_DOP) &&
+                           ((esp->sreg & ESP_STAT_PMASK) != ESP_MOP))
+                               break;
 
-                               scsi_esp_cmd(esp, ESP_CMD_TI);
-                       }
-               } else {
                        esp->ireg = esp_read8(ESP_INTRPT);
-                       if (esp->ireg & ESP_INTR_DC)
+                       if ((esp->ireg & (ESP_INTR_DC | ESP_INTR_BSERV)) !=
+                           ESP_INTR_BSERV)
                                break;
 
-                       n = MAC_ESP_FIFO_SIZE - n;
+                       n = MAC_ESP_FIFO_SIZE -
+                           (esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES);
                        if (n > esp_count)
                                n = esp_count;
 
@@ -429,7 +431,7 @@ static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,
                }
        }
 
-       local_irq_restore(flags);
+       enable_irq(esp->host->irq);
 }
 
 static int mac_esp_irq_pending(struct esp *esp)
@@ -492,29 +494,12 @@ static int __devinit esp_mac_probe(struct platform_device *dev)
        struct Scsi_Host *host;
        struct esp *esp;
        int err;
-       int chips_present;
        struct mac_esp_priv *mep;
 
        if (!MACH_IS_MAC)
                return -ENODEV;
 
-       switch (macintosh_config->scsi_type) {
-       case MAC_SCSI_QUADRA:
-       case MAC_SCSI_QUADRA3:
-               chips_present = 1;
-               break;
-       case MAC_SCSI_QUADRA2:
-               if ((macintosh_config->ident == MAC_MODEL_Q900) ||
-                   (macintosh_config->ident == MAC_MODEL_Q950))
-                       chips_present = 2;
-               else
-                       chips_present = 1;
-               break;
-       default:
-               chips_present = 0;
-       }
-
-       if (dev->id + 1 > chips_present)
+       if (dev->id > 1)
                return -ENODEV;
 
        host = scsi_host_alloc(tpnt, sizeof(struct esp));
@@ -639,55 +624,26 @@ static struct platform_driver esp_mac_driver = {
        .probe    = esp_mac_probe,
        .remove   = __devexit_p(esp_mac_remove),
        .driver   = {
-               .name     = DRV_MODULE_NAME,
+               .name   = DRV_MODULE_NAME,
+               .owner  = THIS_MODULE,
        },
 };
 
 static int __init mac_esp_init(void)
 {
-       int err;
-
-       err = platform_driver_register(&esp_mac_driver);
-       if (err)
-               return err;
-
-       internal_pdev = platform_device_alloc(DRV_MODULE_NAME, 0);
-       if (internal_pdev && platform_device_add(internal_pdev)) {
-               platform_device_put(internal_pdev);
-               internal_pdev = NULL;
-       }
-       external_pdev = platform_device_alloc(DRV_MODULE_NAME, 1);
-       if (external_pdev && platform_device_add(external_pdev)) {
-               platform_device_put(external_pdev);
-               external_pdev = NULL;
-       }
-
-       if (internal_pdev || external_pdev) {
-               return 0;
-       } else {
-               platform_driver_unregister(&esp_mac_driver);
-               return -ENOMEM;
-       }
+       return platform_driver_register(&esp_mac_driver);
 }
 
 static void __exit mac_esp_exit(void)
 {
        platform_driver_unregister(&esp_mac_driver);
-
-       if (internal_pdev) {
-               platform_device_unregister(internal_pdev);
-               internal_pdev = NULL;
-       }
-       if (external_pdev) {
-               platform_device_unregister(external_pdev);
-               external_pdev = NULL;
-       }
 }
 
 MODULE_DESCRIPTION("Mac ESP SCSI driver");
 MODULE_AUTHOR("Finn Thain <fthain@telegraphics.com.au>");
 MODULE_LICENSE("GPL v2");
 MODULE_VERSION(DRV_VERSION);
+MODULE_ALIAS("platform:" DRV_MODULE_NAME);
 
 module_init(mac_esp_init);
 module_exit(mac_esp_exit);