linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff Garzik <jgarzik@pobox.com>
To: Tejun Heo <htejun@gmail.com>
Cc: alan@lxorguk.ukuu.org.uk, mlord@pobox.com, albertcc@tw.ibm.com,
	uchang@tw.ibm.com, forrest.zhao@intel.com, brking@us.ibm.com,
	linux-ide@vger.kernel.org
Subject: Re: [PATCH 6/20] libata: implement legacy ATA init helpers
Date: Tue, 19 Sep 2006 01:26:11 -0400	[thread overview]
Message-ID: <450F7F73.1000409@pobox.com> (raw)
In-Reply-To: <1155977971677-git-send-email-htejun@gmail.com>

Tejun Heo wrote:
> Implement the following legacy ATA init helpers.
> 
> * ata_legacy_acquire_resources()	: acquire legacy ATA resources
> * ata_legacy_release_resources()	: release legacy ATA resources
> * ata_legacy_init_ports()		: init legacy port addresses
> * ata_legacy_request_irqs()		: request legacy ATA IRQs
> * ata_legacy_free_irqs()		: free legacy ATA IRQs
> 
> These helpers can be used independently or called implictly from other
> bus helpers which has support for legacy ATA device for compatibility
> (e.g. PCI).
> 
> Signed-off-by: Tejun Heo <htejun@gmail.com>

The irq part will change based on comments from previous email



> diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
> index 2109d75..1a98559 100644
> --- a/drivers/ata/Kconfig
> +++ b/drivers/ata/Kconfig
> @@ -15,6 +15,11 @@ config ATA
>  	  that "speaks" the ATA protocol, also called ATA controller),
>  	  because you will be asked for it.
>  
> +config ATA_LEGACY
> +	bool
> +	depends on ATA
> +	default n
> +
>  config SATA_AHCI
>  	tristate "AHCI SATA support"
>  	depends on ATA && PCI
> diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
> index c17ae9c..61d3e76 100644
> --- a/drivers/ata/Makefile
> +++ b/drivers/ata/Makefile
> @@ -19,3 +19,6 @@ obj-$(CONFIG_PDC_ADMA)		+= pdc_adma.o
>  
>  libata-objs	:= libata-core.o libata-scsi.o libata-bmdma.o libata-eh.o
>  
> +ifeq ($(CONFIG_ATA_LEGACY),y)
> +libata-objs	+= libata-legacy.o
> +endif
> diff --git a/drivers/ata/libata-legacy.c b/drivers/ata/libata-legacy.c
> new file mode 100644
> index 0000000..00b70b0
> --- /dev/null
> +++ b/drivers/ata/libata-legacy.c
> @@ -0,0 +1,241 @@
> +/*
> + *  libata-legacy.c - helper library for legacy ATA
> + *
> + *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
> + *    		    Please ALWAYS copy linux-ide@vger.kernel.org
> + *		    on emails.
> + *
> + *  Copyright 2006 Tejun Heo <htejun@gmail.com>
> + *
> + *
> + *  This program is free software; you can redistribute it and/or
> + *  modify it under the terms of the GNU General Public License as
> + *  published by the Free Software Foundation; either version 2, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + *  General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with this program; see the file COPYING.  If not, write to
> + *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
> + *  USA.
> + *
> + *
> + *  libata documentation is available via 'make {ps|pdf}docs',
> + *  as Documentation/DocBook/libata.*
> + *
> + *  Hardware documentation available from http://www.t13.org/ and
> + *  http://www.sata-io.org/
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/libata.h>
> +
> +#include "libata.h"
> +
> +static unsigned long ata_legacy_addr(int port, int sel)
> +{
> +	if (port == 0) {
> +		if (sel == 0)
> +			return ATA_PRIMARY_CMD;
> +		else
> +			return ATA_PRIMARY_CTL;
> +	} else {
> +		if (sel == 0)
> +			return ATA_SECONDARY_CMD;
> +		else
> +			return ATA_SECONDARY_CTL;
> +	}
> +}

insufficient long term, but matches current code so ACK for now.

This will change depending on platform, and for easier x86 chipsets



> +static int ata_legacy_acquire_port(struct ata_port *ap)
> +{
> +	struct ata_host *host = ap->host;
> +	unsigned long cmd_addr = ata_legacy_addr(ap->port_no, 0);
> +
> +	if (request_region(cmd_addr, 8, "libata") != NULL)
> +		host->legacy_flags |= ATA_LEGACY_RES_PRI << ap->port_no;
> +	else {
> +		struct resource *conflict, res;
> +
> +		res.start = cmd_addr;
> +		res.end = cmd_addr + 8 - 1;
> +		conflict = ____request_resource(&ioport_resource, &res);
> +
> +		if (strcmp(conflict->name, "libata")) {
> +			printk(KERN_WARNING "ata: 0x%0lX IDE port busy\n",
> +			       cmd_addr);
> +			host->flags |= ATA_HOST_DEV_BUSY;
> +			return -EBUSY;
> +		}
> +		printk("ata: 0x%0lX IDE port preallocated\n", cmd_addr);

obviously needs updating based on the patch I just applied to 
libata#upstream from Arnaud @ Mandriva


> +/**
> + *	ata_legacy_acquire_resources - acquire legacy ATA resources
> + *	@host: target ATA host
> + *	@p_reason: out arg for error message (can be NULL)
> + *
> + *	Acquire legacy ATA resources for ports specified by
> + *	ATA_PORT_PRIMARY/SECONDARY mask in host->legacy_flags.  If the
> + *	port is busy, this function makes the port dummy instead of
> + *	failing.  This is to allow legacy ports to be driven by other
> + *	drivers.
> + *
> + *	LOCKING:
> + *	Inherited from calling layer (may sleep).
> + *
> + *	RETURNS:
> + *	0 on success, -errno otherwise.
> + */
> +int ata_legacy_acquire_resources(struct ata_host *host, const char **p_reason)
> +{
> +	int i;
> +
> +	for (i = 0; i < 2; i++) {
> +		if (!(host->legacy_flags & (ATA_PORT_PRIMARY << i)))
> +			continue;
> +		BUG_ON(i >= host->n_ports);
> +
> +		if (ata_legacy_acquire_port(host->ports[i]))
> +			host->ports[i]->ops = &ata_dummy_port_ops;
> +	}
> +
> +	return 0;
> +}
> +
> +/**
> + *	ata_legacy_release_resources - release legacy ATA resources
> + *	@host: target ATA host
> + *
> + *	Free all legacy ATA resources @host is holding.
> + *
> + *	LOCKING:
> + *	Inherited from calling layer (may sleep).
> + */
> +void ata_legacy_release_resources(struct ata_host *host)
> +{
> +	int i;
> +
> +	for (i = 0; i < 2; i++) {
> +		if (host->legacy_flags & (ATA_LEGACY_RES_PRI << i)) {
> +			release_region(ata_legacy_addr(i, 0), 8);
> +			host->legacy_flags &= ~(ATA_LEGACY_RES_PRI << i);
> +		}
> +	}
> +}
> +
> +/**
> + *	ata_legacy_init_ports - initialize legacy ATA port addresses
> + *	@host: target ATA host
> + *
> + *	Initialize legacy ATA port addresses for non-dummy legacy
> + *	ports in @host.
> + *
> + *	LOCKING:
> + *	Inherited from calling layer.
> + */
> +void ata_legacy_init_ports(struct ata_host *host)
> +{
> +	int i;
> +
> +	for (i = 0; i < 2; i++) {
> +		struct ata_port *ap = host->ports[i];
> +
> +		if (host->legacy_flags & (ATA_PORT_PRIMARY << i) &&
> +		    !ata_port_is_dummy(ap)) {
> +			struct ata_ioports *ioaddr = &ap->ioaddr;
> +			unsigned long cmd_addr = ata_legacy_addr(i, 0);
> +			unsigned long ctl_addr = ata_legacy_addr(i, 1);
> +
> +			ioaddr->cmd_addr = cmd_addr;
> +			ioaddr->altstatus_addr = ctl_addr;
> +			ioaddr->ctl_addr = ctl_addr;
> +			ata_std_ports(ioaddr);
> +		}
> +	}
> +}
> +
> +/**
> + *	ata_legacy_request_irqs - request legacy ATA IRQs
> + *	@host: target ATA host
> + *	@handler: array of IRQ handlers
> + *	@irq_flags: array of IRQ flags
> + *	@dev_id: array of IRQ dev_ids
> + *	@p_reason: out arg for error message (can be NULL)
> + *
> + *	Request legacy IRQs for non-dummy legacy ports in @host.  All
> + *	IRQ parameters are passed as array to allow ports to have
> + *	separate IRQ handlers.
> + *
> + *	LOCKING:
> + *	Inherited from calling layer (may sleep).
> + *
> + *	RETURNS:
> + *	0 on success, -errno otherwise.
> + */
> +int ata_legacy_request_irqs(struct ata_host *host,
> +		irqreturn_t (* const * handler)(int, void *, struct pt_regs *),
> +		const unsigned int *irq_flags, void * const *dev_id,
> +		const char **p_reason)
> +{
> +	const unsigned int legacy_irq[] = { 14, 15 };
> +	const char *reason;
> +	int i, rc;
> +
> +	for (i = 0; i < 2; i++) {
> +		struct ata_port *ap = host->ports[i];
> +		unsigned int irq = legacy_irq[i];
> +
> +		if (!(host->legacy_flags & (ATA_PORT_PRIMARY << i)) ||
> +		    ata_port_is_dummy(ap))
> +			continue;
> +
> +		if (!handler[i]) {
> +			reason = "NULL handler";
> +			rc = -EINVAL;
> +			goto err;
> +		}
> +
> +		rc = ata_host_request_irq_marker(host, irq,
> +					handler[i], irq_flags[i], dev_id[i],
> +					ata_legacy_request_irqs, &reason);
> +		if (rc)
> +			goto err;
> +
> +		/* only for info printing */
> +		if (i == 0)
> +			host->irq = irq;
> +		else
> +			host->irq2 = irq;
> +	}
> +
> +	return 0;
> +
> + err:
> +	ata_legacy_free_irqs(host);
> +	if (p_reason)
> +		*p_reason = reason;
> +	return rc;
> +}
> +
> +/**
> + *	ata_legacy_free_irqs - free legacy ATA IRQs
> + *	@host: target ATA host
> + *
> + *	Free all legacy ATA IRQs of @host.
> + *
> + *	LOCKING:
> + *	Inherited from calling layer (may sleep).
> + */
> +void ata_legacy_free_irqs(struct ata_host *host)
> +{
> +	ata_host_free_irqs_marker(host, ata_legacy_request_irqs);
> +}
> diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
> index 1d24254..0601c4a 100644
> --- a/drivers/ata/libata.h
> +++ b/drivers/ata/libata.h
> @@ -117,6 +117,17 @@ extern void ata_schedule_scsi_eh(struct 
>  extern void ata_scsi_dev_rescan(void *data);
>  extern int ata_bus_probe(struct ata_port *ap);
>  
> +/* libata-legacy.c */
> +extern int ata_legacy_acquire_resources(struct ata_host *host,
> +					const char **p_reason);
> +extern void ata_legacy_release_resources(struct ata_host *host);
> +extern void ata_legacy_init_ports(struct ata_host *host);
> +extern int ata_legacy_request_irqs(struct ata_host *host,
> +		irqreturn_t (* const * handler)(int, void *, struct pt_regs *),
> +		const unsigned int *irq_flags, void * const *dev_id,
> +		const char **p_reason);
> +extern void ata_legacy_free_irqs(struct ata_host *host);
> +
>  /* libata-eh.c */
>  extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
>  extern void ata_scsi_error(struct Scsi_Host *host);
> diff --git a/include/linux/libata.h b/include/linux/libata.h
> index b050517..9535f54 100644
> --- a/include/linux/libata.h
> +++ b/include/linux/libata.h
> @@ -200,8 +200,16 @@ enum {
>  	ATA_QCFLAG_EH_SCHEDULED = (1 << 18), /* EH scheduled (obsolete) */
>  
>  	/* host set flags */
> -	ATA_HOST_SIMPLEX	= (1 << 0),	/* Host is simplex, one DMA channel per host only */
> -	
> +	ATA_HOST_SIMPLEX	= (1 << 0), /* host is simplex, one DMA channel per host only */
> +	ATA_HOST_DEV_BUSY	= (1 << 1), /* host device was busy on init */

this flag is set but never used.  doesn't seem necessary anyway... just 
return an error code.


  reply	other threads:[~2006-09-19  5:26 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-08-19  8:57 [PATCHSET] libata: implement new initialization model w/ iomap support, take 2 Tejun Heo
2006-08-19  8:59 ` [PATCH 1/20] libata: kill ata_host_stop() Tejun Heo
2006-08-19 14:51   ` Jeff Garzik
2006-08-19 15:29     ` Tejun Heo
2006-09-19  4:46   ` Jeff Garzik
2006-09-19  4:50     ` Tejun Heo
2006-08-19  8:59 ` [PATCH 2/20] libata: implement ata_host_start/stop() Tejun Heo
2006-08-19  8:59 ` [PATCH 6/20] libata: implement legacy ATA init helpers Tejun Heo
2006-09-19  5:26   ` Jeff Garzik [this message]
2006-08-19  8:59 ` [PATCH 3/20] libata: implement ata_host_detach() and ata_host_free() Tejun Heo
2006-09-19  4:59   ` Jeff Garzik
2006-08-19  8:59 ` [PATCH 5/20] libata: implement several LLD init helpers Tejun Heo
2006-08-22 22:11   ` Brian King
2006-08-27  9:52     ` Tejun Heo
2006-08-30 21:16       ` Brian King
2006-09-19  5:16   ` Jeff Garzik
2006-09-19  5:57     ` Tejun Heo
2006-08-19  8:59 ` [PATCH 4/20] libata: separate out ata_host_alloc() and ata_host_attach() Tejun Heo
2006-09-19  5:08   ` Jeff Garzik
2006-09-19  5:48     ` Tejun Heo
2006-08-19  8:59 ` [PATCH 7/20] libata: implement PCI ATA init helpers Tejun Heo
2006-09-19  5:29   ` Jeff Garzik
2006-08-19  8:59 ` [PATCH 11/20] libata: use remove_one() for deinit instead of ->host_stop() Tejun Heo
2006-09-19  5:42   ` Jeff Garzik
2006-08-19  8:59 ` [PATCH 8/20] libata: reimplement ata_pci_init_one() using new init helpers Tejun Heo
2006-09-19  5:32   ` Jeff Garzik
2006-09-19  6:04     ` Tejun Heo
2006-09-19  6:09       ` Jeff Garzik
2006-08-19  8:59 ` [PATCH 13/20] libata: kill unused ->host_stop() operation and related functions Tejun Heo
2006-09-19  5:42   ` Jeff Garzik
2006-08-19  8:59 ` [PATCH 10/20] libata: reimplement ata_pci_remove_one() using new PCI init helpers Tejun Heo
2006-08-19  8:59 ` [PATCH 12/20] libata: kill old " Tejun Heo
2006-08-19  8:59 ` [PATCH 15/20] libata: move ->irq_handler from port_ops to port_info Tejun Heo
2006-09-19  5:43   ` Jeff Garzik
2006-08-19  8:59 ` [PATCH 19/20] libata: kill unused ATA_FLAG_MMIO Tejun Heo
2006-08-19  8:59 ` [PATCH 16/20] libata: make ata_host_alloc() take care of hpriv alloc/free Tejun Heo
2006-09-19  5:45   ` Jeff Garzik
2006-08-19  8:59 ` [PATCH 14/20] libata: use LLD name where possible Tejun Heo
2006-09-19  5:43   ` Jeff Garzik
2006-08-19  8:59 ` [PATCH 17/20] libata: make ata_pci_acquire_resources() handle iomap Tejun Heo
2006-09-19  5:47   ` Jeff Garzik
2006-09-19  6:27     ` Tejun Heo
2006-09-19  6:32       ` Jeff Garzik
2006-08-19  8:59 ` [PATCH 20/20] libata: move scattered PCI ATA functions into liata-pci.c Tejun Heo
2006-09-19  5:50   ` Jeff Garzik
2006-08-22 22:10 ` [PATCHSET] libata: implement new initialization model w/ iomap support, take 2 Brian King
2006-08-27 10:12   ` Tejun Heo
2006-08-30 20:58     ` Brian King
2006-09-01 13:45       ` Tejun Heo
2006-09-07 13:22         ` Brian King

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=450F7F73.1000409@pobox.com \
    --to=jgarzik@pobox.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=albertcc@tw.ibm.com \
    --cc=brking@us.ibm.com \
    --cc=forrest.zhao@intel.com \
    --cc=htejun@gmail.com \
    --cc=linux-ide@vger.kernel.org \
    --cc=mlord@pobox.com \
    --cc=uchang@tw.ibm.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).