mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-07-06 17:35:20 +02:00
scsi: mac_scsi: Refactor polling loop
commit 5545c3165c
upstream.
Before the error handling can be revised, some preparation is needed.
Refactor the polling loop with a new function, macscsi_wait_for_drq().
This function will gain more call sites in the next patch.
Cc: stable@vger.kernel.org # 5.15+
Tested-by: Stan Johnson <userm57@yahoo.com>
Signed-off-by: Finn Thain <fthain@linux-m68k.org>
Link: https://lore.kernel.org/r/6a5ffabb4290c0d138c6d285fda8fa3902e926f0.1723001788.git.fthain@linux-m68k.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
6e8dc2050a
commit
0120c7762f
|
@ -208,8 +208,6 @@ __setup("mac5380=", mac_scsi_setup);
|
||||||
".previous \n" \
|
".previous \n" \
|
||||||
: "+a" (addr), "+r" (n), "+r" (result) : "a" (io))
|
: "+a" (addr), "+r" (n), "+r" (result) : "a" (io))
|
||||||
|
|
||||||
#define MAC_PDMA_DELAY 32
|
|
||||||
|
|
||||||
static inline int mac_pdma_recv(void __iomem *io, unsigned char *start, int n)
|
static inline int mac_pdma_recv(void __iomem *io, unsigned char *start, int n)
|
||||||
{
|
{
|
||||||
unsigned char *addr = start;
|
unsigned char *addr = start;
|
||||||
|
@ -274,6 +272,36 @@ static inline void write_ctrl_reg(struct NCR5380_hostdata *hostdata, u32 value)
|
||||||
out_be32(hostdata->io + (CTRL_REG << 4), value);
|
out_be32(hostdata->io + (CTRL_REG << 4), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int macscsi_wait_for_drq(struct NCR5380_hostdata *hostdata)
|
||||||
|
{
|
||||||
|
unsigned int n = 1; /* effectively multiplies NCR5380_REG_POLL_TIME */
|
||||||
|
unsigned char basr;
|
||||||
|
|
||||||
|
again:
|
||||||
|
basr = NCR5380_read(BUS_AND_STATUS_REG);
|
||||||
|
|
||||||
|
if (!(basr & BASR_PHASE_MATCH))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (basr & BASR_IRQ)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (basr & BASR_DRQ)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (n-- == 0) {
|
||||||
|
NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
|
||||||
|
dsprintk(NDEBUG_PSEUDO_DMA, hostdata->host,
|
||||||
|
"%s: DRQ timeout\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
NCR5380_poll_politely2(hostdata,
|
||||||
|
BUS_AND_STATUS_REG, BASR_DRQ, BASR_DRQ,
|
||||||
|
BUS_AND_STATUS_REG, BASR_PHASE_MATCH, 0, 0);
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
|
static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
|
||||||
unsigned char *dst, int len)
|
unsigned char *dst, int len)
|
||||||
{
|
{
|
||||||
|
@ -283,9 +311,7 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
|
||||||
|
|
||||||
hostdata->pdma_residual = len;
|
hostdata->pdma_residual = len;
|
||||||
|
|
||||||
while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
|
while (macscsi_wait_for_drq(hostdata) == 0) {
|
||||||
BASR_DRQ | BASR_PHASE_MATCH,
|
|
||||||
BASR_DRQ | BASR_PHASE_MATCH, 0)) {
|
|
||||||
int bytes, chunk_bytes;
|
int bytes, chunk_bytes;
|
||||||
|
|
||||||
if (macintosh_config->ident == MAC_MODEL_IIFX)
|
if (macintosh_config->ident == MAC_MODEL_IIFX)
|
||||||
|
@ -295,19 +321,16 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
|
||||||
chunk_bytes = min(hostdata->pdma_residual, 512);
|
chunk_bytes = min(hostdata->pdma_residual, 512);
|
||||||
bytes = mac_pdma_recv(s, d, chunk_bytes);
|
bytes = mac_pdma_recv(s, d, chunk_bytes);
|
||||||
|
|
||||||
|
if (macintosh_config->ident == MAC_MODEL_IIFX)
|
||||||
|
write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE);
|
||||||
|
|
||||||
if (bytes > 0) {
|
if (bytes > 0) {
|
||||||
d += bytes;
|
d += bytes;
|
||||||
hostdata->pdma_residual -= bytes;
|
hostdata->pdma_residual -= bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hostdata->pdma_residual == 0)
|
if (hostdata->pdma_residual == 0)
|
||||||
goto out;
|
break;
|
||||||
|
|
||||||
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (bytes == 0)
|
|
||||||
udelay(MAC_PDMA_DELAY);
|
|
||||||
|
|
||||||
if (bytes > 0)
|
if (bytes > 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -321,16 +344,9 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
result = -1;
|
result = -1;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
scmd_printk(KERN_ERR, hostdata->connected,
|
|
||||||
"%s: phase mismatch or !DRQ\n", __func__);
|
|
||||||
NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
|
|
||||||
result = -1;
|
|
||||||
out:
|
|
||||||
if (macintosh_config->ident == MAC_MODEL_IIFX)
|
|
||||||
write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,9 +359,7 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
|
||||||
|
|
||||||
hostdata->pdma_residual = len;
|
hostdata->pdma_residual = len;
|
||||||
|
|
||||||
while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
|
while (macscsi_wait_for_drq(hostdata) == 0) {
|
||||||
BASR_DRQ | BASR_PHASE_MATCH,
|
|
||||||
BASR_DRQ | BASR_PHASE_MATCH, 0)) {
|
|
||||||
int bytes, chunk_bytes;
|
int bytes, chunk_bytes;
|
||||||
|
|
||||||
if (macintosh_config->ident == MAC_MODEL_IIFX)
|
if (macintosh_config->ident == MAC_MODEL_IIFX)
|
||||||
|
@ -355,6 +369,9 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
|
||||||
chunk_bytes = min(hostdata->pdma_residual, 512);
|
chunk_bytes = min(hostdata->pdma_residual, 512);
|
||||||
bytes = mac_pdma_send(s, d, chunk_bytes);
|
bytes = mac_pdma_send(s, d, chunk_bytes);
|
||||||
|
|
||||||
|
if (macintosh_config->ident == MAC_MODEL_IIFX)
|
||||||
|
write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE);
|
||||||
|
|
||||||
if (bytes > 0) {
|
if (bytes > 0) {
|
||||||
s += bytes;
|
s += bytes;
|
||||||
hostdata->pdma_residual -= bytes;
|
hostdata->pdma_residual -= bytes;
|
||||||
|
@ -369,15 +386,9 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
|
||||||
"%s: Last Byte Sent timeout\n", __func__);
|
"%s: Last Byte Sent timeout\n", __func__);
|
||||||
result = -1;
|
result = -1;
|
||||||
}
|
}
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (bytes == 0)
|
|
||||||
udelay(MAC_PDMA_DELAY);
|
|
||||||
|
|
||||||
if (bytes > 0)
|
if (bytes > 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -390,16 +401,9 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
result = -1;
|
result = -1;
|
||||||
goto out;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
scmd_printk(KERN_ERR, hostdata->connected,
|
|
||||||
"%s: phase mismatch or !DRQ\n", __func__);
|
|
||||||
NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host);
|
|
||||||
result = -1;
|
|
||||||
out:
|
|
||||||
if (macintosh_config->ident == MAC_MODEL_IIFX)
|
|
||||||
write_ctrl_reg(hostdata, CTRL_INTERRUPTS_ENABLE);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user