* [PATCH] mac_esp: fix PIO mode
@ 2009-11-23 3:57 Finn Thain
2009-12-02 23:40 ` David Miller
0 siblings, 1 reply; 5+ messages in thread
From: Finn Thain @ 2009-11-23 3:57 UTC (permalink / raw)
To: David S. Miller; +Cc: linux-scsi, linux-m68k
The mac_esp PIO algorithm no longer works in 2.6.31 and crashes my Centris
660av. So here's a better one.
One of the SCSI drives I tested still doesn't like the PIO mode and fails
with "esp: esp0: Reconnect IRQ2 timeout" (the same drive works fine in
PDMA mode).
This failure happens when esp_reconnect_with_tag() tries to read in two
tag bytes but the chip only provides one (0x20). I don't know what causes
this. I decided not to waste any more time trying to fix it because the
best solution is to rip out the PIO mode altogether and use the DMA
engine.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
---
drivers/scsi/esp_scsi.c | 11 ++---
drivers/scsi/mac_esp.c | 97 ++++++++++++++++++++++++------------------------
2 files changed, 55 insertions(+), 53 deletions(-)
Index: linux-2.6.31/drivers/scsi/mac_esp.c
===================================================================
--- linux-2.6.31.orig/drivers/scsi/mac_esp.c 2009-11-23 12:52:45.000000000 +1100
+++ linux-2.6.31/drivers/scsi/mac_esp.c 2009-11-23 12:56:15.000000000 +1100
@@ -22,7 +22,6 @@
#include <asm/irq.h>
#include <asm/dma.h>
-
#include <asm/macints.h>
#include <asm/macintosh.h>
@@ -278,24 +277,27 @@ static void mac_esp_send_pdma_cmd(struct
* 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 {
@@ -307,6 +309,7 @@ static inline int mac_esp_wait_for_intr(
} while (--i);
printk(KERN_ERR PFX "IRQ timeout (sreg %02x)\n", esp->sreg);
+ mep->error = 1;
return 1;
}
@@ -346,11 +349,10 @@ static inline int mac_esp_wait_for_intr(
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;
@@ -358,11 +360,35 @@ static void mac_esp_send_pio_cmd(struct
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);
@@ -373,47 +399,24 @@ static void mac_esp_send_pio_cmd(struct
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;
@@ -428,7 +431,7 @@ static void mac_esp_send_pio_cmd(struct
}
}
- local_irq_restore(flags);
+ enable_irq(esp->host->irq);
}
static int mac_esp_irq_pending(struct esp *esp)
Index: linux-2.6.31/drivers/scsi/esp_scsi.c
===================================================================
--- linux-2.6.31.orig/drivers/scsi/esp_scsi.c 2009-11-23 12:52:45.000000000 +1100
+++ linux-2.6.31/drivers/scsi/esp_scsi.c 2009-11-23 12:53:30.000000000 +1100
@@ -2405,12 +2405,6 @@ static int esp_slave_configure(struct sc
struct esp_target_data *tp = &esp->target[dev->id];
int goal_tags, queue_depth;
- if (esp->flags & ESP_FLAG_DISABLE_SYNC) {
- /* Bypass async domain validation */
- dev->ppr = 0;
- dev->sdtr = 0;
- }
-
goal_tags = 0;
if (dev->tagged_supported) {
@@ -2433,6 +2427,11 @@ static int esp_slave_configure(struct sc
}
tp->flags |= ESP_TGT_DISCONNECT;
+ if (esp->flags & ESP_FLAG_DISABLE_SYNC) {
+ dev->wdtr = spi_support_wide(dev->sdev_target) = 0;
+ dev->sdtr = spi_support_sync(dev->sdev_target) = 0;
+ }
+
if (!spi_initial_dv(dev->sdev_target))
spi_dv_device(dev);
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] mac_esp: fix PIO mode
2009-11-23 3:57 [PATCH] mac_esp: fix PIO mode Finn Thain
@ 2009-12-02 23:40 ` David Miller
2009-12-04 12:58 ` Finn Thain
0 siblings, 1 reply; 5+ messages in thread
From: David Miller @ 2009-12-02 23:40 UTC (permalink / raw)
To: fthain; +Cc: linux-scsi, linux-m68k
From: Finn Thain <fthain@telegraphics.com.au>
Date: Mon, 23 Nov 2009 14:57:42 +1100 (EST)
>
> The mac_esp PIO algorithm no longer works in 2.6.31 and crashes my Centris
> 660av. So here's a better one.
>
> One of the SCSI drives I tested still doesn't like the PIO mode and fails
> with "esp: esp0: Reconnect IRQ2 timeout" (the same drive works fine in
> PDMA mode).
>
> This failure happens when esp_reconnect_with_tag() tries to read in two
> tag bytes but the chip only provides one (0x20). I don't know what causes
> this. I decided not to waste any more time trying to fix it because the
> best solution is to rip out the PIO mode altogether and use the DMA
> engine.
>
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Can you explain why the esp_slave_configure() part of your patch
is necessary?
> Index: linux-2.6.31/drivers/scsi/esp_scsi.c
> ===================================================================
> --- linux-2.6.31.orig/drivers/scsi/esp_scsi.c 2009-11-23 12:52:45.000000000 +1100
> +++ linux-2.6.31/drivers/scsi/esp_scsi.c 2009-11-23 12:53:30.000000000 +1100
> @@ -2405,12 +2405,6 @@ static int esp_slave_configure(struct sc
> struct esp_target_data *tp = &esp->target[dev->id];
> int goal_tags, queue_depth;
>
> - if (esp->flags & ESP_FLAG_DISABLE_SYNC) {
> - /* Bypass async domain validation */
> - dev->ppr = 0;
> - dev->sdtr = 0;
> - }
> -
> goal_tags = 0;
>
> if (dev->tagged_supported) {
> @@ -2433,6 +2427,11 @@ static int esp_slave_configure(struct sc
> }
> tp->flags |= ESP_TGT_DISCONNECT;
>
> + if (esp->flags & ESP_FLAG_DISABLE_SYNC) {
> + dev->wdtr = spi_support_wide(dev->sdev_target) = 0;
> + dev->sdtr = spi_support_sync(dev->sdev_target) = 0;
> + }
> +
> if (!spi_initial_dv(dev->sdev_target))
> spi_dv_device(dev);
>
That part...
Thanks.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] mac_esp: fix PIO mode
2009-12-02 23:40 ` David Miller
@ 2009-12-04 12:58 ` Finn Thain
2009-12-04 15:31 ` James Bottomley
0 siblings, 1 reply; 5+ messages in thread
From: Finn Thain @ 2009-12-04 12:58 UTC (permalink / raw)
To: David Miller; +Cc: linux-scsi, linux-m68k
On Wed, 2 Dec 2009, David Miller wrote:
...
>
> Can you explain why the esp_slave_configure() part of your patch is
> necessary?
>
> > Index: linux-2.6.31/drivers/scsi/esp_scsi.c
> > ===================================================================
> > --- linux-2.6.31.orig/drivers/scsi/esp_scsi.c 2009-11-23 12:52:45.000000000 +1100
> > +++ linux-2.6.31/drivers/scsi/esp_scsi.c 2009-11-23 12:53:30.000000000 +1100
> > @@ -2405,12 +2405,6 @@ static int esp_slave_configure(struct sc
> > struct esp_target_data *tp = &esp->target[dev->id];
> > int goal_tags, queue_depth;
> >
> > - if (esp->flags & ESP_FLAG_DISABLE_SYNC) {
> > - /* Bypass async domain validation */
> > - dev->ppr = 0;
> > - dev->sdtr = 0;
> > - }
> > -
> > goal_tags = 0;
> >
> > if (dev->tagged_supported) {
> > @@ -2433,6 +2427,11 @@ static int esp_slave_configure(struct sc
> > }
> > tp->flags |= ESP_TGT_DISCONNECT;
> >
> > + if (esp->flags & ESP_FLAG_DISABLE_SYNC) {
> > + dev->wdtr = spi_support_wide(dev->sdev_target) = 0;
> > + dev->sdtr = spi_support_sync(dev->sdev_target) = 0;
> > + }
> > +
> > if (!spi_initial_dv(dev->sdev_target))
> > spi_dv_device(dev);
> >
The aim is that domain validation will not test for sync when we know it
can't work (in PIO mode). This is the result:
mac_esp: using PIO for controller 0
esp: esp0, regs[50f18000:(null)] irq[19]
esp: esp0 is a ESP236, 25 MHz (ccf=5), SCSI ID 7
scsi0 : esp
scsi 0:0:6:0: Direct-Access QUANTUM LPS540S 590S PQ: 0 ANSI: 2 CCS
target0:0:6: Beginning Domain Validation
target0:0:6: Ending Domain Validation
sd 0:0:6:0: [sda] 1057616 512-byte logical blocks: (541 MB/516 MiB)
sd 0:0:6:0: [sda] Write Protect is off
sd 0:0:6:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
Whereas, without the esp_slave_configure() code, I get this:
scsi0 : esp
scsi 0:0:6:0: Direct-Access QUANTUM LPS540S 590S PQ: 0 ANSI: 2 CCS
target0:0:6: Beginning Domain Validation
target0:0:6: asynchronous
mac_esp: FIFO is empty (sreg 81)
esp: esp0: DMA length is zero!
esp: esp0: cur adr[010eb082] len[00000000]
target0:0:6: Domain Validation detected failure, dropping back
target0:0:6: asynchronous
mac_esp: FIFO is empty (sreg 81)
esp: esp0: DMA length is zero!
esp: esp0: cur adr[010eb082] len[00000000]
target0:0:6: Domain Validation detected failure, dropping back
target0:0:6: asynchronous
mac_esp: FIFO is empty (sreg 81)
esp: esp0: DMA length is zero!
esp: esp0: cur adr[010eb082] len[00000000]
target0:0:6: Domain Validation detected failure, dropping back
target0:0:6: asynchronous
mac_esp: FIFO is empty (sreg 81)
esp: esp0: DMA length is zero!
esp: esp0: cur adr[010eb082] len[00000000]
target0:0:6: Domain Validation detected failure, dropping back
target0:0:6: asynchronous
mac_esp: FIFO is empty (sreg 81)
esp: esp0: DMA length is zero!
esp: esp0: cur adr[010eb082] len[00000000]
target0:0:6: Domain Validation Failure, dropping back to Asynchronous
target0:0:6: Domain Validation skipping write tests
target0:0:6: Ending Domain Validation
sd 0:0:6:0: [sda] 1057616 512-byte logical blocks: (541 MB/516 MiB)
sd 0:0:6:0: [sda] Write Protect is off
sd 0:0:6:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
Which takes longer but gives the same result. The CDROM drive is worse
however:
scsi0 : esp
scsi 0:0:4:0: CD-ROM TOSHIBA CD-ROM XM-5401TA 1036 PQ: 0 ANSI: 2
target0:0:4: Beginning Domain Validation
target0:0:4: asynchronous
mac_esp: FIFO is empty (sreg 01)
esp: esp0: Aborting command [010dc940:12]
esp: esp0: Current command [010dc940:12]
esp: esp0: Active command [010dc940:12]
esp: esp0: Dumping command log
esp: esp0: ent[27] CMD val[01] sreg[87] seqreg[01] sreg2[00] ireg[10] ss[00] event[06]
esp: esp0: ent[28] CMD val[10] sreg[87] seqreg[01] sreg2[00] ireg[10] ss[00] event[06]
esp: esp0: ent[29] CMD val[12] sreg[87] seqreg[01] sreg2[00] ireg[08] ss[00] event[06]
esp: esp0: ent[30] EVENT val[0d] sreg[87] seqreg[01] sreg2[00] ireg[08] ss[00] event[06]
...
So the esp driver then retries the aborted command a few times, with
delays. Multiply those retries by the five domain validation iterations.
Then, IIRC, the CDROM finally gets offlined at the end of that slow
process.
I did a quick test, and this works too:
@@ -2405,12 +2405,6 @@ static int esp_slave_configure(struct sc
struct esp_target_data *tp = &esp->target[dev->id];
int goal_tags, queue_depth;
- if (esp->flags & ESP_FLAG_DISABLE_SYNC) {
- /* Bypass async domain validation */
- dev->ppr = 0;
- dev->sdtr = 0;
- }
-
goal_tags = 0;
if (dev->tagged_supported) {
@@ -2433,6 +2427,9 @@ static int esp_slave_configure(struct sc
}
tp->flags |= ESP_TGT_DISCONNECT;
+ if (esp->flags & ESP_FLAG_DISABLE_SYNC)
+ spi_support_sync(dev->sdev_target) = 0;
+
if (!spi_initial_dv(dev->sdev_target))
spi_dv_device(dev);
I will resubmit the patch like so if you wish. Or you could go ahead and
make the change.
Finn
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] mac_esp: fix PIO mode
2009-12-04 12:58 ` Finn Thain
@ 2009-12-04 15:31 ` James Bottomley
2009-12-05 1:30 ` [PATCH] mac_esp: fix PIO mode, take 2 Finn Thain
0 siblings, 1 reply; 5+ messages in thread
From: James Bottomley @ 2009-12-04 15:31 UTC (permalink / raw)
To: Finn Thain; +Cc: David Miller, linux-scsi, linux-m68k
On Fri, 2009-12-04 at 23:58 +1100, Finn Thain wrote:
> On Wed, 2 Dec 2009, David Miller wrote:
>
> ...
> >
> > Can you explain why the esp_slave_configure() part of your patch is
> > necessary?
> >
> > > Index: linux-2.6.31/drivers/scsi/esp_scsi.c
> > > ===================================================================
> > > --- linux-2.6.31.orig/drivers/scsi/esp_scsi.c 2009-11-23 12:52:45.000000000 +1100
> > > +++ linux-2.6.31/drivers/scsi/esp_scsi.c 2009-11-23 12:53:30.000000000 +1100
> > > @@ -2405,12 +2405,6 @@ static int esp_slave_configure(struct sc
> > > struct esp_target_data *tp = &esp->target[dev->id];
> > > int goal_tags, queue_depth;
> > >
> > > - if (esp->flags & ESP_FLAG_DISABLE_SYNC) {
> > > - /* Bypass async domain validation */
> > > - dev->ppr = 0;
> > > - dev->sdtr = 0;
> > > - }
> > > -
> > > goal_tags = 0;
> > >
> > > if (dev->tagged_supported) {
> > > @@ -2433,6 +2427,11 @@ static int esp_slave_configure(struct sc
> > > }
> > > tp->flags |= ESP_TGT_DISCONNECT;
> > >
> > > + if (esp->flags & ESP_FLAG_DISABLE_SYNC) {
> > > + dev->wdtr = spi_support_wide(dev->sdev_target) = 0;
> > > + dev->sdtr = spi_support_sync(dev->sdev_target) = 0;
> > > + }
> > > +
> > > if (!spi_initial_dv(dev->sdev_target))
> > > spi_dv_device(dev);
> > >
>
> The aim is that domain validation will not test for sync when we know it
> can't work (in PIO mode). This is the result:
So this isn't the correct way to handle the problem. You're altering
the disk capability flags to trick the transport class. What you want
to be doing is updating esp_set_period so it won't go under whatever you
deem to be a correct period setting (or if it's really async then it
won't set the period at all).
James
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] mac_esp: fix PIO mode, take 2
2009-12-04 15:31 ` James Bottomley
@ 2009-12-05 1:30 ` Finn Thain
0 siblings, 0 replies; 5+ messages in thread
From: Finn Thain @ 2009-12-05 1:30 UTC (permalink / raw)
To: David Miller; +Cc: James Bottomley, linux-scsi, linux-m68k
The mac_esp PIO algorithm no longer works in 2.6.31 and crashes my Centris
660av. So here's a better one.
Also, force async with esp_set_offset() rather than esp_slave_configure().
One of the SCSI drives I tested still doesn't like the PIO mode and fails
with "esp: esp0: Reconnect IRQ2 timeout" (the same drive works fine in
PDMA mode).
This failure happens when esp_reconnect_with_tag() tries to read in two
tag bytes but the chip only provides one (0x20). I don't know what causes
this. I decided not to waste any more time trying to fix it because the
best solution is to rip out the PIO mode altogether and use the DMA
engine.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
---
drivers/scsi/esp_scsi.c | 14 ++-----
drivers/scsi/mac_esp.c | 95 ++++++++++++++++++++++++------------------------
2 files changed, 53 insertions(+), 56 deletions(-)
Index: linux-2.6.31/drivers/scsi/mac_esp.c
===================================================================
--- linux-2.6.31.orig/drivers/scsi/mac_esp.c 2009-12-04 22:48:24.000000000 +1100
+++ linux-2.6.31/drivers/scsi/mac_esp.c 2009-12-04 22:49:02.000000000 +1100
@@ -22,7 +22,6 @@
#include <asm/irq.h>
#include <asm/dma.h>
-
#include <asm/macints.h>
#include <asm/macintosh.h>
@@ -278,24 +277,27 @@ static void mac_esp_send_pdma_cmd(struct
* 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 {
@@ -307,6 +309,7 @@ static inline int mac_esp_wait_for_intr(
} while (--i);
printk(KERN_ERR PFX "IRQ timeout (sreg %02x)\n", esp->sreg);
+ mep->error = 1;
return 1;
}
@@ -346,11 +349,10 @@ static inline int mac_esp_wait_for_intr(
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;
@@ -358,11 +360,35 @@ static void mac_esp_send_pio_cmd(struct
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);
@@ -373,47 +399,24 @@ static void mac_esp_send_pio_cmd(struct
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;
@@ -428,7 +431,7 @@ static void mac_esp_send_pio_cmd(struct
}
}
- local_irq_restore(flags);
+ enable_irq(esp->host->irq);
}
static int mac_esp_irq_pending(struct esp *esp)
Index: linux-2.6.31/drivers/scsi/esp_scsi.c
===================================================================
--- linux-2.6.31.orig/drivers/scsi/esp_scsi.c 2009-12-04 22:48:24.000000000 +1100
+++ linux-2.6.31/drivers/scsi/esp_scsi.c 2009-12-05 12:24:58.000000000 +1100
@@ -1449,9 +1449,6 @@ static void esp_msgin_sdtr(struct esp *e
if (offset > 15)
goto do_reject;
- if (esp->flags & ESP_FLAG_DISABLE_SYNC)
- offset = 0;
-
if (offset) {
int one_clock;
@@ -2405,12 +2402,6 @@ static int esp_slave_configure(struct sc
struct esp_target_data *tp = &esp->target[dev->id];
int goal_tags, queue_depth;
- if (esp->flags & ESP_FLAG_DISABLE_SYNC) {
- /* Bypass async domain validation */
- dev->ppr = 0;
- dev->sdtr = 0;
- }
-
goal_tags = 0;
if (dev->tagged_supported) {
@@ -2660,7 +2651,10 @@ static void esp_set_offset(struct scsi_t
struct esp *esp = shost_priv(host);
struct esp_target_data *tp = &esp->target[target->id];
- tp->nego_goal_offset = offset;
+ if (esp->flags & ESP_FLAG_DISABLE_SYNC)
+ tp->nego_goal_offset = 0;
+ else
+ tp->nego_goal_offset = offset;
tp->flags |= ESP_TGT_CHECK_NEGO;
}
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2009-12-05 1:30 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-23 3:57 [PATCH] mac_esp: fix PIO mode Finn Thain
2009-12-02 23:40 ` David Miller
2009-12-04 12:58 ` Finn Thain
2009-12-04 15:31 ` James Bottomley
2009-12-05 1:30 ` [PATCH] mac_esp: fix PIO mode, take 2 Finn Thain
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox