* Re: configure patch for cross compilation
From: Kay Sievers @ 2010-06-02 14:57 UTC (permalink / raw)
To: linux-hotplug
In-Reply-To: <4C066A21.9090507@san.rr.com>
On Wed, Jun 2, 2010 at 16:26, Paul Bender <pebender@san.rr.com> wrote:
> The message asking about cross compilation reminded me that I have a patch
> that is needed for cross compilation. Because autoconf's AC_CHECK_FILE fails
> when cross compiling, it use in location the pci.ids file needs to be
> surrounded in a conditional. Otherwise, the configure script never allows
> the --with-pci-ids-path to be used.
Why would that fail? There are 3 test in a row, two of them are
expected to always fail. If all of them will fail, if you must specify
the thing on the commandline. That seems to work fine here.
And please never send compressed patches, especially not when the
patch is 2 kb in size. :)
Kay
^ permalink raw reply
* Re: configure patch for cross compilation
From: Paul Bender @ 2010-06-02 15:09 UTC (permalink / raw)
To: linux-hotplug
In-Reply-To: <4C066A21.9090507@san.rr.com>
On 6/2/2010 7:57 AM, Kay Sievers wrote:
> On Wed, Jun 2, 2010 at 16:26, Paul Bender<pebender@san.rr.com> wrote:
>> The message asking about cross compilation reminded me that I have a patch
>> that is needed for cross compilation. Because autoconf's AC_CHECK_FILE fails
>> when cross compiling, it use in location the pci.ids file needs to be
>> surrounded in a conditional. Otherwise, the configure script never allows
>> the --with-pci-ids-path to be used.
>
> Why would that fail? There are 3 test in a row, two of them are
> expected to always fail. If all of them will fail, if you must specify
> the thing on the commandline. That seems to work fine here.
I should not have used the term 'fail'. Rather, I should have used the
term 'die'. The AC_CHECK_FILE macro checks to see whether or not the
package is being cross compiled. If it is, then then it dies, causing
the configure script to stop.
> And please never send compressed patches, especially not when the
> patch is 2 kb in size. :)
No problem, I will try to remember in the future. Some mailing lists
prefer compressing patches because of the mangling that some mail list
archiving software does to text attachments. I have trouble keeping
track of which list prefers which format.
^ permalink raw reply
* Re: configure patch for cross compilation
From: Kay Sievers @ 2010-06-02 15:40 UTC (permalink / raw)
To: linux-hotplug
In-Reply-To: <4C066A21.9090507@san.rr.com>
On Wed, Jun 2, 2010 at 17:09, Paul Bender <pebender@san.rr.com> wrote:
> On 6/2/2010 7:57 AM, Kay Sievers wrote:
>>> when cross compiling, it use in location the pci.ids file needs to be
>>> surrounded in a conditional. Otherwise, the configure script never allows
>>> the --with-pci-ids-path to be used.
>>
>> Why would that fail? There are 3 test in a row, two of them are
>> expected to always fail. If all of them will fail, if you must specify
>> the thing on the commandline. That seems to work fine here.
>
> I should not have used the term 'fail'. Rather, I should have used the term
> 'die'. The AC_CHECK_FILE macro checks to see whether or not the package is
> being cross compiled. If it is, then then it dies, causing the configure
> script to stop.
Ah, great. It's a feature. :)
Applied. Thanks,
Kay
^ permalink raw reply
* RE: [PATCH 1/2] Export firmware assigned labels of network devices
From: Michael Ellerman @ 2010-06-02 23:54 UTC (permalink / raw)
To: Narendra_K
Cc: netdev, linux-hotplug, linux-pci, Matt_Domsch, Jordan_Hargrave,
Charles_Rose, Vijay_Nijhawan
In-Reply-To: <EDA0A4495861324DA2618B4C45DCB3EE612864@blrx3m08.blr.amer.dell.com>
[-- Attachment #1: Type: text/plain, Size: 1048 bytes --]
On Tue, 2010-06-01 at 00:12 +0530, Narendra_K@Dell.com wrote:
> > On Fri, 2010-05-28 at 06:55 -0500, K, Narendra wrote:
> > > Hello,
> > >
> > > This patch is in continuation of an earlier discussion -
> > >
> > > http://marc.info/?l=linux-netdev&m=126712978908314&w=3
> > >
> > > The patch has the following review suggestions from the community
> > > incorporated -
> > >
> > > 1. The name of the attribute has been changed from "smbiosname" to
> > > "label" to hide the implementation details.
> > > 2. The implementation has been moved to a new file
> > > drivers/pci/pci-label.c
> >
> > You've changed the name, which is good, but the implementation is still
> > 100% dependant on ACPI or DMI AFAICS.
> >
> > So it seems to me until it's supported on another platform it may as
> > well go in pci-acpi.c,
>
> You mean the ACPI _DSM ? If yes, it is expected to become a standard
> very soon. I assume you meant non-Dell platforms by another platform.
No. I mean non-x86 platforms, yes they still exist.
cheers
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* [PATCH 0/3] Add virtio-blk support to persistent-storage rules
From: Ryan Harper @ 2010-06-03 19:07 UTC (permalink / raw)
To: linux-hotplug; +Cc: John Cooper, Rusty Russell, Ryan Harper, qemu-devel
This patch series provides updates to udev to allow the creation symlinks for
virtio-blk devices, specifically disk/by-id and disk/by-path. This is most
useful for virtio-blk devices that do not yet have any filesystem for which a
UUID can be extracted (disk/by-uuid). These patches (save the path_id fix)
require an updated[1] qemu (on the host) and virtio-blk (in the guest) to
generate the by-id path; however if the guest or host qemu isn't capable
then no action is taken.
1. http://lists.gnu.org/archive/html/qemu-devel/2010-03/msg01869.html
Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
^ permalink raw reply
* [PATCH 1/3] Add virtioblk_id tool to extract drive serial numbers
From: Ryan Harper @ 2010-06-03 19:07 UTC (permalink / raw)
To: linux-hotplug
Use the 'VBID' virtio-blk ioctl to extract drive serial numbers
to be used for building disk/by-id symlinks. After extracting
the serial number of the device it prints out the minimum info
needed in a similar format to `scsi_id --export` so that the
persistent-storage rules can process the serial information.
This program depends on the virtio-blk serial device patches posted
here[1] being applied to qemu and linux-kernel.
Here is what the output looks like:
% ./virtioblk_id /dev/vdb
ID_VIRTIO=1
ID_TYPE=disk
ID_VIRTIO_SERIAL=QM00001
1. http://lists.gnu.org/archive/html/qemu-devel/2010-03/msg01869.html
Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
---
Makefile.am | 7 +++
| 81 ++++++++++++++++++++++++++++++++++++
2 files changed, 88 insertions(+), 0 deletions(-)
create mode 100644 extras/virtioblk_id/virtioblk_id.c
diff --git a/Makefile.am b/Makefile.am
index b0eeaf1..d2d3036 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -250,6 +250,13 @@ extras_path_id_path_id_LDADD = libudev/libudev-private.la
libexec_PROGRAMS += extras/path_id/path_id
# ------------------------------------------------------------------------------
+# virtioblk_id - virtioblk inquery to extract disk serial numbers
+# ------------------------------------------------------------------------------
+extras_virtioblk_id_virtioblk_id_SOURCES = extras/virtioblk_id/virtioblk_id.c
+extras_virtioblk_id_virtioblk_id_LDADD = libudev/libudev-private.la
+libexec_PROGRAMS += extras/virtioblk_id/virtioblk_id
+
+# ------------------------------------------------------------------------------
# fstab_import - import /etc/fstab entry for block device
# ------------------------------------------------------------------------------
extras_fstab_import_fstab_import_SOURCES = extras/fstab_import/fstab_import.c
--git a/extras/virtioblk_id/virtioblk_id.c b/extras/virtioblk_id/virtioblk_id.c
new file mode 100644
index 0000000..81afd03
--- /dev/null
+++ b/extras/virtioblk_id/virtioblk_id.c
@@ -0,0 +1,81 @@
+/*
+ * extract disk serial from virtio-blk devices
+ * and print enough values to allow udev to create disk/by-id/ symlinks
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ * John Cooper <john.cooper@redhat.com>
+ * Ryan Harper <ryanh@us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <stdio.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <linux/hdreg.h>
+#include <getopt.h>
+
+#define IOCTL_CMD "VBID"
+
+int main(int argc, char **argv)
+{
+ int fd, rv;
+ const char *device;
+ char buf[255];
+
+ int opt_debug = 0;
+ static const char *option_string = "d";
+ static struct option options[] = {
+ {"debug", 0, NULL, 'd'},
+ {"help", 0, NULL, 'h'},
+ {0, 0, NULL, 0}
+ };
+
+ while (1) {
+ int option;
+ option = getopt_long(argc, argv, "dh", options, NULL);
+ if (option = -1)
+ break;
+ switch (option) {
+ case 'd':
+ opt_debug = 1;
+ break;
+ case 'h':
+ printf("Usage: virtioblk_id [--debug] [--help] <device>\n"
+ " --debug print debugging information\n"
+ " --help print this help text\n\n");
+ default:
+ rv = 1;
+ goto exit;
+ }
+ }
+
+ device = argv[optind];
+ if (device = NULL) {
+ fprintf(stderr, "no device specified\n");
+ rv = 1;
+ goto exit;
+ }
+
+
+ bzero(buf, sizeof (buf));
+ if ((fd = open(device, O_RDONLY)) < 0) {
+ if (opt_debug = 1)
+ perror("open");
+ } else if ((rv = ioctl(fd, IOCTL_CMD, buf)) < 0) {
+ if (opt_debug = 1)
+ perror("ioctl");
+ } else {
+ printf("ID_VIRTIO=1\n");
+ printf("ID_TYPE=disk\n");
+ printf("ID_VIRTIO_SERIAL=%s\n", buf);
+ rv = 0;
+ }
+
+ exit:
+ return rv;
+}
--
1.6.3.3
^ permalink raw reply related
* [PATCH 2/3] Add virtio-blk support to path_id
From: Ryan Harper @ 2010-06-03 19:07 UTC (permalink / raw)
To: linux-hotplug
This patch adds a case handling path_id invoked on a virtio-blk device.
Currently path_id walks the parent path to virtio-pci but doesn't know
that it's the end of the path and exits without building the path (providing no
output resulting in no disk/by-path symlinks to virtio-blk devices).
This patch handles the virtio-pci path and updates the path accordingly.
/lib/udev/path_id --debug /block/vda
udev_device_new_from_syspath: device 0x2300120 has devpath '/devices/virtio-pci/virtio1/block/vda'
udev_device_new_from_syspath: device 0x2300380 has devpath '/devices/virtio-pci/virtio1'
udev_device_new_from_syspath: device 0x2300670 has devpath '/devices/virtio-pci'
ID_PATH=virtio-pci-virtio1
And with the current persistent-storage rules generates:
% ls -al /dev/disk/by-path | grep vda
lrwxrwxrwx. 1 root root 9 Jun 1 22:09 virtio-pci-virtio1 -> ../../vda
Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
---
| 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
--git a/extras/path_id/path_id.c b/extras/path_id/path_id.c
index dcee378..c19bfd0 100644
--- a/extras/path_id/path_id.c
+++ b/extras/path_id/path_id.c
@@ -448,6 +448,9 @@ int main(int argc, char **argv)
} else if (strcmp(subsys, "xen") = 0) {
path_prepend(&path, "xen-%s", udev_device_get_sysname(parent));
parent = skip_subsystem(parent, "xen");
+ } else if (strcmp(subsys, "virtio") = 0) {
+ path_prepend(&path, "virtio-pci-%s", udev_device_get_sysname(parent));
+ parent = skip_subsystem(parent, "virtio");
}
parent = udev_device_get_parent(parent);
--
1.6.3.3
^ permalink raw reply related
* [PATCH 3/3] Add virtio-blk support to persistent-storage rules
From: Ryan Harper @ 2010-06-03 19:07 UTC (permalink / raw)
To: linux-hotplug
Using virtioblk_id add rules to extract drive serial numbers and generate
by-id links for the block device and partitions.
With these rules added, we now see the following symlinks in disk/by-id
% ls -al /dev/disk/by-id | grep vdb
lrwxrwxrwx. 1 root root 9 Jun 1 22:09 virtio-QM00001 -> ../../vda
lrwxrwxrwx. 1 root root 10 Jun 1 22:09 virtio-QM00001-part1 -> ../../vda1
Signed-off-by: Ryan Harper <ryanh@us.ibm.com>
---
rules/rules.d/60-persistent-storage.rules | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/rules/rules.d/60-persistent-storage.rules b/rules/rules.d/60-persistent-storage.rules
index 1f46041..b913758 100644
--- a/rules/rules.d/60-persistent-storage.rules
+++ b/rules/rules.d/60-persistent-storage.rules
@@ -30,6 +30,11 @@ KERNEL="cciss*", ENV{DEVTYPE}="disk", ENV{ID_SERIAL}!="?*", IMPORT{program}="s
KERNEL="sd*|sr*|cciss*", ENV{DEVTYPE}="disk", ENV{ID_SERIAL}="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
KERNEL="sd*|cciss*", ENV{DEVTYPE}="partition", ENV{ID_SERIAL}="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n"
+# virtioblk
+KERNEL="vd*[!0-9]", IMPORT{program}="virtioblk_id $tempnode"
+KERNEL="vd*[!0-9]", ENV{ID_VIRTIO_SERIAL}="?*", SYMLINK+="disk/by-id/virtio-$env{ID_VIRTIO_SERIAL}"
+KERNEL="vd*[0-9]", ENV{ID_VIRTIO_SERIAL}="?*", SYMLINK+="disk/by-id/virtio-$env{ID_VIRTIO_SERIAL}-part%n"
+
# firewire
KERNEL="sd*[!0-9]|sr*", ATTRS{ieee1394_id}="?*", SYMLINK+="disk/by-id/ieee1394-$attr{ieee1394_id}"
KERNEL="sd*[0-9]", ATTRS{ieee1394_id}="?*", SYMLINK+="disk/by-id/ieee1394-$attr{ieee1394_id}-part%n"
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH 1/3] Add virtioblk_id tool to extract drive serial numbers
From: Kay Sievers @ 2010-06-03 19:52 UTC (permalink / raw)
To: linux-hotplug
In-Reply-To: <1275592024-2625-2-git-send-email-ryanh@us.ibm.com>
On Thu, Jun 3, 2010 at 21:07, Ryan Harper <ryanh@us.ibm.com> wrote:
> Use the 'VBID' virtio-blk ioctl to extract drive serial numbers
> to be used for building disk/by-id symlinks. Â After extracting
> the serial number of the device it prints out the minimum info
> needed in a similar format to `scsi_id --export` so that the
> persistent-storage rules can process the serial information.
>
> This program depends on the virtio-blk serial device patches posted
> here[1] being applied to qemu and linux-kernel.
>
> Here is what the output looks like:
>
> % ./virtioblk_id /dev/vdb
> ID_VIRTIO=1
> ID_TYPE=disk
> ID_VIRTIO_SERIAL=QM00001
Yikes! An ioctl to copy a plain string, and an entire binary to call
that ioctl and print it. If we don't have enough problems we make new
ones? :)
What's the reason to drop the ATA identify, that would work out-of-the
box without any of this stuff. It could also support WWN, which is
what people are looking for these days.
Confused,
Kay
^ permalink raw reply
* Re: [PATCH 1/3] Add virtioblk_id tool to extract drive serial numbers
From: Ryan Harper @ 2010-06-03 20:01 UTC (permalink / raw)
To: linux-hotplug
In-Reply-To: <1275592024-2625-2-git-send-email-ryanh@us.ibm.com>
* Kay Sievers <kay.sievers@vrfy.org> [2010-06-03 14:53]:
> On Thu, Jun 3, 2010 at 21:07, Ryan Harper <ryanh@us.ibm.com> wrote:
> > Use the 'VBID' virtio-blk ioctl to extract drive serial numbers
> > to be used for building disk/by-id symlinks. After extracting
> > the serial number of the device it prints out the minimum info
> > needed in a similar format to `scsi_id --export` so that the
> > persistent-storage rules can process the serial information.
> >
> > This program depends on the virtio-blk serial device patches posted
> > here[1] being applied to qemu and linux-kernel.
> >
> > Here is what the output looks like:
> >
> > % ./virtioblk_id /dev/vdb
> > ID_VIRTIO=1
> > ID_TYPE=disk
> > ID_VIRTIO_SERIAL=QM00001
>
> Yikes! An ioctl to copy a plain string, and an entire binary to call
> that ioctl and print it. If we don't have enough problems we make new
> ones? :)
>
> What's the reason to drop the ATA identify, that would work out-of-the
> box without any of this stuff. It could also support WWN, which is
> what people are looking for these days.
http://www.mail-archive.com/qemu-devel@nongnu.org/msg24321.html
1. Virtio-blk isn't an ATA device
2. The ATA identify page is too large to fit into the virtio config
space
I'm not finding the older threads where this was discussed in detail.
I'll keep looking if the above isn't a sufficient explaination.
--
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
ryanh@us.ibm.com
^ permalink raw reply
* Re: [PATCH 1/3] Add virtioblk_id tool to extract drive serial numbers
From: Kay Sievers @ 2010-06-03 20:04 UTC (permalink / raw)
To: linux-hotplug
In-Reply-To: <1275592024-2625-2-git-send-email-ryanh@us.ibm.com>
On Thu, Jun 3, 2010 at 22:01, Ryan Harper <ryanh@us.ibm.com> wrote:
> * Kay Sievers <kay.sievers@vrfy.org> [2010-06-03 14:53]:
>> On Thu, Jun 3, 2010 at 21:07, Ryan Harper <ryanh@us.ibm.com> wrote:
>> > Use the 'VBID' virtio-blk ioctl to extract drive serial numbers
>> > to be used for building disk/by-id symlinks. Â After extracting
>> > the serial number of the device it prints out the minimum info
>> > needed in a similar format to `scsi_id --export` so that the
>> > persistent-storage rules can process the serial information.
>> >
>> > This program depends on the virtio-blk serial device patches posted
>> > here[1] being applied to qemu and linux-kernel.
>> >
>> > Here is what the output looks like:
>> >
>> > % ./virtioblk_id /dev/vdb
>> > ID_VIRTIO=1
>> > ID_TYPE=disk
>> > ID_VIRTIO_SERIAL=QM00001
>>
>> Yikes! An ioctl to copy a plain string, and an entire binary to call
>> that ioctl and print it. If we don't have enough problems we make new
>> ones? :)
>>
>> What's the reason to drop the ATA identify, that would work out-of-the
>> box without any of this stuff. It could also support WWN, which is
>> what people are looking for these days.
>
> http://www.mail-archive.com/qemu-devel@nongnu.org/msg24321.html
>
> 1. Virtio-blk isn't an ATA device
> 2. The ATA identify page is too large to fit into the virtio config
> space
>
> I'm not finding the older threads where this was discussed in detail.
> I'll keep looking if the above isn't a sufficient explaination.
Well, if ATA doesn't fit, then put that string in sysfs like mmc block
devices are doing it. It looks really awkward to require a new binary
and a new ioctl to get a single string out of something that was just
invented.
Thanks,
Kay
^ permalink raw reply
* Re: [PATCH 1/3] Add virtioblk_id tool to extract drive serial numbers
From: David Zeuthen @ 2010-06-03 20:13 UTC (permalink / raw)
To: linux-hotplug
In-Reply-To: <1275592024-2625-2-git-send-email-ryanh@us.ibm.com>
Hey,
On Thu, Jun 3, 2010 at 3:07 PM, Ryan Harper <ryanh@us.ibm.com> wrote:
> % ./virtioblk_id /dev/vdb
> ID_VIRTIO=1
> ID_TYPE=disk
> ID_VIRTIO_SERIAL=QM00001
Why ID_VIRTIO_SERIAL? Please use ID_SERIAL (and ID_SERIAL_SHORT) like
ata_id, scsi_id and usb_id already does.
David
^ permalink raw reply
* Re: [PATCH 1/3] Add virtioblk_id tool to extract drive serial numbers
From: Ryan Harper @ 2010-06-03 21:03 UTC (permalink / raw)
To: linux-hotplug
In-Reply-To: <1275592024-2625-2-git-send-email-ryanh@us.ibm.com>
* Kay Sievers <kay.sievers@vrfy.org> [2010-06-03 15:06]:
> On Thu, Jun 3, 2010 at 22:01, Ryan Harper <ryanh@us.ibm.com> wrote:
> > * Kay Sievers <kay.sievers@vrfy.org> [2010-06-03 14:53]:
> >> On Thu, Jun 3, 2010 at 21:07, Ryan Harper <ryanh@us.ibm.com> wrote:
> >> > Use the 'VBID' virtio-blk ioctl to extract drive serial numbers
> >> > to be used for building disk/by-id symlinks. After extracting
> >> > the serial number of the device it prints out the minimum info
> >> > needed in a similar format to `scsi_id --export` so that the
> >> > persistent-storage rules can process the serial information.
> >> >
> >> > This program depends on the virtio-blk serial device patches posted
> >> > here[1] being applied to qemu and linux-kernel.
> >> >
> >> > Here is what the output looks like:
> >> >
> >> > % ./virtioblk_id /dev/vdb
> >> > ID_VIRTIO=1
> >> > ID_TYPE=disk
> >> > ID_VIRTIO_SERIAL=QM00001
> >>
> >> Yikes! An ioctl to copy a plain string, and an entire binary to call
> >> that ioctl and print it. If we don't have enough problems we make new
> >> ones? :)
> >>
> >> What's the reason to drop the ATA identify, that would work out-of-the
> >> box without any of this stuff. It could also support WWN, which is
> >> what people are looking for these days.
> >
> > http://www.mail-archive.com/qemu-devel@nongnu.org/msg24321.html
> >
> > 1. Virtio-blk isn't an ATA device
> > 2. The ATA identify page is too large to fit into the virtio config
> > space
> >
> > I'm not finding the older threads where this was discussed in detail.
> > I'll keep looking if the above isn't a sufficient explaination.
>
> Well, if ATA doesn't fit, then put that string in sysfs like mmc block
> devices are doing it. It looks really awkward to require a new binary
> and a new ioctl to get a single string out of something that was just
> invented.
John,
you mentioned that you had a sys interface in-mind earlier. I'm not
sure how to proceed given the virtio-blk kernel side patches are
already upstream[1][2]. Are we looking to revert and switch?
1. http://repo.or.cz/w/linux-2.6.git/commitdiff/234f2725a5d03f78539f1d36cb32f2c4f9b1822c
2. http://repo.or.cz/w/linux-2.6.git/commitdiff/4cb2ea28c55cf5e5ef83aec535099ffce3c583df
--
Ryan Harper
Software Engineer; Linux Technology Center
IBM Corp., Austin, Tx
ryanh@us.ibm.com
^ permalink raw reply
* Re: [PATCH V2 1/2] Export firmware assigned labels of network devices to sysfs
From: Narendra K @ 2010-06-03 21:07 UTC (permalink / raw)
To: greg; +Cc: netdev, linux-hotplug, linux-pci, matt_domsch
In-Reply-To: <EDA0A4495861324DA2618B4C45DCB3EE6128E1@blrx3m08.blr.amer.dell.com>
> -----Original Message-----
> From: Greg KH [mailto:greg@kroah.com]
> Sent: Friday, May 28, 2010 9:11 PM
> To: K, Narendra
> Cc: netdev@vger.kernel.org; linux-hotplug@vger.kernel.org;
> linux-pci@vger.kernel.org; Domsch, Matt; Hargrave, Jordan; Rose,
> Charles; Nijhawan, Vijay
> Subject: Re: [PATCH 1/2] Export firmware assigned labels of network
> devices to sysfs
>
Thanks for the comments.
> On Fri, May 28, 2010 at 06:55:21AM -0500, K, Narendra wrote:
> > Please refer to the PCI-SIG Draft ECN
> > "PCIe Device Labeling under Operating Systems Draft ECN" at this link
> -
> > http://www.pcisig.com/specifications/pciexpress/review_zone/.
> >
> > It would be great to know your views on this ECN. Please let us know
> if you have
> > have any suggestions or changes.
>
> Note that only members of the PCI-SIG can do this, which pretty much
> rules out any "normal" Linux kernel developer :(
>
> Care to post a public version of this for us to review?
> > --- /dev/null
> > +++ b/drivers/pci/pci-label.c
> > @@ -0,0 +1,242 @@
> > +/*
> > + * File: drivers/pci/pci-label.c
>
> This line is not needed, we know the file name :)
>
> > + * Purpose: Export the firmware label associated with a pci
> network interface
> > + * device to sysfs
> > + * Copyright (C) 2010 Dell Inc.
> > + * by Narendra K <Narendra_K@dell.com>, Jordan Hargrave
> <Jordan_Hargrave@dell.com>
> > + *
> > + * This code checks if the pci network device has a related ACPI
> _DSM. If
> > + * available, the code calls the _DSM to retrieve the index and
> string and
> > + * exports them to sysfs. If the ACPI _DSM is not available, it falls
> back on
> > + * SMBIOS. SMBIOS defines type 41 for onboard pci devices. This code
> retrieves
> > + * strings associated with the type 41 and exports it to sysfs.
> > + *
> > + * Please see http://linux.dell.com/wiki/index.php/Oss/libnetdevname
> for more
> > + * information.
> > + */
> > +
> > +#include <linux/pci-label.h>
>
> Why is this file in include/linux/ ? Who needs it there? Can't it just
> be in in the drivers/pci/ directory? Actually all you need is 2
> functions in there, so it could go into the internal pci.h file in that
> directory without a problem, right?
>
This file is removed and functions are moved to the internal pci.h
> > +
> > +static ssize_t
> > +smbiosname_string_exists(struct device *dev, char *buf)
> > +{
> > + struct pci_dev *pdev = to_pci_dev(dev);
> > + const struct dmi_device *dmi;
> > + struct dmi_devslot *dslot;
> > + int bus;
> > + int devfn;
> > +
> > + bus = pdev->bus->number;
> > + devfn = pdev->devfn;
> > +
> > + dmi = NULL;
> > + while ((dmi = dmi_find_device(DMI_DEV_TYPE_DEVSLOT, NULL,
> dmi)) != NULL) {
> > + dslot = dmi->device_data;
> > + if (dslot && dslot->bus = bus && dslot->devfn =
> devfn) {
> > + if (buf)
> > + return scnprintf(buf, PAGE_SIZE,
> "%s\n", dmi->name);
> > + return strlen(dmi->name);
> > + }
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static ssize_t
> > +smbiosname_show(struct device *dev, struct device_attribute *attr,
> char *buf)
> > +{
> > + return smbiosname_string_exists(dev, buf);
> > +}
> > +
> > +struct smbios_attribute smbios_attr_label = {
> > + .attr = {.name = __stringify(label), .mode = 0444, .owner > THIS_MODULE},
>
> Can't you just put "label" as the name?
>
This is fixed.
> > + .show = smbiosname_show,
> > + .test = smbiosname_string_exists,
> > +};
> > +
> > +static int
> > +pci_create_smbiosname_file(struct pci_dev *pdev)
> > +{
> > + if (smbios_attr_label.test &&
> smbios_attr_label.test(&pdev->dev, NULL)) {
> > + sysfs_create_file(&pdev->dev.kobj,
> &smbios_attr_label.attr);
> > + return 0;
> > + }
> > + return -1;
> > +}
> > +
> > +static int
> > +pci_remove_smbiosname_file(struct pci_dev *pdev)
> > +{
> > + if (smbios_attr_label.test &&
> smbios_attr_label.test(&pdev->dev, NULL)) {
> > + sysfs_remove_file(&pdev->dev.kobj,
> &smbios_attr_label.attr);
> > + return 0;
> > + }
> > + return -1;
> > +}
> > +
> > +static const char dell_dsm_uuid[] = {
>
> Um, a dell specific uuid in a generic file? What happens when we need
> to support another manufacturer?
>
My understanding of uuid was incorrect. I have renamed it to a more generic
device_label_dsm_uuid and ACPI_DSM_FUNCTION to DEVICE_LABEL_DSM
> > + 0xD0, 0x37, 0xC9, 0xE5, 0x53, 0x35, 0x7A, 0x4D,
> > + 0x91, 0x17, 0xEA, 0x4D, 0x19, 0xC3, 0x43, 0x4D
> > +};
> > +
> > +
> > +static int
> > +dsm_get_label(acpi_handle handle, int func,
> > + struct acpi_buffer *output,
> > + char *buf, char *attribute)
> > +{
> > + struct acpi_object_list input;
> > + union acpi_object params[4];
> > + union acpi_object *obj;
> > + int len = 0;
> > +
> > + int err;
> > +
> > + input.count = 4;
> > + input.pointer = params;
> > + params[0].type = ACPI_TYPE_BUFFER;
> > + params[0].buffer.length = sizeof(dell_dsm_uuid);
> > + params[0].buffer.pointer = (char *)dell_dsm_uuid;
> > + params[1].type = ACPI_TYPE_INTEGER;
> > + params[1].integer.value = 0x02;
> > + params[2].type = ACPI_TYPE_INTEGER;
> > + params[2].integer.value = func;
> > + params[3].type = ACPI_TYPE_PACKAGE;
> > + params[3].package.count = 0;
> > + params[3].package.elements = NULL;
> > +
> > + err = acpi_evaluate_object(handle, "_DSM", &input, output);
> > + if (err) {
> > + printk(KERN_INFO "failed to evaulate _DSM\n");
> > + return -1;
> > + }
> > +
> > + obj = (union acpi_object *)output->pointer;
> > +
> > + switch (obj->type) {
> > + case ACPI_TYPE_PACKAGE:
> > + if (obj->package.count = 2) {
> > + len = obj->package.elements[0].integer.value;
> > + if (buf) {
> > + if (!strncmp(attribute, "index",
> strlen(attribute)))
> > + scnprintf(buf, PAGE_SIZE,
> "%lu\n",
> > +
> obj->package.elements[0].integer.value);
> > + else
> > + scnprintf(buf, PAGE_SIZE,
> "%s\n",
> > +
> obj->package.elements[1].string.pointer);
> > + kfree(output->pointer);
> > + return strlen(buf);
> > + }
> > + }
> > + kfree(output->pointer);
> > + return len;
> > + break;
> > + default:
> > + return -1;
> > + }
> > +}
> > +
> > +static ssize_t
> > +acpi_index_string_exist(struct device *dev, char *buf, char
> *attribute)
> > +{
> > + struct pci_dev *pdev = to_pci_dev(dev);
> > +
> > + struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
> > + acpi_handle handle;
> > + int length;
> > + int is_addin_card = 0;
> > +
> > + if ((pdev->class >> 16) != PCI_BASE_CLASS_NETWORK)
> > + return -1;
> > +
> > + handle = DEVICE_ACPI_HANDLE(dev);
> > +
> > + if (!handle) {
> > + /*
> > + * The device is an add-in network controller and does
> have
> > + * a valid handle. Try until we get the handle for the
> parent
> > + * bridge
> > + */
> > + struct pci_bus *pbus;
> > + for (pbus = pdev->bus; pbus; pbus = pbus->parent) {
> > + handle > DEVICE_ACPI_HANDLE(&(pbus->self->dev));
> > + if (handle)
> > + break;
> > +
> > + }
> > + }
> > +
> > + if ((length = dsm_get_label(handle, DELL_DSM_NETWORK,
> > + &output, buf, attribute)) < 0)
> > + return -1;
> > +
> > + return length;
> > +}
> > +
> > +static ssize_t
> > +acpilabel_show(struct device *dev, struct device_attribute *attr,
> char *buf)
> > +{
> > + return acpi_index_string_exist(dev, buf, "label");
> > +}
> > +
> > +static ssize_t
> > +acpiindex_show(struct device *dev, struct device_attribute *attr,
> char *buf)
> > +{
> > + return acpi_index_string_exist(dev, buf, "index");
> > +}
> > +
> > +struct acpi_attribute acpi_attr_label = {
> > + .attr = {.name = __stringify(label), .mode = 0444, .owner > THIS_MODULE},
> > + .show = acpilabel_show,
> > + .test = acpi_index_string_exist,
> > +};
> > +
> > +struct acpi_attribute acpi_attr_index = {
> > + .attr = {.name = __stringify(index), .mode = 0444, .owner > THIS_MODULE},
> > + .show = acpiindex_show,
> > + .test = acpi_index_string_exist,
> > +};
> > +
> > +static int
> > +pci_create_acpi_index_label_files(struct pci_dev *pdev)
> > +{
> > + if (acpi_attr_label.test && acpi_attr_label.test(&pdev->dev,
> NULL) > 0) {
> > + sysfs_create_file(&pdev->dev.kobj,
> &acpi_attr_label.attr);
> > + sysfs_create_file(&pdev->dev.kobj,
> &acpi_attr_index.attr);
> > + return 0;
> > + }
> > + return -1;
> > +}
> > +
> > +static int
> > +pci_remove_acpi_index_label_files(struct pci_dev *pdev)
> > +{
> > + if (acpi_attr_label.test && acpi_attr_label.test(&pdev->dev,
> NULL) > 0) {
> > + sysfs_remove_file(&pdev->dev.kobj,
> &acpi_attr_label.attr);
> > + sysfs_remove_file(&pdev->dev.kobj,
> &acpi_attr_index.attr);
> > + return 0;
> > + }
> > + return -1;
> > +}
> > +
> > +int pci_create_acpi_attr_files(struct pci_dev *pdev)
> > +{
> > + if (!pci_create_acpi_index_label_files(pdev))
> > + return 0;
> > + if (!pci_create_smbiosname_file(pdev))
> > + return 0;
> > + return -ENODEV;
> > +}
> > +EXPORT_SYMBOL(pci_create_acpi_attr_files);
>
> EXPORT_SYMBOL_GPL?
>
> Wait, why does this need to be exported at all? What module is ever
> going to call this function?
>
> > +int pci_remove_acpi_attr_files(struct pci_dev *pdev)
> > +{
> > + if (!pci_remove_acpi_index_label_files(pdev))
> > + return 0;
> > + if (!pci_remove_smbiosname_file(pdev))
> > + return 0;
> > + return -ENODEV;
> > +
> > +}
> > +EXPORT_SYMBOL(pci_remove_acpi_attr_files);
>
> Same here, what module will call this?
>
These functions need not be exported as they are not called by any module.
> > +++ b/include/linux/pci-label.h
>
> As discussed above, this whole file does not need to exist.
>
> > +extern int pci_create_acpi_attr_files(struct pci_dev *pdev);
> > +extern int pci_remove_acpi_attr_files(struct pci_dev *pdev);
>
> Just put these two functions in the drivers/pci/pci.h file.
>
Fixed.
In addition to these changes there are a coulple of changes i have done -
1.Removed the check for network devices and evaulate _DSM for any pci device
that has _DSM defined in adherence to the spec.
2.Renamed the functions pci_create,remove-acpi_attr_files to
pci_create,remove_firmware_label_files.
3.Added checks for conditional compilation of if CONFIG_ACPI || CONFIG_DMI
Note: While testing the patch with CONFIG_ACPI set to no, the compilation
would fail with the below message.
CC drivers/pci/pci-label.o
In file included from drivers/pci/pci-label.c:24:
include/linux/pci-acpi.h:39: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’
before ‘acpi_find_root_bridge_handle’
I had to add make this change to proceed with the compilation. It would be
great to know if i am missing something in the way conditional compilation
is implemented or is it a issue.
---
include/linux/pci-acpi.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
index c8b6473..bc40827 100644
--- a/include/linux/pci-acpi.h
+++ b/include/linux/pci-acpi.h
@@ -36,8 +36,8 @@ static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus)
pbus->number);
}
#else
-static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
-{ return NULL; }
+static inline void acpi_find_root_bridge_handle(struct pci_dev *pdev)
+{ }
#endif
#endif /* _PCI_ACPI_H_ */
Please find the patch with above suggestions and changes -
From: Narendra K <narendra_k@dell.com>
Subject: [PATCH V2 1/2] Export firmware assigned labels of pci devices to sysfs
This patch exports the firmware assigned labels of pci devices to
sysfs which could be used by user space.
Signed-off-by: Jordan Hargrave <jordan_hargrave@dell.com>
Signed-off-by: Narendra K <narendra_k@dell.com>
---
drivers/firmware/dmi_scan.c | 24 ++++
drivers/pci/Makefile | 2 +-
drivers/pci/pci-label.c | 273 +++++++++++++++++++++++++++++++++++++++++++
drivers/pci/pci-sysfs.c | 5 +
drivers/pci/pci.h | 2 +
include/linux/dmi.h | 9 ++
6 files changed, 314 insertions(+), 1 deletions(-)
create mode 100644 drivers/pci/pci-label.c
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index d464672..7d8439b 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -277,6 +277,28 @@ static void __init dmi_save_ipmi_device(const struct dmi_header *dm)
list_add_tail(&dev->list, &dmi_devices);
}
+static void __init dmi_save_devslot(int id, int seg, int bus, int devfn, const char *name)
+{
+ struct dmi_devslot *slot;
+
+ slot = dmi_alloc(sizeof(*slot) + strlen(name) + 1);
+ if (!slot) {
+ printk(KERN_ERR "dmi_save_devslot: out of memory.\n");
+ return;
+ }
+ slot->id = id;
+ slot->seg = seg;
+ slot->bus = bus;
+ slot->devfn = devfn;
+
+ strcpy((char *)&slot[1], name);
+ slot->dev.type = DMI_DEV_TYPE_DEVSLOT;
+ slot->dev.name = (char *)&slot[1];
+ slot->dev.device_data = slot;
+
+ list_add(&slot->dev.list, &dmi_devices);
+}
+
static void __init dmi_save_extended_devices(const struct dmi_header *dm)
{
const u8 *d = (u8*) dm + 5;
@@ -285,6 +307,7 @@ static void __init dmi_save_extended_devices(const struct dmi_header *dm)
if ((*d & 0x80) = 0)
return;
+ dmi_save_devslot(-1, *(u16 *)(d+2), *(d+4), *(d+5), dmi_string_nosave(dm, *(d-1)));
dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1)));
}
@@ -333,6 +356,7 @@ static void __init dmi_decode(const struct dmi_header *dm, void *dummy)
break;
case 41: /* Onboard Devices Extended Information */
dmi_save_extended_devices(dm);
+ break;
}
}
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 0b51857..69c503a 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -4,7 +4,7 @@
obj-y += access.o bus.o probe.o remove.o pci.o \
pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \
- irq.o vpd.o
+ irq.o vpd.o pci-label.o
obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_SYSFS) += slot.o
diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c
new file mode 100644
index 0000000..b35d48c
--- /dev/null
+++ b/drivers/pci/pci-label.c
@@ -0,0 +1,273 @@
+/*
+ * Purpose: Export the firmware label associated with a pci network interface
+ * device to sysfs
+ * Copyright (C) 2010 Dell Inc.
+ * by Narendra K <Narendra_K@dell.com>, Jordan Hargrave <Jordan_Hargrave@dell.com>
+ *
+ * This code checks if the pci network device has a related ACPI _DSM. If
+ * available, the code calls the _DSM to retrieve the index and string and
+ * exports them to sysfs. If the ACPI _DSM is not available, it falls back on
+ * SMBIOS. SMBIOS defines type 41 for onboard pci devices. This code retrieves
+ * strings associated with the type 41 and exports it to sysfs.
+ *
+ * Please see http://linux.dell.com/wiki/index.php/Oss/libnetdevname for more
+ * information.
+ */
+
+#include <linux/dmi.h>
+#include <linux/sysfs.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/pci-acpi.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+#include "pci.h"
+
+#define DEVICE_LABEL_DSM 0x07
+
+#if defined CONFIG_DMI
+
+struct smbios_attribute {
+ struct attribute attr;
+ ssize_t (*show) (struct device *dev, char *buf);
+ ssize_t (*test) (struct device *dev, char *buf);
+};
+
+static ssize_t
+smbiosname_string_exists(struct device *dev, char *buf)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ const struct dmi_device *dmi;
+ struct dmi_devslot *dslot;
+ int bus;
+ int devfn;
+
+ bus = pdev->bus->number;
+ devfn = pdev->devfn;
+
+ dmi = NULL;
+ while ((dmi = dmi_find_device(DMI_DEV_TYPE_DEVSLOT, NULL, dmi)) != NULL) {
+ dslot = dmi->device_data;
+ if (dslot && dslot->bus = bus && dslot->devfn = devfn) {
+ if (buf)
+ return scnprintf(buf, PAGE_SIZE, "%s\n", dmi->name);
+ return strlen(dmi->name);
+ }
+ }
+
+ return 0;
+}
+
+static ssize_t
+smbiosname_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return smbiosname_string_exists(dev, buf);
+}
+
+struct smbios_attribute smbios_attr_label = {
+ .attr = {.name = "label", .mode = 0444, .owner = THIS_MODULE},
+ .show = smbiosname_show,
+ .test = smbiosname_string_exists,
+};
+
+static int
+pci_create_smbiosname_file(struct pci_dev *pdev)
+{
+ if (smbios_attr_label.test && smbios_attr_label.test(&pdev->dev, NULL)) {
+ sysfs_create_file(&pdev->dev.kobj, &smbios_attr_label.attr);
+ return 0;
+ }
+ return -1;
+}
+
+static int
+pci_remove_smbiosname_file(struct pci_dev *pdev)
+{
+ if (smbios_attr_label.test && smbios_attr_label.test(&pdev->dev, NULL)) {
+ sysfs_remove_file(&pdev->dev.kobj, &smbios_attr_label.attr);
+ return 0;
+ }
+ return -1;
+}
+#else
+static inline int
+pci_create_smbiosname_file(struct pci_dev *pdev)
+{
+ return -1;
+}
+
+static inline int
+pci_remove_smbiosname_file(struct pci_dev *pdev)
+{
+ return -1;
+}
+#endif
+
+#if defined CONFIG_ACPI
+
+static const char device_label_dsm_uuid[] = {
+ 0xD0, 0x37, 0xC9, 0xE5, 0x53, 0x35, 0x7A, 0x4D,
+ 0x91, 0x17, 0xEA, 0x4D, 0x19, 0xC3, 0x43, 0x4D
+};
+
+struct acpi_attribute {
+ struct attribute attr;
+ ssize_t (*show) (struct device *dev, char *buf);
+ ssize_t (*test) (struct device *dev, char *buf);
+};
+
+static int
+dsm_get_label(acpi_handle handle, int func,
+ struct acpi_buffer *output,
+ char *buf, char *attribute)
+{
+ struct acpi_object_list input;
+ union acpi_object params[4];
+ union acpi_object *obj;
+ int len = 0;
+
+ int err;
+
+ input.count = 4;
+ input.pointer = params;
+ params[0].type = ACPI_TYPE_BUFFER;
+ params[0].buffer.length = sizeof(device_label_dsm_uuid);
+ params[0].buffer.pointer = (char *)device_label_dsm_uuid;
+ params[1].type = ACPI_TYPE_INTEGER;
+ params[1].integer.value = 0x02;
+ params[2].type = ACPI_TYPE_INTEGER;
+ params[2].integer.value = func;
+ params[3].type = ACPI_TYPE_PACKAGE;
+ params[3].package.count = 0;
+ params[3].package.elements = NULL;
+
+ err = acpi_evaluate_object(handle, "_DSM", &input, output);
+ if (err)
+ return -1;
+
+
+ obj = (union acpi_object *)output->pointer;
+
+ switch (obj->type) {
+ case ACPI_TYPE_PACKAGE:
+ if (obj->package.count != 2)
+ break;
+ len = obj->package.elements[0].integer.value;
+ if (buf) {
+ if (!strncmp(attribute, "index", strlen(attribute)))
+ scnprintf(buf, PAGE_SIZE, "%lu\n",
+ obj->package.elements[0].integer.value);
+ else
+ scnprintf(buf, PAGE_SIZE, "%s\n",
+ obj->package.elements[1].string.pointer);
+ kfree(output->pointer);
+ return strlen(buf);
+ }
+ kfree(output->pointer);
+ return len;
+ break;
+ default:
+ kfree(output->pointer);
+ return -1;
+ }
+}
+
+static ssize_t
+acpi_index_string_exist(struct device *dev, char *buf, char *attribute)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+ acpi_handle handle;
+ int length;
+
+ handle = DEVICE_ACPI_HANDLE(dev);
+
+ if (!handle)
+ return -1;
+
+ if ((length = dsm_get_label(handle, DEVICE_LABEL_DSM,
+ &output, buf, attribute)) < 0)
+ return -1;
+
+ return length;
+}
+
+static ssize_t
+acpilabel_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return acpi_index_string_exist(dev, buf, "label");
+}
+
+static ssize_t
+acpiindex_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return acpi_index_string_exist(dev, buf, "index");
+}
+
+struct acpi_attribute acpi_attr_label = {
+ .attr = {.name = "label", .mode = 0444, .owner = THIS_MODULE},
+ .show = acpilabel_show,
+ .test = acpi_index_string_exist,
+};
+
+struct acpi_attribute acpi_attr_index = {
+ .attr = {.name = "index", .mode = 0444, .owner = THIS_MODULE},
+ .show = acpiindex_show,
+ .test = acpi_index_string_exist,
+};
+
+static int
+pci_create_acpi_index_label_files(struct pci_dev *pdev)
+{
+ if (acpi_attr_label.test && acpi_attr_label.test(&pdev->dev, NULL) > 0) {
+ sysfs_create_file(&pdev->dev.kobj, &acpi_attr_label.attr);
+ sysfs_create_file(&pdev->dev.kobj, &acpi_attr_index.attr);
+ return 0;
+ }
+ return -1;
+}
+
+static int
+pci_remove_acpi_index_label_files(struct pci_dev *pdev)
+{
+ if (acpi_attr_label.test && acpi_attr_label.test(&pdev->dev, NULL) > 0) {
+ sysfs_remove_file(&pdev->dev.kobj, &acpi_attr_label.attr);
+ sysfs_remove_file(&pdev->dev.kobj, &acpi_attr_index.attr);
+ return 0;
+ }
+ return -1;
+}
+#else
+static inline int
+pci_create_acpi_index_label_files(struct pci_dev *pdev)
+{
+ return -1;
+}
+
+static inline int
+pci_remove_acpi_index_label_files(struct pci_dev *pdev)
+{
+ return -1;
+}
+#endif
+
+int pci_create_firmware_label_files(struct pci_dev *pdev)
+{
+ if (!pci_create_acpi_index_label_files(pdev))
+ return 0;
+ if (!pci_create_smbiosname_file(pdev))
+ return 0;
+ return -ENODEV;
+}
+
+int pci_remove_firmware_label_files(struct pci_dev *pdev)
+{
+ if (!pci_remove_acpi_index_label_files(pdev))
+ return 0;
+ if (!pci_remove_smbiosname_file(pdev))
+ return 0;
+ return -ENODEV;
+}
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index fad9398..4ed517f 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1073,6 +1073,8 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
if (retval)
goto err_vga_file;
+ pci_create_firmware_label_files(pdev);
+
return 0;
err_vga_file:
@@ -1140,6 +1142,9 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
kfree(pdev->rom_attr);
}
+
+ pci_remove_firmware_label_files(pdev);
+
}
static int __init pci_sysfs_init(void)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 4eb10f4..f223283 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -11,6 +11,8 @@
extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env);
extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
+extern int pci_create_firmware_label_files(struct pci_dev *pdev);
+extern int pci_remove_firmware_label_files(struct pci_dev *pdev);
extern void pci_cleanup_rom(struct pci_dev *dev);
#ifdef HAVE_PCI_MMAP
extern int pci_mmap_fits(struct pci_dev *pdev, int resno,
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index a8a3e1a..cc57c3a 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -20,6 +20,7 @@ enum dmi_device_type {
DMI_DEV_TYPE_SAS,
DMI_DEV_TYPE_IPMI = -1,
DMI_DEV_TYPE_OEM_STRING = -2,
+ DMI_DEV_TYPE_DEVSLOT = -3,
};
struct dmi_header {
@@ -37,6 +38,14 @@ struct dmi_device {
#ifdef CONFIG_DMI
+struct dmi_devslot {
+ struct dmi_device dev;
+ int id;
+ int seg;
+ int bus;
+ int devfn;
+};
+
extern int dmi_check_system(const struct dmi_system_id *list);
const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list);
extern const char * dmi_get_system_info(int field);
--
1.6.5.2
With regards,
Narendra K
^ permalink raw reply related
* Re: [PATCH 1/3] Add virtioblk_id tool to extract drive serial numbers
From: john cooper @ 2010-06-04 15:06 UTC (permalink / raw)
To: Ryan Harper
Cc: Kay Sievers, john.cooper, Rusty Russell, linux-hotplug,
qemu-devel, Marc Haber
In-Reply-To: <20100603210359.GP19185@us.ibm.com>
Ryan Harper wrote:
> * Kay Sievers <kay.sievers@vrfy.org> [2010-06-03 15:06]:
>> On Thu, Jun 3, 2010 at 22:01, Ryan Harper <ryanh@us.ibm.com> wrote:
>>> * Kay Sievers <kay.sievers@vrfy.org> [2010-06-03 14:53]:
>>>> On Thu, Jun 3, 2010 at 21:07, Ryan Harper <ryanh@us.ibm.com> wrote:
>>>>> Use the 'VBID' virtio-blk ioctl to extract drive serial numbers
>>>>> to be used for building disk/by-id symlinks. After extracting
>>>>> the serial number of the device it prints out the minimum info
>>>>> needed in a similar format to `scsi_id --export` so that the
>>>>> persistent-storage rules can process the serial information.
>>>>>
>>>>> This program depends on the virtio-blk serial device patches posted
>>>>> here[1] being applied to qemu and linux-kernel.
>>>>>
>>>>> Here is what the output looks like:
>>>>>
>>>>> % ./virtioblk_id /dev/vdb
>>>>> ID_VIRTIO=1
>>>>> ID_TYPE=disk
>>>>> ID_VIRTIO_SERIAL=QM00001
>>>> Yikes! An ioctl to copy a plain string, and an entire binary to call
>>>> that ioctl and print it. If we don't have enough problems we make new
>>>> ones? :)
[Jumping in the thread here as I hadn't seen the comments
until now. This issue has been discussed ad nauseam in the
context of qemu so here is a summary]
Packaging this up this data within a mock ATA_IDENTIFY was
proposed. However that is a large bag of largely archaic
bits most of which are dummied up normally, and would be even
more so in the case here of virtio. Putting a proposed
identify struct mock-up in qemu made the most sense in this
scenario as that's where the disk geometry information exists,
unfortunately doing so didn't fly with the maintainer. Locating
this mock-up in the virtio driver makes less sense as the
geometry data for mock-up would need to be packaged up in yet
another structure and passed to the driver for formatting onto
the identify data. No one even seriously considered doing this
as it combines the worst of both worlds.
>>>> What's the reason to drop the ATA identify, that would work out-of-the
>>>> box without any of this stuff. It could also support WWN, which is
>>>> what people are looking for these days.
That is the singular, very strong argument for ATA_IDENTIFY
and one which I'd made several times however it isn't the only
consideration in this multi-way trade off.
>>> http://www.mail-archive.com/qemu-devel@nongnu.org/msg24321.html
>>>
>>> 1. Virtio-blk isn't an ATA device
>>> 2. The ATA identify page is too large to fit into the virtio config
>>> space
Passing this data in PCI config made sense in the original
version of this patch when I was just shuffling 20 bytes of
id to the driver. But when the ATA_IDENTIFY argument arose
it extended the size of the passed data to 512 bytes which caused
breakage of PCI config space due to the size now consumed to
quietly exceed the PCI specification. Moving the identify
scheme to pass data by virtio request was proposed but by this
time the maintainer was strongly objecting to mock-up of this data
within qemu.
>>> I'm not finding the older threads where this was discussed in detail.
>>> I'll keep looking if the above isn't a sufficient explaination.
>> Well, if ATA doesn't fit, then put that string in sysfs like mmc block
>> devices are doing it. It looks really awkward to require a new binary
>> and a new ioctl to get a single string out of something that was just
>> invented.
There are two issues:
- Getting the serial/id string exported from qemu to the driver.
This is the much less contentious portion unless we're still
bent on using the identify scheme which will surely torpedo
the effort once again. Assuming we're satisfied with qemu
exporting the serial/id string alone we should be quite close
here.
- Presentation of the serial/id to the application by the
virtio driver. ATA_IDENTIFY would be nice if the above restrictions
didn't exist, but they do. So let's just get the job done
once and for all. No one wants to invent yet another ioctl
interface but it is the best compromise available as the code
in both the driver and application is trivial. The other
alternatives at their respective extremes (/sys: new but pretty
interface, over powered for the job, more cruft in the driver;
ATA_IDENTIFY: existing interface, ugliest possible code, even
more cruft in the driver) have been proposed and abandoned for
reasons cited above.
> John,
>
> you mentioned that you had a sys interface in-mind earlier. I'm not
> sure how to proceed given the virtio-blk kernel side patches are
> already upstream[1][2]. Are we looking to revert and switch?
No, we can use the interface as-is, however we have an opportunity
to make it more usage friendly.
> 1. http://repo.or.cz/w/linux-2.6.git/commitdiff/234f2725a5d03f78539f1d36cb32f2c4f9b1822c
My slight modification to the above commit makes it possible
for the application to determine the data size the driver intends
to copy out, and allows the user to indicate the destination data
size for the copy operation. Otherwise the caller needs to have
the size assumption built-in.
Your immediate use case here I believe to be the needed motivation
to finally drive this to a conclusion. So folks lets just tie this
one off.
Thanks,
-john
--
john.cooper@redhat.com
^ permalink raw reply
* RE: [PATCH V2 1/2] Export firmware assigned labels of network devices to sysfs
From: Narendra_K @ 2010-06-04 20:43 UTC (permalink / raw)
To: Narendra_K, greg; +Cc: netdev, linux-hotplug, linux-pci, Matt_Domsch
In-Reply-To: <20100603210715.GA18025@auslistsprd01.us.dell.com>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1254", Size: 26538 bytes --]
With regards,
Narendra K
> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-
> owner@vger.kernel.org] On Behalf Of Narendra K
> Sent: Friday, June 04, 2010 2:37 AM
> To: greg@kroah.com
> Cc: netdev@vger.kernel.org; linux-hotplug@vger.kernel.org; linux-
> pci@vger.kernel.org; Domsch, Matt
> Subject: Re: [PATCH V2 1/2] Export firmware assigned labels of network
> devices to sysfs
>
> > -----Original Message-----
> > From: Greg KH [mailto:greg@kroah.com]
> > Sent: Friday, May 28, 2010 9:11 PM
> > To: K, Narendra
> > Cc: netdev@vger.kernel.org; linux-hotplug@vger.kernel.org;
> > linux-pci@vger.kernel.org; Domsch, Matt; Hargrave, Jordan; Rose,
> > Charles; Nijhawan, Vijay
> > Subject: Re: [PATCH 1/2] Export firmware assigned labels of network
> > devices to sysfs
> >
> Thanks for the comments.
>
> > On Fri, May 28, 2010 at 06:55:21AM -0500, K, Narendra wrote:
> > > Please refer to the PCI-SIG Draft ECN
> > > "PCIe Device Labeling under Operating Systems Draft ECN" at this
> link
> > -
> > > http://www.pcisig.com/specifications/pciexpress/review_zone/.
> > >
> > > It would be great to know your views on this ECN. Please let us
> know
> > if you have
> > > have any suggestions or changes.
> >
> > Note that only members of the PCI-SIG can do this, which pretty much
> > rules out any "normal" Linux kernel developer :(
> >
> > Care to post a public version of this for us to review?
> > > --- /dev/null
> > > +++ b/drivers/pci/pci-label.c
> > > @@ -0,0 +1,242 @@
> > > +/*
> > > + * File: drivers/pci/pci-label.c
> >
> > This line is not needed, we know the file name :)
> >
> > > + * Purpose: Export the firmware label associated with a pci
> > network interface
> > > + * device to sysfs
> > > + * Copyright (C) 2010 Dell Inc.
> > > + * by Narendra K <Narendra_K@dell.com>, Jordan Hargrave
> > <Jordan_Hargrave@dell.com>
> > > + *
> > > + * This code checks if the pci network device has a related ACPI
> > _DSM. If
> > > + * available, the code calls the _DSM to retrieve the index and
> > string and
> > > + * exports them to sysfs. If the ACPI _DSM is not available, it
> falls
> > back on
> > > + * SMBIOS. SMBIOS defines type 41 for onboard pci devices. This
> code
> > retrieves
> > > + * strings associated with the type 41 and exports it to sysfs.
> > > + *
> > > + * Please see
> http://linux.dell.com/wiki/index.php/Oss/libnetdevname
> > for more
> > > + * information.
> > > + */
> > > +
> > > +#include <linux/pci-label.h>
> >
> > Why is this file in include/linux/ ? Who needs it there? Can't it
> just
> > be in in the drivers/pci/ directory? Actually all you need is 2
> > functions in there, so it could go into the internal pci.h file in
> that
> > directory without a problem, right?
> >
>
> This file is removed and functions are moved to the internal pci.h
>
> > > +
> > > +static ssize_t
> > > +smbiosname_string_exists(struct device *dev, char *buf)
> > > +{
> > > + struct pci_dev *pdev = to_pci_dev(dev);
> > > + const struct dmi_device *dmi;
> > > + struct dmi_devslot *dslot;
> > > + int bus;
> > > + int devfn;
> > > +
> > > + bus = pdev->bus->number;
> > > + devfn = pdev->devfn;
> > > +
> > > + dmi = NULL;
> > > + while ((dmi = dmi_find_device(DMI_DEV_TYPE_DEVSLOT, NULL,
> > dmi)) != NULL) {
> > > + dslot = dmi->device_data;
> > > + if (dslot && dslot->bus = bus && dslot->devfn =
> > devfn) {
> > > + if (buf)
> > > + return scnprintf(buf, PAGE_SIZE,
> > "%s\n", dmi->name);
> > > + return strlen(dmi->name);
> > > + }
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static ssize_t
> > > +smbiosname_show(struct device *dev, struct device_attribute *attr,
> > char *buf)
> > > +{
> > > + return smbiosname_string_exists(dev, buf);
> > > +}
> > > +
> > > +struct smbios_attribute smbios_attr_label = {
> > > + .attr = {.name = __stringify(label), .mode = 0444, .owner > > THIS_MODULE},
> >
> > Can't you just put "label" as the name?
> >
>
> This is fixed.
>
> > > + .show = smbiosname_show,
> > > + .test = smbiosname_string_exists,
> > > +};
> > > +
> > > +static int
> > > +pci_create_smbiosname_file(struct pci_dev *pdev)
> > > +{
> > > + if (smbios_attr_label.test &&
> > smbios_attr_label.test(&pdev->dev, NULL)) {
> > > + sysfs_create_file(&pdev->dev.kobj,
> > &smbios_attr_label.attr);
> > > + return 0;
> > > + }
> > > + return -1;
> > > +}
> > > +
> > > +static int
> > > +pci_remove_smbiosname_file(struct pci_dev *pdev)
> > > +{
> > > + if (smbios_attr_label.test &&
> > smbios_attr_label.test(&pdev->dev, NULL)) {
> > > + sysfs_remove_file(&pdev->dev.kobj,
> > &smbios_attr_label.attr);
> > > + return 0;
> > > + }
> > > + return -1;
> > > +}
> > > +
> > > +static const char dell_dsm_uuid[] = {
> >
> > Um, a dell specific uuid in a generic file? What happens when we
> need
> > to support another manufacturer?
> >
>
> My understanding of uuid was incorrect. I have renamed it to a more
> generic
> device_label_dsm_uuid and ACPI_DSM_FUNCTION to DEVICE_LABEL_DSM
>
> > > + 0xD0, 0x37, 0xC9, 0xE5, 0x53, 0x35, 0x7A, 0x4D,
> > > + 0x91, 0x17, 0xEA, 0x4D, 0x19, 0xC3, 0x43, 0x4D
> > > +};
> > > +
> > > +
> > > +static int
> > > +dsm_get_label(acpi_handle handle, int func,
> > > + struct acpi_buffer *output,
> > > + char *buf, char *attribute)
> > > +{
> > > + struct acpi_object_list input;
> > > + union acpi_object params[4];
> > > + union acpi_object *obj;
> > > + int len = 0;
> > > +
> > > + int err;
> > > +
> > > + input.count = 4;
> > > + input.pointer = params;
> > > + params[0].type = ACPI_TYPE_BUFFER;
> > > + params[0].buffer.length = sizeof(dell_dsm_uuid);
> > > + params[0].buffer.pointer = (char *)dell_dsm_uuid;
> > > + params[1].type = ACPI_TYPE_INTEGER;
> > > + params[1].integer.value = 0x02;
> > > + params[2].type = ACPI_TYPE_INTEGER;
> > > + params[2].integer.value = func;
> > > + params[3].type = ACPI_TYPE_PACKAGE;
> > > + params[3].package.count = 0;
> > > + params[3].package.elements = NULL;
> > > +
> > > + err = acpi_evaluate_object(handle, "_DSM", &input, output);
> > > + if (err) {
> > > + printk(KERN_INFO "failed to evaulate _DSM\n");
> > > + return -1;
> > > + }
> > > +
> > > + obj = (union acpi_object *)output->pointer;
> > > +
> > > + switch (obj->type) {
> > > + case ACPI_TYPE_PACKAGE:
> > > + if (obj->package.count = 2) {
> > > + len = obj-
> >package.elements[0].integer.value;
> > > + if (buf) {
> > > + if (!strncmp(attribute, "index",
> > strlen(attribute)))
> > > + scnprintf(buf, PAGE_SIZE,
> > "%lu\n",
> > > +
> > obj->package.elements[0].integer.value);
> > > + else
> > > + scnprintf(buf, PAGE_SIZE,
> > "%s\n",
> > > +
> > obj->package.elements[1].string.pointer);
> > > + kfree(output->pointer);
> > > + return strlen(buf);
> > > + }
> > > + }
> > > + kfree(output->pointer);
> > > + return len;
> > > + break;
> > > + default:
> > > + return -1;
> > > + }
> > > +}
> > > +
> > > +static ssize_t
> > > +acpi_index_string_exist(struct device *dev, char *buf, char
> > *attribute)
> > > +{
> > > + struct pci_dev *pdev = to_pci_dev(dev);
> > > +
> > > + struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
> > > + acpi_handle handle;
> > > + int length;
> > > + int is_addin_card = 0;
> > > +
> > > + if ((pdev->class >> 16) != PCI_BASE_CLASS_NETWORK)
> > > + return -1;
> > > +
> > > + handle = DEVICE_ACPI_HANDLE(dev);
> > > +
> > > + if (!handle) {
> > > + /*
> > > + * The device is an add-in network controller and
> does
> > have
> > > + * a valid handle. Try until we get the handle for
> the
> > parent
> > > + * bridge
> > > + */
> > > + struct pci_bus *pbus;
> > > + for (pbus = pdev->bus; pbus; pbus = pbus->parent) {
> > > + handle > > DEVICE_ACPI_HANDLE(&(pbus->self->dev));
> > > + if (handle)
> > > + break;
> > > +
> > > + }
> > > + }
> > > +
> > > + if ((length = dsm_get_label(handle, DELL_DSM_NETWORK,
> > > + &output, buf, attribute)) < 0)
> > > + return -1;
> > > +
> > > + return length;
> > > +}
> > > +
> > > +static ssize_t
> > > +acpilabel_show(struct device *dev, struct device_attribute *attr,
> > char *buf)
> > > +{
> > > + return acpi_index_string_exist(dev, buf, "label");
> > > +}
> > > +
> > > +static ssize_t
> > > +acpiindex_show(struct device *dev, struct device_attribute *attr,
> > char *buf)
> > > +{
> > > + return acpi_index_string_exist(dev, buf, "index");
> > > +}
> > > +
> > > +struct acpi_attribute acpi_attr_label = {
> > > + .attr = {.name = __stringify(label), .mode = 0444, .owner > > THIS_MODULE},
> > > + .show = acpilabel_show,
> > > + .test = acpi_index_string_exist,
> > > +};
> > > +
> > > +struct acpi_attribute acpi_attr_index = {
> > > + .attr = {.name = __stringify(index), .mode = 0444, .owner > > THIS_MODULE},
> > > + .show = acpiindex_show,
> > > + .test = acpi_index_string_exist,
> > > +};
> > > +
> > > +static int
> > > +pci_create_acpi_index_label_files(struct pci_dev *pdev)
> > > +{
> > > + if (acpi_attr_label.test && acpi_attr_label.test(&pdev-
> >dev,
> > NULL) > 0) {
> > > + sysfs_create_file(&pdev->dev.kobj,
> > &acpi_attr_label.attr);
> > > + sysfs_create_file(&pdev->dev.kobj,
> > &acpi_attr_index.attr);
> > > + return 0;
> > > + }
> > > + return -1;
> > > +}
> > > +
> > > +static int
> > > +pci_remove_acpi_index_label_files(struct pci_dev *pdev)
> > > +{
> > > + if (acpi_attr_label.test && acpi_attr_label.test(&pdev-
> >dev,
> > NULL) > 0) {
> > > + sysfs_remove_file(&pdev->dev.kobj,
> > &acpi_attr_label.attr);
> > > + sysfs_remove_file(&pdev->dev.kobj,
> > &acpi_attr_index.attr);
> > > + return 0;
> > > + }
> > > + return -1;
> > > +}
> > > +
> > > +int pci_create_acpi_attr_files(struct pci_dev *pdev)
> > > +{
> > > + if (!pci_create_acpi_index_label_files(pdev))
> > > + return 0;
> > > + if (!pci_create_smbiosname_file(pdev))
> > > + return 0;
> > > + return -ENODEV;
> > > +}
> > > +EXPORT_SYMBOL(pci_create_acpi_attr_files);
> >
> > EXPORT_SYMBOL_GPL?
> >
> > Wait, why does this need to be exported at all? What module is ever
> > going to call this function?
> >
> > > +int pci_remove_acpi_attr_files(struct pci_dev *pdev)
> > > +{
> > > + if (!pci_remove_acpi_index_label_files(pdev))
> > > + return 0;
> > > + if (!pci_remove_smbiosname_file(pdev))
> > > + return 0;
> > > + return -ENODEV;
> > > +
> > > +}
> > > +EXPORT_SYMBOL(pci_remove_acpi_attr_files);
> >
> > Same here, what module will call this?
> >
>
> These functions need not be exported as they are not called by any
> module.
>
> > > +++ b/include/linux/pci-label.h
> >
> > As discussed above, this whole file does not need to exist.
> >
> > > +extern int pci_create_acpi_attr_files(struct pci_dev *pdev);
> > > +extern int pci_remove_acpi_attr_files(struct pci_dev *pdev);
> >
> > Just put these two functions in the drivers/pci/pci.h file.
> >
> Fixed.
>
> In addition to these changes there are a coulple of changes i have done
> -
>
> 1.Removed the check for network devices and evaulate _DSM for any pci
> device
> that has _DSM defined in adherence to the spec.
>
> 2.Renamed the functions pci_create,remove-acpi_attr_files to
> pci_create,remove_firmware_label_files.
>
> 3.Added checks for conditional compilation of if CONFIG_ACPI ||
> CONFIG_DMI
>
> Note: While testing the patch with CONFIG_ACPI set to no, the
> compilation
> would fail with the below message.
>
> CC drivers/pci/pci-label.o
> In file included from drivers/pci/pci-label.c:24:
> include/linux/pci-acpi.h:39: error: expected â=â, â,â, â;â, âasmâ or
> â__attribute__â
> before âacpi_find_root_bridge_handleâ
>
> I had to add make this change to proceed with the compilation. It would
> be
> great to know if i am missing something in the way conditional
> compilation
> is implemented or is it a issue.
>
> ---
> include/linux/pci-acpi.h | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h
> index c8b6473..bc40827 100644
> --- a/include/linux/pci-acpi.h
> +++ b/include/linux/pci-acpi.h
> @@ -36,8 +36,8 @@ static inline acpi_handle
> acpi_pci_get_bridge_handle(struct pci_bus *pbus)
> pbus->number);
> }
> #else
> -static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev
> *pdev)
> -{ return NULL; }
> +static inline void acpi_find_root_bridge_handle(struct pci_dev *pdev)
> +{ }
> #endif
>
> #endif /* _PCI_ACPI_H_ */
>
>
> Please find the patch with above suggestions and changes -
>
>
> From: Narendra K <narendra_k@dell.com>
> Subject: [PATCH V2 1/2] Export firmware assigned labels of pci devices
> to sysfs
>
> This patch exports the firmware assigned labels of pci devices to
> sysfs which could be used by user space.
>
> Signed-off-by: Jordan Hargrave <jordan_hargrave@dell.com>
> Signed-off-by: Narendra K <narendra_k@dell.com>
> ---
> drivers/firmware/dmi_scan.c | 24 ++++
> drivers/pci/Makefile | 2 +-
> drivers/pci/pci-label.c | 273
> +++++++++++++++++++++++++++++++++++++++++++
> drivers/pci/pci-sysfs.c | 5 +
> drivers/pci/pci.h | 2 +
> include/linux/dmi.h | 9 ++
> 6 files changed, 314 insertions(+), 1 deletions(-)
> create mode 100644 drivers/pci/pci-label.c
>
> diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
> index d464672..7d8439b 100644
> --- a/drivers/firmware/dmi_scan.c
> +++ b/drivers/firmware/dmi_scan.c
> @@ -277,6 +277,28 @@ static void __init dmi_save_ipmi_device(const
> struct dmi_header *dm)
> list_add_tail(&dev->list, &dmi_devices);
> }
>
> +static void __init dmi_save_devslot(int id, int seg, int bus, int
> devfn, const char *name)
> +{
> + struct dmi_devslot *slot;
> +
> + slot = dmi_alloc(sizeof(*slot) + strlen(name) + 1);
> + if (!slot) {
> + printk(KERN_ERR "dmi_save_devslot: out of memory.\n");
> + return;
> + }
> + slot->id = id;
> + slot->seg = seg;
> + slot->bus = bus;
> + slot->devfn = devfn;
> +
> + strcpy((char *)&slot[1], name);
> + slot->dev.type = DMI_DEV_TYPE_DEVSLOT;
> + slot->dev.name = (char *)&slot[1];
> + slot->dev.device_data = slot;
> +
> + list_add(&slot->dev.list, &dmi_devices);
> +}
> +
> static void __init dmi_save_extended_devices(const struct dmi_header
> *dm)
> {
> const u8 *d = (u8*) dm + 5;
> @@ -285,6 +307,7 @@ static void __init dmi_save_extended_devices(const
> struct dmi_header *dm)
> if ((*d & 0x80) = 0)
> return;
>
> + dmi_save_devslot(-1, *(u16 *)(d+2), *(d+4), *(d+5),
> dmi_string_nosave(dm, *(d-1)));
> dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1)));
> }
>
> @@ -333,6 +356,7 @@ static void __init dmi_decode(const struct
> dmi_header *dm, void *dummy)
> break;
> case 41: /* Onboard Devices Extended Information */
> dmi_save_extended_devices(dm);
> + break;
> }
> }
>
> diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
> index 0b51857..69c503a 100644
> --- a/drivers/pci/Makefile
> +++ b/drivers/pci/Makefile
> @@ -4,7 +4,7 @@
>
> obj-y += access.o bus.o probe.o remove.o pci.o \
> pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \
> - irq.o vpd.o
> + irq.o vpd.o pci-label.o
> obj-$(CONFIG_PROC_FS) += proc.o
> obj-$(CONFIG_SYSFS) += slot.o
>
> diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c
> new file mode 100644
> index 0000000..b35d48c
> --- /dev/null
> +++ b/drivers/pci/pci-label.c
> @@ -0,0 +1,273 @@
> +/*
> + * Purpose: Export the firmware label associated with a pci network
> interface
> + * device to sysfs
> + * Copyright (C) 2010 Dell Inc.
> + * by Narendra K <Narendra_K@dell.com>, Jordan Hargrave
> <Jordan_Hargrave@dell.com>
> + *
> + * This code checks if the pci network device has a related ACPI _DSM.
> If
> + * available, the code calls the _DSM to retrieve the index and string
> and
> + * exports them to sysfs. If the ACPI _DSM is not available, it falls
> back on
> + * SMBIOS. SMBIOS defines type 41 for onboard pci devices. This code
> retrieves
> + * strings associated with the type 41 and exports it to sysfs.
> + *
> + * Please see http://linux.dell.com/wiki/index.php/Oss/libnetdevname
> for more
> + * information.
> + */
> +
> +#include <linux/dmi.h>
> +#include <linux/sysfs.h>
> +#include <linux/pci.h>
> +#include <linux/pci_ids.h>
> +#include <linux/module.h>
> +#include <linux/acpi.h>
> +#include <linux/pci-acpi.h>
> +#include <acpi/acpi_drivers.h>
> +#include <acpi/acpi_bus.h>
> +#include "pci.h"
> +
> +#define DEVICE_LABEL_DSM 0x07
> +
> +#if defined CONFIG_DMI
> +
> +struct smbios_attribute {
> + struct attribute attr;
> + ssize_t (*show) (struct device *dev, char *buf);
> + ssize_t (*test) (struct device *dev, char *buf);
> +};
> +
> +static ssize_t
> +smbiosname_string_exists(struct device *dev, char *buf)
> +{
> + struct pci_dev *pdev = to_pci_dev(dev);
> + const struct dmi_device *dmi;
> + struct dmi_devslot *dslot;
> + int bus;
> + int devfn;
> +
> + bus = pdev->bus->number;
> + devfn = pdev->devfn;
> +
> + dmi = NULL;
> + while ((dmi = dmi_find_device(DMI_DEV_TYPE_DEVSLOT, NULL, dmi))
> != NULL) {
> + dslot = dmi->device_data;
> + if (dslot && dslot->bus = bus && dslot->devfn = devfn) {
> + if (buf)
> + return scnprintf(buf, PAGE_SIZE, "%s\n",
> dmi->name);
> + return strlen(dmi->name);
> + }
> + }
> +
> + return 0;
> +}
> +
> +static ssize_t
> +smbiosname_show(struct device *dev, struct device_attribute *attr,
> char *buf)
> +{
> + return smbiosname_string_exists(dev, buf);
> +}
> +
> +struct smbios_attribute smbios_attr_label = {
> + .attr = {.name = "label", .mode = 0444, .owner = THIS_MODULE},
> + .show = smbiosname_show,
> + .test = smbiosname_string_exists,
> +};
> +
> +static int
> +pci_create_smbiosname_file(struct pci_dev *pdev)
> +{
> + if (smbios_attr_label.test && smbios_attr_label.test(&pdev->dev,
> NULL)) {
> + sysfs_create_file(&pdev->dev.kobj,
> &smbios_attr_label.attr);
> + return 0;
> + }
> + return -1;
> +}
> +
> +static int
> +pci_remove_smbiosname_file(struct pci_dev *pdev)
> +{
> + if (smbios_attr_label.test && smbios_attr_label.test(&pdev->dev,
> NULL)) {
> + sysfs_remove_file(&pdev->dev.kobj,
> &smbios_attr_label.attr);
> + return 0;
> + }
> + return -1;
> +}
> +#else
> +static inline int
> +pci_create_smbiosname_file(struct pci_dev *pdev)
> +{
> + return -1;
> +}
> +
> +static inline int
> +pci_remove_smbiosname_file(struct pci_dev *pdev)
> +{
> + return -1;
> +}
> +#endif
> +
> +#if defined CONFIG_ACPI
> +
> +static const char device_label_dsm_uuid[] = {
> + 0xD0, 0x37, 0xC9, 0xE5, 0x53, 0x35, 0x7A, 0x4D,
> + 0x91, 0x17, 0xEA, 0x4D, 0x19, 0xC3, 0x43, 0x4D
> +};
> +
> +struct acpi_attribute {
> + struct attribute attr;
> + ssize_t (*show) (struct device *dev, char *buf);
> + ssize_t (*test) (struct device *dev, char *buf);
> +};
> +
> +static int
> +dsm_get_label(acpi_handle handle, int func,
> + struct acpi_buffer *output,
> + char *buf, char *attribute)
> +{
> + struct acpi_object_list input;
> + union acpi_object params[4];
> + union acpi_object *obj;
> + int len = 0;
> +
> + int err;
> +
> + input.count = 4;
> + input.pointer = params;
> + params[0].type = ACPI_TYPE_BUFFER;
> + params[0].buffer.length = sizeof(device_label_dsm_uuid);
> + params[0].buffer.pointer = (char *)device_label_dsm_uuid;
> + params[1].type = ACPI_TYPE_INTEGER;
> + params[1].integer.value = 0x02;
> + params[2].type = ACPI_TYPE_INTEGER;
> + params[2].integer.value = func;
> + params[3].type = ACPI_TYPE_PACKAGE;
> + params[3].package.count = 0;
> + params[3].package.elements = NULL;
> +
> + err = acpi_evaluate_object(handle, "_DSM", &input, output);
> + if (err)
> + return -1;
> +
> +
> + obj = (union acpi_object *)output->pointer;
> +
> + switch (obj->type) {
> + case ACPI_TYPE_PACKAGE:
> + if (obj->package.count != 2)
> + break;
> + len = obj->package.elements[0].integer.value;
> + if (buf) {
> + if (!strncmp(attribute, "index", strlen(attribute)))
> + scnprintf(buf, PAGE_SIZE, "%lu\n",
> + obj->package.elements[0].integer.value);
> + else
> + scnprintf(buf, PAGE_SIZE, "%s\n",
> + obj->package.elements[1].string.pointer);
> + kfree(output->pointer);
> + return strlen(buf);
> + }
> + kfree(output->pointer);
> + return len;
> + break;
> + default:
> + kfree(output->pointer);
> + return -1;
> + }
> +}
> +
> +static ssize_t
> +acpi_index_string_exist(struct device *dev, char *buf, char
> *attribute)
> +{
> + struct pci_dev *pdev = to_pci_dev(dev);
> +
> + struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
> + acpi_handle handle;
> + int length;
> +
> + handle = DEVICE_ACPI_HANDLE(dev);
> +
> + if (!handle)
> + return -1;
> +
> + if ((length = dsm_get_label(handle, DEVICE_LABEL_DSM,
> + &output, buf, attribute)) < 0)
> + return -1;
> +
> + return length;
> +}
> +
> +static ssize_t
> +acpilabel_show(struct device *dev, struct device_attribute *attr, char
> *buf)
> +{
> + return acpi_index_string_exist(dev, buf, "label");
> +}
> +
> +static ssize_t
> +acpiindex_show(struct device *dev, struct device_attribute *attr, char
> *buf)
> +{
> + return acpi_index_string_exist(dev, buf, "index");
> +}
> +
> +struct acpi_attribute acpi_attr_label = {
> + .attr = {.name = "label", .mode = 0444, .owner = THIS_MODULE},
> + .show = acpilabel_show,
> + .test = acpi_index_string_exist,
> +};
> +
> +struct acpi_attribute acpi_attr_index = {
> + .attr = {.name = "index", .mode = 0444, .owner = THIS_MODULE},
> + .show = acpiindex_show,
> + .test = acpi_index_string_exist,
> +};
> +
> +static int
> +pci_create_acpi_index_label_files(struct pci_dev *pdev)
> +{
> + if (acpi_attr_label.test && acpi_attr_label.test(&pdev->dev,
> NULL) > 0) {
> + sysfs_create_file(&pdev->dev.kobj, &acpi_attr_label.attr);
> + sysfs_create_file(&pdev->dev.kobj, &acpi_attr_index.attr);
> + return 0;
> + }
> + return -1;
> +}
> +
> +static int
> +pci_remove_acpi_index_label_files(struct pci_dev *pdev)
> +{
> + if (acpi_attr_label.test && acpi_attr_label.test(&pdev->dev,
> NULL) > 0) {
> + sysfs_remove_file(&pdev->dev.kobj, &acpi_attr_label.attr);
> + sysfs_remove_file(&pdev->dev.kobj, &acpi_attr_index.attr);
> + return 0;
> + }
> + return -1;
> +}
> +#else
> +static inline int
> +pci_create_acpi_index_label_files(struct pci_dev *pdev)
> +{
> + return -1;
> +}
> +
> +static inline int
> +pci_remove_acpi_index_label_files(struct pci_dev *pdev)
> +{
> + return -1;
> +}
> +#endif
> +
> +int pci_create_firmware_label_files(struct pci_dev *pdev)
> +{
> + if (!pci_create_acpi_index_label_files(pdev))
> + return 0;
> + if (!pci_create_smbiosname_file(pdev))
> + return 0;
> + return -ENODEV;
> +}
> +
> +int pci_remove_firmware_label_files(struct pci_dev *pdev)
> +{
> + if (!pci_remove_acpi_index_label_files(pdev))
> + return 0;
> + if (!pci_remove_smbiosname_file(pdev))
> + return 0;
> + return -ENODEV;
> +}
> diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
> index fad9398..4ed517f 100644
> --- a/drivers/pci/pci-sysfs.c
> +++ b/drivers/pci/pci-sysfs.c
> @@ -1073,6 +1073,8 @@ int __must_check pci_create_sysfs_dev_files
> (struct pci_dev *pdev)
> if (retval)
> goto err_vga_file;
>
> + pci_create_firmware_label_files(pdev);
> +
> return 0;
>
> err_vga_file:
> @@ -1140,6 +1142,9 @@ void pci_remove_sysfs_dev_files(struct pci_dev
> *pdev)
> sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
> kfree(pdev->rom_attr);
> }
> +
> + pci_remove_firmware_label_files(pdev);
> +
> }
>
> static int __init pci_sysfs_init(void)
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index 4eb10f4..f223283 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -11,6 +11,8 @@
> extern int pci_uevent(struct device *dev, struct kobj_uevent_env
> *env);
> extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
> extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
> +extern int pci_create_firmware_label_files(struct pci_dev *pdev);
> +extern int pci_remove_firmware_label_files(struct pci_dev *pdev);
> extern void pci_cleanup_rom(struct pci_dev *dev);
> #ifdef HAVE_PCI_MMAP
> extern int pci_mmap_fits(struct pci_dev *pdev, int resno,
> diff --git a/include/linux/dmi.h b/include/linux/dmi.h
> index a8a3e1a..cc57c3a 100644
> --- a/include/linux/dmi.h
> +++ b/include/linux/dmi.h
> @@ -20,6 +20,7 @@ enum dmi_device_type {
> DMI_DEV_TYPE_SAS,
> DMI_DEV_TYPE_IPMI = -1,
> DMI_DEV_TYPE_OEM_STRING = -2,
> + DMI_DEV_TYPE_DEVSLOT = -3,
> };
>
> struct dmi_header {
> @@ -37,6 +38,14 @@ struct dmi_device {
>
> #ifdef CONFIG_DMI
>
> +struct dmi_devslot {
> + struct dmi_device dev;
> + int id;
> + int seg;
> + int bus;
> + int devfn;
> +};
> +
> extern int dmi_check_system(const struct dmi_system_id *list);
> const struct dmi_system_id *dmi_first_match(const struct dmi_system_id
> *list);
> extern const char * dmi_get_system_info(int field);
> --
> 1.6.5.2
>
> With regards,
> Narendra K
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
ÿôèº{.nÇ+·®+%Ëÿ±éݶ\x17¥wÿº{.nÇ+·¥{±þ\x1a-¦[ þ)í
æèw*\x1fjg¬±¨\x1e¶Ý¢jÿ¾\a«þG«éÿ¢¸\f¢·¦j:+v¨wèjØm¶ÿþø\x1e¯ù\x1e®w¥þàþf£¢·hâúÿÙ¥
^ permalink raw reply
* Re: [PATCH V2 1/2] Export firmware assigned labels of network
From: Greg KH @ 2010-06-04 20:49 UTC (permalink / raw)
To: Narendra_K; +Cc: netdev, linux-hotplug, linux-pci, Matt_Domsch
In-Reply-To: <EDA0A4495861324DA2618B4C45DCB3EE612913@blrx3m08.blr.amer.dell.com>
On Sat, Jun 05, 2010 at 02:01:35AM +0530, Narendra_K@Dell.com wrote:
>
>
> With regards,
Um, what?
Why are you resending this over and over with no additional content
added?
If you have a new patch, send it. Don't bury it at the bottom of
another message, and then linewrap the thing...
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH V2 1/2] Export firmware assigned labels of network
From: Greg KH @ 2010-06-04 21:01 UTC (permalink / raw)
To: Narendra_K; +Cc: netdev, linux-hotplug, linux-pci, Matt_Domsch
In-Reply-To: <20100604204955.GA20329@kroah.com>
On Fri, Jun 04, 2010 at 01:49:55PM -0700, Greg KH wrote:
> On Sat, Jun 05, 2010 at 02:01:35AM +0530, Narendra_K@Dell.com wrote:
> >
> >
> > With regards,
>
> Um, what?
>
> Why are you resending this over and over with no additional content
> added?
And you have an out-of-office autoreply.
I give up...
^ permalink raw reply
* Re: [PATCH V3 1/2] Export firmware assigned labels of network devices to sysfs
From: Narendra K @ 2010-06-04 21:07 UTC (permalink / raw)
To: greg
Cc: netdev, linux-hotplug, linux-pci, matt_domsch, jordan_hargrave,
charles_rose
In-Reply-To: <EDA0A4495861324DA2618B4C45DCB3EE612918@blrx3m08.blr.amer.dell.com>
> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org] On Behalf Of Narendra K
> Sent: Friday, June 04, 2010 2:37 AM
> To: greg@kroah.com
> Cc: netdev@vger.kernel.org; linux-hotplug@vger.kernel.org; linux-pci@vger.kernel.org; Domsch, Matt
> Subject: Re: [PATCH V2 1/2] Export firmware assigned labels of network devices to sysfs
>
> In addition to these changes there are a coulple of changes i have done -
>
> 1.Removed the check for network devices and evaulate _DSM for any pci device
> that has _DSM defined in adherence to the spec.
>
> 2.Renamed the functions pci_create,remove-acpi_attr_files to
> pci_create,remove_firmware_label_files.
>
> 3.Added checks for conditional compilation of if CONFIG_ACPI || CONFIG_DMI
>
V2 -> V3: I had missed fixing warnings in the patch. Please find the V3
of the patch with the warnings fixed -
From: Narendra K <narendra_k@dell.com>
Subject: [PATCH V3 1/2] Export firmware assigned labels of pci devices to sysfs
This patch exports the firmware assigned labels of pci devices to
sysfs which could be used by user space.
Signed-off-by: Jordan Hargrave <jordan_hargrave@dell.com>
Signed-off-by: Narendra K <narendra_k@dell.com>
---
drivers/firmware/dmi_scan.c | 24 ++++
drivers/pci/Makefile | 2 +-
drivers/pci/pci-label.c | 274 +++++++++++++++++++++++++++++++++++++++++++
drivers/pci/pci-sysfs.c | 5 +
drivers/pci/pci.h | 2 +
include/linux/dmi.h | 9 ++
6 files changed, 315 insertions(+), 1 deletions(-)
create mode 100644 drivers/pci/pci-label.c
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index d464672..7d8439b 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -277,6 +277,28 @@ static void __init dmi_save_ipmi_device(const struct dmi_header *dm)
list_add_tail(&dev->list, &dmi_devices);
}
+static void __init dmi_save_devslot(int id, int seg, int bus, int devfn, const char *name)
+{
+ struct dmi_devslot *slot;
+
+ slot = dmi_alloc(sizeof(*slot) + strlen(name) + 1);
+ if (!slot) {
+ printk(KERN_ERR "dmi_save_devslot: out of memory.\n");
+ return;
+ }
+ slot->id = id;
+ slot->seg = seg;
+ slot->bus = bus;
+ slot->devfn = devfn;
+
+ strcpy((char *)&slot[1], name);
+ slot->dev.type = DMI_DEV_TYPE_DEVSLOT;
+ slot->dev.name = (char *)&slot[1];
+ slot->dev.device_data = slot;
+
+ list_add(&slot->dev.list, &dmi_devices);
+}
+
static void __init dmi_save_extended_devices(const struct dmi_header *dm)
{
const u8 *d = (u8*) dm + 5;
@@ -285,6 +307,7 @@ static void __init dmi_save_extended_devices(const struct dmi_header *dm)
if ((*d & 0x80) = 0)
return;
+ dmi_save_devslot(-1, *(u16 *)(d+2), *(d+4), *(d+5), dmi_string_nosave(dm, *(d-1)));
dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1)));
}
@@ -333,6 +356,7 @@ static void __init dmi_decode(const struct dmi_header *dm, void *dummy)
break;
case 41: /* Onboard Devices Extended Information */
dmi_save_extended_devices(dm);
+ break;
}
}
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 0b51857..69c503a 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -4,7 +4,7 @@
obj-y += access.o bus.o probe.o remove.o pci.o \
pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \
- irq.o vpd.o
+ irq.o vpd.o pci-label.o
obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_SYSFS) += slot.o
diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c
new file mode 100644
index 0000000..d6e0e9b
--- /dev/null
+++ b/drivers/pci/pci-label.c
@@ -0,0 +1,274 @@
+/*
+ * Purpose: Export the firmware label associated with a pci network interface
+ * device to sysfs
+ * Copyright (C) 2010 Dell Inc.
+ * by Narendra K <Narendra_K@dell.com>, Jordan Hargrave <Jordan_Hargrave@dell.com>
+ *
+ * This code checks if the pci network device has a related ACPI _DSM. If
+ * available, the code calls the _DSM to retrieve the index and string and
+ * exports them to sysfs. If the ACPI _DSM is not available, it falls back on
+ * SMBIOS. SMBIOS defines type 41 for onboard pci devices. This code retrieves
+ * strings associated with the type 41 and exports it to sysfs.
+ *
+ * Please see http://linux.dell.com/wiki/index.php/Oss/libnetdevname for more
+ * information.
+ */
+
+#include <linux/dmi.h>
+#include <linux/sysfs.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <linux/pci-acpi.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+#include "pci.h"
+
+#define DEVICE_LABEL_DSM 0x07
+
+#if defined CONFIG_DMI
+
+struct smbios_attribute {
+ struct attribute attr;
+ ssize_t (*show) (struct device *dev, struct device_attribute *, char *buf);
+ ssize_t (*test) (struct device *dev, char *buf);
+};
+
+static ssize_t
+smbiosname_string_exists(struct device *dev, char *buf)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ const struct dmi_device *dmi;
+ struct dmi_devslot *dslot;
+ int bus;
+ int devfn;
+
+ bus = pdev->bus->number;
+ devfn = pdev->devfn;
+
+ dmi = NULL;
+ while ((dmi = dmi_find_device(DMI_DEV_TYPE_DEVSLOT, NULL, dmi)) != NULL) {
+ dslot = dmi->device_data;
+ if (dslot && dslot->bus = bus && dslot->devfn = devfn) {
+ if (buf)
+ return scnprintf(buf, PAGE_SIZE, "%s\n", dmi->name);
+ return strlen(dmi->name);
+ }
+ }
+
+ return 0;
+}
+
+static ssize_t
+smbiosname_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return smbiosname_string_exists(dev, buf);
+}
+
+struct smbios_attribute smbios_attr_label = {
+ .attr = {.name = "label", .mode = 0444, .owner = THIS_MODULE},
+ .show = smbiosname_show,
+ .test = smbiosname_string_exists,
+};
+
+static int
+pci_create_smbiosname_file(struct pci_dev *pdev)
+{
+ if (smbios_attr_label.test && smbios_attr_label.test(&pdev->dev, NULL)) {
+ if (sysfs_create_file(&pdev->dev.kobj, &smbios_attr_label.attr))
+ return -1;
+ return 0;
+ }
+ return -1;
+}
+
+static int
+pci_remove_smbiosname_file(struct pci_dev *pdev)
+{
+ if (smbios_attr_label.test && smbios_attr_label.test(&pdev->dev, NULL)) {
+ sysfs_remove_file(&pdev->dev.kobj, &smbios_attr_label.attr);
+ return 0;
+ }
+ return -1;
+}
+#else
+static inline int
+pci_create_smbiosname_file(struct pci_dev *pdev)
+{
+ return -1;
+}
+
+static inline int
+pci_remove_smbiosname_file(struct pci_dev *pdev)
+{
+ return -1;
+}
+#endif
+
+#if defined CONFIG_ACPI
+
+static const char device_label_dsm_uuid[] = {
+ 0xD0, 0x37, 0xC9, 0xE5, 0x53, 0x35, 0x7A, 0x4D,
+ 0x91, 0x17, 0xEA, 0x4D, 0x19, 0xC3, 0x43, 0x4D
+};
+
+struct acpi_attribute {
+ struct attribute attr;
+ ssize_t (*show) (struct device *dev, struct device_attribute *attr, char *buf);
+ ssize_t (*test) (struct device *dev, char *buf, char *attribute);
+};
+
+static int
+dsm_get_label(acpi_handle handle, int func,
+ struct acpi_buffer *output,
+ char *buf, char *attribute)
+{
+ struct acpi_object_list input;
+ union acpi_object params[4];
+ union acpi_object *obj;
+ int len = 0;
+
+ int err;
+
+ input.count = 4;
+ input.pointer = params;
+ params[0].type = ACPI_TYPE_BUFFER;
+ params[0].buffer.length = sizeof(device_label_dsm_uuid);
+ params[0].buffer.pointer = (char *)device_label_dsm_uuid;
+ params[1].type = ACPI_TYPE_INTEGER;
+ params[1].integer.value = 0x02;
+ params[2].type = ACPI_TYPE_INTEGER;
+ params[2].integer.value = func;
+ params[3].type = ACPI_TYPE_PACKAGE;
+ params[3].package.count = 0;
+ params[3].package.elements = NULL;
+
+ err = acpi_evaluate_object(handle, "_DSM", &input, output);
+ if (err)
+ return -1;
+
+
+ obj = (union acpi_object *)output->pointer;
+
+ switch (obj->type) {
+ case ACPI_TYPE_PACKAGE:
+ if (obj->package.count != 2)
+ break;
+ len = obj->package.elements[0].integer.value;
+ if (buf) {
+ if (!strncmp(attribute, "index", strlen(attribute)))
+ scnprintf(buf, PAGE_SIZE, "%llu\n",
+ obj->package.elements[0].integer.value);
+ else
+ scnprintf(buf, PAGE_SIZE, "%s\n",
+ obj->package.elements[1].string.pointer);
+ kfree(output->pointer);
+ return strlen(buf);
+ }
+ kfree(output->pointer);
+ return len;
+ break;
+ default:
+ kfree(output->pointer);
+ }
+ return -1;
+}
+
+static ssize_t
+acpi_index_string_exist(struct device *dev, char *buf, char *attribute)
+{
+ struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+ acpi_handle handle;
+ int length;
+
+ handle = DEVICE_ACPI_HANDLE(dev);
+
+ if (!handle)
+ return -1;
+
+ if ((length = dsm_get_label(handle, DEVICE_LABEL_DSM,
+ &output, buf, attribute)) < 0)
+ return -1;
+
+ return length;
+}
+
+static ssize_t
+acpilabel_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return acpi_index_string_exist(dev, buf, "label");
+}
+
+static ssize_t
+acpiindex_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return acpi_index_string_exist(dev, buf, "index");
+}
+
+struct acpi_attribute acpi_attr_label = {
+ .attr = {.name = "label", .mode = 0444, .owner = THIS_MODULE},
+ .show = acpilabel_show,
+ .test = acpi_index_string_exist,
+};
+
+struct acpi_attribute acpi_attr_index = {
+ .attr = {.name = "index", .mode = 0444, .owner = THIS_MODULE},
+ .show = acpiindex_show,
+ .test = acpi_index_string_exist,
+};
+
+static int
+pci_create_acpi_index_label_files(struct pci_dev *pdev)
+{
+ if (acpi_attr_label.test && acpi_attr_label.test(&pdev->dev, NULL, NULL) > 0) {
+ if (sysfs_create_file(&pdev->dev.kobj, &acpi_attr_label.attr))
+ return -1;
+ if (sysfs_create_file(&pdev->dev.kobj, &acpi_attr_index.attr))
+ return -1;
+ return 0;
+ }
+ return -1;
+}
+
+static int
+pci_remove_acpi_index_label_files(struct pci_dev *pdev)
+{
+ if (acpi_attr_label.test && acpi_attr_label.test(&pdev->dev, NULL, NULL) > 0) {
+ sysfs_remove_file(&pdev->dev.kobj, &acpi_attr_label.attr);
+ sysfs_remove_file(&pdev->dev.kobj, &acpi_attr_index.attr);
+ return 0;
+ }
+ return -1;
+}
+#else
+static inline int
+pci_create_acpi_index_label_files(struct pci_dev *pdev)
+{
+ return -1;
+}
+
+static inline int
+pci_remove_acpi_index_label_files(struct pci_dev *pdev)
+{
+ return -1;
+}
+#endif
+
+int pci_create_firmware_label_files(struct pci_dev *pdev)
+{
+ if (!pci_create_acpi_index_label_files(pdev))
+ return 0;
+ if (!pci_create_smbiosname_file(pdev))
+ return 0;
+ return -ENODEV;
+}
+
+int pci_remove_firmware_label_files(struct pci_dev *pdev)
+{
+ if (!pci_remove_acpi_index_label_files(pdev))
+ return 0;
+ if (!pci_remove_smbiosname_file(pdev))
+ return 0;
+ return -ENODEV;
+}
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index fad9398..4ed517f 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1073,6 +1073,8 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
if (retval)
goto err_vga_file;
+ pci_create_firmware_label_files(pdev);
+
return 0;
err_vga_file:
@@ -1140,6 +1142,9 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
kfree(pdev->rom_attr);
}
+
+ pci_remove_firmware_label_files(pdev);
+
}
static int __init pci_sysfs_init(void)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 4eb10f4..f223283 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -11,6 +11,8 @@
extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env);
extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
+extern int pci_create_firmware_label_files(struct pci_dev *pdev);
+extern int pci_remove_firmware_label_files(struct pci_dev *pdev);
extern void pci_cleanup_rom(struct pci_dev *dev);
#ifdef HAVE_PCI_MMAP
extern int pci_mmap_fits(struct pci_dev *pdev, int resno,
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index a8a3e1a..cc57c3a 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -20,6 +20,7 @@ enum dmi_device_type {
DMI_DEV_TYPE_SAS,
DMI_DEV_TYPE_IPMI = -1,
DMI_DEV_TYPE_OEM_STRING = -2,
+ DMI_DEV_TYPE_DEVSLOT = -3,
};
struct dmi_header {
@@ -37,6 +38,14 @@ struct dmi_device {
#ifdef CONFIG_DMI
+struct dmi_devslot {
+ struct dmi_device dev;
+ int id;
+ int seg;
+ int bus;
+ int devfn;
+};
+
extern int dmi_check_system(const struct dmi_system_id *list);
const struct dmi_system_id *dmi_first_match(const struct dmi_system_id *list);
extern const char * dmi_get_system_info(int field);
--
1.6.5.2
With regards,
Narendra K
^ permalink raw reply related
* RE: [PATCH V2 1/2] Export firmware assigned labels of network devices to sysfs
From: Narendra_K @ 2010-06-04 21:27 UTC (permalink / raw)
To: greg; +Cc: netdev, linux-hotplug, linux-pci, Matt_Domsch
In-Reply-To: <20100604204955.GA20329@kroah.com>
>
> Um, what?
>
> Why are you resending this over and over with no additional content
> added?
>
> If you have a new patch, send it. Don't bury it at the bottom of
> another message, and then linewrap the thing...
>
Greg, Sorry for the inconvenience caused. I have sent the V3 patch with
changes mentioned.
With regards,
Narendra K
^ permalink raw reply
* can dependency on CONFIG_NET be dropped for
From: Robert P. J. Day @ 2010-06-07 11:53 UTC (permalink / raw)
To: linux-hotplug
based on a discussion on another mailing list, it would appear that
this dependency in kernel/sysctl.c is overkill:
#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
{
.procname = "hotplug",
.data = &uevent_helper,
.maxlen = UEVENT_HELPER_PATH_LEN,
.mode = 0644,
.proc_handler = proc_dostring,
},
#endif
as someone else explained, there is no need for that CONFIG_NET
dependency anymore, is there? as i read it, you'll already have
hotplug support -- all the above gives you is the
/proc/sys/kernel/hotplug file that allows you to override the default
setting of /sbin/hotplug, yes?
in the simple case, if it's feasible, one could just drop that
second dependency. or if you wanted to make the proc file a truly
separate config choice, just invent a new Kconfig variable like, say,
HOTPLUG_PROC_FILE which depends on HOTPLUG.
thoughts?
rday
p.s. the poster on the other list referred to these links:
http://article.gmane.org/gmane.linux.kernel/363682
http://article.gmane.org/gmane.linux.kernel/402057
by way of explanation.
--
====================================
Robert P. J. Day Waterloo, Ontario, CANADA
Linux Consulting, Training and Kernel Pedantry.
Web page: http://crashcourse.ca
Twitter: http://twitter.com/rpjday
====================================
^ permalink raw reply
* Re: can dependency on CONFIG_NET be dropped for
From: Greg KH @ 2010-06-07 17:32 UTC (permalink / raw)
To: linux-hotplug
In-Reply-To: <alpine.DEB.2.00.1006070748180.25592@lynx>
On Mon, Jun 07, 2010 at 07:53:19AM -0400, Robert P. J. Day wrote:
>
> based on a discussion on another mailing list, it would appear that
> this dependency in kernel/sysctl.c is overkill:
>
> #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
> {
> .procname = "hotplug",
> .data = &uevent_helper,
> .maxlen = UEVENT_HELPER_PATH_LEN,
> .mode = 0644,
> .proc_handler = proc_dostring,
> },
> #endif
>
> as someone else explained, there is no need for that CONFIG_NET
> dependency anymore, is there?
Try changing it and building, I think there is a dependancy resolution
problem if it is removed. Look at the commit history for the lines for
details.
> as i read it, you'll already have hotplug support -- all the above
> gives you is the /proc/sys/kernel/hotplug file that allows you to
> override the default setting of /sbin/hotplug, yes?
Yes. Which is pretty obsolete these days anyway.
> in the simple case, if it's feasible, one could just drop that
> second dependency. or if you wanted to make the proc file a truly
> separate config choice, just invent a new Kconfig variable like, say,
> HOTPLUG_PROC_FILE which depends on HOTPLUG.
>
> thoughts?
Is it really worth the change?
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH 1/2] Export firmware assigned labels of network devices to sysfs
From: Matt Domsch @ 2010-06-09 4:17 UTC (permalink / raw)
To: Greg KH
Cc: K, Narendra, netdev@vger.kernel.org,
linux-hotplug@vger.kernel.org, linux-pci@vger.kernel.org,
Hargrave, Jordan, Rose, Charles, Nijhawan, Vijay
In-Reply-To: <20100529045140.GA22563@mdomsch-pws380.aus.amer.dell.com>
On Fri, May 28, 2010 at 11:51:40PM -0500, Domsch, Matt wrote:
> On Fri, May 28, 2010 at 05:27:45PM -0500, Greg KH wrote:
> > Care to post that ECN publically? And no, the Linux Foundation does not
> > have a PCI-SIG membership, the PCI-SIG keeps forbidding it. Other
> > operating systems are allowed to join but not Linux. Strange but
> > true...
>
> I'm looking into it, and should know more next week.
I'm advised that I cannot post the ECN publically, due to it being an
in-progress work item of a SIG working group, and therefore falls
under the confidentiality rules that SIG members agree to. Members of
the PCI SIG have access, which unfortunately is not everyone.
--
Matt Domsch
Technology Strategist
Dell | Office of the CTO
^ permalink raw reply
* Re: [PATCH 1/2] Export firmware assigned labels of network devices
From: Greg KH @ 2010-06-09 15:02 UTC (permalink / raw)
To: Matt Domsch
Cc: K, Narendra, netdev@vger.kernel.org,
linux-hotplug@vger.kernel.org, linux-pci@vger.kernel.org,
Hargrave, Jordan, Rose, Charles, Nijhawan, Vijay
In-Reply-To: <20100609041709.GA7280@auslistsprd01.us.dell.com>
On Tue, Jun 08, 2010 at 11:17:09PM -0500, Matt Domsch wrote:
> On Fri, May 28, 2010 at 11:51:40PM -0500, Domsch, Matt wrote:
> > On Fri, May 28, 2010 at 05:27:45PM -0500, Greg KH wrote:
> > > Care to post that ECN publically? And no, the Linux Foundation does not
> > > have a PCI-SIG membership, the PCI-SIG keeps forbidding it. Other
> > > operating systems are allowed to join but not Linux. Strange but
> > > true...
> >
> > I'm looking into it, and should know more next week.
>
> I'm advised that I cannot post the ECN publically, due to it being an
> in-progress work item of a SIG working group, and therefore falls
> under the confidentiality rules that SIG members agree to. Members of
> the PCI SIG have access, which unfortunately is not everyone.
Then we can't properly review this, sorry. How about waiting until the
ECN is finalized? Then we could review and possibly accept this.
thanks,
greg k-h
^ permalink raw reply
* Questions on udev-acl rules, ACL_MANAGE + bug report
From: Julien BLACHE @ 2010-06-09 17:01 UTC (permalink / raw)
To: linux-hotplug
Hi,
[Please Cc: me on replies, I'm not subscribed]
I am wondering how one is supposed to integrate/interact with udev-acl
outside of its dedicated rules file, as using ACL_MANAGE outside this
file is strictly forbidden.
Setting dedicated variables via other rules to have them checked and
acted upon by the dedicated udev-acl rules seems suboptimal in more than
one way :/
So, what's the long-term plan on this? I've discussed this with Marco
d'Itri, our udev maintainer, and a couple other Debian developers and we
all wonder how this is supposed to work on the long term. Can someone
shed light on this for us, please?
[SANE upstream hat on]
Second point in this mail, the rules used for SCSI scanners by udev-acl
are too broad as they are today; they may match SCSI devices that aren't
scanners (like tape libraries and other SCSI equipment reporting a
control interface with a SCSI type of "Processor", for instance - this
has been seen before).
Instead of duplicating the rules from libsane, I propose to also set
libsane_matched for SCSI scanners starting with the next SANE release
(whenever that happens, and I'd encourage distributors to patch the SANE
rules right now already).
Would that be OK with you?
Thanks,
JB.
--
Julien BLACHE <jblache@debian.org> | Debian, because code matters more
Debian & GNU/Linux Developer | <http://www.debian.org>
Public key available on <http://www.jblache.org> - KeyID: F5D6 5169
GPG Fingerprint : 935A 79F1 C8B3 3521 FD62 7CC7 CD61 4FD7 F5D6 5169
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox