Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1673059 > unrolled thread
| Started by | Ondrej Zary <linux@rainbow-software.org> |
|---|---|
| First post | 2017-06-22 23:30 +0200 |
| Last post | 2017-06-24 04:50 +0200 |
| Articles | 5 — 2 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [PATCH 0/4] g_NCR5380: PDMA fixes and cleanup Ondrej Zary <linux@rainbow-software.org> - 2017-06-22 23:30 +0200
Re: [PATCH 0/4] g_NCR5380: PDMA fixes and cleanup Finn Thain <fthain@telegraphics.com.au> - 2017-06-23 03:10 +0200
Re: [PATCH 0/4] g_NCR5380: PDMA fixes and cleanup Finn Thain <fthain@telegraphics.com.au> - 2017-06-23 13:10 +0200
Re: [PATCH 0/4] g_NCR5380: PDMA fixes and cleanup Ondrej Zary <linux@rainbow-software.org> - 2017-06-23 22:20 +0200
Re: [PATCH 0/4] g_NCR5380: PDMA fixes and cleanup Finn Thain <fthain@telegraphics.com.au> - 2017-06-24 04:50 +0200
| From | Ondrej Zary <linux@rainbow-software.org> |
|---|---|
| Date | 2017-06-22 23:30 +0200 |
| Subject | Re: [PATCH 0/4] g_NCR5380: PDMA fixes and cleanup |
| Message-ID | <tVhPP-1Gi-5@gated-at.bofh.it> |
On Thursday 15 June 2017 14:17:56 Finn Thain wrote: > Ondrej, would you please test this patch series? One of your patches > has been modified slightly and the two I wrote are untested. Works only with HDD on non-DTC chips. CD-ROM hangs. DTC hangs even with HDD. The PDMA code really needs to be fixed. -- Ondrej Zary
[toc] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2017-06-23 03:10 +0200 |
| Message-ID | <tVlgK-3S1-9@gated-at.bofh.it> |
| In reply to | #1673059 |
On Thu, 22 Jun 2017, Ondrej Zary wrote:
> Works only with HDD on non-DTC chips. CD-ROM hangs. DTC hangs even with
> HDD. The PDMA code really needs to be fixed.
>
Does this patch help? It should be applied on top of this series of 4.
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 4c31cb316a38..95ae8edbecbc 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -481,6 +481,30 @@ static void generic_NCR5380_release_resources(struct Scsi_Host *instance)
release_mem_region(base, region_size);
}
+/* wait_for_53c80_access - wait for 53C80 registers to become accessible
+ * @hostdata: scsi host private data
+ *
+ * The registers within the 53C80 logic block are inaccessible until
+ * bit 7 in the 53C400 control status register gets asserted.
+ */
+
+static int wait_for_53c80_access(struct NCR5380_hostdata *hostdata)
+{
+ int count = 10000;
+
+ do {
+ udelay(4); /* DTC436 chip hangs without this */
+ if (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)
+ return 0;
+ } while (--count > 0);
+
+ scmd_printk(KERN_ERR, hostdata->connected,
+ "53c80 registers not accessible, device will be reset\n");
+ NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
+ NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
+ return -1;
+}
+
/**
* generic_NCR5380_pread - pseudo DMA receive
* @hostdata: scsi host private data
@@ -493,33 +517,19 @@ static void generic_NCR5380_release_resources(struct Scsi_Host *instance)
static inline int generic_NCR5380_pread(struct NCR5380_hostdata *hostdata,
unsigned char *dst, int len)
{
- int start, retries;
- u8 csr, basr;
+ int result;
+ int start;
NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR);
NCR5380_write(hostdata->c400_blk_cnt, len / 128);
for (start = 0; start < len; start += 128) {
- retries = 10000;
- 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;
- }
- }
+ if (NCR5380_poll_politely2(hostdata, hostdata->c400_ctl_status,
+ CSR_HOST_BUF_NOT_RDY, 0,
+ hostdata->c400_ctl_status,
+ CSR_GATED_53C80_IRQ,
+ CSR_GATED_53C80_IRQ, HZ / 64) < 0)
+ break;
if (hostdata->io_port && hostdata->io_width == 2)
insw(hostdata->io_port + hostdata->c400_host_buf,
@@ -532,24 +542,14 @@ static inline int generic_NCR5380_pread(struct NCR5380_hostdata *hostdata,
hostdata->io + NCR53C400_host_buffer, 128);
}
-out_wait:
- /* wait for 53C80 registers to be available */
- retries = 10000;
- while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) {
- if (retries-- < 1) {
- shost_printk(KERN_ERR, hostdata->host, "53C400r: 53C80 registers not ready in time\n");
- NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
- NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
- break;
- }
- }
+ result = wait_for_53c80_access(hostdata);
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
pr_err("%s: No end dma signal (%d/%d)\n", __func__, start, len);
- hostdata->pdma_residual = len - start;
+ hostdata->pdma_residual = NCR5380_read(hostdata->c400_blk_cnt) * 128;
- return 0;
+ return result;
}
/**
@@ -564,41 +564,19 @@ static inline int generic_NCR5380_pread(struct NCR5380_hostdata *hostdata,
static inline int generic_NCR5380_pwrite(struct NCR5380_hostdata *hostdata,
unsigned char *src, int len)
{
- int start, retries;
- u8 csr, basr;
+ int result;
+ int start;
NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
NCR5380_write(hostdata->c400_blk_cnt, len / 128);
for (start = 0; start < len; start += 128) {
- retries = 10000;
- 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("w basr=0x%02x csr=0x%02x at start=%d\n", basr, csr, start);
- /* the previous block was not written properly */
- start -= 2 * 128;
- if (start < 0)
- start = 0;
- goto out_wait;
- }
- }
- if (retries-- < 1) {
- shost_printk(KERN_ERR, hostdata->host, "53C400w: host buffer not ready in time\n");
- NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
- NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
- /* the previous block was not written properly */
- start -= 2 * 128;
- if (start < 0)
- start = 0;
- goto out_wait;
- }
- }
+ if (NCR5380_poll_politely2(hostdata, hostdata->c400_ctl_status,
+ CSR_HOST_BUF_NOT_RDY, 0,
+ hostdata->c400_ctl_status,
+ CSR_GATED_53C80_IRQ,
+ CSR_GATED_53C80_IRQ, HZ / 64) < 0)
+ break;
if (hostdata->io_port && hostdata->io_width == 2)
outsw(hostdata->io_port + hostdata->c400_host_buf,
@@ -611,24 +589,12 @@ static inline int generic_NCR5380_pwrite(struct NCR5380_hostdata *hostdata,
src + start, 128);
}
-out_wait:
- /* wait for 53C80 registers to be available */
- udelay(4); /* DTC436 chip hangs without this */
- retries = 10000;
- while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) {
- udelay(4); /* DTC436 chip hangs without this */
- if (retries-- < 1) {
- shost_printk(KERN_ERR, hostdata->host, "53C400w: 53C80 registers not ready in time, start=%d, len=%d\n", start, len);
- NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
- NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
- break;
- }
- }
+ result = wait_for_53c80_access(hostdata);
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
pr_err("%s: No end dma signal (%d/%d)\n", __func__, start, len);
- hostdata->pdma_residual = len - start;
+ hostdata->pdma_residual = NCR5380_read(hostdata->c400_blk_cnt) * 128;
if (hostdata->pdma_residual == 0 &&
NCR5380_poll_politely(hostdata, TARGET_COMMAND_REG,
@@ -637,7 +603,7 @@ static inline int generic_NCR5380_pwrite(struct NCR5380_hostdata *hostdata,
scmd_printk(KERN_ERR, hostdata->connected,
"%s: Last Byte Sent timeout\n", __func__);
- return 0;
+ return result;
}
static int generic_NCR5380_dma_xfer_len(struct NCR5380_hostdata *hostdata,
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2017-06-23 13:10 +0200 |
| Message-ID | <tVuDo-1pp-5@gated-at.bofh.it> |
| In reply to | #1673157 |
On Fri, 23 Jun 2017, I wrote:
>
> Does this patch help? It should be applied on top of this series of 4.
>
Sorry, I sent the wrong diff. Please try this patch instead.
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index e9a942d86865..95ae8edbecbc 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -481,6 +481,30 @@ static void generic_NCR5380_release_resources(struct Scsi_Host *instance)
release_mem_region(base, region_size);
}
+/* wait_for_53c80_access - wait for 53C80 registers to become accessible
+ * @hostdata: scsi host private data
+ *
+ * The registers within the 53C80 logic block are inaccessible until
+ * bit 7 in the 53C400 control status register gets asserted.
+ */
+
+static int wait_for_53c80_access(struct NCR5380_hostdata *hostdata)
+{
+ int count = 10000;
+
+ do {
+ udelay(4); /* DTC436 chip hangs without this */
+ if (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)
+ return 0;
+ } while (--count > 0);
+
+ scmd_printk(KERN_ERR, hostdata->connected,
+ "53c80 registers not accessible, device will be reset\n");
+ NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
+ NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
+ return -1;
+}
+
/**
* generic_NCR5380_pread - pseudo DMA receive
* @hostdata: scsi host private data
@@ -493,18 +517,19 @@ static void generic_NCR5380_release_resources(struct Scsi_Host *instance)
static inline int generic_NCR5380_pread(struct NCR5380_hostdata *hostdata,
unsigned char *dst, int len)
{
- int blocks = len / 128;
- int start = 0;
+ int result;
+ int start;
NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR);
- NCR5380_write(hostdata->c400_blk_cnt, blocks);
- while (1) {
- if (NCR5380_read(hostdata->c400_blk_cnt) == 0)
+ NCR5380_write(hostdata->c400_blk_cnt, len / 128);
+
+ for (start = 0; start < len; start += 128) {
+ if (NCR5380_poll_politely2(hostdata, hostdata->c400_ctl_status,
+ CSR_HOST_BUF_NOT_RDY, 0,
+ hostdata->c400_ctl_status,
+ CSR_GATED_53C80_IRQ,
+ CSR_GATED_53C80_IRQ, HZ / 64) < 0)
break;
- if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)
- goto out_wait;
- while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
- ; /* FIXME - no timeout */
if (hostdata->io_port && hostdata->io_width == 2)
insw(hostdata->io_port + hostdata->c400_host_buf,
@@ -515,43 +540,16 @@ static inline int generic_NCR5380_pread(struct NCR5380_hostdata *hostdata,
else
memcpy_fromio(dst + start,
hostdata->io + NCR53C400_host_buffer, 128);
-
- start += 128;
- blocks--;
- }
-
- if (blocks) {
- while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
- ; /* FIXME - no timeout */
-
- if (hostdata->io_port && hostdata->io_width == 2)
- insw(hostdata->io_port + hostdata->c400_host_buf,
- dst + start, 64);
- else if (hostdata->io_port)
- insb(hostdata->io_port + hostdata->c400_host_buf,
- dst + start, 128);
- else
- memcpy_fromio(dst + start,
- hostdata->io + NCR53C400_host_buffer, 128);
-
- start += 128;
- blocks--;
}
- if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
- printk("53C400r: no 53C80 gated irq after transfer");
-
-out_wait:
- /* wait for 53C80 registers to be available */
- while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG))
- ;
+ result = wait_for_53c80_access(hostdata);
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
pr_err("%s: No end dma signal (%d/%d)\n", __func__, start, len);
- hostdata->pdma_residual = len - start;
+ hostdata->pdma_residual = NCR5380_read(hostdata->c400_blk_cnt) * 128;
- return 0;
+ return result;
}
/**
@@ -566,36 +564,19 @@ static inline int generic_NCR5380_pread(struct NCR5380_hostdata *hostdata,
static inline int generic_NCR5380_pwrite(struct NCR5380_hostdata *hostdata,
unsigned char *src, int len)
{
- int blocks = len / 128;
- int start = 0;
+ int result;
+ int start;
NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
- NCR5380_write(hostdata->c400_blk_cnt, blocks);
- while (1) {
- if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)
- goto out_wait;
-
- if (NCR5380_read(hostdata->c400_blk_cnt) == 0)
+ NCR5380_write(hostdata->c400_blk_cnt, len / 128);
+
+ for (start = 0; start < len; start += 128) {
+ if (NCR5380_poll_politely2(hostdata, hostdata->c400_ctl_status,
+ CSR_HOST_BUF_NOT_RDY, 0,
+ hostdata->c400_ctl_status,
+ CSR_GATED_53C80_IRQ,
+ CSR_GATED_53C80_IRQ, HZ / 64) < 0)
break;
- while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
- ; // FIXME - timeout
-
- if (hostdata->io_port && hostdata->io_width == 2)
- outsw(hostdata->io_port + hostdata->c400_host_buf,
- src + start, 64);
- else if (hostdata->io_port)
- outsb(hostdata->io_port + hostdata->c400_host_buf,
- src + start, 128);
- else
- memcpy_toio(hostdata->io + NCR53C400_host_buffer,
- src + start, 128);
-
- start += 128;
- blocks--;
- }
- if (blocks) {
- while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
- ; // FIXME - no timeout
if (hostdata->io_port && hostdata->io_width == 2)
outsw(hostdata->io_port + hostdata->c400_host_buf,
@@ -606,26 +587,23 @@ static inline int generic_NCR5380_pwrite(struct NCR5380_hostdata *hostdata,
else
memcpy_toio(hostdata->io + NCR53C400_host_buffer,
src + start, 128);
-
- start += 128;
- blocks--;
}
-out_wait:
- /* wait for 53C80 registers to be available */
- while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) {
- udelay(4); /* DTC436 chip hangs without this */
- /* FIXME - no timeout */
- }
+ result = wait_for_53c80_access(hostdata);
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
pr_err("%s: No end dma signal (%d/%d)\n", __func__, start, len);
- hostdata->pdma_residual = len - start;
+ hostdata->pdma_residual = NCR5380_read(hostdata->c400_blk_cnt) * 128;
- while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
- ; // TIMEOUT
- return 0;
+ if (hostdata->pdma_residual == 0 &&
+ NCR5380_poll_politely(hostdata, TARGET_COMMAND_REG,
+ TCR_LAST_BYTE_SENT, TCR_LAST_BYTE_SENT,
+ HZ / 64) < 0)
+ scmd_printk(KERN_ERR, hostdata->connected,
+ "%s: Last Byte Sent timeout\n", __func__);
+
+ return result;
}
static int generic_NCR5380_dma_xfer_len(struct NCR5380_hostdata *hostdata,
[toc] | [prev] | [next] | [standalone]
| From | Ondrej Zary <linux@rainbow-software.org> |
|---|---|
| Date | 2017-06-23 22:20 +0200 |
| Message-ID | <tVDdD-6Lb-7@gated-at.bofh.it> |
| In reply to | #1673475 |
On Friday 23 June 2017 13:01:53 Finn Thain wrote: > On Fri, 23 Jun 2017, I wrote: > > Does this patch help? It should be applied on top of this series of 4. > > Sorry, I sent the wrong diff. Please try this patch instead. Thanks, much better now: both HDD and CD-ROM seem to work on DTC and non-DTC chips. I get many of these messages with CD-ROM: [ 912.397076] generic_NCR5380_pread: No end dma signal (4096/4096) [ 913.141225] generic_NCR5380_pread: No end dma signal (4096/4096) Maybe just remove this error message as in my original patch? -- Ondrej Zary
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2017-06-24 04:50 +0200 |
| Message-ID | <tVJj3-22E-13@gated-at.bofh.it> |
| In reply to | #1673816 |
On Fri, 23 Jun 2017, Ondrej Zary wrote: > On Friday 23 June 2017 13:01:53 Finn Thain wrote: > > On Fri, 23 Jun 2017, I wrote: > > > Does this patch help? It should be applied on top of this series of 4. > > > > Sorry, I sent the wrong diff. Please try this patch instead. > > Thanks, much better now: both HDD and CD-ROM seem to work on DTC and non-DTC > chips. I get many of these messages with CD-ROM: > [ 912.397076] generic_NCR5380_pread: No end dma signal (4096/4096) > [ 913.141225] generic_NCR5380_pread: No end dma signal (4096/4096) > > Maybe just remove this error message as in my original patch? > The "data loop" algorithm in the datasheet syas that if End of DMA doesn't become asserted after a transfer, this is an error condition. Your log (above) shows 4096/4096 bytes so I think that End of DMA is tested too soon: the datasheet says that End of DMA takes 100 ns to become asserted even after all of the relevant signals reach their final state. I'll re-do the series to account for this. Thanks for testing. --
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web