From patchwork Fri Jan 8 20:29:53 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Milard X-Patchwork-Id: 59395 Delivered-To: patch@linaro.org Received: by 10.112.130.2 with SMTP id oa2csp754174lbb; Fri, 8 Jan 2016 11:44:35 -0800 (PST) X-Received: by 10.140.18.167 with SMTP id 36mr99626734qgf.38.1452282275865; Fri, 08 Jan 2016 11:44:35 -0800 (PST) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id b15si39852126qge.125.2016.01.08.11.44.35; Fri, 08 Jan 2016 11:44:35 -0800 (PST) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dkim=neutral (body hash did not verify) header.i=@linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 5D8CD61695; Fri, 8 Jan 2016 19:44:35 +0000 (UTC) Authentication-Results: lists.linaro.org; dkim=fail reason="verification failed; unprotected key" header.d=linaro.org header.i=@linaro.org header.b=eqFjrpcG; dkim-adsp=none (unprotected policy); dkim-atps=neutral X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID, URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 7704661CE8; Fri, 8 Jan 2016 19:33:47 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id BF95961CCA; Fri, 8 Jan 2016 19:33:33 +0000 (UTC) Received: from mail-lf0-f42.google.com (mail-lf0-f42.google.com [209.85.215.42]) by lists.linaro.org (Postfix) with ESMTPS id EBAEF617AB for ; Fri, 8 Jan 2016 19:31:45 +0000 (UTC) Received: by mail-lf0-f42.google.com with SMTP id d17so15375181lfb.1 for ; Fri, 08 Jan 2016 11:31:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=kmUEiDj482lwbc7V2V/WfL0eE3rImL6Zutv8JJuF8Vw=; b=eqFjrpcGC2VSVS6HlGaQNyVuaP8U768of4IwicDxy9/q48DErSLQDwuiyZ5UiLKisn LJuKDWuUcmyruIKOS5I2QQKJCs80ePFS+OVbbo+BJeMWSfgEbrv8sIkc+bAEk76i4QBb 4y6uOTua6MgqZOtvDqkE9O07OA76JvX9kga/I= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=kmUEiDj482lwbc7V2V/WfL0eE3rImL6Zutv8JJuF8Vw=; b=hoN/lEISTolIL8eD00n+LaWsUp/owJx0Wbhmru7Rpczga0OmNjJZmdP2T8VkY4Zlr4 n9SuilqWwgjJwZP36DaJBnI/axQwwRbK7co5odKoRtrR/B6faXCYfJFLbZTPkMsmse1R Dkmk0OEpJTAtm6Yk+FiTpRgrEhdMkWDhVw2yKzE6Fo8YPesVO9rMc1j/rHFxNivir4Uh IgSuYqrQkk/sW2lFOg9FQxC5YRjpT1BwtqZpxOdm1Fysgo7dKO3+bCFvsDuN+h9I38Q5 MJFU1wwk4En5KZUILj+XvmQm2PXgOG552R61ykbOm+jhHeQxwUfmGLeJ6caQC57JXeyG LLew== X-Gm-Message-State: ALoCoQkiDrPBe+jw7m2iqPhUKhT1q09Yqte7kFD5opv4Kb/7bpOMfs5LaZXi5ksNo5+BtL2Gb5wukJZUGMkBTzgbZBL9X4XA9A== X-Received: by 10.25.143.143 with SMTP id r137mr37583684lfd.93.1452281504862; Fri, 08 Jan 2016 11:31:44 -0800 (PST) Received: from erachmi-ericsson.ki.sw.ericsson.se (c-83-233-90-46.cust.bredband2.com. [83.233.90.46]) by smtp.gmail.com with ESMTPSA id l204sm2085534lfg.49.2016.01.08.11.31.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 08 Jan 2016 11:31:44 -0800 (PST) From: Christophe Milard To: anders.roxell@linaro.org, mike.holmes@linaro.org, stuart.haslam@linaro.org, maxim.uvarov@linaro.org, bill.fischofer@linaro.org, petri.savolainen@linaro.org, edavis@broadcom.com Date: Fri, 8 Jan 2016 21:29:53 +0100 Message-Id: <1452285014-60320-11-git-send-email-christophe.milard@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1452285014-60320-1-git-send-email-christophe.milard@linaro.org> References: <1452285014-60320-1-git-send-email-christophe.milard@linaro.org> Cc: lng-odp@lists.linaro.org Subject: [lng-odp] [API-NEXT RFC 10/31] linux-generic: generic PCI implementation X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" This implementation just acts as a simple wrapper around pci-vfio. This could grow if other pci access (such as user-io) get involved. Signed-off-by: Christophe Milard --- platform/linux-generic/Makefile.am | 1 + platform/linux-generic/odp_pci.c | 190 +++++++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 platform/linux-generic/odp_pci.c diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 6a08811..999c932 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -139,6 +139,7 @@ __LIB__libodp_la_SOURCES = \ odp_packet.c \ odp_packet_flags.c \ odp_packet_io.c \ + odp_pci.c \ odp_pci_vfio.c \ pktio/io_ops.c \ pktio/pktio_common.c \ diff --git a/platform/linux-generic/odp_pci.c b/platform/linux-generic/odp_pci.c new file mode 100644 index 0000000..7cce69f --- /dev/null +++ b/platform/linux-generic/odp_pci.c @@ -0,0 +1,190 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices" + +/* operations on PCI devices: */ + +uint16_t odp_pci_get_vendor(odp_pci_dev_t dev_hdl) +{ + return ((pci_dev_t *)dev_hdl)->pci_id.vendor_id; +} + +uint16_t odp_pci_get_device(odp_pci_dev_t dev_hdl) +{ + return ((pci_dev_t *)dev_hdl)->pci_id.device_id; +} + +uint16_t odp_pci_get_subsystem_vendor(odp_pci_dev_t dev_hdl) +{ + return ((pci_dev_t *)dev_hdl)->pci_id.subsystem_vendor_id; +} + +uint16_t odp_pci_get_subsystem_device(odp_pci_dev_t dev_hdl) +{ + return ((pci_dev_t *)dev_hdl)->pci_id.subsystem_device_id; +} + +void *odp_pci_get_resource_addr(odp_pci_dev_t dev_hdl, int bar) +{ + return ((pci_dev_t *)dev_hdl)->bar_maps[bar].addr; +} + +char *odp_pci_get_addr_str(odp_pci_dev_t dev_hdl) +{ + return ((pci_dev_t *)dev_hdl)->pci_address; +} + +/* + * parse a sysfs (or other) file containing one integer value + */ +static int parse_sysfs_value(const char *filename, unsigned long *val) +{ + FILE *f; + char buf[BUFSIZ]; + char *end = NULL; + + f = fopen(filename, "r"); + if (!f) { + ODP_ERR("%s(): cannot open sysfs value %s\n", + __func__, filename); + return -1; + } + + if (fgets(buf, sizeof(buf), f) == NULL) { + ODP_ERR("%s(): cannot read sysfs value %s\n", + __func__, filename); + fclose(f); + return -1; + } + *val = strtoul(buf, &end, 0); + if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) { + ODP_ERR("%s(): cannot parse sysfs value %s\n", + __func__, filename); + fclose(f); + return -1; + } + fclose(f); + return 0; +} + +odp_pci_dev_t _odp_pci_init(const char *pci_addr) +{ + char filename[PATH_MAX]; + unsigned long tmp; + pci_dev_t *dev; + + dev = malloc(sizeof(pci_dev_t)); + if (!dev) + return NULL; + + /* currentely only vfio is supported */ + if (_odp_pci_vfio_init(pci_addr, dev) < 0) + goto pci_init_err; + + /* get vendor id */ + snprintf(filename, sizeof(filename), SYSFS_PCI_DEVICES "/%s/vendor", + pci_addr); + if (parse_sysfs_value(filename, &tmp) < 0) + goto pci_init_err; + + dev->pci_id.vendor_id = (uint16_t)tmp; + + /* get device id */ + snprintf(filename, sizeof(filename), SYSFS_PCI_DEVICES "/%s/device", + pci_addr); + if (parse_sysfs_value(filename, &tmp) < 0) + goto pci_init_err; + + dev->pci_id.device_id = (uint16_t)tmp; + + /* get subsystem_vendor id */ + snprintf(filename, sizeof(filename), + SYSFS_PCI_DEVICES "/%s/subsystem_vendor", + pci_addr); + if (parse_sysfs_value(filename, &tmp) < 0) + goto pci_init_err; + + dev->pci_id.subsystem_vendor_id = (uint16_t)tmp; + + /* get subsystem_device id */ + snprintf(filename, sizeof(filename), + SYSFS_PCI_DEVICES "/%s/subsystem_device", + pci_addr); + if (parse_sysfs_value(filename, &tmp) < 0) + goto pci_init_err; + + dev->pci_id.subsystem_device_id = (uint16_t)tmp; + + return (odp_pci_dev_t)dev; + +pci_init_err: + free(dev); + return NULL; +} + +void _odp_pci_release(odp_pci_dev_t pci_dev) +{ + /* currentely only vfio is supported */ + _odp_pci_vfio_release((pci_dev_t *)pci_dev); + free(pci_dev); +} + +int odp_pci_map_dma_region(odp_pci_dev_t dev_hdl, + odp_dma_map_t region) +{ + pci_dev_t *dev = (pci_dev_t *)dev_hdl; + dma_map_t *map_s = dma_map_handle_to_map(region); + + /* map fragments one by one */ + /* currentely only vfio is supported */ + do { + if (_odp_pci_vfio_map_dma_region_f(dev, map_s)) { + /* remove partially mapped region: */ + odp_pci_unmap_dma_region(dev_hdl, region); + return -1; + } + map_s = map_s->next; + } while (map_s); + + return 0; +} + +int odp_pci_unmap_dma_region(odp_pci_dev_t dev_hdl, + odp_dma_map_t region) +{ + pci_dev_t *dev = (pci_dev_t *)dev_hdl; + dma_map_t *map_s = dma_map_handle_to_map(region); + + /* unmap fragments one by one */ + /* currentely only vfio is supported */ + do { + _odp_pci_vfio_unmap_dma_region_f(dev, map_s); + map_s = map_s->next; + } while (map_s); + + return 0; +} + +int odp_pci_read_config(odp_pci_dev_t dev, void *buf, size_t len, int offs) +{ + return _odp_pci_vfio_read_config((pci_dev_t *)dev, buf, len, offs); +} + +int odp_pci_write_config(odp_pci_dev_t dev, const void *buf, + size_t len, int offs) +{ + return _odp_pci_vfio_write_config((pci_dev_t *)dev, buf, len, offs); +}