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 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);  |