mirror of
https://github.com/torvalds/linux.git
synced 2024-09-20 06:53:04 +00:00
scsi: mac_scsi: Refactor polling loop
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>
This commit is contained in:
parent
5ec4f820cb
commit
5545c3165c
|
@ -208,8 +208,6 @@ __setup("mac5380=", mac_scsi_setup);
|
|||
".previous \n" \
|
||||
: "+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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
unsigned char *dst, int len)
|
||||
{
|
||||
|
@ -283,9 +311,7 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
|
|||
|
||||
hostdata->pdma_residual = len;
|
||||
|
||||
while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
|
||||
BASR_DRQ | BASR_PHASE_MATCH,
|
||||
BASR_DRQ | BASR_PHASE_MATCH, 0)) {
|
||||
while (macscsi_wait_for_drq(hostdata) == 0) {
|
||||
int bytes, chunk_bytes;
|
||||
|
||||
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);
|
||||
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) {
|
||||
d += bytes;
|
||||
hostdata->pdma_residual -= bytes;
|
||||
}
|
||||
|
||||
if (hostdata->pdma_residual == 0)
|
||||
goto out;
|
||||
|
||||
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
|
||||
goto out;
|
||||
|
||||
if (bytes == 0)
|
||||
udelay(MAC_PDMA_DELAY);
|
||||
break;
|
||||
|
||||
if (bytes > 0)
|
||||
continue;
|
||||
|
@ -321,16 +344,9 @@ static inline int macscsi_pread(struct NCR5380_hostdata *hostdata,
|
|||
continue;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -343,9 +359,7 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
|
|||
|
||||
hostdata->pdma_residual = len;
|
||||
|
||||
while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
|
||||
BASR_DRQ | BASR_PHASE_MATCH,
|
||||
BASR_DRQ | BASR_PHASE_MATCH, 0)) {
|
||||
while (macscsi_wait_for_drq(hostdata) == 0) {
|
||||
int bytes, chunk_bytes;
|
||||
|
||||
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);
|
||||
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) {
|
||||
s += 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__);
|
||||
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)
|
||||
continue;
|
||||
|
||||
|
@ -390,16 +401,9 @@ static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata,
|
|||
continue;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user