summaryrefslogtreecommitdiff
path: root/src/common_iterator.c
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2012-11-04 06:59:27 -0800
committerAnas Nashif <anas.nashif@intel.com>2012-11-04 06:59:27 -0800
commitb1016de6a14fb7ba64ca78cd8841fe404a8cff61 (patch)
tree5abd357ad4efe9a7fa00dd5b3aca9c3987c7330f /src/common_iterator.c
downloadlibpciaccess-upstream.tar.gz
libpciaccess-upstream.tar.bz2
libpciaccess-upstream.zip
Imported Upstream version 0.13.1upstream/0.13.1upstream
Diffstat (limited to 'src/common_iterator.c')
-rw-r--r--src/common_iterator.c231
1 files changed, 231 insertions, 0 deletions
diff --git a/src/common_iterator.c b/src/common_iterator.c
new file mode 100644
index 0000000..ccf656d
--- /dev/null
+++ b/src/common_iterator.c
@@ -0,0 +1,231 @@
+/*
+ * (C) Copyright IBM Corporation 2006
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file common_iterator.c
+ * Platform independent iterator support routines.
+ *
+ * \author Ian Romanick <idr@us.ibm.com>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "pciaccess.h"
+#include "pciaccess_private.h"
+
+/**
+ * Track device iteration state
+ *
+ * \private
+ */
+struct pci_device_iterator {
+ unsigned next_index;
+
+ enum {
+ match_any,
+ match_slot,
+ match_id
+ } mode;
+
+ union {
+ struct pci_slot_match slot;
+ struct pci_id_match id;
+ } match;
+};
+
+
+/**
+ * Create an iterator based on a regular expression.
+ *
+ * \return
+ * A pointer to a fully initialized \c pci_device_iterator structure on
+ * success, or \c NULL on failure.
+ *
+ * \sa pci_id_match_iterator_create, pci_device_next, pci_iterator_destroy
+ */
+struct pci_device_iterator *
+pci_slot_match_iterator_create( const struct pci_slot_match * match )
+{
+ struct pci_device_iterator * iter;
+
+ if ( pci_sys == NULL ) {
+ return NULL;
+ }
+
+ iter = malloc( sizeof( *iter ) );
+ if ( iter != NULL ) {
+ iter->next_index = 0;
+
+ if ( match != NULL ) {
+ iter->mode = match_slot;
+
+ (void) memcpy( & iter->match.slot, match, sizeof( *match ) );
+ }
+ else {
+ iter->mode = match_any;
+ }
+ }
+
+ return iter;
+}
+
+
+/**
+ * Create an iterator based on a regular expression.
+ *
+ * \return
+ * A pointer to a fully initialized \c pci_device_iterator structure on
+ * success, or \c NULL on failure.
+ *
+ * \sa pci_slot_match_iterator_create, pci_device_next, pci_iterator_destroy
+ */
+struct pci_device_iterator *
+pci_id_match_iterator_create( const struct pci_id_match * match )
+{
+ struct pci_device_iterator * iter;
+
+ if ( pci_sys == NULL ) {
+ return NULL;
+ }
+
+ iter = malloc( sizeof( *iter ) );
+ if ( iter != NULL ) {
+ iter->next_index = 0;
+
+ if ( match != NULL ) {
+ iter->mode = match_id;
+
+ (void) memcpy( & iter->match.id, match, sizeof( *match ) );
+ }
+ else {
+ iter->mode = match_any;
+ }
+ }
+
+ return iter;
+}
+
+
+/**
+ * Destroy an iterator previously created with \c pci_iterator_create.
+ *
+ * \param iter Iterator to be destroyed.
+ *
+ * \sa pci_device_next, pci_iterator_create
+ */
+void
+pci_iterator_destroy( struct pci_device_iterator * iter )
+{
+ if ( iter != NULL ) {
+ free( iter );
+ }
+}
+
+
+/**
+ * Iterate to the next PCI device.
+ *
+ * \param iter Device iterator returned by \c pci_device_iterate.
+ *
+ * \return
+ * A pointer to a \c pci_device, or \c NULL when all devices have been
+ * iterated.
+ */
+struct pci_device *
+pci_device_next( struct pci_device_iterator * iter )
+{
+ struct pci_device_private * d = NULL;
+
+ if (!iter)
+ return NULL;
+
+ switch( iter->mode ) {
+ case match_any:
+ if ( iter->next_index < pci_sys->num_devices ) {
+ d = & pci_sys->devices[ iter->next_index ];
+ iter->next_index++;
+ }
+
+ break;
+
+ case match_slot: {
+ while ( iter->next_index < pci_sys->num_devices ) {
+ struct pci_device_private * const temp =
+ & pci_sys->devices[ iter->next_index ];
+
+ iter->next_index++;
+ if ( PCI_ID_COMPARE( iter->match.slot.domain, temp->base.domain )
+ && PCI_ID_COMPARE( iter->match.slot.bus, temp->base.bus )
+ && PCI_ID_COMPARE( iter->match.slot.dev, temp->base.dev )
+ && PCI_ID_COMPARE( iter->match.slot.func, temp->base.func ) ) {
+ d = temp;
+ break;
+ }
+ }
+
+ break;
+ }
+
+ case match_id: {
+ while ( iter->next_index < pci_sys->num_devices ) {
+ struct pci_device_private * const temp =
+ & pci_sys->devices[ iter->next_index ];
+
+ iter->next_index++;
+ if ( PCI_ID_COMPARE( iter->match.id.vendor_id, temp->base.vendor_id )
+ && PCI_ID_COMPARE( iter->match.id.device_id, temp->base.device_id )
+ && PCI_ID_COMPARE( iter->match.id.subvendor_id, temp->base.subvendor_id )
+ && PCI_ID_COMPARE( iter->match.id.subdevice_id, temp->base.subdevice_id )
+ && ((temp->base.device_class & iter->match.id.device_class_mask)
+ == iter->match.id.device_class) ) {
+ d = temp;
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ return (struct pci_device *) d;
+}
+
+
+struct pci_device *
+pci_device_find_by_slot( uint32_t domain, uint32_t bus, uint32_t dev,
+ uint32_t func )
+{
+ struct pci_device_iterator iter;
+
+
+ iter.next_index = 0;
+ iter.mode = match_slot;
+ iter.match.slot.domain = domain;
+ iter.match.slot.bus = bus;
+ iter.match.slot.dev = dev;
+ iter.match.slot.func = func;
+
+ return pci_device_next( & iter );
+}