scsi: mac_scsi: Enable PDMA on Mac IIfx
Add support for Apple's custom "SCSI DMA" chip. This patch doesn't make use of its DMA capability. Just the PDMA capability is sufficient to improve sequential read throughput by a factor of 5. Cc: Michael Schmitz <schmitzmic@gmail.com> Cc: Joshua Thompson <funaho@jurai.org> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Tested-by: Stan Johnson <userm57@yahoo.com> Tested-by: Michael Schmitz <schmitzmic@gmail.com> Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
78ff751f8e
commit
8fb9a64eb6
@ -911,6 +911,10 @@ static const struct resource mac_scsi_iifx_rsrc[] __initconst = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = 0x50008000,
|
||||
.end = 0x50009FFF,
|
||||
}, {
|
||||
.flags = IORESOURCE_MEM,
|
||||
.start = 0x50008000,
|
||||
.end = 0x50009FFF,
|
||||
},
|
||||
};
|
||||
|
||||
@ -1012,10 +1016,12 @@ int __init mac_platform_init(void)
|
||||
case MAC_SCSI_IIFX:
|
||||
/* Addresses from The Guide to Mac Family Hardware.
|
||||
* $5000 8000 - $5000 9FFF: SCSI DMA
|
||||
* $5000 A000 - $5000 BFFF: Alternate SCSI
|
||||
* $5000 C000 - $5000 DFFF: Alternate SCSI (DMA)
|
||||
* $5000 E000 - $5000 FFFF: Alternate SCSI (Hsk)
|
||||
* The SCSI DMA custom IC embeds the 53C80 core. mac_scsi does
|
||||
* not make use of its DMA or hardware handshaking logic.
|
||||
* The A/UX header file sys/uconfig.h says $50F0 8000.
|
||||
* The "SCSI DMA" custom IC embeds the 53C80 core and
|
||||
* supports Programmed IO, DMA and PDMA (hardware handshake).
|
||||
*/
|
||||
platform_device_register_simple("mac_scsi", 0,
|
||||
mac_scsi_iifx_rsrc, ARRAY_SIZE(mac_scsi_iifx_rsrc));
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <asm/hwtest.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/macintosh.h>
|
||||
#include <asm/macints.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
@ -262,11 +263,22 @@ out:
|
||||
return addr - start;
|
||||
}
|
||||
|
||||
/* The "SCSI DMA" chip on the IIfx implements this register. */
|
||||
#define CTRL_REG 0x8
|
||||
#define CTRL_INTERRUPTS_ENABLE BIT(1)
|
||||
#define CTRL_HANDSHAKE_MODE BIT(3)
|
||||
|
||||
static inline void write_ctrl_reg(struct NCR5380_hostdata *hostdata, u32 value)
|
||||
{
|
||||
out_be32(hostdata->io + (CTRL_REG << 4), value);
|
||||
}
|
||||
|
||||
static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
|
||||
unsigned char *dst, int len)
|
||||
{
|
||||
u8 __iomem *s = hostdata->pdma_io + (INPUT_DATA_REG << 4);
|
||||
unsigned char *d = dst;
|
||||
int result = 0;
|
||||
|
||||
hostdata->pdma_residual = len;
|
||||
|
||||
@ -275,6 +287,10 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
|
||||
BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) {
|
||||
int bytes;
|
||||
|
||||
if (macintosh_config->ident == MAC_MODEL_IIFX)
|
||||
write_ctrl_reg(hostdata, CTRL_HANDSHAKE_MODE |
|
||||
CTRL_INTERRUPTS_ENABLE);
|
||||
|
||||
bytes = mac_pdma_recv(s, d, min(hostdata->pdma_residual, 512));
|
||||
|
||||
if (bytes > 0) {
|
||||
@ -283,7 +299,7 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
|
||||
}
|
||||
|
||||
if (hostdata->pdma_residual == 0)
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
if (NCR5380_poll_politely2(hostdata, STATUS_REG, SR_REQ, SR_REQ,
|
||||
BUS_AND_STATUS_REG, BASR_ACK,
|
||||
@ -291,7 +307,7 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
|
||||
scmd_printk(KERN_DEBUG, hostdata->connected,
|
||||
"%s: !REQ and !ACK\n", __func__);
|
||||
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
if (bytes == 0)
|
||||
udelay(MAC_PDMA_DELAY);
|
||||
@ -302,13 +318,18 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
|
||||
dsprintk(NDEBUG_PSEUDO_DMA, hostdata->host,
|
||||
"%s: bus error (%d/%d)\n", __func__, d - dst, len);
|
||||
NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
|
||||
return -1;
|
||||
result = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
scmd_printk(KERN_ERR, hostdata->connected,
|
||||
"%s: phase mismatch or !DRQ\n", __func__);
|
||||
NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
|
||||
return -1;
|
||||
result = -1;
|
||||
out:
|
||||
if (macintosh_config->ident == MAC_MODEL_IIFX)
|
||||
write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE);
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
|
||||
@ -316,6 +337,7 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
|
||||
{
|
||||
unsigned char *s = src;
|
||||
u8 __iomem *d = hostdata->pdma_io + (OUTPUT_DATA_REG << 4);
|
||||
int result = 0;
|
||||
|
||||
hostdata->pdma_residual = len;
|
||||
|
||||
@ -324,6 +346,10 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
|
||||
BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) {
|
||||
int bytes;
|
||||
|
||||
if (macintosh_config->ident == MAC_MODEL_IIFX)
|
||||
write_ctrl_reg(hostdata, CTRL_HANDSHAKE_MODE |
|
||||
CTRL_INTERRUPTS_ENABLE);
|
||||
|
||||
bytes = mac_pdma_send(s, d, min(hostdata->pdma_residual, 512));
|
||||
|
||||
if (bytes > 0) {
|
||||
@ -337,7 +363,7 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
|
||||
TCR_LAST_BYTE_SENT, HZ / 64) < 0)
|
||||
scmd_printk(KERN_ERR, hostdata->connected,
|
||||
"%s: Last Byte Sent timeout\n", __func__);
|
||||
return 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (NCR5380_poll_politely2(hostdata, STATUS_REG, SR_REQ, SR_REQ,
|
||||
@ -346,7 +372,7 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
|
||||
scmd_printk(KERN_DEBUG, hostdata->connected,
|
||||
"%s: !REQ and !ACK\n", __func__);
|
||||
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
if (bytes == 0)
|
||||
udelay(MAC_PDMA_DELAY);
|
||||
@ -357,13 +383,18 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
|
||||
dsprintk(NDEBUG_PSEUDO_DMA, hostdata->host,
|
||||
"%s: bus error (%d/%d)\n", __func__, s - src, len);
|
||||
NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
|
||||
return -1;
|
||||
result = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
scmd_printk(KERN_ERR, hostdata->connected,
|
||||
"%s: phase mismatch or !DRQ\n", __func__);
|
||||
NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
|
||||
return -1;
|
||||
result = -1;
|
||||
out:
|
||||
if (macintosh_config->ident == MAC_MODEL_IIFX)
|
||||
write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int macscsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
|
||||
|
Loading…
Reference in New Issue
Block a user