From: "zhichang.yuan" <zhichang.yuan02@gmail.com>
To: kbuild test robot <lkp@intel.com>, fengguang.wu@intel.com
Cc: "zhichang.yuan" <yuanzhichang@hisilicon.com>,
kbuild-all@01.org, catalin.marinas@arm.com, will.deacon@arm.com,
robh+dt@kernel.org, frowand.list@gmail.com, bhelgaas@google.com,
rafael@kernel.org, arnd@arndb.de,
linux-arm-kernel@lists.infradead.org, mark.rutland@arm.com,
brian.starkey@arm.com, olof@lixom.net, lorenzo.pieralisi@arm.com,
benh@kernel.crashing.org, linux-kernel@vger.kernel.org,
linux-acpi@vger.kernel.org, linuxarm@huawei.com,
devicetree@vger.kernel.org, linux-pci@vger.kernel.org,
minyard@acm.org, zourongrong@gmail.com, john.garry@huawei.com,
gabriele.paoloni@huawei.com, xuwei5@hisilicon.com
Subject: Re: [PATCH V8 1/6] LIBIO: Introduce a generic PIO mapping method
Date: Wed, 5 Apr 2017 20:18:55 +0800 [thread overview]
Message-ID: <9fb5224f-eec3-5b03-e5f9-169280ef4c49@gmail.com> (raw)
In-Reply-To: <201704011328.1YdgEHnc%fengguang.wu@intel.com>
Hi,
Thanks for your report!
I am sorry for that!
This issue was caused by missing the '#include <linux/logic_pio.h>' in
logic_pio.c for some architectures where the 'asm-generic/io.h' wasn't been
included.
Will be fixed in the next V9.
Apologized for this!
-Zhichang
On 04/01/2017 01:58 PM, kbuild test robot wrote:
> Hi zhichang.yuan,
>
> [auto build test ERROR on linus/master]
> [also build test ERROR on v4.11-rc4 next-20170331]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/zhichang-yuan/LIBIO-Introduce-a-generic-PIO-mapping-method/20170401-104801
> config: alpha-allyesconfig (attached as .config)
> compiler: alpha-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
> reproduce:
> wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> make.cross ARCH=alpha
>
> All error/warnings (new ones prefixed by >>):
>
>>> lib/logic_pio.c:32:50: error: 'PIO_MAX_SECT' undeclared here (not in a function)
> static struct logic_pio_root logic_pio_root_list[PIO_MAX_SECT] = {
> ^~~~~~~~~~~~
>>> lib/logic_pio.c:39:3: error: 'PIO_CPU_MMIO' undeclared here (not in a function)
> [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
> ^~~~~~~~~~~~
>>> lib/logic_pio.c:39:20: error: 'PIO_INDIRECT' undeclared here (not in a function)
> [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
> ^~~~~~~~~~~~
>>> lib/logic_pio.c:39:3: error: array index in initializer not of integer type
> [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
> ^~~~~~~~~~~~
> lib/logic_pio.c:39:3: note: (near initialization for 'logic_pio_root_list')
>>> lib/logic_pio.c:40:3: error: field name not in record or union initializer
> .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
> ^
> lib/logic_pio.c:40:3: note: (near initialization for 'logic_pio_root_list')
> lib/logic_pio.c:41:3: error: field name not in record or union initializer
> .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
> ^
> lib/logic_pio.c:41:3: note: (near initialization for 'logic_pio_root_list')
>>> lib/logic_pio.c:41:14: error: implicit declaration of function 'PIO_SECT_MIN' [-Werror=implicit-function-declaration]
> .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
> ^~~~~~~~~~~~
> lib/logic_pio.c:42:3: error: field name not in record or union initializer
> .sec_max = PIO_SECT_MAX(PIO_INDIRECT - 1),
> ^
> lib/logic_pio.c:42:3: note: (near initialization for 'logic_pio_root_list')
>>> lib/logic_pio.c:42:14: error: implicit declaration of function 'PIO_SECT_MAX' [-Werror=implicit-function-declaration]
> .sec_max = PIO_SECT_MAX(PIO_INDIRECT - 1),
> ^~~~~~~~~~~~
> lib/logic_pio.c:46:3: error: array index in initializer not of integer type
> [PIO_INDIRECT] = {
> ^~~~~~~~~~~~
> lib/logic_pio.c:46:3: note: (near initialization for 'logic_pio_root_list')
> lib/logic_pio.c:47:3: error: field name not in record or union initializer
> .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_INDIRECT].sec_head),
> ^
> lib/logic_pio.c:47:3: note: (near initialization for 'logic_pio_root_list')
> lib/logic_pio.c:48:3: error: field name not in record or union initializer
> .sec_min = PIO_SECT_MIN(PIO_INDIRECT),
> ^
> lib/logic_pio.c:48:3: note: (near initialization for 'logic_pio_root_list')
> lib/logic_pio.c:49:3: error: field name not in record or union initializer
> .sec_max = PIO_SECT_MAX(PIO_INDIRECT),
> ^
> lib/logic_pio.c:49:3: note: (near initialization for 'logic_pio_root_list')
> In file included from include/linux/list.h:8:0,
> from include/linux/kobject.h:20,
> from include/linux/of.h:21,
> from lib/logic_pio.c:18:
> lib/logic_pio.c: In function 'logic_pio_find_range_byaddr':
>>> include/linux/rculist.h:351:49: error: dereferencing pointer to incomplete type 'struct logic_pio_hwaddr'
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
>
> include/linux/kernel.h:852:18: note: in definition of macro 'container_of'
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> ^~~~
>>> include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
> ^~~~~~~~~~~~~~
>>> lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
> list_for_each_entry_rcu(range, &io_range_list, list) {
> ^~~~~~~~~~~~~~~~~~~~~~~
> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> ^
>>> include/linux/rculist.h:277:2: note: in expansion of macro 'container_of'
> container_of(lockless_dereference(ptr), type, member)
> ^~~~~~~~~~~~
>>> include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
> ^~~~~~~~~~~~~~
>>> lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
> list_for_each_entry_rcu(range, &io_range_list, list) {
> ^~~~~~~~~~~~~~~~~~~~~~~
>>> include/linux/kernel.h:852:48: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> ^
>>> include/linux/rculist.h:277:2: note: in expansion of macro 'container_of'
> container_of(lockless_dereference(ptr), type, member)
> ^~~~~~~~~~~~
> include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
> pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
> ^~~~~~~~~~~~~~
>>> lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
> list_for_each_entry_rcu(range, &io_range_list, list) {
> ^~~~~~~~~~~~~~~~~~~~~~~
> lib/logic_pio.c: In function 'logic_pio_alloc_range':
>>> lib/logic_pio.c:109:19: error: dereferencing pointer to incomplete type 'struct logic_pio_root'
> idle_start = root->sec_min;
> ^~
> In file included from include/linux/list.h:8:0,
> from include/linux/kobject.h:20,
> from include/linux/of.h:21,
> from lib/logic_pio.c:18:
>>> include/linux/rculist.h:351:49: error: dereferencing pointer to incomplete type 'struct logic_pio_sect'
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
>
> include/linux/kernel.h:852:18: note: in definition of macro 'container_of'
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> ^~~~
>>> include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
> ^~~~~~~~~~~~~~
> lib/logic_pio.c:111:2: note: in expansion of macro 'list_for_each_entry_rcu'
> list_for_each_entry_rcu(entry, &root->sec_head, list) {
> ^~~~~~~~~~~~~~~~~~~~~~~
>>> include/linux/kernel.h:852:48: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> ^
>
> vim +/PIO_MAX_SECT +32 lib/logic_pio.c
>
> 12 * GNU General Public License for more details.
> 13 *
> 14 * You should have received a copy of the GNU General Public License
> 15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
> 16 */
> 17
> > 18 #include <linux/of.h>
> 19 #include <linux/io.h>
> 20 #include <linux/mm.h>
> 21 #include <linux/rculist.h>
> 22 #include <linux/sizes.h>
> 23 #include <linux/slab.h>
> 24
> 25 /* The unique hardware address list. */
> 26 static LIST_HEAD(io_range_list);
> 27 static DEFINE_MUTEX(io_range_mutex);
> 28
> 29 /*
> 30 * These are the lists for PIO. The highest PIO_SECT_BITS of PIO is the index.
> 31 */
> > 32 static struct logic_pio_root logic_pio_root_list[PIO_MAX_SECT] = {
> 33 #ifdef CONFIG_INDIRECT_PIO
> 34 /*
> 35 * At this moment, assign all the other logic PIO space to MMIO.
> 36 * If more elements added, please adjust the ending index and .sec_max;
> 37 * Please keep MMIO element started from index ZERO.
> 38 */
> > 39 [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
> > 40 .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
> > 41 .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
> > 42 .sec_max = PIO_SECT_MAX(PIO_INDIRECT - 1),
> 43 },
> 44
> 45 /* The last element */
> 46 [PIO_INDIRECT] = {
> 47 .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_INDIRECT].sec_head),
> 48 .sec_min = PIO_SECT_MIN(PIO_INDIRECT),
> 49 .sec_max = PIO_SECT_MAX(PIO_INDIRECT),
> 50 },
> 51 #else
> 52 [PIO_CPU_MMIO] = {
> 53 .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
> 54 .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
> 55 .sec_max = PIO_SECT_MAX(PIO_CPU_MMIO),
> 56 },
> 57
> 58 #endif
> 59 };
> 60
> 61 /*
> 62 * Search a io_range registered which match the fwnode and addr.
> 63 *
> 64 * @fwnode: the host fwnode which must be valid;
> 65 * @start: the start hardware address of this search;
> 66 * @end: the end hardware address of this search. can be equal to @start;
> 67 *
> 68 * return NULL when there is no matched node; IS_ERR() means ERROR;
> 69 * valid virtual address represent a matched node was found.
> 70 */
> 71 static struct logic_pio_hwaddr *
> 72 logic_pio_find_range_byaddr(struct fwnode_handle *fwnode,
> 73 resource_size_t start, resource_size_t end)
> 74 {
> 75 struct logic_pio_hwaddr *range;
> 76
> > 77 list_for_each_entry_rcu(range, &io_range_list, list) {
> 78 if (!range->pio_peer) {
> 79 pr_warn("Invalid cpu addr node(%pa) in list!\n",
> 80 &range->hw_start);
> 81 continue;
> 82 }
> 83 if (range->fwnode != fwnode)
> 84 continue;
> 85 /* without any overlap with current range */
> 86 if (start >= range->hw_start + range->size ||
> 87 end < range->hw_start)
> 88 continue;
> 89 /* overlap is not supported now. */
> 90 if (start < range->hw_start ||
> 91 end >= range->hw_start + range->size)
> 92 return ERR_PTR(-EBUSY);
> 93 /* had been registered. */
> 94 return range;
> 95 }
> 96
> 97 return NULL;
> 98 }
> 99
> 100
> 101 static int logic_pio_alloc_range(struct logic_pio_root *root,
> 102 resource_size_t size, unsigned long align,
> 103 struct list_head **prev, resource_size_t *pio_alloc)
> 104 {
> 105 struct logic_pio_sect *entry;
> 106 resource_size_t tmp_start;
> 107 resource_size_t idle_start, idle_end;
> 108
> > 109 idle_start = root->sec_min;
> 110 *prev = &root->sec_head;
> 111 list_for_each_entry_rcu(entry, &root->sec_head, list) {
> 112 if (!entry->hwpeer ||
> 113 idle_start > entry->io_start) {
> 114 WARN(1, "skip an invalid io range during traversal!\n");
> 115 goto nextentry;
> 116 }
> 117 /* set the end edge. */
> 118 if (idle_start == entry->io_start) {
> 119 struct logic_pio_sect *next;
> 120
> 121 idle_start = entry->io_start + entry->hwpeer->size;
> > 122 next = list_next_or_null_rcu(&root->sec_head,
> > 123 &entry->list, struct logic_pio_sect, list);
> 124 if (next) {
> 125 entry = next;
> 126 } else {
> 127 *prev = &entry->list;
> 128 break;
> 129 }
> 130 }
> 131 idle_end = entry->io_start - 1;
> 132
> 133 /* contiguous range... */
> 134 if (idle_start > idle_end)
> 135 goto nextentry;
> 136
> 137 tmp_start = idle_start;
> 138 idle_start = ALIGN(idle_start, align);
> 139 if (idle_start >= tmp_start &&
> 140 idle_start + size <= idle_end) {
> 141 *prev = &entry->list;
> 142 *pio_alloc = idle_start;
> 143 return 0;
> 144 }
> 145
> 146 nextentry:
> 147 idle_start = entry->io_start + entry->hwpeer->size;
> 148 *prev = &entry->list;
> 149 }
> 150 /* check the last free gap... */
> 151 idle_end = root->sec_max;
> 152
> 153 tmp_start = idle_start;
> 154 idle_start = ALIGN(idle_start, align);
> 155 if (idle_start >= tmp_start &&
> 156 idle_start + size <= idle_end) {
> 157 *pio_alloc = idle_start;
> 158 return 0;
> 159 }
> 160
> 161 return -EBUSY;
> 162 }
> 163
> 164 /*
> 165 * register a io range node in the io range list.
> 166 *
> 167 * @newrange: pointer to the io range to be registered.
> 168 *
> 169 * return 'newrange' when success, ERR_VALUE() is for failures.
> 170 * specially, return a valid pointer which is not equal to 'newrange' when
> 171 * the io range had been registered before.
> 172 */
> 173 struct logic_pio_hwaddr
> 174 *logic_pio_register_range(struct logic_pio_hwaddr *newrange,
> 175 unsigned long align)
> 176 {
> 177 struct logic_pio_hwaddr *range;
> 178 struct logic_pio_sect *newsect;
> 179 resource_size_t pio_alloc;
> 180 struct list_head *prev, *hwprev;
> 181 unsigned long sect_id;
> 182 int err;
> 183
> 184 if (!newrange || !newrange->fwnode || !newrange->size)
> 185 return ERR_PTR(-EINVAL);
> 186
> 187 sect_id = newrange->flags;
> 188 if (sect_id >= PIO_MAX_SECT)
> 189 return ERR_PTR(-EINVAL);
> 190
> 191 mutex_lock(&io_range_mutex);
> 192 range = logic_pio_find_range_byaddr(newrange->fwnode,
> 193 newrange->hw_start,
> 194 newrange->hw_start + newrange->size - 1);
> 195 if (range) {
> 196 if (!IS_ERR(range))
> 197 pr_info("the request IO range had been registered!\n");
> 198 else
> 199 pr_err("registering IO[%pa - sz%pa) got failed!\n",
> 200 &newrange->hw_start, &newrange->size);
> 201 mutex_unlock(&io_range_mutex);
> 202 return range;
> 203 }
> 204
> 205 err = logic_pio_alloc_range(&logic_pio_root_list[sect_id],
> 206 newrange->size, align, &prev, &pio_alloc);
> 207 if (err) {
> 208 pr_err("can't find free %pa logical IO range!\n",
> 209 &newrange->size);
> 210 goto exitproc;
> 211 }
> 212
> 213 if (prev == &logic_pio_root_list[sect_id].sec_head) {
> 214 hwprev = &io_range_list;
> 215 } else {
> > 216 newsect = to_pio_sect(prev);
> > 217 hwprev = &newsect->hwpeer->list;
> 218 }
> 219
> 220 newsect = kzalloc(sizeof(*newsect), GFP_KERNEL);
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation
>
WARNING: multiple messages have this Message-ID (diff)
From: "zhichang.yuan" <zhichang.yuan02@gmail.com>
To: kbuild test robot <lkp@intel.com>, fengguang.wu@intel.com
Cc: mark.rutland@arm.com, benh@kernel.crashing.org,
gabriele.paoloni@huawei.com, rafael@kernel.org,
linux-pci@vger.kernel.org, will.deacon@arm.com,
linuxarm@huawei.com, frowand.list@gmail.com,
lorenzo.pieralisi@arm.com, arnd@arndb.de, xuwei5@hisilicon.com,
linux-acpi@vger.kernel.org, catalin.marinas@arm.com,
devicetree@vger.kernel.org, minyard@acm.org,
john.garry@huawei.com, olof@lixom.net, robh+dt@kernel.org,
bhelgaas@google.com, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org,
"zhichang.yuan" <yuanzhichang@hisilicon.com>,
kbuild-all@01.org, zourongrong@gmail.com, brian.starkey@arm.com
Subject: Re: [PATCH V8 1/6] LIBIO: Introduce a generic PIO mapping method
Date: Wed, 5 Apr 2017 20:18:55 +0800 [thread overview]
Message-ID: <9fb5224f-eec3-5b03-e5f9-169280ef4c49@gmail.com> (raw)
In-Reply-To: <201704011328.1YdgEHnc%fengguang.wu@intel.com>
Hi,
Thanks for your report!
I am sorry for that!
This issue was caused by missing the '#include <linux/logic_pio.h>' in
logic_pio.c for some architectures where the 'asm-generic/io.h' wasn't been
included.
Will be fixed in the next V9.
Apologized for this!
-Zhichang
On 04/01/2017 01:58 PM, kbuild test robot wrote:
> Hi zhichang.yuan,
>
> [auto build test ERROR on linus/master]
> [also build test ERROR on v4.11-rc4 next-20170331]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/zhichang-yuan/LIBIO-Introduce-a-generic-PIO-mapping-method/20170401-104801
> config: alpha-allyesconfig (attached as .config)
> compiler: alpha-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
> reproduce:
> wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> make.cross ARCH=alpha
>
> All error/warnings (new ones prefixed by >>):
>
>>> lib/logic_pio.c:32:50: error: 'PIO_MAX_SECT' undeclared here (not in a function)
> static struct logic_pio_root logic_pio_root_list[PIO_MAX_SECT] = {
> ^~~~~~~~~~~~
>>> lib/logic_pio.c:39:3: error: 'PIO_CPU_MMIO' undeclared here (not in a function)
> [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
> ^~~~~~~~~~~~
>>> lib/logic_pio.c:39:20: error: 'PIO_INDIRECT' undeclared here (not in a function)
> [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
> ^~~~~~~~~~~~
>>> lib/logic_pio.c:39:3: error: array index in initializer not of integer type
> [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
> ^~~~~~~~~~~~
> lib/logic_pio.c:39:3: note: (near initialization for 'logic_pio_root_list')
>>> lib/logic_pio.c:40:3: error: field name not in record or union initializer
> .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
> ^
> lib/logic_pio.c:40:3: note: (near initialization for 'logic_pio_root_list')
> lib/logic_pio.c:41:3: error: field name not in record or union initializer
> .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
> ^
> lib/logic_pio.c:41:3: note: (near initialization for 'logic_pio_root_list')
>>> lib/logic_pio.c:41:14: error: implicit declaration of function 'PIO_SECT_MIN' [-Werror=implicit-function-declaration]
> .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
> ^~~~~~~~~~~~
> lib/logic_pio.c:42:3: error: field name not in record or union initializer
> .sec_max = PIO_SECT_MAX(PIO_INDIRECT - 1),
> ^
> lib/logic_pio.c:42:3: note: (near initialization for 'logic_pio_root_list')
>>> lib/logic_pio.c:42:14: error: implicit declaration of function 'PIO_SECT_MAX' [-Werror=implicit-function-declaration]
> .sec_max = PIO_SECT_MAX(PIO_INDIRECT - 1),
> ^~~~~~~~~~~~
> lib/logic_pio.c:46:3: error: array index in initializer not of integer type
> [PIO_INDIRECT] = {
> ^~~~~~~~~~~~
> lib/logic_pio.c:46:3: note: (near initialization for 'logic_pio_root_list')
> lib/logic_pio.c:47:3: error: field name not in record or union initializer
> .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_INDIRECT].sec_head),
> ^
> lib/logic_pio.c:47:3: note: (near initialization for 'logic_pio_root_list')
> lib/logic_pio.c:48:3: error: field name not in record or union initializer
> .sec_min = PIO_SECT_MIN(PIO_INDIRECT),
> ^
> lib/logic_pio.c:48:3: note: (near initialization for 'logic_pio_root_list')
> lib/logic_pio.c:49:3: error: field name not in record or union initializer
> .sec_max = PIO_SECT_MAX(PIO_INDIRECT),
> ^
> lib/logic_pio.c:49:3: note: (near initialization for 'logic_pio_root_list')
> In file included from include/linux/list.h:8:0,
> from include/linux/kobject.h:20,
> from include/linux/of.h:21,
> from lib/logic_pio.c:18:
> lib/logic_pio.c: In function 'logic_pio_find_range_byaddr':
>>> include/linux/rculist.h:351:49: error: dereferencing pointer to incomplete type 'struct logic_pio_hwaddr'
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
>
> include/linux/kernel.h:852:18: note: in definition of macro 'container_of'
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> ^~~~
>>> include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
> ^~~~~~~~~~~~~~
>>> lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
> list_for_each_entry_rcu(range, &io_range_list, list) {
> ^~~~~~~~~~~~~~~~~~~~~~~
> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> ^
>>> include/linux/rculist.h:277:2: note: in expansion of macro 'container_of'
> container_of(lockless_dereference(ptr), type, member)
> ^~~~~~~~~~~~
>>> include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
> ^~~~~~~~~~~~~~
>>> lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
> list_for_each_entry_rcu(range, &io_range_list, list) {
> ^~~~~~~~~~~~~~~~~~~~~~~
>>> include/linux/kernel.h:852:48: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> ^
>>> include/linux/rculist.h:277:2: note: in expansion of macro 'container_of'
> container_of(lockless_dereference(ptr), type, member)
> ^~~~~~~~~~~~
> include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
> pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
> ^~~~~~~~~~~~~~
>>> lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
> list_for_each_entry_rcu(range, &io_range_list, list) {
> ^~~~~~~~~~~~~~~~~~~~~~~
> lib/logic_pio.c: In function 'logic_pio_alloc_range':
>>> lib/logic_pio.c:109:19: error: dereferencing pointer to incomplete type 'struct logic_pio_root'
> idle_start = root->sec_min;
> ^~
> In file included from include/linux/list.h:8:0,
> from include/linux/kobject.h:20,
> from include/linux/of.h:21,
> from lib/logic_pio.c:18:
>>> include/linux/rculist.h:351:49: error: dereferencing pointer to incomplete type 'struct logic_pio_sect'
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
>
> include/linux/kernel.h:852:18: note: in definition of macro 'container_of'
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> ^~~~
>>> include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
> ^~~~~~~~~~~~~~
> lib/logic_pio.c:111:2: note: in expansion of macro 'list_for_each_entry_rcu'
> list_for_each_entry_rcu(entry, &root->sec_head, list) {
> ^~~~~~~~~~~~~~~~~~~~~~~
>>> include/linux/kernel.h:852:48: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> ^
>
> vim +/PIO_MAX_SECT +32 lib/logic_pio.c
>
> 12 * GNU General Public License for more details.
> 13 *
> 14 * You should have received a copy of the GNU General Public License
> 15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
> 16 */
> 17
> > 18 #include <linux/of.h>
> 19 #include <linux/io.h>
> 20 #include <linux/mm.h>
> 21 #include <linux/rculist.h>
> 22 #include <linux/sizes.h>
> 23 #include <linux/slab.h>
> 24
> 25 /* The unique hardware address list. */
> 26 static LIST_HEAD(io_range_list);
> 27 static DEFINE_MUTEX(io_range_mutex);
> 28
> 29 /*
> 30 * These are the lists for PIO. The highest PIO_SECT_BITS of PIO is the index.
> 31 */
> > 32 static struct logic_pio_root logic_pio_root_list[PIO_MAX_SECT] = {
> 33 #ifdef CONFIG_INDIRECT_PIO
> 34 /*
> 35 * At this moment, assign all the other logic PIO space to MMIO.
> 36 * If more elements added, please adjust the ending index and .sec_max;
> 37 * Please keep MMIO element started from index ZERO.
> 38 */
> > 39 [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
> > 40 .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
> > 41 .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
> > 42 .sec_max = PIO_SECT_MAX(PIO_INDIRECT - 1),
> 43 },
> 44
> 45 /* The last element */
> 46 [PIO_INDIRECT] = {
> 47 .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_INDIRECT].sec_head),
> 48 .sec_min = PIO_SECT_MIN(PIO_INDIRECT),
> 49 .sec_max = PIO_SECT_MAX(PIO_INDIRECT),
> 50 },
> 51 #else
> 52 [PIO_CPU_MMIO] = {
> 53 .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
> 54 .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
> 55 .sec_max = PIO_SECT_MAX(PIO_CPU_MMIO),
> 56 },
> 57
> 58 #endif
> 59 };
> 60
> 61 /*
> 62 * Search a io_range registered which match the fwnode and addr.
> 63 *
> 64 * @fwnode: the host fwnode which must be valid;
> 65 * @start: the start hardware address of this search;
> 66 * @end: the end hardware address of this search. can be equal to @start;
> 67 *
> 68 * return NULL when there is no matched node; IS_ERR() means ERROR;
> 69 * valid virtual address represent a matched node was found.
> 70 */
> 71 static struct logic_pio_hwaddr *
> 72 logic_pio_find_range_byaddr(struct fwnode_handle *fwnode,
> 73 resource_size_t start, resource_size_t end)
> 74 {
> 75 struct logic_pio_hwaddr *range;
> 76
> > 77 list_for_each_entry_rcu(range, &io_range_list, list) {
> 78 if (!range->pio_peer) {
> 79 pr_warn("Invalid cpu addr node(%pa) in list!\n",
> 80 &range->hw_start);
> 81 continue;
> 82 }
> 83 if (range->fwnode != fwnode)
> 84 continue;
> 85 /* without any overlap with current range */
> 86 if (start >= range->hw_start + range->size ||
> 87 end < range->hw_start)
> 88 continue;
> 89 /* overlap is not supported now. */
> 90 if (start < range->hw_start ||
> 91 end >= range->hw_start + range->size)
> 92 return ERR_PTR(-EBUSY);
> 93 /* had been registered. */
> 94 return range;
> 95 }
> 96
> 97 return NULL;
> 98 }
> 99
> 100
> 101 static int logic_pio_alloc_range(struct logic_pio_root *root,
> 102 resource_size_t size, unsigned long align,
> 103 struct list_head **prev, resource_size_t *pio_alloc)
> 104 {
> 105 struct logic_pio_sect *entry;
> 106 resource_size_t tmp_start;
> 107 resource_size_t idle_start, idle_end;
> 108
> > 109 idle_start = root->sec_min;
> 110 *prev = &root->sec_head;
> 111 list_for_each_entry_rcu(entry, &root->sec_head, list) {
> 112 if (!entry->hwpeer ||
> 113 idle_start > entry->io_start) {
> 114 WARN(1, "skip an invalid io range during traversal!\n");
> 115 goto nextentry;
> 116 }
> 117 /* set the end edge. */
> 118 if (idle_start == entry->io_start) {
> 119 struct logic_pio_sect *next;
> 120
> 121 idle_start = entry->io_start + entry->hwpeer->size;
> > 122 next = list_next_or_null_rcu(&root->sec_head,
> > 123 &entry->list, struct logic_pio_sect, list);
> 124 if (next) {
> 125 entry = next;
> 126 } else {
> 127 *prev = &entry->list;
> 128 break;
> 129 }
> 130 }
> 131 idle_end = entry->io_start - 1;
> 132
> 133 /* contiguous range... */
> 134 if (idle_start > idle_end)
> 135 goto nextentry;
> 136
> 137 tmp_start = idle_start;
> 138 idle_start = ALIGN(idle_start, align);
> 139 if (idle_start >= tmp_start &&
> 140 idle_start + size <= idle_end) {
> 141 *prev = &entry->list;
> 142 *pio_alloc = idle_start;
> 143 return 0;
> 144 }
> 145
> 146 nextentry:
> 147 idle_start = entry->io_start + entry->hwpeer->size;
> 148 *prev = &entry->list;
> 149 }
> 150 /* check the last free gap... */
> 151 idle_end = root->sec_max;
> 152
> 153 tmp_start = idle_start;
> 154 idle_start = ALIGN(idle_start, align);
> 155 if (idle_start >= tmp_start &&
> 156 idle_start + size <= idle_end) {
> 157 *pio_alloc = idle_start;
> 158 return 0;
> 159 }
> 160
> 161 return -EBUSY;
> 162 }
> 163
> 164 /*
> 165 * register a io range node in the io range list.
> 166 *
> 167 * @newrange: pointer to the io range to be registered.
> 168 *
> 169 * return 'newrange' when success, ERR_VALUE() is for failures.
> 170 * specially, return a valid pointer which is not equal to 'newrange' when
> 171 * the io range had been registered before.
> 172 */
> 173 struct logic_pio_hwaddr
> 174 *logic_pio_register_range(struct logic_pio_hwaddr *newrange,
> 175 unsigned long align)
> 176 {
> 177 struct logic_pio_hwaddr *range;
> 178 struct logic_pio_sect *newsect;
> 179 resource_size_t pio_alloc;
> 180 struct list_head *prev, *hwprev;
> 181 unsigned long sect_id;
> 182 int err;
> 183
> 184 if (!newrange || !newrange->fwnode || !newrange->size)
> 185 return ERR_PTR(-EINVAL);
> 186
> 187 sect_id = newrange->flags;
> 188 if (sect_id >= PIO_MAX_SECT)
> 189 return ERR_PTR(-EINVAL);
> 190
> 191 mutex_lock(&io_range_mutex);
> 192 range = logic_pio_find_range_byaddr(newrange->fwnode,
> 193 newrange->hw_start,
> 194 newrange->hw_start + newrange->size - 1);
> 195 if (range) {
> 196 if (!IS_ERR(range))
> 197 pr_info("the request IO range had been registered!\n");
> 198 else
> 199 pr_err("registering IO[%pa - sz%pa) got failed!\n",
> 200 &newrange->hw_start, &newrange->size);
> 201 mutex_unlock(&io_range_mutex);
> 202 return range;
> 203 }
> 204
> 205 err = logic_pio_alloc_range(&logic_pio_root_list[sect_id],
> 206 newrange->size, align, &prev, &pio_alloc);
> 207 if (err) {
> 208 pr_err("can't find free %pa logical IO range!\n",
> 209 &newrange->size);
> 210 goto exitproc;
> 211 }
> 212
> 213 if (prev == &logic_pio_root_list[sect_id].sec_head) {
> 214 hwprev = &io_range_list;
> 215 } else {
> > 216 newsect = to_pio_sect(prev);
> > 217 hwprev = &newsect->hwpeer->list;
> 218 }
> 219
> 220 newsect = kzalloc(sizeof(*newsect), GFP_KERNEL);
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
WARNING: multiple messages have this Message-ID (diff)
From: zhichang.yuan02@gmail.com (zhichang.yuan)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH V8 1/6] LIBIO: Introduce a generic PIO mapping method
Date: Wed, 5 Apr 2017 20:18:55 +0800 [thread overview]
Message-ID: <9fb5224f-eec3-5b03-e5f9-169280ef4c49@gmail.com> (raw)
In-Reply-To: <201704011328.1YdgEHnc%fengguang.wu@intel.com>
Hi,
Thanks for your report!
I am sorry for that!
This issue was caused by missing the '#include <linux/logic_pio.h>' in
logic_pio.c for some architectures where the 'asm-generic/io.h' wasn't been
included.
Will be fixed in the next V9.
Apologized for this!
-Zhichang
On 04/01/2017 01:58 PM, kbuild test robot wrote:
> Hi zhichang.yuan,
>
> [auto build test ERROR on linus/master]
> [also build test ERROR on v4.11-rc4 next-20170331]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/zhichang-yuan/LIBIO-Introduce-a-generic-PIO-mapping-method/20170401-104801
> config: alpha-allyesconfig (attached as .config)
> compiler: alpha-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
> reproduce:
> wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> make.cross ARCH=alpha
>
> All error/warnings (new ones prefixed by >>):
>
>>> lib/logic_pio.c:32:50: error: 'PIO_MAX_SECT' undeclared here (not in a function)
> static struct logic_pio_root logic_pio_root_list[PIO_MAX_SECT] = {
> ^~~~~~~~~~~~
>>> lib/logic_pio.c:39:3: error: 'PIO_CPU_MMIO' undeclared here (not in a function)
> [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
> ^~~~~~~~~~~~
>>> lib/logic_pio.c:39:20: error: 'PIO_INDIRECT' undeclared here (not in a function)
> [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
> ^~~~~~~~~~~~
>>> lib/logic_pio.c:39:3: error: array index in initializer not of integer type
> [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
> ^~~~~~~~~~~~
> lib/logic_pio.c:39:3: note: (near initialization for 'logic_pio_root_list')
>>> lib/logic_pio.c:40:3: error: field name not in record or union initializer
> .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
> ^
> lib/logic_pio.c:40:3: note: (near initialization for 'logic_pio_root_list')
> lib/logic_pio.c:41:3: error: field name not in record or union initializer
> .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
> ^
> lib/logic_pio.c:41:3: note: (near initialization for 'logic_pio_root_list')
>>> lib/logic_pio.c:41:14: error: implicit declaration of function 'PIO_SECT_MIN' [-Werror=implicit-function-declaration]
> .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
> ^~~~~~~~~~~~
> lib/logic_pio.c:42:3: error: field name not in record or union initializer
> .sec_max = PIO_SECT_MAX(PIO_INDIRECT - 1),
> ^
> lib/logic_pio.c:42:3: note: (near initialization for 'logic_pio_root_list')
>>> lib/logic_pio.c:42:14: error: implicit declaration of function 'PIO_SECT_MAX' [-Werror=implicit-function-declaration]
> .sec_max = PIO_SECT_MAX(PIO_INDIRECT - 1),
> ^~~~~~~~~~~~
> lib/logic_pio.c:46:3: error: array index in initializer not of integer type
> [PIO_INDIRECT] = {
> ^~~~~~~~~~~~
> lib/logic_pio.c:46:3: note: (near initialization for 'logic_pio_root_list')
> lib/logic_pio.c:47:3: error: field name not in record or union initializer
> .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_INDIRECT].sec_head),
> ^
> lib/logic_pio.c:47:3: note: (near initialization for 'logic_pio_root_list')
> lib/logic_pio.c:48:3: error: field name not in record or union initializer
> .sec_min = PIO_SECT_MIN(PIO_INDIRECT),
> ^
> lib/logic_pio.c:48:3: note: (near initialization for 'logic_pio_root_list')
> lib/logic_pio.c:49:3: error: field name not in record or union initializer
> .sec_max = PIO_SECT_MAX(PIO_INDIRECT),
> ^
> lib/logic_pio.c:49:3: note: (near initialization for 'logic_pio_root_list')
> In file included from include/linux/list.h:8:0,
> from include/linux/kobject.h:20,
> from include/linux/of.h:21,
> from lib/logic_pio.c:18:
> lib/logic_pio.c: In function 'logic_pio_find_range_byaddr':
>>> include/linux/rculist.h:351:49: error: dereferencing pointer to incomplete type 'struct logic_pio_hwaddr'
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
>
> include/linux/kernel.h:852:18: note: in definition of macro 'container_of'
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> ^~~~
>>> include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
> ^~~~~~~~~~~~~~
>>> lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
> list_for_each_entry_rcu(range, &io_range_list, list) {
> ^~~~~~~~~~~~~~~~~~~~~~~
> include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> ^
>>> include/linux/rculist.h:277:2: note: in expansion of macro 'container_of'
> container_of(lockless_dereference(ptr), type, member)
> ^~~~~~~~~~~~
>>> include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
> ^~~~~~~~~~~~~~
>>> lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
> list_for_each_entry_rcu(range, &io_range_list, list) {
> ^~~~~~~~~~~~~~~~~~~~~~~
>>> include/linux/kernel.h:852:48: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> ^
>>> include/linux/rculist.h:277:2: note: in expansion of macro 'container_of'
> container_of(lockless_dereference(ptr), type, member)
> ^~~~~~~~~~~~
> include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
> pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
> ^~~~~~~~~~~~~~
>>> lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
> list_for_each_entry_rcu(range, &io_range_list, list) {
> ^~~~~~~~~~~~~~~~~~~~~~~
> lib/logic_pio.c: In function 'logic_pio_alloc_range':
>>> lib/logic_pio.c:109:19: error: dereferencing pointer to incomplete type 'struct logic_pio_root'
> idle_start = root->sec_min;
> ^~
> In file included from include/linux/list.h:8:0,
> from include/linux/kobject.h:20,
> from include/linux/of.h:21,
> from lib/logic_pio.c:18:
>>> include/linux/rculist.h:351:49: error: dereferencing pointer to incomplete type 'struct logic_pio_sect'
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
>
> include/linux/kernel.h:852:18: note: in definition of macro 'container_of'
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> ^~~~
>>> include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
> for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
> ^~~~~~~~~~~~~~
> lib/logic_pio.c:111:2: note: in expansion of macro 'list_for_each_entry_rcu'
> list_for_each_entry_rcu(entry, &root->sec_head, list) {
> ^~~~~~~~~~~~~~~~~~~~~~~
>>> include/linux/kernel.h:852:48: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
> const typeof( ((type *)0)->member ) *__mptr = (ptr); \
> ^
>
> vim +/PIO_MAX_SECT +32 lib/logic_pio.c
>
> 12 * GNU General Public License for more details.
> 13 *
> 14 * You should have received a copy of the GNU General Public License
> 15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
> 16 */
> 17
> > 18 #include <linux/of.h>
> 19 #include <linux/io.h>
> 20 #include <linux/mm.h>
> 21 #include <linux/rculist.h>
> 22 #include <linux/sizes.h>
> 23 #include <linux/slab.h>
> 24
> 25 /* The unique hardware address list. */
> 26 static LIST_HEAD(io_range_list);
> 27 static DEFINE_MUTEX(io_range_mutex);
> 28
> 29 /*
> 30 * These are the lists for PIO. The highest PIO_SECT_BITS of PIO is the index.
> 31 */
> > 32 static struct logic_pio_root logic_pio_root_list[PIO_MAX_SECT] = {
> 33 #ifdef CONFIG_INDIRECT_PIO
> 34 /*
> 35 * At this moment, assign all the other logic PIO space to MMIO.
> 36 * If more elements added, please adjust the ending index and .sec_max;
> 37 * Please keep MMIO element started from index ZERO.
> 38 */
> > 39 [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
> > 40 .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
> > 41 .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
> > 42 .sec_max = PIO_SECT_MAX(PIO_INDIRECT - 1),
> 43 },
> 44
> 45 /* The last element */
> 46 [PIO_INDIRECT] = {
> 47 .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_INDIRECT].sec_head),
> 48 .sec_min = PIO_SECT_MIN(PIO_INDIRECT),
> 49 .sec_max = PIO_SECT_MAX(PIO_INDIRECT),
> 50 },
> 51 #else
> 52 [PIO_CPU_MMIO] = {
> 53 .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
> 54 .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
> 55 .sec_max = PIO_SECT_MAX(PIO_CPU_MMIO),
> 56 },
> 57
> 58 #endif
> 59 };
> 60
> 61 /*
> 62 * Search a io_range registered which match the fwnode and addr.
> 63 *
> 64 * @fwnode: the host fwnode which must be valid;
> 65 * @start: the start hardware address of this search;
> 66 * @end: the end hardware address of this search. can be equal to @start;
> 67 *
> 68 * return NULL when there is no matched node; IS_ERR() means ERROR;
> 69 * valid virtual address represent a matched node was found.
> 70 */
> 71 static struct logic_pio_hwaddr *
> 72 logic_pio_find_range_byaddr(struct fwnode_handle *fwnode,
> 73 resource_size_t start, resource_size_t end)
> 74 {
> 75 struct logic_pio_hwaddr *range;
> 76
> > 77 list_for_each_entry_rcu(range, &io_range_list, list) {
> 78 if (!range->pio_peer) {
> 79 pr_warn("Invalid cpu addr node(%pa) in list!\n",
> 80 &range->hw_start);
> 81 continue;
> 82 }
> 83 if (range->fwnode != fwnode)
> 84 continue;
> 85 /* without any overlap with current range */
> 86 if (start >= range->hw_start + range->size ||
> 87 end < range->hw_start)
> 88 continue;
> 89 /* overlap is not supported now. */
> 90 if (start < range->hw_start ||
> 91 end >= range->hw_start + range->size)
> 92 return ERR_PTR(-EBUSY);
> 93 /* had been registered. */
> 94 return range;
> 95 }
> 96
> 97 return NULL;
> 98 }
> 99
> 100
> 101 static int logic_pio_alloc_range(struct logic_pio_root *root,
> 102 resource_size_t size, unsigned long align,
> 103 struct list_head **prev, resource_size_t *pio_alloc)
> 104 {
> 105 struct logic_pio_sect *entry;
> 106 resource_size_t tmp_start;
> 107 resource_size_t idle_start, idle_end;
> 108
> > 109 idle_start = root->sec_min;
> 110 *prev = &root->sec_head;
> 111 list_for_each_entry_rcu(entry, &root->sec_head, list) {
> 112 if (!entry->hwpeer ||
> 113 idle_start > entry->io_start) {
> 114 WARN(1, "skip an invalid io range during traversal!\n");
> 115 goto nextentry;
> 116 }
> 117 /* set the end edge. */
> 118 if (idle_start == entry->io_start) {
> 119 struct logic_pio_sect *next;
> 120
> 121 idle_start = entry->io_start + entry->hwpeer->size;
> > 122 next = list_next_or_null_rcu(&root->sec_head,
> > 123 &entry->list, struct logic_pio_sect, list);
> 124 if (next) {
> 125 entry = next;
> 126 } else {
> 127 *prev = &entry->list;
> 128 break;
> 129 }
> 130 }
> 131 idle_end = entry->io_start - 1;
> 132
> 133 /* contiguous range... */
> 134 if (idle_start > idle_end)
> 135 goto nextentry;
> 136
> 137 tmp_start = idle_start;
> 138 idle_start = ALIGN(idle_start, align);
> 139 if (idle_start >= tmp_start &&
> 140 idle_start + size <= idle_end) {
> 141 *prev = &entry->list;
> 142 *pio_alloc = idle_start;
> 143 return 0;
> 144 }
> 145
> 146 nextentry:
> 147 idle_start = entry->io_start + entry->hwpeer->size;
> 148 *prev = &entry->list;
> 149 }
> 150 /* check the last free gap... */
> 151 idle_end = root->sec_max;
> 152
> 153 tmp_start = idle_start;
> 154 idle_start = ALIGN(idle_start, align);
> 155 if (idle_start >= tmp_start &&
> 156 idle_start + size <= idle_end) {
> 157 *pio_alloc = idle_start;
> 158 return 0;
> 159 }
> 160
> 161 return -EBUSY;
> 162 }
> 163
> 164 /*
> 165 * register a io range node in the io range list.
> 166 *
> 167 * @newrange: pointer to the io range to be registered.
> 168 *
> 169 * return 'newrange' when success, ERR_VALUE() is for failures.
> 170 * specially, return a valid pointer which is not equal to 'newrange' when
> 171 * the io range had been registered before.
> 172 */
> 173 struct logic_pio_hwaddr
> 174 *logic_pio_register_range(struct logic_pio_hwaddr *newrange,
> 175 unsigned long align)
> 176 {
> 177 struct logic_pio_hwaddr *range;
> 178 struct logic_pio_sect *newsect;
> 179 resource_size_t pio_alloc;
> 180 struct list_head *prev, *hwprev;
> 181 unsigned long sect_id;
> 182 int err;
> 183
> 184 if (!newrange || !newrange->fwnode || !newrange->size)
> 185 return ERR_PTR(-EINVAL);
> 186
> 187 sect_id = newrange->flags;
> 188 if (sect_id >= PIO_MAX_SECT)
> 189 return ERR_PTR(-EINVAL);
> 190
> 191 mutex_lock(&io_range_mutex);
> 192 range = logic_pio_find_range_byaddr(newrange->fwnode,
> 193 newrange->hw_start,
> 194 newrange->hw_start + newrange->size - 1);
> 195 if (range) {
> 196 if (!IS_ERR(range))
> 197 pr_info("the request IO range had been registered!\n");
> 198 else
> 199 pr_err("registering IO[%pa - sz%pa) got failed!\n",
> 200 &newrange->hw_start, &newrange->size);
> 201 mutex_unlock(&io_range_mutex);
> 202 return range;
> 203 }
> 204
> 205 err = logic_pio_alloc_range(&logic_pio_root_list[sect_id],
> 206 newrange->size, align, &prev, &pio_alloc);
> 207 if (err) {
> 208 pr_err("can't find free %pa logical IO range!\n",
> 209 &newrange->size);
> 210 goto exitproc;
> 211 }
> 212
> 213 if (prev == &logic_pio_root_list[sect_id].sec_head) {
> 214 hwprev = &io_range_list;
> 215 } else {
> > 216 newsect = to_pio_sect(prev);
> > 217 hwprev = &newsect->hwpeer->list;
> 218 }
> 219
> 220 newsect = kzalloc(sizeof(*newsect), GFP_KERNEL);
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation
>
next prev parent reply other threads:[~2017-04-05 12:18 UTC|newest]
Thread overview: 76+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-30 15:26 [PATCH V8 0/7] LPC: legacy ISA I/O support zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-03-30 15:26 ` [PATCH V8 1/6] LIBIO: Introduce a generic PIO mapping method zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-04-01 5:58 ` kbuild test robot
2017-04-01 5:58 ` kbuild test robot
2017-04-01 5:58 ` kbuild test robot
2017-04-01 5:58 ` kbuild test robot
2017-04-05 12:18 ` zhichang.yuan [this message]
2017-04-05 12:18 ` zhichang.yuan
2017-04-05 12:18 ` zhichang.yuan
2017-04-01 6:31 ` kbuild test robot
2017-04-01 6:31 ` kbuild test robot
2017-04-01 6:31 ` kbuild test robot
2017-03-30 15:26 ` [PATCH V8 2/6] PCI: Apply the new generic I/O management on PCI IO hosts zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-03-30 15:26 ` [PATCH V8 3/6] OF: Add missing I/O range exception for indirect-IO devices zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-03-30 15:26 ` [PATCH V8 4/6] LPC: Support the device-tree LPC host on Hip06/Hip07 zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-03-30 15:26 ` [PATCH V8 5/6] ACPI: Support the probing on the devices which apply indirect-IO zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
[not found] ` <1490887619-61732-6-git-send-email-yuanzhichang-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
2017-03-30 20:31 ` Rafael J. Wysocki
2017-03-30 20:31 ` Rafael J. Wysocki
2017-03-30 20:31 ` Rafael J. Wysocki
2017-03-30 20:31 ` Rafael J. Wysocki
2017-03-31 6:52 ` zhichang.yuan
2017-03-31 6:52 ` zhichang.yuan
2017-03-31 6:52 ` zhichang.yuan
2017-03-31 6:52 ` zhichang.yuan
2017-03-31 23:02 ` Rafael J. Wysocki
2017-03-31 23:02 ` Rafael J. Wysocki
2017-03-31 23:02 ` Rafael J. Wysocki
2017-04-01 2:16 ` zhichang.yuan
2017-04-01 2:16 ` zhichang.yuan
2017-04-01 2:16 ` zhichang.yuan
2017-04-01 2:16 ` zhichang.yuan
2017-04-01 9:52 ` Rafael J. Wysocki
2017-04-01 9:52 ` Rafael J. Wysocki
2017-04-01 9:52 ` Rafael J. Wysocki
[not found] ` <CAJZ5v0iYD=2HVP9D-2fBBDUzkOJLrzzH7Rwg1ALQ-kBx-iSeTg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-04-02 14:58 ` Gabriele Paoloni
2017-04-02 14:58 ` Gabriele Paoloni
2017-04-02 14:58 ` Gabriele Paoloni
2017-04-02 14:58 ` Gabriele Paoloni
2017-04-20 20:57 ` dann frazier
2017-04-20 20:57 ` dann frazier
2017-04-20 20:57 ` dann frazier
2017-04-20 20:57 ` dann frazier
2017-04-21 2:22 ` zhichang.yuan
2017-04-21 2:22 ` zhichang.yuan
2017-04-21 2:22 ` zhichang.yuan
2017-04-21 2:22 ` zhichang.yuan
2017-04-21 17:14 ` Lorenzo Pieralisi
2017-04-21 17:14 ` Lorenzo Pieralisi
2017-04-21 17:14 ` Lorenzo Pieralisi
2017-04-21 17:14 ` Lorenzo Pieralisi
2017-03-30 15:26 ` [PATCH V8 6/6] LPC: Add the ACPI LPC support zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-03-30 15:26 ` zhichang.yuan
2017-03-30 21:42 ` [PATCH V8 0/7] LPC: legacy ISA I/O support dann frazier
2017-03-30 21:42 ` dann frazier
2017-03-30 21:42 ` dann frazier
2017-03-30 21:42 ` dann frazier
2017-03-31 6:36 ` zhichang.yuan
2017-03-31 6:36 ` zhichang.yuan
2017-03-31 6:36 ` zhichang.yuan
2017-03-31 6:36 ` zhichang.yuan
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=9fb5224f-eec3-5b03-e5f9-169280ef4c49@gmail.com \
--to=zhichang.yuan02@gmail.com \
--cc=arnd@arndb.de \
--cc=benh@kernel.crashing.org \
--cc=bhelgaas@google.com \
--cc=brian.starkey@arm.com \
--cc=catalin.marinas@arm.com \
--cc=devicetree@vger.kernel.org \
--cc=fengguang.wu@intel.com \
--cc=frowand.list@gmail.com \
--cc=gabriele.paoloni@huawei.com \
--cc=john.garry@huawei.com \
--cc=kbuild-all@01.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linuxarm@huawei.com \
--cc=lkp@intel.com \
--cc=lorenzo.pieralisi@arm.com \
--cc=mark.rutland@arm.com \
--cc=minyard@acm.org \
--cc=olof@lixom.net \
--cc=rafael@kernel.org \
--cc=robh+dt@kernel.org \
--cc=will.deacon@arm.com \
--cc=xuwei5@hisilicon.com \
--cc=yuanzhichang@hisilicon.com \
--cc=zourongrong@gmail.com \
/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.