Re: [PATCH v3 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-27 Thread Finn Thain
On Tue, 27 Jun 2017, Ondrej Zary wrote:

> On Tuesday 27 June 2017 14:42:29 Finn Thain wrote:
> 
> > > ... it triggers sometimes: the value is 1 instead of 0. As we use 
> > > only 16-bit writes, I don't see how the value could ever be odd. 
> > > Looks like a bug in the chip. The index register corrupts during the 
> > > transfer, not after IRQ or timeout. The same check at beginning of 
> > > pwrite() did not trigger.
> >
> > Are you reading this register at the right moment? Have you tried 
> > waiting for it to reach zero, as in,
> >
> > if (NCR5380_poll_politely(hostdata, 13, 0xff, 0, HZ / 64) < 0)
> > /* printk, reset etc */;
> 
> I have not but will try (expecting that it will not change by itself).
> 

Now that I know that it is the byte at the beginning of the block that 
went missing, I agree that there's no point waiting for the byte count to 
change.

I've included a patch with your 512 B limit in v4.

Thanks.

> > Even if this is a reliable way to detect a short transfer, it would be 
> > nice to know the root cause. But I'm being unrealistic: the DTC436 
> > vendor never responded to my requests for technical documentation.
> 
> According to the data corruption observed, it's not a short transfer. 
> The corruption is always the same: one byte missing at the beginning of 
> a 128 B block. It happens only with slow Quantum LPS 240 drive, not with 
> faster IBM DORS-32160.
> 

-- 


Re: [PATCH v3 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-27 Thread Finn Thain
On Tue, 27 Jun 2017, Ondrej Zary wrote:

> On Tuesday 27 June 2017 03:49:16 Finn Thain wrote:
> >
> > ... As long as there's no gated IRQ, we poll for buffer readiness 
> > until timeout. And when there is a gated IRQ, we break both the 
> > polling loop and the transfer loop immediately. Your code and mine are 
> > basically in agreement here.
> 
> Yes, it stops transfer when an IRQ arrives. But the host buffer could be 
> ready at the same time. The IRQ can be an "end-of-DMA" IRQ (IIRC DTC 
> chips assert this earlier than 53C400). Or just a disconnect that 
> occured right now but the chip already read a buffer full of data.
> 

The IRQ should not normally arise during the loop. A BASR_END_DMA_TRANSFER 
interrupt could only happen after the loop has finished sending/receiving, 
which is when /EOP becomes active.

The BASR_PHASE_MATCH interrupt could happen during the transfer if the 
target disconnects suddenly.

It is possible that the 53c400 core would assert /EOP upon 
BASR_PHASE_MATCH interrupt, which could then cause the 53c80 to raise a 
BASR_END_DMA_TRANSFER interrupt too. But who knows?

> > > According to my tests, buffer ready signal is most important - if 
> > > there is any data to read/write, do the transfer. If not, only then 
> > > check why - maybe we got an IRQ (that terminated PDMA). Or no IRQ, 
> > > sometimes the wait for buffer ready times out - we need to terminate 
> > > PDMA manually then (reset).
> > >
> > > Then 53C80 registers should become ready.
> >
> > You seem to be saying that we should ignore the IRQ signal if the 
> > buffers have become ready. Maybe so. Can we try simply resetting the 
> > block counter? (I could imagine that the 53c400 core might leave the 
> > 53c80 registers inaccessible unless we keep accessing the buffers in 
> > the 53c400 core until the transfer is done.)
> 
> We can't reset the block counter because 0 means 256 blocks to transfer 
> (page 13 in datasheet).

I forgot about that. How awful.

> Yes, the 53C80 registers seem to become available only when the PDMA 
> transfer ends by either:
> 1. transferring all blocks (block counter decrementing to zero)
> 2. IRQ

I don't think that Gated IRQ is sufficient to make the 53c80 registers 
available again. If it was, you probably wouldn't have seen "switching to 
slow handshake" when you tested my earlier patch series.

> 3. reset
> 

Maybe we need to do the reset whenever IRQ is detected. I'll put this in 
v4. Please try commenting it out, to see what difference that makes.

> > BTW, with regard to your patch, note that this construct is race prone:
> >
> > while (1) { /* monitor IRQ while waiting for host buffer */
> > csr = NCR5380_read(hostdata->c400_ctl_status);
> > if (!(csr & CSR_HOST_BUF_NOT_RDY))
> > break;
> > if (csr & CSR_GATED_53C80_IRQ) {
> > basr = NCR5380_read(BUS_AND_STATUS_REG);
> > if (!(basr & BASR_PHASE_MATCH) ||
> >(basr & BASR_BUSY_ERROR)) {
> > printk("basr=0x%02x csr=0x%02x at start=%d\n", basr, 
> > csr, start);
> > goto out_wait;
> > }
> > }
> > if (retries-- < 1) {
> > shost_printk(KERN_ERR, hostdata->host, "53C400r: host buffer 
> > not ready in
> > time\n"); NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
> > NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
> > goto out_wait;
> > }
> > }
> >
> > This code can "goto out_wait" when !(csr & CSR_HOST_BUF_NOT_RDY). It 
> > depends on timing. This would seem to be contrary to your stated aim.
> >
> > Moreover, this code can also "break" when (csr & CSR_GATED_53C80_IRQ). 
> > That depends on timing too. But this may be an improvement on my code 
> > if it allows the 53c80 registers to become accessible, by allowing the 
> > block counter to be decremented.
> 
> Yes, it continue the transfer even if the IRQ is asserted - as long as 
> the buffer is ready. That's intended.
> 

If we continue to try to send when there is a phase mismatch (i.e. sudden 
disconnection) we'll probably end up with a buffer ready timeout. And we 
may also have trouble calculating the residual correctly.

Hence my version of your patch always breaks out of the transfer loop as 
soon as any Gated IRQ is detected. If that then means a compulsory reset 
of the 53c400 core, I guess I can live with that.

> > The uncertainty here was one of the reasons I reworked this code.
> 
> My version reads CSR only once per loop but that probably does not help 
> at all as the HW state could change anytime. The chip's design seems to 
> be very race-prone.
> 
> > > This is a log from writing 230 MB file using my code with some debug 
> > > prints, on a NCR53C400. No 53C80 timeouts, only disconnects and some 
> > > host buffer timeouts (maybe the drive sometimes just slows down 
> > > without disconnecting?)
> > >
> > > [ 3378.503828] basr=0x10 csr=0xd5 at start=512
> > > [ 3461.257973] w 

Re: [PATCH v3 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-27 Thread Ondrej Zary
On Tuesday 27 June 2017 03:49:16 Finn Thain wrote:
> On Mon, 26 Jun 2017, Ondrej Zary wrote:
> > No apparent change in behavior, the first write test resulted in:
> > [  842.830802] sd 2:0:1:0: [sdb] tag#0 53c80 registers not accessible,
> > device will be reset [  842.830802] sd 2:0:1:0: [sdb] tag#0 switching to
> > slow handshake
> >
> > Checking for IRQ after poll_politely2 does not seem right because we can
> > miss the buffer ready signal.
>
> How so? As long as there's no gated IRQ, we poll for buffer readiness
> until timeout. And when there is a gated IRQ, we break both the polling
> loop and the transfer loop immediately. Your code and mine are basically
> in agreement here.

Yes, it stops transfer when an IRQ arrives. But the host buffer could be ready
at the same time. The IRQ can be an "end-of-DMA" IRQ (IIRC DTC chips assert
this earlier than 53C400). Or just a disconnect that occured right now but the
chip already read a buffer full of data.

> > According to my tests, buffer ready signal is most important - if there
> > is any data to read/write, do the transfer. If not, only then check why
> > - maybe we got an IRQ (that terminated PDMA). Or no IRQ, sometimes the
> > wait for buffer ready times out - we need to terminate PDMA manually
> > then (reset).
> >
> > Then 53C80 registers should become ready.
>
> You seem to be saying that we should ignore the IRQ signal if the buffers
> have become ready. Maybe so. Can we try simply resetting the block
> counter? (I could imagine that the 53c400 core might leave the 53c80
> registers inaccessible unless we keep accessing the buffers in the 53c400
> core until the transfer is done.)

We can't reset the block counter because 0 means 256 blocks to transfer (page
13 in datasheet).
Yes, the 53C80 registers seem to become available only when the PDMA transfer
ends by either:
1. transferring all blocks (block counter decrementing to zero)
2. IRQ
3. reset

> BTW, with regard to your patch, note that this construct is race prone:
>
> while (1) {   /* monitor IRQ while waiting for host buffer */
>   csr = NCR5380_read(hostdata->c400_ctl_status);
>   if (!(csr & CSR_HOST_BUF_NOT_RDY))
>   break;
>   if (csr & CSR_GATED_53C80_IRQ) {
>   basr = NCR5380_read(BUS_AND_STATUS_REG);
>   if (!(basr & BASR_PHASE_MATCH) ||
>  (basr & BASR_BUSY_ERROR)) {
>   printk("basr=0x%02x csr=0x%02x at start=%d\n", basr, 
> csr, start);
>   goto out_wait;
>   }
>   }
>   if (retries-- < 1) {
>   shost_printk(KERN_ERR, hostdata->host, "53C400r: host buffer 
> not ready in
> time\n"); NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
>   NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
>   goto out_wait;
>   }
> }
>
> This code can "goto out_wait" when !(csr & CSR_HOST_BUF_NOT_RDY). It
> depends on timing. This would seem to be contrary to your stated aim.
>
> Moreover, this code can also "break" when (csr & CSR_GATED_53C80_IRQ).
> That depends on timing too. But this may be an improvement on my code if
> it allows the 53c80 registers to become accessible, by allowing the block
> counter to be decremented.

Yes, it continue the transfer even if the IRQ is asserted - as long as the
buffer is ready. That's intended.

> The uncertainty here was one of the reasons I reworked this code.

My version reads CSR only once per loop but that probably does not help at all
as the HW state could change anytime. The chip's design seems to be very
race-prone.

> > This is a log from writing 230 MB file using my code with some debug
> > prints, on a NCR53C400. No 53C80 timeouts, only disconnects and some
> > host buffer timeouts (maybe the drive sometimes just slows down without
> > disconnecting?)
> >
> > [ 3378.503828] basr=0x10 csr=0xd5 at start=512
> > [ 3461.257973] w basr=0x10 csr=0x95 at start=3840
> > [ 3461.838225] w basr=0x10 csr=0x95 at start=3840
> > [ 3462.683446] w basr=0x10 csr=0x95 at start=3840
> > [ 3463.416911] w basr=0x10 csr=0x95 at start=3840
> > [ 3465.117804] scsi host2: 53C400w: host buffer not ready in time
> > [ 3465.276375] w basr=0x10 csr=0x95 at start=3328
> > [ 3466.457701] w basr=0x10 csr=0x95 at start=1792
> > [ 3467.019643] scsi host2: 53C400w: host buffer not ready in time
> > [ 3467.619058] scsi host2: 53C400w: host buffer not ready in time
> > [ 3467.799619] w basr=0x10 csr=0x95 at start=3840
> > [ 3552.123501] w basr=0x10 csr=0x95 at start=2304
> > [ 3552.771223] w basr=0x10 csr=0x95 at start=1280
> > [ 3554.556451] w basr=0x10 csr=0x95 at start=2816
> > [ 3555.229646] w basr=0x10 csr=0x95 at start=1792
> > [ 3555.630632] scsi host2: 53C400w: host buffer not ready in time
> > [ 3555.774560] w basr=0x10 csr=0x95 at start=768
> > [ 3625.541608] w basr=0x10 csr=0x95 at start=3328
> > [ 3640.099861] w basr=0x10 csr=0x95 at start=1792
> > [ 3641.442671] w basr=0x10 csr=0x95 at start=2816
> > 

Re: [PATCH v3 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-27 Thread Ondrej Zary
On Tuesday 27 June 2017 14:42:29 Finn Thain wrote:
> On Tue, 27 Jun 2017, Ondrej Zary wrote:
> > BTW. I've probably found the DTC write corruption. Added the following
> > check (13 is host buffer index register) -
>
> That register is not mentioned in my 53c400 datasheet.

Yes, it's not there. But we don't have 53C400A and DTC436 datasheets (this 
register works on both).

> > and it triggers sometimes: the value is 1 instead of 0. As we use only
> > 16-bit writes, I don't see how the value could ever be odd. Looks like a
> > bug in the chip. The index register corrupts during the transfer, not
> > after IRQ or timeout. The same check at beginning of pwrite() did not
> > trigger.
>
> Are you reading this register at the right moment? Have you tried waiting
> for it to reach zero, as in,
>
>   if (NCR5380_poll_politely(hostdata, 13, 0xff, 0, HZ / 64) < 0)
>   /* printk, reset etc */;

I have not but will try (expecting that it will not change by itself).

> Even if this is a reliable way to detect a short transfer, it would be
> nice to know the root cause. But I'm being unrealistic: the DTC436 vendor
> never responded to my requests for technical documentation.

According to the data corruption observed, it's not a short transfer. The 
corruption is always the same: one byte missing at the beginning of a 128 B 
block. It happens only with slow Quantum LPS 240 drive, not with faster IBM 
DORS-32160.

> > The index register is not writable so we must(?) reset the PDMA engine
> > to recover. However, this quick attempt to fix does not work, maybe we
> > should reload the block count and continue?
>
> I don't know if it is possible to recover. If the last byte never reached
> the scsi bus, then once you reset the 53c400 core, you need the driver to
> perform a single-byte PIO transfer after the short PDMA transfer. This
> would require that you set the residual appropriately (though in my
> experience that may not be sufficient).
>
> It may be better to simply limit the transfer to 512 bytes instead of
> attempting to recover based on an undocumented (?) register, etc. Seems
> like a bit of a hack.
>
> > --- a/drivers/scsi/g_NCR5380.c
> > +++ b/drivers/scsi/g_NCR5380.c
> > @@ -595,7 +603,13 @@ static inline int generic_NCR5380_pwrite(struct
> > NCR5380_hostdata *hostdata,
> > goto out_wait;
> > }
> > }
> > -
> > +   idx = NCR5380_read(13);
> > +   if (idx != 0) {
> > +   printk("host idx=%d, start=%d\n", idx, start);
> > +   NCR5380_write(hostdata->c400_ctl_status,
> > CSR_RESET); +  
> > NCR5380_write(hostdata->c400_ctl_status, CSR_BASE); +
> >   goto out_wait;
> > +   }
> > if (hostdata->io_port && hostdata->io_width == 2)
> > outsw(hostdata->io_port +
> > hostdata->c400_host_buf, src + start, 64);
>
> I find it hard to reason about this code. For example, out_wait is to be
> removed. Let's get the preceding patches working and signed-off. Please go
> ahead and use a 512 B transfer for DTC436 testing if that will help get
> this patch series over the line.

OK, I agree. Let's fix the problems first and leave this hack for later.

-- 
Ondrej Zary


Re: [PATCH v3 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-27 Thread Finn Thain

On Tue, 27 Jun 2017, Michael Schmitz wrote:

> Ondrej,
> 
> could this be a partial write (target did not transfer the last byte)?
> 

We do wait for TCR_LAST_BYTE_SENT, but only when there is no residual.

Perhaps we should wait for TCR_LAST_BYTE_SENT whenever the 53c400 asserts 
/EOP. That is, whenever BASR_END_DMA_TRANSFER is set.

-- 

> One would suppose the chip posts a phase mismatch in that case ...
> 
> Cheers,
> 
>   Michael
> 


Re: [PATCH v3 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-27 Thread Finn Thain
On Tue, 27 Jun 2017, Ondrej Zary wrote:

> BTW. I've probably found the DTC write corruption. Added the following 
> check (13 is host buffer index register) -

That register is not mentioned in my 53c400 datasheet.

> and it triggers sometimes: the value is 1 instead of 0. As we use only 
> 16-bit writes, I don't see how the value could ever be odd. Looks like a 
> bug in the chip. The index register corrupts during the transfer, not 
> after IRQ or timeout. The same check at beginning of pwrite() did not 
> trigger.
> 

Are you reading this register at the right moment? Have you tried waiting 
for it to reach zero, as in,

if (NCR5380_poll_politely(hostdata, 13, 0xff, 0, HZ / 64) < 0)
/* printk, reset etc */;

Even if this is a reliable way to detect a short transfer, it would be 
nice to know the root cause. But I'm being unrealistic: the DTC436 vendor 
never responded to my requests for technical documentation.

> The index register is not writable so we must(?) reset the PDMA engine 
> to recover. However, this quick attempt to fix does not work, maybe we 
> should reload the block count and continue?
> 

I don't know if it is possible to recover. If the last byte never reached 
the scsi bus, then once you reset the 53c400 core, you need the driver to 
perform a single-byte PIO transfer after the short PDMA transfer. This 
would require that you set the residual appropriately (though in my 
experience that may not be sufficient).

It may be better to simply limit the transfer to 512 bytes instead of 
attempting to recover based on an undocumented (?) register, etc. Seems 
like a bit of a hack.

> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -595,7 +603,13 @@ static inline int generic_NCR5380_pwrite(struct 
> NCR5380_hostdata *hostdata,
> goto out_wait;
> }
> }
> -
> +   idx = NCR5380_read(13);
> +   if (idx != 0) {
> +   printk("host idx=%d, start=%d\n", idx, start);
> +   NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
> +   NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
> +   goto out_wait;
> +   }
> if (hostdata->io_port && hostdata->io_width == 2)
> outsw(hostdata->io_port + hostdata->c400_host_buf,
> src + start, 64);
> 

I find it hard to reason about this code. For example, out_wait is to be 
removed. Let's get the preceding patches working and signed-off. Please go 
ahead and use a 512 B transfer for DTC436 testing if that will help get 
this patch series over the line.

-- 


Re: [PATCH v3 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-27 Thread Michael Schmitz
Ondrej,

could this be a partial write (target did not transfer the last byte)?

One would suppose the chip posts a phase mismatch in that case ...

Cheers,

Michael


Am 27.06.2017 um 18:28 schrieb Ondrej Zary:
> On Monday 26 June 2017, Ondrej Zary wrote:
>> On Monday 26 June 2017 09:30:33 Finn Thain wrote:
>>> Ondrej, would you please test this new series?
>>>
>>> Changed since v1:
>>> - PDMA transfer residual is calculated earlier.
>>> - End of DMA flag check is now polled (if there is any residual).
>>>
>>> Changed since v2:
>>> - Bail out of transfer loops when Gated IRQ gets asserted.
>>> - Make udelay conditional on board type.
>>> - Drop sg_tablesize patch due to performance regression.
>>>
>>>
>>> Finn Thain (1):
>>>   g_NCR5380: Cleanup comments and whitespace
>>>
>>> Ondrej Zary (3):
>>>   g_NCR5380: Fix PDMA transfer size
>>>   g_NCR5380: End PDMA transfer correctly on target disconnection
>>>   g_NCR5380: Re-work PDMA loops
>>>
>>>  drivers/scsi/g_NCR5380.c | 239
>>> +++ 1 file changed, 116
>>> insertions(+), 123 deletions(-)
> 
> BTW. I've probably found the DTC write corruption.
> Added the following check (13 is host buffer index register) - and it 
> triggers 
> sometimes: the value is 1 instead of 0. As we use only 16-bit writes, I don't 
> see how the value could ever be odd. Looks like a bug in the chip.
> The index register corrupts during the transfer, not after IRQ or timeout. 
> The 
> same check at beginning of pwrite() did not trigger.
> 
> The index register is not writable so we must(?) reset the PDMA engine to 
> recover. However, this quick attempt to fix does not work, maybe we should 
> reload the block count and continue?
> 
> --- a/drivers/scsi/g_NCR5380.c
> +++ b/drivers/scsi/g_NCR5380.c
> @@ -595,7 +603,13 @@ static inline int generic_NCR5380_pwrite(struct 
> NCR5380_hostdata *hostdata,
> goto out_wait;
> }
> }
> -
> +   idx = NCR5380_read(13);
> +   if (idx != 0) {
> +   printk("host idx=%d, start=%d\n", idx, start);
> +   NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
> +   NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
> +   goto out_wait;
> +   }
> if (hostdata->io_port && hostdata->io_width == 2)
> outsw(hostdata->io_port + hostdata->c400_host_buf,
> src + start, 64);
> 
> 


Re: [PATCH v3 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-27 Thread Ondrej Zary
On Monday 26 June 2017, Ondrej Zary wrote:
> On Monday 26 June 2017 09:30:33 Finn Thain wrote:
> > Ondrej, would you please test this new series?
> >
> > Changed since v1:
> > - PDMA transfer residual is calculated earlier.
> > - End of DMA flag check is now polled (if there is any residual).
> >
> > Changed since v2:
> > - Bail out of transfer loops when Gated IRQ gets asserted.
> > - Make udelay conditional on board type.
> > - Drop sg_tablesize patch due to performance regression.
> >
> >
> > Finn Thain (1):
> >   g_NCR5380: Cleanup comments and whitespace
> >
> > Ondrej Zary (3):
> >   g_NCR5380: Fix PDMA transfer size
> >   g_NCR5380: End PDMA transfer correctly on target disconnection
> >   g_NCR5380: Re-work PDMA loops
> >
> >  drivers/scsi/g_NCR5380.c | 239
> > +++ 1 file changed, 116
> > insertions(+), 123 deletions(-)

BTW. I've probably found the DTC write corruption.
Added the following check (13 is host buffer index register) - and it triggers 
sometimes: the value is 1 instead of 0. As we use only 16-bit writes, I don't 
see how the value could ever be odd. Looks like a bug in the chip.
The index register corrupts during the transfer, not after IRQ or timeout. The 
same check at beginning of pwrite() did not trigger.

The index register is not writable so we must(?) reset the PDMA engine to 
recover. However, this quick attempt to fix does not work, maybe we should 
reload the block count and continue?

--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -595,7 +603,13 @@ static inline int generic_NCR5380_pwrite(struct 
NCR5380_hostdata *hostdata,
goto out_wait;
}
}
-
+   idx = NCR5380_read(13);
+   if (idx != 0) {
+   printk("host idx=%d, start=%d\n", idx, start);
+   NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
+   NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
+   goto out_wait;
+   }
if (hostdata->io_port && hostdata->io_width == 2)
outsw(hostdata->io_port + hostdata->c400_host_buf,
src + start, 64);


-- 
Ondrej Zary


Re: [PATCH v3 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-26 Thread Finn Thain
On Mon, 26 Jun 2017, Ondrej Zary wrote:

> 
> No apparent change in behavior, the first write test resulted in:
> [  842.830802] sd 2:0:1:0: [sdb] tag#0 53c80 registers not accessible, device 
> will be reset
> [  842.830802] sd 2:0:1:0: [sdb] tag#0 switching to slow handshake
> 
> Checking for IRQ after poll_politely2 does not seem right because we can 
> miss the buffer ready signal.
> 

How so? As long as there's no gated IRQ, we poll for buffer readiness 
until timeout. And when there is a gated IRQ, we break both the polling 
loop and the transfer loop immediately. Your code and mine are basically 
in agreement here.

> According to my tests, buffer ready signal is most important - if there 
> is any data to read/write, do the transfer. If not, only then check why 
> - maybe we got an IRQ (that terminated PDMA). Or no IRQ, sometimes the 
> wait for buffer ready times out - we need to terminate PDMA manually 
> then (reset).
> 
> Then 53C80 registers should become ready.
> 

You seem to be saying that we should ignore the IRQ signal if the buffers 
have become ready. Maybe so. Can we try simply resetting the block 
counter? (I could imagine that the 53c400 core might leave the 53c80 
registers inaccessible unless we keep accessing the buffers in the 53c400 
core until the transfer is done.)

BTW, with regard to your patch, note that this construct is race prone:

while (1) { /* monitor IRQ while waiting for host buffer */
csr = NCR5380_read(hostdata->c400_ctl_status);
if (!(csr & CSR_HOST_BUF_NOT_RDY))
break;
if (csr & CSR_GATED_53C80_IRQ) {
basr = NCR5380_read(BUS_AND_STATUS_REG);
if (!(basr & BASR_PHASE_MATCH) ||
   (basr & BASR_BUSY_ERROR)) {
printk("basr=0x%02x csr=0x%02x at start=%d\n", basr, 
csr, start);
goto out_wait;
}
}
if (retries-- < 1) {
shost_printk(KERN_ERR, hostdata->host, "53C400r: host buffer 
not ready in time\n");
NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
goto out_wait;
}
}

This code can "goto out_wait" when !(csr & CSR_HOST_BUF_NOT_RDY). It 
depends on timing. This would seem to be contrary to your stated aim.

Moreover, this code can also "break" when (csr & CSR_GATED_53C80_IRQ). 
That depends on timing too. But this may be an improvement on my code if 
it allows the 53c80 registers to become accessible, by allowing the block 
counter to be decremented.

The uncertainty here was one of the reasons I reworked this code.

> This is a log from writing 230 MB file using my code with some debug 
> prints, on a NCR53C400. No 53C80 timeouts, only disconnects and some 
> host buffer timeouts (maybe the drive sometimes just slows down without 
> disconnecting?)
> 
> [ 3378.503828] basr=0x10 csr=0xd5 at start=512
> [ 3461.257973] w basr=0x10 csr=0x95 at start=3840
> [ 3461.838225] w basr=0x10 csr=0x95 at start=3840
> [ 3462.683446] w basr=0x10 csr=0x95 at start=3840
> [ 3463.416911] w basr=0x10 csr=0x95 at start=3840
> [ 3465.117804] scsi host2: 53C400w: host buffer not ready in time
> [ 3465.276375] w basr=0x10 csr=0x95 at start=3328
> [ 3466.457701] w basr=0x10 csr=0x95 at start=1792
> [ 3467.019643] scsi host2: 53C400w: host buffer not ready in time
> [ 3467.619058] scsi host2: 53C400w: host buffer not ready in time
> [ 3467.799619] w basr=0x10 csr=0x95 at start=3840
> [ 3552.123501] w basr=0x10 csr=0x95 at start=2304
> [ 3552.771223] w basr=0x10 csr=0x95 at start=1280
> [ 3554.556451] w basr=0x10 csr=0x95 at start=2816
> [ 3555.229646] w basr=0x10 csr=0x95 at start=1792
> [ 3555.630632] scsi host2: 53C400w: host buffer not ready in time
> [ 3555.774560] w basr=0x10 csr=0x95 at start=768
> [ 3625.541608] w basr=0x10 csr=0x95 at start=3328
> [ 3640.099861] w basr=0x10 csr=0x95 at start=1792
> [ 3641.442671] w basr=0x10 csr=0x95 at start=2816
> [ 3641.865469] w basr=0x10 csr=0x95 at start=768
> [ 3642.939223] w basr=0x10 csr=0x95 at start=1280
> [ 3643.356858] w basr=0x10 csr=0x95 at start=3328
> [ 3643.701636] w basr=0x10 csr=0x95 at start=3840
> [ 3645.153405] w basr=0x10 csr=0x95 at start=2304
> [ 3646.135642] w basr=0x10 csr=0x95 at start=1280
> [ 3647.007321] w basr=0x10 csr=0x95 at start=2816
> [ 3648.065874] w basr=0x10 csr=0x95 at start=3328
> [ 3650.071961] w basr=0x10 csr=0x95 at start=1280
> [ 3650.827630] w basr=0x10 csr=0x95 at start=1792
> [ 3651.827011] w basr=0x10 csr=0x95 at start=2816
> [ 3652.559984] w basr=0x10 csr=0x95 at start=2816
> [ 3653.203566] w basr=0x10 csr=0x95 at start=3328
> [ 3653.594376] w basr=0x10 csr=0x95 at start=1280
> [ 3653.903437] w basr=0x10 csr=0x95 at start=3840
> [ 3654.305753] w basr=0x10 csr=0x95 at start=1792
> [ 3654.676009] w basr=0x10 csr=0x95 at start=2304
> [ 3655.367686] w basr=0x10 csr=0x95 at start=2816
> [ 3655.733854] w 

Re: [PATCH v3 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-26 Thread Ondrej Zary
On Monday 26 June 2017 09:30:33 Finn Thain wrote:
> Ondrej, would you please test this new series?
>
> Changed since v1:
> - PDMA transfer residual is calculated earlier.
> - End of DMA flag check is now polled (if there is any residual).
>
> Changed since v2:
> - Bail out of transfer loops when Gated IRQ gets asserted.
> - Make udelay conditional on board type.
> - Drop sg_tablesize patch due to performance regression.
>
>
> Finn Thain (1):
>   g_NCR5380: Cleanup comments and whitespace
>
> Ondrej Zary (3):
>   g_NCR5380: Fix PDMA transfer size
>   g_NCR5380: End PDMA transfer correctly on target disconnection
>   g_NCR5380: Re-work PDMA loops
>
>  drivers/scsi/g_NCR5380.c | 239
> +++ 1 file changed, 116
> insertions(+), 123 deletions(-)

No apparent change in behavior, the first write test resulted in:
[  842.830802] sd 2:0:1:0: [sdb] tag#0 53c80 registers not accessible, device 
will be reset
[  842.830802] sd 2:0:1:0: [sdb] tag#0 switching to slow handshake

Checking for IRQ after poll_politely2 does not seem right because we can
miss the buffer ready signal.

According to my tests, buffer ready signal is most important - if there is
any data to read/write, do the transfer. If not, only then check why - maybe
we got an IRQ (that terminated PDMA). Or no IRQ, sometimes the wait for buffer
ready times out - we need to terminate PDMA manually then (reset).

Then 53C80 registers should become ready.

This is a log from writing 230 MB file using my code with some debug
prints, on a NCR53C400. No 53C80 timeouts, only disconnects and some host
buffer timeouts (maybe the drive sometimes just slows down without
disconnecting?)
[ 3378.503828] basr=0x10 csr=0xd5 at start=512
[ 3461.257973] w basr=0x10 csr=0x95 at start=3840
[ 3461.838225] w basr=0x10 csr=0x95 at start=3840
[ 3462.683446] w basr=0x10 csr=0x95 at start=3840
[ 3463.416911] w basr=0x10 csr=0x95 at start=3840
[ 3465.117804] scsi host2: 53C400w: host buffer not ready in time
[ 3465.276375] w basr=0x10 csr=0x95 at start=3328
[ 3466.457701] w basr=0x10 csr=0x95 at start=1792
[ 3467.019643] scsi host2: 53C400w: host buffer not ready in time
[ 3467.619058] scsi host2: 53C400w: host buffer not ready in time
[ 3467.799619] w basr=0x10 csr=0x95 at start=3840
[ 3552.123501] w basr=0x10 csr=0x95 at start=2304
[ 3552.771223] w basr=0x10 csr=0x95 at start=1280
[ 3554.556451] w basr=0x10 csr=0x95 at start=2816
[ 3555.229646] w basr=0x10 csr=0x95 at start=1792
[ 3555.630632] scsi host2: 53C400w: host buffer not ready in time
[ 3555.774560] w basr=0x10 csr=0x95 at start=768
[ 3625.541608] w basr=0x10 csr=0x95 at start=3328
[ 3640.099861] w basr=0x10 csr=0x95 at start=1792
[ 3641.442671] w basr=0x10 csr=0x95 at start=2816
[ 3641.865469] w basr=0x10 csr=0x95 at start=768
[ 3642.939223] w basr=0x10 csr=0x95 at start=1280
[ 3643.356858] w basr=0x10 csr=0x95 at start=3328
[ 3643.701636] w basr=0x10 csr=0x95 at start=3840
[ 3645.153405] w basr=0x10 csr=0x95 at start=2304
[ 3646.135642] w basr=0x10 csr=0x95 at start=1280
[ 3647.007321] w basr=0x10 csr=0x95 at start=2816
[ 3648.065874] w basr=0x10 csr=0x95 at start=3328
[ 3650.071961] w basr=0x10 csr=0x95 at start=1280
[ 3650.827630] w basr=0x10 csr=0x95 at start=1792
[ 3651.827011] w basr=0x10 csr=0x95 at start=2816
[ 3652.559984] w basr=0x10 csr=0x95 at start=2816
[ 3653.203566] w basr=0x10 csr=0x95 at start=3328
[ 3653.594376] w basr=0x10 csr=0x95 at start=1280
[ 3653.903437] w basr=0x10 csr=0x95 at start=3840
[ 3654.305753] w basr=0x10 csr=0x95 at start=1792
[ 3654.676009] w basr=0x10 csr=0x95 at start=2304
[ 3655.367686] w basr=0x10 csr=0x95 at start=2816
[ 3655.733854] w basr=0x10 csr=0x95 at start=768
[ 3656.075023] w basr=0x10 csr=0x95 at start=3328
[ 3656.493046] w basr=0x10 csr=0x95 at start=2816
[ 3657.208089] w basr=0x10 csr=0x95 at start=1280
[ 3657.537223] w basr=0x10 csr=0x95 at start=1280

And this is from reading the file back:
[ 3799.053067] basr=0x10 csr=0xd5 at start=512
[ 3801.056337] basr=0x10 csr=0xd5 at start=3584
[ 3976.323836] scsi host2: 53C400r: host buffer not ready in time
[ 3976.404699] basr=0x10 csr=0xd5 at start=512
[ 3977.800647] basr=0x10 csr=0xd5 at start=512
[ 3979.240611] scsi host2: 53C400r: host buffer not ready in time
[ 3979.320698] basr=0x10 csr=0xd5 at start=512
[ 3980.040220] scsi host2: 53C400r: host buffer not ready in time
[ 3980.096401] basr=0x10 csr=0xd5 at start=512
[ 3980.394854] scsi host2: 53C400r: host buffer not ready in time


-- 
Ondrej Zary


[PATCH v3 0/4] g_NCR5380: PDMA fixes and cleanup

2017-06-26 Thread Finn Thain
Ondrej, would you please test this new series?

Changed since v1:
- PDMA transfer residual is calculated earlier.
- End of DMA flag check is now polled (if there is any residual).

Changed since v2:
- Bail out of transfer loops when Gated IRQ gets asserted.
- Make udelay conditional on board type.
- Drop sg_tablesize patch due to performance regression.


Finn Thain (1):
  g_NCR5380: Cleanup comments and whitespace

Ondrej Zary (3):
  g_NCR5380: Fix PDMA transfer size
  g_NCR5380: End PDMA transfer correctly on target disconnection
  g_NCR5380: Re-work PDMA loops

 drivers/scsi/g_NCR5380.c | 239 +++
 1 file changed, 116 insertions(+), 123 deletions(-)

-- 
2.13.0