All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Marc-André Lureau" <mlureau@redhat.com>
To: Marcel Apfelbaum <marcel@redhat.com>
Cc: "Marc-André Lureau" <marcandre.lureau@redhat.com>,
	qemu-devel@nongnu.org, mst@redhat.com
Subject: Re: [Qemu-devel] [PATCHv2] cutils: factor out pci_host_device_address_parse()
Date: Thu, 16 Feb 2017 07:08:10 -0500 (EST)	[thread overview]
Message-ID: <783754281.5755288.1487246890217.JavaMail.zimbra@redhat.com> (raw)
In-Reply-To: <352f44a4-e9be-f97d-ac26-f5d84c7dbe38@redhat.com>

Hi

----- Original Message -----
> On 02/16/2017 01:19 PM, Marc-André Lureau wrote:
> > Hi
> >
> > ----- Original Message -----
> >> On 02/16/2017 12:58 PM, Marc-André Lureau wrote:
> >>> This will allow the function to be used outside of QOM properties.
> >>>
> >>
> >> Hi Mark-Andre,
> >>
> >> I am not sure cutil.h is the right header for the function, because is too
> >> PCI
> >> related for a utility library.
> >
> > It's in the pci.h header, implementation and test is put in
> > {test-,}cutils.c
> >
> 
> sorry about the miss-match, I war referring to the implementation.
> 
> > I can try to put it in pci/pci.c, but it will be harder to link to for
> > testing (note: I haven't tried). I could also put it in a seperate
> > pci-parse.c for example.
> 
> no need for a new file, but hw/pci/pci_host.c should be a good place.

It pulls in pci/pci.c for pci_find_device() and friends, plus type registration etc.

I'll move it to a standalone pci/pci-util.c

> 
> regarding the tests, an new pci test file would be welcomed.
> 
> >
> >
> >> Also, maybe we can post the patch together with the code that uses the
> >> exposed function.
> >
> > I dropped the patch using it for now, but I thought it would still be nice
> > to have the test, doc and strtoul change.
> >
> 
> I agree if Michael has nothing against this.
> 
> Thanks,
> Marcel
> 
> >>
> >> And thanks for the unit-tests, much appreciated!
> >
> > thanks
> >
> >> Marcel
> >>
> >>> Add tests and replace strtoul usage for qemu_strtoul while touching it.
> >>>
> >>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> >>> ---
> >>> v2:
> >>>  - fixed incompatible type warning/error
> >>>
> >>> include/hw/pci/pci.h      | 12 ++++++++++
> >>>  hw/core/qdev-properties.c | 61
> >>>  +++--------------------------------------------
> >>>  tests/test-cutils.c       | 46 +++++++++++++++++++++++++++++++++++
> >>>  util/cutils.c             | 59
> >>>  +++++++++++++++++++++++++++++++++++++++++++++
> >>>  4 files changed, 120 insertions(+), 58 deletions(-)
> >>>
> >>> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> >>> index cbc1fdfb5b..61718080ea 100644
> >>> --- a/include/hw/pci/pci.h
> >>> +++ b/include/hw/pci/pci.h
> >>> @@ -815,4 +815,16 @@ extern const VMStateDescription vmstate_pci_device;
> >>>
> >>>  MSIMessage pci_get_msi_message(PCIDevice *dev, int vector);
> >>>
> >>> +/**
> >>> + * pci_host_device_address_parse:
> >>> + * @str: string to parse
> >>> + * @addr: destination structure or NULL
> >>> + *
> >>> + * Parse [<domain>:]<bus>:<slot>.<func>
> >>> + *   if <domain> is not supplied, it's assumed to be 0.
> >>> + *
> >>> + * Returns: -1 on failure, 0 on success.
> >>> + */
> >>> +int pci_host_device_address_parse(const char *str, PCIHostDeviceAddress
> >>> *addr);
> >>> +
> >>>  #endif
> >>> diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
> >>> index 6ab4265eb4..5dd0774e88 100644
> >>> --- a/hw/core/qdev-properties.c
> >>> +++ b/hw/core/qdev-properties.c
> >>> @@ -722,10 +722,6 @@ static void get_pci_host_devaddr(Object *obj,
> >>> Visitor
> >>> *v, const char *name,
> >>>      visit_type_str(v, name, &p, errp);
> >>>  }
> >>>
> >>> -/*
> >>> - * Parse [<domain>:]<bus>:<slot>.<func>
> >>> - *   if <domain> is not supplied, it's assumed to be 0.
> >>> - */
> >>>  static void set_pci_host_devaddr(Object *obj, Visitor *v, const char
> >>>  *name,
> >>>                                   void *opaque, Error **errp)
> >>>  {
> >>> @@ -733,11 +729,7 @@ static void set_pci_host_devaddr(Object *obj,
> >>> Visitor
> >>> *v, const char *name,
> >>>      Property *prop = opaque;
> >>>      PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
> >>>      Error *local_err = NULL;
> >>> -    char *str, *p;
> >>> -    char *e;
> >>> -    unsigned long val;
> >>> -    unsigned long dom = 0, bus = 0;
> >>> -    unsigned int slot = 0, func = 0;
> >>> +    char *str;
> >>>
> >>>      if (dev->realized) {
> >>>          qdev_prop_set_after_realize(dev, name, errp);
> >>> @@ -750,58 +742,11 @@ static void set_pci_host_devaddr(Object *obj,
> >>> Visitor
> >>> *v, const char *name,
> >>>          return;
> >>>      }
> >>>
> >>> -    p = str;
> >>> -    val = strtoul(p, &e, 16);
> >>> -    if (e == p || *e != ':') {
> >>> -        goto inval;
> >>> -    }
> >>> -    bus = val;
> >>> -
> >>> -    p = e + 1;
> >>> -    val = strtoul(p, &e, 16);
> >>> -    if (e == p) {
> >>> -        goto inval;
> >>> -    }
> >>> -    if (*e == ':') {
> >>> -        dom = bus;
> >>> -        bus = val;
> >>> -        p = e + 1;
> >>> -        val = strtoul(p, &e, 16);
> >>> -        if (e == p) {
> >>> -            goto inval;
> >>> -        }
> >>> -    }
> >>> -    slot = val;
> >>> -
> >>> -    if (*e != '.') {
> >>> -        goto inval;
> >>> +    if (!pci_host_device_address_parse(str, addr)) {
> >>> +        error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> >>>      }
> >>> -    p = e + 1;
> >>> -    val = strtoul(p, &e, 10);
> >>> -    if (e == p) {
> >>> -        goto inval;
> >>> -    }
> >>> -    func = val;
> >>> -
> >>> -    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
> >>> -        goto inval;
> >>> -    }
> >>> -
> >>> -    if (*e) {
> >>> -        goto inval;
> >>> -    }
> >>> -
> >>> -    addr->domain = dom;
> >>> -    addr->bus = bus;
> >>> -    addr->slot = slot;
> >>> -    addr->function = func;
> >>>
> >>>      g_free(str);
> >>> -    return;
> >>> -
> >>> -inval:
> >>> -    error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
> >>> -    g_free(str);
> >>>  }
> >>>
> >>>  PropertyInfo qdev_prop_pci_host_devaddr = {
> >>> diff --git a/tests/test-cutils.c b/tests/test-cutils.c
> >>> index 20b0f59ba2..81c4f072f3 100644
> >>> --- a/tests/test-cutils.c
> >>> +++ b/tests/test-cutils.c
> >>> @@ -28,6 +28,7 @@
> >>>  #include "qemu/osdep.h"
> >>>
> >>>  #include "qemu/cutils.h"
> >>> +#include "hw/pci/pci.h"
> >>>
> >>>  static void test_parse_uint_null(void)
> >>>  {
> >>> @@ -1437,6 +1438,46 @@ static void test_qemu_strtosz_suffix_unit(void)
> >>>      g_assert_cmpint(res, ==, 12345000);
> >>>  }
> >>>
> >>> +static void test_pci_parse_valid(void)
> >>> +{
> >>> +    PCIHostDeviceAddress addr = { 0xff, 0xff, 0xff, 0xff };
> >>> +    int i, res;
> >>> +    const struct {
> >>> +        const char *str;
> >>> +        PCIHostDeviceAddress addr;
> >>> +    } tests[] = {
> >>> +        { "1:2.3", { 0, 1, 2, 3 } },
> >>> +        { "4:1:2.3", { 4, 1, 2, 3 } },
> >>> +        { "a:a:a.7", { 10, 10, 10, 7 } },
> >>> +    };
> >>> +
> >>> +    for (i = 0; i < ARRAY_SIZE(tests); i++) {
> >>> +        res = pci_host_device_address_parse(tests[i].str, &addr);
> >>> +        g_assert_cmpint(res, ==, 0);
> >>> +
> >>> +        g_assert_cmpint(addr.domain, ==, tests[i].addr.domain);
> >>> +        g_assert_cmpint(addr.bus, ==, tests[i].addr.bus);
> >>> +        g_assert_cmpint(addr.slot, ==, tests[i].addr.slot);
> >>> +        g_assert_cmpint(addr.function, ==, tests[i].addr.function);
> >>> +    }
> >>> +}
> >>> +
> >>> +static void test_pci_parse_invalid(void)
> >>> +{
> >>> +    int i, res;
> >>> +    const char *tests[] =  {
> >>> +        "", "foo", "1:2.3 foo",
> >>> +        "a:a:a.a",
> >>> +        "1", "1:", "1:2", "1:2:", "1:2:3", ":1:2:3.",
> >>> +        "-1:1:2.3", "-1:2.3", "1:-1.3", "1:2.-3",
> >>> +        "0x10000:1:1.1", "0x100:1.1", "1:0x20.1", "1:1.8" };
> >>> +
> >>> +    for (i = 0; i < ARRAY_SIZE(tests); i++) {
> >>> +        res = pci_host_device_address_parse(tests[i], NULL);
> >>> +        g_assert_cmpint(res, ==, -1);
> >>> +    }
> >>> +}
> >>> +
> >>>  int main(int argc, char **argv)
> >>>  {
> >>>      g_test_init(&argc, &argv, NULL);
> >>> @@ -1598,5 +1639,10 @@ int main(int argc, char **argv)
> >>>      g_test_add_func("/cutils/strtosz/suffix-unit",
> >>>                      test_qemu_strtosz_suffix_unit);
> >>>
> >>> +    g_test_add_func("/cutils/pci-parse/valid",
> >>> +                    test_pci_parse_valid);
> >>> +    g_test_add_func("/cutils/pci-parse/invalid",
> >>> +                    test_pci_parse_invalid);
> >>> +
> >>>      return g_test_run();
> >>>  }
> >>> diff --git a/util/cutils.c b/util/cutils.c
> >>> index 4fefcf3be3..fc71c85816 100644
> >>> --- a/util/cutils.c
> >>> +++ b/util/cutils.c
> >>> @@ -29,6 +29,7 @@
> >>>  #include "qemu/sockets.h"
> >>>  #include "qemu/iov.h"
> >>>  #include "net/net.h"
> >>> +#include "hw/pci/pci.h"
> >>>  #include "qemu/cutils.h"
> >>>
> >>>  void strpadcpy(char *buf, int buf_size, const char *str, char pad)
> >>> @@ -594,3 +595,61 @@ const char *qemu_ether_ntoa(const MACAddr *mac)
> >>>
> >>>      return ret;
> >>>  }
> >>> +
> >>> +int pci_host_device_address_parse(const char *str, PCIHostDeviceAddress
> >>> *addr)
> >>> +{
> >>> +    const char *p = str;
> >>> +    const char *e;
> >>> +    unsigned long val;
> >>> +    unsigned int dom = 0, bus = 0;
> >>> +    unsigned int slot = 0, func = 0;
> >>> +
> >>> +    if (qemu_strtoul(p, &e, 16, &val) < 0
> >>> +        || e == p || *e != ':') {
> >>> +        return -1;
> >>> +    }
> >>> +    bus = val;
> >>> +
> >>> +    p = e + 1;
> >>> +    if (qemu_strtoul(p, &e, 16, &val) < 0
> >>> +        || e == p) {
> >>> +        return -1;
> >>> +    }
> >>> +    if (*e == ':') {
> >>> +        dom = bus;
> >>> +        bus = val;
> >>> +        p = e + 1;
> >>> +        if (qemu_strtoul(p, &e, 16, &val) < 0
> >>> +            || e == p) {
> >>> +            return -1;
> >>> +        }
> >>> +    }
> >>> +    slot = val;
> >>> +
> >>> +    if (*e != '.') {
> >>> +        return -1;
> >>> +    }
> >>> +    p = e + 1;
> >>> +    if (qemu_strtoul(p, &e, 10, &val) < 0
> >>> +        || e == p) {
> >>> +        return -1;
> >>> +    }
> >>> +    func = val;
> >>> +
> >>> +    if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
> >>> +        return -1;
> >>> +    }
> >>> +
> >>> +    if (*e) {
> >>> +        return -1;
> >>> +    }
> >>> +
> >>> +    if (addr) {
> >>> +        addr->domain = dom;
> >>> +        addr->bus = bus;
> >>> +        addr->slot = slot;
> >>> +        addr->function = func;
> >>> +    }
> >>> +
> >>> +    return 0;
> >>> +}
> >>>
> >>
> >>
> 
> 

  reply	other threads:[~2017-02-16 12:08 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-16 10:58 [Qemu-devel] [PATCHv2] cutils: factor out pci_host_device_address_parse() Marc-André Lureau
2017-02-16 11:13 ` Marcel Apfelbaum
2017-02-16 11:19   ` Marc-André Lureau
2017-02-16 11:30     ` Marcel Apfelbaum
2017-02-16 12:08       ` Marc-André Lureau [this message]
2017-02-16 14:37 ` Michael S. Tsirkin
2017-02-16 15:07   ` Marc-André Lureau
2017-02-16 15:29     ` Michael S. Tsirkin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=783754281.5755288.1487246890217.JavaMail.zimbra@redhat.com \
    --to=mlureau@redhat.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=marcel@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.