From: Sergei Shtylyov <sshtylyov@ru.mvista.com>
To: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Cc: linux-mips@linux-mips.org, linux-ide@vger.kernel.org,
Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>,
ralf@linux-mips.org
Subject: Re: [PATCH 1/2] ide: Add tx4939ide driver
Date: Tue, 09 Sep 2008 21:50:32 +0400 [thread overview]
Message-ID: <48C6B768.4010200@ru.mvista.com> (raw)
In-Reply-To: <20080910.010824.07456636.anemo@mba.ocn.ne.jp>
Atsushi Nemoto wrote:
> This is the driver for the Toshiba TX4939 SoC ATA controller.
> This controller has standard ATA taskfile registers and DMA
> command/status registers, but the register layout is swapped on big
> endian. There are some other endian issue and some special registers
> which requires many custom dma_ops/port_ops routines.
> Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
> ---
> This patch is against linux-next 20080905.
> drivers/ide/Kconfig | 6 +
> drivers/ide/mips/Makefile | 1 +
> drivers/ide/mips/tx4939ide.c | 762 ++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 769 insertions(+), 0 deletions(-)
> create mode 100644 drivers/ide/mips/tx4939ide.c
> diff --git a/drivers/ide/mips/tx4939ide.c b/drivers/ide/mips/tx4939ide.c
> new file mode 100644
> index 0000000..ba9776d
> --- /dev/null
> +++ b/drivers/ide/mips/tx4939ide.c
> @@ -0,0 +1,762 @@
[...]
> +static void tx4939ide_set_mode(ide_drive_t *drive, const u8 speed)
> +{
> + ide_hwif_t *hwif = HWIF(drive);
> + unsigned long base = TX4939IDE_BASE(hwif);
> + int is_slave = drive->dn & 1;
> + u16 value;
> + int safe_speed = speed;
> + int i;
> +
> + for (i = 0; i < MAX_DRIVES; i++) {
Use ide_get_paired_drive() ISO this loop.
> + if (drive != &hwif->drives[i] &&
> + (hwif->drives[i].dev_flags & IDE_DFLAG_PRESENT))
> + safe_speed = min(safe_speed,
> + (int)hwif->drives[i].current_speed);
You shouldn't clamp the command PIO mode timings like this, and shouldn't
do it at all when DMA mode is set. Call ide_get_best_pio_mode(255, 4) to get
the mate drive's fastest PIO mode which should be a clamping value.
> + /* Command Transfer Mode Select */
> + switch (safe_speed) {
> + case XFER_UDMA_5:
> + case XFER_UDMA_4:
> + case XFER_UDMA_3:
> + case XFER_UDMA_2:
> + case XFER_UDMA_1:
> + case XFER_UDMA_0:
> + case XFER_MW_DMA_2:
You shouldn't change the command PIO mode when DMA mode is selected.
> + case XFER_MW_DMA_1:
> + case XFER_MW_DMA_0:
> + case XFER_PIO_4:
MWDMA0/1 timings don't match PIO4, they are [much] slower.
> + value |= 0x0400;
> + break;
> + case XFER_PIO_3:
> + value |= 0x0300;
> + break;
> + case XFER_PIO_2:
> + value |= 0x0200;
> + break;
> + case XFER_PIO_1:
> + value |= 0x0100;
> + break;
> + default:
> + case XFER_PIO_0:
> + value |= 0x0000;
> + break;
> + }
> +
> + if (is_slave)
> + hwif->select_data =
> + (hwif->select_data & ~0xffff0000) | (value << 16);
Why not just 0x0000ffff?
> + else
> + hwif->select_data = (hwif->select_data & ~0x0000ffff) | value;
Why not just 0xffff0000?
> + TX4939IDE_writew(value, base, Sys_Ctl);
> +}
> +
> +static void tx4939ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
> +{
> + tx4939ide_set_mode(drive, XFER_PIO_0 + pio);
> +}
I suggest that you implement tx4939ide_set_{dma|pio}_mode() as seperate
functions, possibly using a common function to do a final part. These 2
methods are quite different functionally.
> +
> +static void tx4939ide_check_error_ints(ide_hwif_t *hwif, u16 stat)
> +{
> + if (stat & TX4939IDE_INT_BUSERR) {
> + unsigned long base = TX4939IDE_BASE(hwif);
> + /* reset FIFO */
> + TX4939IDE_writew(TX4939IDE_readw(base, Sys_Ctl) |
> + 0x4000,
> + base, Sys_Ctl);
> + }
> + if (stat & (TX4939IDE_INT_ADDRERR | TX4939IDE_INT_REACHMUL |
> + TX4939IDE_INT_DEVTIMING | TX4939IDE_INT_BUSERR))
> + pr_err("%s: Error interrupt %#x (%s%s%s%s )\n",
> + hwif->name, stat,
> + (stat & TX4939IDE_INT_ADDRERR) ?
> + " Address-Error" : "",
> + (stat & TX4939IDE_INT_REACHMUL) ?
> + " Reach-Multiple" : "",
> + (stat & TX4939IDE_INT_DEVTIMING) ?
> + " DEV-Timing" : "",
> + (stat & TX4939IDE_INT_BUSERR) ?
> + " Bus-Error" : "");
> +}
> +
> +static void tx4939ide_clear_irq(ide_drive_t *drive)
> +{
> + ide_hwif_t *hwif;
> + unsigned long base;
> + u16 ctl;
> +
> + /*
> + * tx4939ide_dma_test_irq() and tx4939ide_dma_end() do all
> + * jobs for DMA case.
> + */
> + if (drive->waiting_for_dma)
> + return;
> + hwif = HWIF(drive);
> + base = TX4939IDE_BASE(hwif);
> + ctl = TX4939IDE_readw(base, int_ctl);
> +
> + tx4939ide_check_error_ints(hwif, ctl);
> + TX4939IDE_writew(ctl, base, int_ctl);
> +}
> +
> +static int tx4939ide_dma_setup(ide_drive_t *drive)
> +{
> + ide_hwif_t *hwif = HWIF(drive);
> + unsigned long base = TX4939IDE_BASE(hwif);
> + int is_slave = drive->dn & 1;
> + unsigned int nframes;
> + int rc, i;
> + unsigned int sect_size = queue_hardsect_size(drive->queue);
> + u16 select_data;
> +
> + select_data = (hwif->select_data >> (is_slave ? 16 : 0)) & 0xffff;
> + TX4939IDE_writew(select_data, base, Sys_Ctl);
Unfortunately, programming the timings from the dma_setup() method isn't
enough since it won't be called for PIO transfers. You'll have to use the
selectproc() method.
MBR, Sergei
next prev parent reply other threads:[~2008-09-09 17:49 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-09 16:08 [PATCH 1/2] ide: Add tx4939ide driver Atsushi Nemoto
2008-09-09 16:44 ` Alan Cox
2008-09-09 17:08 ` Sergei Shtylyov
2008-09-10 15:12 ` Atsushi Nemoto
2008-09-10 15:06 ` Atsushi Nemoto
2008-09-13 13:37 ` Atsushi Nemoto
2008-09-09 17:50 ` Sergei Shtylyov [this message]
2008-09-10 15:32 ` Atsushi Nemoto
2008-09-10 15:55 ` Sergei Shtylyov
2008-09-10 16:25 ` Sergei Shtylyov
2008-09-11 15:03 ` Atsushi Nemoto
2008-09-11 15:18 ` Sergei Shtylyov
2008-09-10 23:02 ` Sergei Shtylyov
2008-09-11 15:52 ` Atsushi Nemoto
2008-09-12 15:34 ` Sergei Shtylyov
2008-09-12 15:59 ` Atsushi Nemoto
2008-09-12 16:44 ` Sergei Shtylyov
2008-09-12 17:19 ` Sergei Shtylyov
2008-09-13 12:32 ` Atsushi Nemoto
2008-09-16 21:15 ` Sergei Shtylyov
2008-09-16 21:39 ` Sergei Shtylyov
2008-09-27 16:19 ` Bartlomiej Zolnierkiewicz
2008-09-27 22:09 ` Tejun Heo
2008-09-30 13:07 ` Atsushi Nemoto
2008-09-30 15:09 ` James Bottomley
2008-10-04 2:56 ` Tejun Heo
2008-10-07 12:09 ` Jens Axboe
2008-09-28 8:41 ` Ralf Baechle
2008-09-11 22:33 ` Sergei Shtylyov
2008-09-12 14:37 ` Atsushi Nemoto
2008-09-12 15:01 ` Sergei Shtylyov
2008-09-13 21:48 ` Sergei Shtylyov
2008-09-14 13:05 ` Atsushi Nemoto
2008-09-16 10:29 ` Sergei Shtylyov
2008-09-16 15:20 ` Atsushi Nemoto
2008-09-16 15:32 ` Sergei Shtylyov
2008-09-16 16:24 ` Sergei Shtylyov
2008-09-16 21:02 ` Sergei Shtylyov
2008-09-14 20:55 ` Sergei Shtylyov
2008-09-15 14:01 ` Atsushi Nemoto
2008-09-16 21:59 ` Sergei Shtylyov
2008-09-17 15:12 ` Atsushi Nemoto
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=48C6B768.4010200@ru.mvista.com \
--to=sshtylyov@ru.mvista.com \
--cc=anemo@mba.ocn.ne.jp \
--cc=bzolnier@gmail.com \
--cc=linux-ide@vger.kernel.org \
--cc=linux-mips@linux-mips.org \
--cc=ralf@linux-mips.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).