public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Alex Williamson <alex.williamson@redhat.com>
To: linux-pci@vger.kernel.org, Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: linux-kernel@vger.kernel.org, chrisw@redhat.com,
	ddutile@redhat.com, bjorn.helgaas@hp.com, eike-kernel@sf-tec.de
Subject: Re: [PATCH v2] pci: Allow read/write access to sysfs I/O port resources
Date: Fri, 23 Jul 2010 09:10:27 -0600	[thread overview]
Message-ID: <1279897827.4601.89.camel@x201> (raw)
In-Reply-To: <20100719154321.11535.39055.stgit@localhost6.localdomain6>

On Mon, 2010-07-19 at 09:45 -0600, Alex Williamson wrote:
> PCI sysfs resource files currently only allow mmap'ing.  On x86 this
> works fine for memory backed BARs, but doesn't work at all for I/O
> port backed BARs.  Add read/write to I/O port PCI sysfs resource
> files to allow userspace access to these device regions.
> 
> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
> ---

Any thoughts on this for -next?  Thanks,

Alex

>  v2: hopefully better commit log, remove unneeded cast, use bool
> 
>  Documentation/filesystems/sysfs-pci.txt |    7 ++-
>  drivers/pci/pci-sysfs.c                 |   68 +++++++++++++++++++++++++++++++
>  2 files changed, 73 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt
> index 85354b3..74eaac2 100644
> --- a/Documentation/filesystems/sysfs-pci.txt
> +++ b/Documentation/filesystems/sysfs-pci.txt
> @@ -39,7 +39,7 @@ files, each with their own function.
>         local_cpus	   nearby CPU mask (cpumask, ro)
>         remove		   remove device from kernel's list (ascii, wo)
>         resource		   PCI resource host addresses (ascii, ro)
> -       resource0..N	   PCI resource N, if present (binary, mmap)
> +       resource0..N	   PCI resource N, if present (binary, mmap, rw[1])
>         resource0_wc..N_wc  PCI WC map resource N, if prefetchable (binary, mmap)
>         rom		   PCI ROM resource, if present (binary, ro)
>         subsystem_device	   PCI subsystem device (ascii, ro)
> @@ -54,13 +54,16 @@ files, each with their own function.
>    binary - file contains binary data
>    cpumask - file contains a cpumask type
>  
> +[1] rw for RESOURCE_IO (I/O port) regions only
> +
>  The read only files are informational, writes to them will be ignored, with
>  the exception of the 'rom' file.  Writable files can be used to perform
>  actions on the device (e.g. changing config space, detaching a device).
>  mmapable files are available via an mmap of the file at offset 0 and can be
>  used to do actual device programming from userspace.  Note that some platforms
>  don't support mmapping of certain resources, so be sure to check the return
> -value from any attempted mmap.
> +value from any attempted mmap.  The most notable of these are I/O port
> +resources, which also provide read/write access.
>  
>  The 'enable' file provides a counter that indicates how many times the device 
>  has been enabled.  If the 'enable' file currently returns '4', and a '1' is
> diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
> index 5935b85..f7692dc 100644
> --- a/drivers/pci/pci-sysfs.c
> +++ b/drivers/pci/pci-sysfs.c
> @@ -778,6 +778,70 @@ pci_mmap_resource_wc(struct file *filp, struct kobject *kobj,
>  	return pci_mmap_resource(kobj, attr, vma, 1);
>  }
>  
> +static ssize_t
> +pci_resource_io(struct file *filp, struct kobject *kobj,
> +		struct bin_attribute *attr, char *buf,
> +		loff_t off, size_t count, bool write)
> +{
> +	struct pci_dev *pdev = to_pci_dev(container_of(kobj,
> +						       struct device, kobj));
> +	struct resource *res = attr->private;
> +	unsigned long port = off;
> +	int i;
> +
> +	for (i = 0; i < PCI_ROM_RESOURCE; i++)
> +		if (res == &pdev->resource[i])
> +			break;
> +	if (i >= PCI_ROM_RESOURCE)
> +		return -ENODEV;
> +
> +	port += pci_resource_start(pdev, i);
> +
> +	if (port > pci_resource_end(pdev, i))
> +		return 0;
> +
> +	if (port + count - 1 > pci_resource_end(pdev, i))
> +		return -EINVAL;
> +
> +	switch (count) {
> +	case 1:
> +		if (write)
> +			outb(*(u8 *)buf, port);
> +		else
> +			*(u8 *)buf = inb(port);
> +		return 1;
> +	case 2:
> +		if (write)
> +			outw(*(u16 *)buf, port);
> +		else
> +			*(u16 *)buf = inw(port);
> +		return 2;
> +	case 4:
> +		if (write)
> +			outl(*(u32 *)buf, port);
> +		else
> +			*(u32 *)buf = inl(port);
> +		return 4;
> +	}
> +	return -EINVAL;
> +}
> +
> +static ssize_t
> +pci_read_resource_io(struct file *filp, struct kobject *kobj,
> +		     struct bin_attribute *attr, char *buf,
> +		     loff_t off, size_t count)
> +{
> +	return pci_resource_io(filp, kobj, attr, buf, off, count, false);
> +}
> +
> +static ssize_t
> +pci_write_resource_io(struct file *filp, struct kobject *kobj,
> +		      struct bin_attribute *attr, char *buf,
> +		      loff_t off, size_t count)
> +{
> +	return pci_resource_io(filp, kobj, attr, buf, off, count, true);
> +}
> +
>  /**
>   * pci_remove_resource_files - cleanup resource files
>   * @pdev: dev to cleanup
> @@ -828,6 +892,10 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
>  			sprintf(res_attr_name, "resource%d", num);
>  			res_attr->mmap = pci_mmap_resource_uc;
>  		}
> +		if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
> +			res_attr->read = pci_read_resource_io;
> +			res_attr->write = pci_write_resource_io;
> +		}
>  		res_attr->attr.name = res_attr_name;
>  		res_attr->attr.mode = S_IRUSR | S_IWUSR;
>  		res_attr->size = pci_resource_len(pdev, num);
> 




  reply	other threads:[~2010-07-23 15:11 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-07-19  3:15 [PATCH] pci: Allow read/write access to I/O port resources Alex Williamson
2010-07-19  5:56 ` Rolf Eike Beer
2010-07-19 15:45 ` [PATCH v2] pci: Allow read/write access to sysfs " Alex Williamson
2010-07-23 15:10   ` Alex Williamson [this message]
2010-07-23 16:28     ` Jesse Barnes
2010-07-23 17:42       ` Chris Wright
2010-07-30 16:36   ` Jesse Barnes

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=1279897827.4601.89.camel@x201 \
    --to=alex.williamson@redhat.com \
    --cc=bjorn.helgaas@hp.com \
    --cc=chrisw@redhat.com \
    --cc=ddutile@redhat.com \
    --cc=eike-kernel@sf-tec.de \
    --cc=jbarnes@virtuousgeek.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.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