[linux-yocto] [PATCH] libata: support the ata host which implements a queue depth less than 32

Bruce Ashfield bruce.ashfield at windriver.com
Tue Jul 22 06:51:54 PDT 2014


On 14-07-19 09:37 AM, Kevin Hao wrote:
> From: Kevin Hao <haokexin at gmail.com>

Ack'd. I'll apply this shortly, I'm just sorting out some 3.16 issues
first.

Bruce

>
> commit 1871ee134b73fb4cadab75752a7152ed2813c751 from
> git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
>
> The sata on fsl mpc8315e is broken after the commit 8a4aeec8d2d6
> ("libata/ahci: accommodate tag ordered controllers"). The reason is
> that the ata controller on this SoC only implement a queue depth of
> 16. When issuing the commands in tag order, all the commands in tag
> 16 ~ 31 are mapped to tag 0 unconditionally and then causes the sata
> malfunction. It makes no senses to use a 32 queue in software while
> the hardware has less queue depth. So consider the queue depth
> implemented by the hardware when requesting a command tag.
>
> Fixes: 8a4aeec8d2d6 ("libata/ahci: accommodate tag ordered controllers")
> Cc: stable at vger.kernel.org
> Signed-off-by: Kevin Hao <haokexin at gmail.com>
> Acked-by: Dan Williams <dan.j.williams at intel.com>
> Signed-off-by: Tejun Heo <tj at kernel.org>
> ---
> Hi Bruce,
>
> This is the fix for Bug 6489 - SATA harddisk error on mpc8315e-rdb
>
>   drivers/ata/libata-core.c | 22 +++++++++++++++++++---
>   1 file changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
> index 0a79c540169c..5f627d9b80a5 100644
> --- a/drivers/ata/libata-core.c
> +++ b/drivers/ata/libata-core.c
> @@ -4787,6 +4787,10 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
>    *	ata_qc_new - Request an available ATA command, for queueing
>    *	@ap: target port
>    *
> + *	Some ATA host controllers may implement a queue depth which is less
> + *	than ATA_MAX_QUEUE. So we shouldn't allocate a tag which is beyond
> + *	the hardware limitation.
> + *
>    *	LOCKING:
>    *	None.
>    */
> @@ -4794,14 +4798,16 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
>   static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
>   {
>   	struct ata_queued_cmd *qc = NULL;
> -	unsigned int i, tag;
> +	unsigned int i, tag, max_queue;
> +
> +	max_queue = ap->scsi_host->can_queue;
>
>   	/* no command while frozen */
>   	if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
>   		return NULL;
>
> -	for (i = 0; i < ATA_MAX_QUEUE; i++) {
> -		tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
> +	for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) {
> +		tag = tag < max_queue ? tag : 0;
>
>   		/* the last tag is reserved for internal command. */
>   		if (tag == ATA_TAG_INTERNAL)
> @@ -6184,6 +6190,16 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
>   {
>   	int i, rc;
>
> +	/*
> +	 * The max queue supported by hardware must not be greater than
> +	 * ATA_MAX_QUEUE.
> +	 */
> +	if (sht->can_queue > ATA_MAX_QUEUE) {
> +		dev_err(host->dev, "BUG: the hardware max queue is too large\n");
> +		WARN_ON(1);
> +		return -EINVAL;
> +	}
> +
>   	/* host must have been started */
>   	if (!(host->flags & ATA_HOST_STARTED)) {
>   		dev_err(host->dev, "BUG: trying to register unstarted host\n");
>



More information about the linux-yocto mailing list