Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144738933
D26598.id82331.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
21 KB
Referenced Files
None
Subscribers
None
D26598.id82331.diff
View Options
Index: sys/compat/linuxkpi/common/include/asm/unaligned.h
===================================================================
--- /dev/null
+++ sys/compat/linuxkpi/common/include/asm/unaligned.h
@@ -0,0 +1,78 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 The FreeBSD Foundation
+ *
+ * This software was developed by Björn Zeeb under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _ASM_UNALIGNED_H
+#define _ASM_UNALIGNED_H
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+static __inline uint32_t
+get_unaligned_le32(const void *p)
+{
+
+ return (le32_to_cpup((const __le32 *)p));
+}
+
+static __inline void
+put_unaligned_le32(__le32 v, void *p)
+{
+ __le32 x;
+
+ x = cpu_to_le32(v);
+ memcpy(p, &x, sizeof(x));
+}
+
+static __inline void
+put_unaligned_le64(__le64 v, void *p)
+{
+ __le64 x;
+
+ x = cpu_to_le64(v);
+ memcpy(p, &x, sizeof(x));
+}
+
+static __inline uint16_t
+get_unaligned_be16(const void *p)
+{
+
+ return (be16_to_cpup((const __be16 *)p));
+}
+
+static __inline uint32_t
+get_unaligned_be32(const void *p)
+{
+
+ return (be32_to_cpup((const __be32 *)p));
+}
+
+#endif /* _ASM_UNALIGNED_H */
Index: sys/compat/linuxkpi/common/include/linux/device.h
===================================================================
--- sys/compat/linuxkpi/common/include/linux/device.h
+++ sys/compat/linuxkpi/common/include/linux/device.h
@@ -562,5 +562,47 @@
char *kvasprintf(gfp_t, const char *, va_list);
char *kasprintf(gfp_t, const char *, ...);
+char *lkpi_devm_kasprintf(struct device *, gfp_t, const char *, ...);
+
+#define devm_kasprintf(_dev, _gfp, _fmt, ...) \
+ lkpi_devm_kasprintf(_dev, _gfp, _fmt, ##__VA_ARGS__)
+
+void *lkpi_devres_alloc(void(*release)(struct device *, void *), size_t, gfp_t);
+void lkpi_devres_add(struct device *, void *);
+void lkpi_devres_free(void *);
+void *lkpi_devres_find(struct device *, void(*release)(struct device *, void *),
+ int (*match)(struct device *, void *, void *), void *);
+int lkpi_devres_destroy(struct device *, void(*release)(struct device *, void *),
+ int (*match)(struct device *, void *, void *), void *);
+#define devres_alloc(_r, _s, _g) lkpi_devres_alloc(_r, _s, _g)
+#define devres_add(_d, _p) lkpi_devres_add(_d, _p)
+#define devres_free(_p) lkpi_devres_free(_p)
+#define devres_find(_d, _rfn, _mfn, _mp) \
+ lkpi_devres_find(_d, _rfn, _mfn, _mp)
+#define devres_destroy(_d, _rfn, _mfn, _mp) \
+ lkpi_devres_destroy(_d, _rfn, _mfn, _mp)
+
+/* LinuxKPI internal functions. */
+void lkpi_devres_release_free_list(struct device *);
+void lkpi_devres_unlink(struct device *, void *);
+void lkpi_devm_kmalloc_release(struct device *, void *);
+
+static __inline void *
+devm_kmalloc(struct device *dev, size_t size, gfp_t gfp)
+{
+ void *p;
+
+ p = lkpi_devres_alloc(lkpi_devm_kmalloc_release, size, gfp);
+ if (p != NULL)
+ lkpi_devres_add(dev, p);
+
+ return (p);
+}
+
+#define devm_kzalloc(_dev, _size, _gfp) \
+ devm_kmalloc((_dev), (_size), (_gfp) | __GFP_ZERO)
+
+#define devm_kcalloc(_dev, _sizen, _size, _gfp) \
+ devm_kmalloc((_dev), ((_sizen) * (_size)), (_gfp) | __GFP_ZERO)
#endif /* _LINUX_DEVICE_H_ */
Index: sys/compat/linuxkpi/common/include/linux/kernel.h
===================================================================
--- sys/compat/linuxkpi/common/include/linux/kernel.h
+++ sys/compat/linuxkpi/common/include/linux/kernel.h
@@ -593,4 +593,45 @@
#define TAINT_WARN 0
#define test_taint(x) (0)
+/*
+ * Checking if an option is defined would be easy if we could do CPP inside CPP.
+ * The defined case whether -Dxxx or -Dxxx=1 are easy to deal with. In either
+ * case the defined value is "1". A more general -Dxxx=<c> case will require
+ * more effort to deal with all possible "true" values. Hope we do not have
+ * to do this as well.
+ * The real problem is the undefined case. To avoid this problem we do the
+ * concat/varargs trick: "yyy" ## xxx can make two arguments if xxx is "1"
+ * by having a #define for yyy_1 which is "ignore,".
+ * Otherwise we will just get "yyy".
+ * Need to be careful about variable substitutions in macros though.
+ * This way we make a (true, false) problem a (don't care, true, false) or a
+ * (don't care true, false). Then we can use a variadic macro to only select
+ * the always well known and defined argument #2. And that seems to be
+ * exactly what we need.
+ */
+#define ___XAB_1 dontcare,
+#define ___IS_XAB(_ignore, _x, ...) (_x)
+#define __IS_XAB(_x) ___IS_XAB(_x true, false)
+#define _IS_XAB(_x) __IS_XAB(__CONCAT(___XAB_, _x))
+
+/* This is if CONFIG_ccc=y. */
+#define IS_BUILTIN(_x) _IS_XAB(_x)
+/* This is if CONFIG_ccc=m. */
+#define IS_MODULE(_x) _IS_XAB(_x ## _MODULE)
+/* This is if CONFIG_ccc is compiled in(=y) or a module(=m). */
+#define IS_ENABLED(_x) (IS_BUILTIN(_x) || IS_MODULE(_x))
+/*
+ * This is weird case. If the CONFIG_ccc is builtin (=y) this returns true;
+ * or if the CONFIG_ccc is a module (=m) and the caller is built as a module
+ * (-DMODULE defined) this returns true, but if the callers is not a module
+ * (-DMODULE not defined, which means caller is BUILTIN) then it returns
+ * false. In other words, a module can reach the kernel, a module can reach
+ * a module, but the kernel cannot reach a module, and code never compiled
+ * cannot be reached either.
+ * XXX -- I'd hope the module-to-module case would be handled by a proper
+ * module dependency definition (MODULE_DEPEND() in FreeBSD).
+ */
+#define IS_REACHABLE(_x) (IS_BUILTIN(_x) || \
+ (IS_MODULE(_x) && IS_BUILTIN(MODULE)))
+
#endif /* _LINUX_KERNEL_H_ */
Index: sys/compat/linuxkpi/common/include/linux/kobject.h
===================================================================
--- sys/compat/linuxkpi/common/include/linux/kobject.h
+++ sys/compat/linuxkpi/common/include/linux/kobject.h
@@ -41,6 +41,8 @@
struct kobject;
struct sysctl_oid;
+#define KOBJ_CHANGE 0x01
+
struct kobj_type {
void (*release)(struct kobject *kobj);
const struct sysfs_ops *sysfs_ops;
@@ -151,4 +153,16 @@
int kobject_init_and_add(struct kobject *kobj, const struct kobj_type *ktype,
struct kobject *parent, const char *fmt, ...);
+static __inline void
+kobject_uevent_env(struct kobject *kobj, int action, char *envp[])
+{
+
+ /*
+ * iwlwifi(4) sends an INACCESSIBLE event when it detects that the card
+ * (pice endpoint) is gone and it attempts a removal cleanup.
+ * Not sure if we do anything related to udev/sysfs at the moment or
+ * need a shortcut or simply ignore it (for now).
+ */
+}
+
#endif /* _LINUX_KOBJECT_H_ */
Index: sys/compat/linuxkpi/common/include/linux/lockdep.h
===================================================================
--- sys/compat/linuxkpi/common/include/linux/lockdep.h
+++ sys/compat/linuxkpi/common/include/linux/lockdep.h
@@ -42,6 +42,7 @@
#define lockdep_set_class_and_name(lock, key, name)
#define lockdep_set_current_reclaim_state(g) do { } while (0)
#define lockdep_clear_current_reclaim_state() do { } while (0)
+#define lockdep_init_map(_map, _name, _key, _x) do { } while(0)
#ifdef INVARIANTS
#define lockdep_assert_held(m) do { \
Index: sys/compat/linuxkpi/common/include/linux/pci.h
===================================================================
--- sys/compat/linuxkpi/common/include/linux/pci.h
+++ sys/compat/linuxkpi/common/include/linux/pci.h
@@ -338,6 +338,14 @@
dev_set_drvdata(&pdev->dev, data);
}
+static __inline void
+pci_dev_put(struct pci_dev *pdev)
+{
+
+ if (pdev != NULL)
+ put_device(&pdev->dev);
+}
+
static inline int
pci_enable_device(struct pci_dev *pdev)
{
@@ -1094,7 +1102,7 @@
pci_domain_nr(struct pci_bus *pbus)
{
- return (pci_get_domain(pbus->self->dev.bsddev));
+ return (pbus->domain);
}
static inline int
Index: sys/compat/linuxkpi/common/include/linux/pm.h
===================================================================
--- /dev/null
+++ sys/compat/linuxkpi/common/include/linux/pm.h
@@ -0,0 +1,52 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 The FreeBSD Foundation
+ *
+ * This software was developed by Björn Zeeb under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LINUXKPI_LINUX_PM_H
+#define _LINUXKPI_LINUX_PM_H
+
+#ifdef CONFIG_PM_SLEEP
+#define SIMPLE_DEV_PM_OPS(_name, _suspendfunc, _resumefunc) \
+const struct dev_pm_ops _name = { \
+ .suspend = _suspendfunc, \
+ .resume = _resumefunc, \
+ .freeze = _suspendfunc, \
+ .thaw = _resumefunc, \
+ .poweroff = _suspendfunc, \
+ .restore = _resumefunc, \
+}
+#else
+#define SIMPLE_DEV_PM_OPS(_name, _suspendfunc, _resumefunc) \
+const struct dev_pm_ops _name = { \
+}
+#endif
+
+#endif /* _LINUXKPI_LINUX_PM_H */
Index: sys/compat/linuxkpi/common/include/linux/scatterlist.h
===================================================================
--- sys/compat/linuxkpi/common/include/linux/scatterlist.h
+++ sys/compat/linuxkpi/common/include/linux/scatterlist.h
@@ -32,6 +32,9 @@
#ifndef _LINUX_SCATTERLIST_H_
#define _LINUX_SCATTERLIST_H_
+#include <sys/types.h>
+#include <sys/sf_buf.h>
+
#include <linux/page.h>
#include <linux/slab.h>
#include <linux/mm.h>
@@ -479,4 +482,55 @@
return (nth_page(sg_page(piter->sg), piter->sg_pgoffset));
}
+static __inline size_t
+sg_pcopy_from_buffer(struct scatterlist *sgl, unsigned int nents,
+ const void *buf, size_t buflen, off_t skip)
+{
+ struct sg_page_iter piter;
+ struct page *page;
+ struct sf_buf *sf;
+ size_t len, copied;
+ char *p, *b;
+
+ if (buflen == 0)
+ return (0);
+
+ b = __DECONST(char *, buf);
+ copied = 0;
+ sched_pin();
+ for_each_sg_page(sgl, &piter, nents, 0) {
+
+ /* Skip to the start. */
+ if (piter.sg->length <= skip) {
+ skip -= piter.sg->length;
+ continue;
+ }
+
+ /* See how much to copy. */
+ KASSERT(((piter.sg->length - skip) != 0 && (buflen != 0)),
+ ("%s: sg len %u - skip %ju || buflen %zu is 0\n",
+ __func__, piter.sg->length, (uintmax_t)skip, buflen));
+ len = min(piter.sg->length - skip, buflen);
+
+ page = sg_page_iter_page(&piter);
+ sf = sf_buf_alloc(page, SFB_CPUPRIVATE | SFB_NOWAIT);
+ if (sf == NULL)
+ break;
+ p = (char *)sf_buf_kva(sf) + piter.sg_pgoffset + skip;
+ memcpy(p, b, len);
+ sf_buf_free(sf);
+
+ copied += len;
+ /* Either we exactly filled the page, or we are done. */
+ buflen -= len;
+ if (buflen == 0)
+ break;
+ skip -= len;
+ b += len;
+ }
+ sched_unpin();
+
+ return (copied);
+}
+
#endif /* _LINUX_SCATTERLIST_H_ */
Index: sys/compat/linuxkpi/common/src/linux_compat.c
===================================================================
--- sys/compat/linuxkpi/common/src/linux_compat.c
+++ sys/compat/linuxkpi/common/src/linux_compat.c
@@ -3,8 +3,13 @@
* Copyright (c) 2010 iX Systems, Inc.
* Copyright (c) 2010 Panasas, Inc.
* Copyright (c) 2013-2018 Mellanox Technologies, Ltd.
+ * Copyright (c) 2020 The FreeBSD Foundation
+ *
* All rights reserved.
*
+ * This software was developed by Bj\xc3\xb6rn Zeeb under sponsorship from
+ * the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -257,6 +262,190 @@
.release = linux_kobject_kfree
};
+/* -------------------------------------------------------------------------- */
+/* devres */
+
+struct devres {
+ struct list_head entry;
+ void (*release)(struct device *, void *);
+ uint8_t __drdata[] __aligned(CACHE_LINE_SIZE);
+};
+
+void *
+lkpi_devres_alloc(void(*release)(struct device *, void *),
+ size_t size, gfp_t gfp)
+{
+ void *p;
+ struct devres *dr;
+ size_t total;
+
+ if (size == 0)
+ return (NULL);
+
+ total = sizeof(*dr) + size;
+ dr = kmalloc(total, gfp);
+ if (dr == NULL)
+ return (NULL);
+
+ INIT_LIST_HEAD(&dr->entry);
+ dr->release = release;;
+ p = (void *)(dr+1);
+
+ return (p);
+}
+
+static void
+_lkpi_devres_free_dr(struct devres *dr)
+{
+
+ /*
+ * We have no dev, so cannot lock. This means someone else has
+ * to do this prior to us if devres_add() had been called.
+ */
+ KASSERT(list_empty_careful(&dr->entry),
+ ("%s: dr %p still on devres_head\n", __func__, dr));
+ kfree(dr);
+}
+
+void
+lkpi_devres_free(void *p)
+{
+ struct devres *dr;
+
+ if (p == NULL)
+ return;
+
+ dr = container_of(p, struct devres, __drdata);
+ _lkpi_devres_free_dr(dr);
+}
+
+void
+lkpi_devres_add(struct device *dev, void *p)
+{
+ struct devres *dr;
+
+ KASSERT(dev != NULL && p != NULL, ("%s: dev %p p %p\n",
+ __func__, dev, p));
+
+ dr = container_of(p, struct devres, __drdata);
+ spin_lock(&dev->devres_lock);
+ list_add(&dr->entry, &dev->devres_head);
+ spin_unlock(&dev->devres_lock);
+}
+
+static struct devres *
+lkpi_devres_find_dr(struct device *dev, void(*release)(struct device *, void *),
+ int (*match)(struct device *, void *, void *), void *mp)
+{
+ struct devres *dr, *next;
+ void *p;
+
+ KASSERT(dev != NULL, ("%s: dev %p\n", __func__, dev));
+ assert_spin_locked(&dev->devres_lock);
+
+ list_for_each_entry_safe(dr, next, &dev->devres_head, entry) {
+ if (dr->release != release)
+ continue;
+ p = (void *)(dr+1);
+ if (match != NULL && match(dev, p, mp) == false)
+ continue;
+ return (dr);
+ }
+
+ return (NULL);
+}
+
+void *
+lkpi_devres_find(struct device *dev, void(*release)(struct device *, void *),
+ int (*match)(struct device *, void *, void *), void *mp)
+{
+ struct devres *dr;
+
+ KASSERT(dev != NULL, ("%s: dev %p\n", __func__, dev));
+
+ spin_lock(&dev->devres_lock);
+ dr = lkpi_devres_find_dr(dev, release, match, mp);
+ spin_unlock(&dev->devres_lock);
+
+ if (dr == NULL)
+ return (NULL);
+
+ return ((void *)(dr + 1));
+}
+
+static void
+lkpi_devres_unlink_locked(struct device *dev, struct devres *dr)
+{
+ KASSERT(dev != NULL, ("%s: dev %p\n", __func__, dev));
+ KASSERT(dr != NULL, ("%s: dr %p\n", __func__, dr));
+ assert_spin_locked(&dev->devres_lock);
+
+ list_del_init(&dr->entry);
+}
+
+void
+lkpi_devres_unlink(struct device *dev, void *p)
+{
+ struct devres *dr;
+
+ KASSERT(dev != NULL && p != NULL, ("%s: dev %p p %p\n",
+ __func__, dev, p));
+
+ dr = container_of(p, struct devres, __drdata);
+ spin_lock(&dev->devres_lock);
+ lkpi_devres_unlink_locked(dev, dr);
+ spin_unlock(&dev->devres_lock);
+}
+
+/* This is called on device free. */
+void
+lkpi_devres_release_free_list(struct device *dev)
+{
+ struct devres *dr, *next;
+ void *p;
+
+ /* Free any resources allocated on the device. */
+ /* No need to lock anymore. */
+ list_for_each_entry_safe(dr, next, &dev->devres_head, entry) {
+ p = (void *)(dr+1);
+ if (dr->release != NULL)
+ dr->release(dev, p);
+ /* This should probably be a function of some kind. */
+ list_del_init(&dr->entry);
+ lkpi_devres_free(p);
+ }
+}
+
+int
+lkpi_devres_destroy(struct device *dev, void(*release)(struct device *, void *),
+ int (*match)(struct device *, void *, void *), void *mp)
+{
+ struct devres *dr;
+
+ spin_lock(&dev->devres_lock);
+ dr = lkpi_devres_find_dr(dev, release, match, mp);
+ if (dr != NULL)
+ lkpi_devres_unlink_locked(dev, dr);
+ spin_unlock(&dev->devres_lock);
+
+ if (dr == NULL)
+ return (-ENOENT);
+ _lkpi_devres_free_dr(dr);
+
+ return (0);
+}
+
+/* -------------------------------------------------------------------------- */
+
+void
+lkpi_devm_kmalloc_release(struct device *dev __unused, void *p __unused)
+{
+
+ /* Nothing to do. Freed with the devres. */
+}
+
+/* -------------------------------------------------------------------------- */
+
static void
linux_device_release(struct device *dev)
{
@@ -1854,8 +2043,8 @@
kfree(vmmap);
}
-char *
-kvasprintf(gfp_t gfp, const char *fmt, va_list ap)
+static char *
+devm_kvasprintf(struct device *dev, gfp_t gfp, const char *fmt, va_list ap)
{
unsigned int len;
char *p;
@@ -1865,13 +2054,36 @@
len = vsnprintf(NULL, 0, fmt, aq);
va_end(aq);
- p = kmalloc(len + 1, gfp);
+ if (dev != NULL)
+ p = devm_kmalloc(dev, len + 1, gfp);
+ else
+ p = kmalloc(len + 1, gfp);
if (p != NULL)
vsnprintf(p, len + 1, fmt, ap);
return (p);
}
+char *
+kvasprintf(gfp_t gfp, const char *fmt, va_list ap)
+{
+
+ return (devm_kvasprintf(NULL, gfp, fmt, ap));
+}
+
+char *
+lkpi_devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...)
+{
+ va_list ap;
+ char *p;
+
+ va_start(ap, fmt);
+ p = devm_kvasprintf(dev, gfp, fmt, ap);
+ va_end(ap);
+
+ return (p);
+}
+
char *
kasprintf(gfp_t gfp, const char *fmt, ...)
{
Index: sys/compat/linuxkpi/common/src/linux_pci.c
===================================================================
--- sys/compat/linuxkpi/common/src/linux_pci.c
+++ sys/compat/linuxkpi/common/src/linux_pci.c
@@ -220,24 +220,42 @@
pdev->devfn = PCI_DEVFN(pci_get_slot(dev), pci_get_function(dev));
pdev->vendor = pci_get_vendor(dev);
pdev->device = pci_get_device(dev);
+ pdev->subsystem_vendor = pci_get_subvendor(dev);
+ pdev->subsystem_device = pci_get_subdevice(dev);
pdev->class = pci_get_class(dev);
pdev->revision = pci_get_revid(dev);
- pdev->dev.bsddev = dev;
+ pdev->bus = malloc(sizeof(*pdev->bus), M_DEVBUF, M_WAITOK | M_ZERO);
pdev->bus->self = pdev;
pdev->bus->number = pci_get_bus(dev);
pdev->bus->domain = pci_get_domain(dev);
+ pdev->dev.bsddev = dev;
+ pdev->dev.parent = &linux_root_device;
+ INIT_LIST_HEAD(&pdev->dev.irqents);
+ kobject_init(&pdev->dev.kobj, &linux_dev_ktype);
+ kobject_set_name(&pdev->dev.kobj, device_get_nameunit(dev));
+ kobject_add(&pdev->dev.kobj, &linux_root_device.kobj,
+ kobject_name(&pdev->dev.kobj));
+}
+
+static void
+lkpinew_pci_dev_release(struct device *dev)
+{
+ struct pci_dev *pdev;
+
+ pdev = to_pci_dev(dev);
+ free(pdev->bus, M_DEVBUF);
+ free(pdev, M_DEVBUF);
}
static struct pci_dev *
lkpinew_pci_dev(device_t dev)
{
struct pci_dev *pdev;
- struct pci_bus *pbus;
pdev = malloc(sizeof(*pdev), M_DEVBUF, M_WAITOK|M_ZERO);
- pbus = malloc(sizeof(*pbus), M_DEVBUF, M_WAITOK|M_ZERO);
- pdev->bus = pbus;
lkpifill_pci_dev(dev, pdev);
+ pdev->dev.release = lkpinew_pci_dev_release;
+
return (pdev);
}
@@ -309,7 +327,6 @@
const struct pci_device_id *id, struct pci_dev *pdev)
{
struct resource_list_entry *rle;
- struct pci_devinfo *dinfo;
device_t parent;
uintptr_t rid;
int error;
@@ -321,30 +338,19 @@
isdrm = pdrv != NULL && pdrv->isdrm;
if (isdrm) {
+ struct pci_devinfo *dinfo;
+
dinfo = device_get_ivars(parent);
device_set_ivars(dev, dinfo);
- } else {
- dinfo = device_get_ivars(dev);
}
- pdev->bus = malloc(sizeof(*pdev->bus), M_DEVBUF, M_WAITOK | M_ZERO);
lkpifill_pci_dev(dev, pdev);
- pdev->dev.parent = &linux_root_device;
- INIT_LIST_HEAD(&pdev->dev.irqents);
if (isdrm)
PCI_GET_ID(device_get_parent(parent), parent, PCI_ID_RID, &rid);
else
PCI_GET_ID(parent, dev, PCI_ID_RID, &rid);
pdev->devfn = rid;
- pdev->device = dinfo->cfg.device;
- pdev->vendor = dinfo->cfg.vendor;
- pdev->subsystem_vendor = dinfo->cfg.subvendor;
- pdev->subsystem_device = dinfo->cfg.subdevice;
pdev->pdrv = pdrv;
- kobject_init(&pdev->dev.kobj, &linux_dev_ktype);
- kobject_set_name(&pdev->dev.kobj, device_get_nameunit(dev));
- kobject_add(&pdev->dev.kobj, &linux_root_device.kobj,
- kobject_name(&pdev->dev.kobj));
rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 0);
if (rle != NULL)
pdev->dev.irq = rle->start;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Feb 12, 10:48 PM (12 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28671174
Default Alt Text
D26598.id82331.diff (21 KB)
Attached To
Mode
D26598: linuxkpi: upstream drm-kmod conflicting changes
Attached
Detach File
Event Timeline
Log In to Comment