summaryrefslogtreecommitdiff
path: root/drivers/scsi/mac_esp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mac_esp.c')
-rw-r--r--drivers/scsi/mac_esp.c152
1 files changed, 54 insertions, 98 deletions
diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c
index c24e86f0780..4a90eaf7cb6 100644
--- a/drivers/scsi/mac_esp.c
+++ b/drivers/scsi/mac_esp.c
@@ -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);