linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stanislaw Gruszka <stf_xl@wp.pl>
To: Igor Plyatov <plyatov@gmail.com>
Cc: Jeff Garzik <jgarzik@pobox.com>,
	linux-ide@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] ATA: pata_at91.c bugfixes
Date: Sat, 23 Apr 2011 11:36:23 +0200	[thread overview]
Message-ID: <20110423093623.GA3410@localhost.localdomain> (raw)
In-Reply-To: <1303299877-12088-1-git-send-email-plyatov@gmail.com>

Hi Igor

On Wed, Apr 20, 2011 at 03:44:37PM +0400, Igor Plyatov wrote:
> * Fix "initial_timing" structure initialisation. The "struct ata_timing" must
>   contain 10 members, but ".dmack_hold" member was not initialised.
> * The AT91SAM9 microcontrollers use special coding scheme for SMC_SETUP,
>   SMC_PULSE, SMC_CYCLE registers.
>   Old driver operates correctly only with low master clock values, but
>   with high master clock it incorrectly calculates SMC values and stops
>   to operate, because SMC can be setup only to admissible ranges in special
>   format.
>   New code correctly calculates SMC registers values, adjusts calculated
>   to admissible ranges, enlarges cycles if required and converts values
>   into SMC's format.
> * Old driver calculates CS_SETUP and CS_PULSE cycles incorrectly
>   because of wrong assumptions.
>   New code calculates:
>       CS_SETUP = SETUP/2

If you to this, then {RD,WR}_SETUP have to be equal SETUP + SETUP/2
to generate proper setup (t0) time on IDE bus. I think the best way is
set CS_SETUP and CS_HOLD to 0 (what your code do if SETUP and HOLD <=1),
but to do this you need to take care of data float (t6z) 

> +static const struct ata_timing initial_timing = {
> +	.mode		= XFER_PIO_0,
> +	.setup		= 70,
> +	.act8b		= 290,
> +	.rec8b		= 240,
> +	.cyc8b		= 600,
> +	.active		= 165,
> +	.recover	= 150,
> +	.dmack_hold	= 0,
> +	.cycle		= 600,
> +	.udma		= 0
> +};

Is this really needed, why not use ata_timing_find_mode(XFER_PIO_0)?

> +static int adjust_smc_value(unsigned int *value, int *prange,
> +				unsigned int size)
> +{
> +	unsigned char i;
> +	int remainder;
> +
> +	for (i = 0; i < size; i = i + 2) {
> +		if (*value < prange[i]) {
> +			remainder = prange[i] - *value;
> +			*value = prange[i]; /* nearest valid value */
> +			return remainder;
> +		}
> +		else if ((prange[i] <= *value) && (*value <= prange[i+1])) {
> +			return 0;
> +		}
> +	}
> +	*value = prange[size - 1]; /* assign maximal possible value */
> +
> +	return -1; /* invalid value */
> +}
[snip]
> +static void calc_smc_vals(struct device *dev,
> +				unsigned int *setup, unsigned int *cs_setup,
> +				unsigned int *pulse, unsigned int *cs_pulse,
> +				unsigned int *cycle)
> +{
> +	int ret_val;
> +	int cs_hold;
> +	int range_setup[] = {	/* SMC_SETUP valid ranges */
> +		0, 31,		/* first  range */
> +		128, 159,	/* second range */
> +	};
> +	int range_pulse[] = {	/* SMC_PULSE valid ranges */
> +		0, 63,		/* first  range */
> +		256, 319,	/* second range */
> +	};
> +	int range_cycle[] = {	/* SMC_CYCLE valid ranges */
> +		0, 127,		/* first  range */
> +		256, 383,	/* second range */
> +		512, 639,	/* third  range */
> +		768, 895,	/* fourth range */
> +	};

Introducing helper structure like

struct smc_range {
	u16 min, max;
};

would be a bit cleaner way of coding that (hint: ARRAY_SIZE could be used
instead of sizeof then)

> -	dev_dbg(dev, "ATA timings: nrd_setup = %lu nrd_pulse = %lu nrd_cycle = %lu\n",
> -			nrd_setup, nrd_pulse, read_cycle);
> -	dev_dbg(dev, "ATA timings: nwe_setup = %lu nwe_pulse = %lu nwe_cycle = %lu\n",
> -			nwe_setup, nwe_pulse, write_cycle);
> -	dev_dbg(dev, "ATA timings: ncs_read_setup = %lu ncs_read_pulse = %lu\n",
> -			ncs_read_setup, ncs_read_pulse);
> -	dev_dbg(dev, "ATA timings: ncs_write_setup = %lu ncs_write_pulse = %lu\n",
> -			ncs_write_setup, ncs_write_pulse);

It's worth to have some debugging prints to check if values are calculated
properly.

Thanks
Stanislaw

  reply	other threads:[~2011-04-23  9:36 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-20 11:44 [PATCH] ATA: pata_at91.c bugfixes Igor Plyatov
2011-04-23  9:36 ` Stanislaw Gruszka [this message]
2011-04-26  6:38   ` Igor Plyatov
2011-04-27 18:38     ` Stanislaw Gruszka
2011-04-29  7:56       ` Stanisław Gruszka
2011-04-24 15:35 ` Jeff Garzik
2011-05-12 12:05   ` Igor Plyatov

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=20110423093623.GA3410@localhost.localdomain \
    --to=stf_xl@wp.pl \
    --cc=jgarzik@pobox.com \
    --cc=linux-ide@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=plyatov@gmail.com \
    /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).