abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * CDDL HEADER START
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * The contents of this file are subject to the terms of the
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * Common Development and Distribution License (the "License").
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * You may not use this file except in compliance with the License.
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * or http://www.opensolaris.org/os/licensing.
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * See the License for the specific language governing permissions
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * and limitations under the License.
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * When distributing Covered Code, include this CDDL HEADER in each
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * If applicable, add the following below this CDDL HEADER, with the
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * fields enclosed by brackets "[]" replaced with your own identifying
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * information: Portions Copyright [yyyy] [name of copyright owner]
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * CDDL HEADER END
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * Copyright (c) 2012, Joyent, Inc. All rights reserved.
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * This library exists to understand and parse the pci.ids database that is
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * maintained at http://pci-ids.ucw.cz/ and in the gate at cmd/hwdata. This
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * database provides a way to map the PCI device, vendor, and subsystem ids to
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * a human understandable name.
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * This library exports this data in a similar way to a tree. The handle that
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * is returned from pcidb_open is the root of the tree. The next level are the
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * vendors. Each vendor has a unique set of devices and each device has a unique
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * set of subvendor and subdevice pairs.
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * Parsing information:
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * The database is formatted in the following basic format:
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * vendor_id<two spaces>vendor_name
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * <tab>device_id<two spaces>device_name
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * <tab><tab>subvendor<space>subdevice<two spaces>subsystem_name
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * For any given vendor, there can be multiple devices. And for any given device
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * there will be multiple subsystems. In addition, there can be comments that
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * start a line which use the '#' character.
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * At the end of the file, there are a series of PCI classes. Those will start
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * with a single C<space>. Once we hit those, we stop all parsing. We currently
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi * don't care about consuming or presenting those.
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi/* Forward declarations */
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchistatic const char *pci_db = "/usr/share/hwdata/pci.ids";
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchipcihdl_add_vendor(pcidb_hdl_t *hdl, pcidb_vendor_t *v)
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi if (hdl->ph_vstart == NULL && hdl->ph_vend == NULL) {
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi (void) strlcpy(v->pv_name, buf, PCI_NAME_MAX);
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchiinsert_device(pcidb_vendor_t *v, pcidb_device_t *d)
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi if (v->pv_dstart == NULL && v->pv_dend == NULL) {
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi (void) strlcpy(d->pd_name, buf, PCI_NAME_MAX);
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchiinsert_subdev(pcidb_device_t *d, pcidb_subvd_t *s)
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi (void) strlcpy(s->ps_name, buf, PCI_NAME_MAX);
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi if (parse_db(f, h) < 0) {
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi while (v != NULL) {
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi while (d != NULL) {
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi while (s != NULL) {
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchipcidb_lookup_vendor(pcidb_hdl_t *hdl, uint16_t id)
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi for (v = hdl->ph_vstart; v != NULL; v = v->pv_next) {
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchipcidb_lookup_device_by_vendor(pcidb_vendor_t *v, uint16_t id)
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi for (d = v->pv_dstart; d != NULL; d = d->pd_next)
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchipcidb_lookup_device(pcidb_hdl_t *h, uint16_t vid, uint16_t did)
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi return (pcidb_lookup_device_by_vendor(v, did));
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchipcidb_lookup_subvd_by_device(pcidb_device_t *d, uint16_t svid, uint16_t sdid)
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi for (s = d->pd_sstart; s != NULL; s = s->ps_next)
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi if (s->ps_vid == svid && s->ps_did == sdid)
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchipcidb_lookup_subvd_by_vendor(pcidb_vendor_t *v, uint16_t devid, uint16_t svid,
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi d = pcidb_lookup_device_by_vendor(v, devid);
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchi return (pcidb_lookup_subvd_by_device(d, svid, sdid));
abc79d9dd51e98eafb6fc25b4a0b4f66bef40b00Robert Mustacchipcidb_lookup_subvd(pcidb_hdl_t *h, uint16_t vid, uint16_t did, uint16_t svid,