1235778Sgber/*- 2235778Sgber * Copyright (c) 2012 Semihalf. 3235778Sgber * All rights reserved. 4235778Sgber * 5235778Sgber * Redistribution and use in source and binary forms, with or without 6235778Sgber * modification, are permitted provided that the following conditions 7235778Sgber * are met: 8235778Sgber * 1. Redistributions of source code must retain the above copyright 9235778Sgber * notice, this list of conditions and the following disclaimer. 10235778Sgber * 2. Redistributions in binary form must reproduce the above copyright 11235778Sgber * notice, this list of conditions and the following disclaimer in the 12235778Sgber * documentation and/or other materials provided with the distribution. 13235778Sgber * 14235778Sgber * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15235778Sgber * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16235778Sgber * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17235778Sgber * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18235778Sgber * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19235778Sgber * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20235778Sgber * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21235778Sgber * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22235778Sgber * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23235778Sgber * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24235778Sgber * SUCH DAMAGE. 25235778Sgber */ 26235778Sgber 27235778Sgber#include <sys/cdefs.h> 28235778Sgber__FBSDID("$FreeBSD: releng/10.2/sys/dev/fdt/fdt_slicer.c 261077 2014-01-23 12:02:04Z loos $"); 29235778Sgber 30235778Sgber#include <sys/param.h> 31235778Sgber#include <sys/systm.h> 32235778Sgber#include <sys/kernel.h> 33235778Sgber#include <sys/module.h> 34235778Sgber#include <sys/slicer.h> 35235778Sgber 36235778Sgber#include <dev/fdt/fdt_common.h> 37235778Sgber 38235778Sgber#ifdef DEBUG 39235778Sgber#define debugf(fmt, args...) do { printf("%s(): ", __func__); \ 40235778Sgber printf(fmt,##args); } while (0) 41235778Sgber#else 42235778Sgber#define debugf(fmt, args...) 43235778Sgber#endif 44235778Sgber 45235778Sgberint 46235778Sgberflash_fill_slices(device_t dev, struct flash_slice *slices, int *slices_num) 47235778Sgber{ 48235778Sgber char *slice_name; 49235778Sgber phandle_t dt_node, dt_child; 50235778Sgber u_long base, size; 51235778Sgber int i; 52235778Sgber ssize_t name_len; 53235778Sgber 54235778Sgber /* 55235778Sgber * We assume the caller provides buffer for FLASH_SLICES_MAX_NUM 56235778Sgber * flash_slice structures. 57235778Sgber */ 58235778Sgber if (slices == NULL) { 59235778Sgber *slices_num = 0; 60235778Sgber return (ENOMEM); 61235778Sgber } 62235778Sgber 63235778Sgber dt_node = ofw_bus_get_node(dev); 64235778Sgber for (dt_child = OF_child(dt_node), i = 0; dt_child != 0; 65235778Sgber dt_child = OF_peer(dt_child)) { 66235778Sgber 67235778Sgber if (i == FLASH_SLICES_MAX_NUM) { 68235778Sgber debugf("not enough buffer for slice i=%d\n", i); 69235778Sgber break; 70235778Sgber } 71235778Sgber 72235778Sgber /* 73235778Sgber * Retrieve start and size of the slice. 74235778Sgber */ 75235778Sgber if (fdt_regsize(dt_child, &base, &size) != 0) { 76235778Sgber debugf("error during processing reg property, i=%d\n", 77235778Sgber i); 78235778Sgber continue; 79235778Sgber } 80235778Sgber 81235778Sgber if (size == 0) { 82235778Sgber debugf("slice i=%d with no size\n", i); 83235778Sgber continue; 84235778Sgber } 85235778Sgber 86235778Sgber /* 87235778Sgber * Retrieve label. 88235778Sgber */ 89235778Sgber name_len = OF_getprop_alloc(dt_child, "label", sizeof(char), 90235778Sgber (void **)&slice_name); 91235778Sgber if (name_len <= 0) { 92235778Sgber /* Use node name if no label defined */ 93235778Sgber name_len = OF_getprop_alloc(dt_child, "name", sizeof(char), 94235778Sgber (void **)&slice_name); 95235778Sgber if (name_len <= 0) { 96235778Sgber debugf("slice i=%d with no name\n", i); 97235778Sgber slice_name = NULL; 98235778Sgber } 99235778Sgber } 100235778Sgber 101235778Sgber /* 102235778Sgber * Fill slice entry data. 103235778Sgber */ 104235778Sgber slices[i].base = base; 105235778Sgber slices[i].size = size; 106235778Sgber slices[i].label = slice_name; 107235778Sgber i++; 108235778Sgber } 109235778Sgber 110235778Sgber *slices_num = i; 111235778Sgber return (0); 112235778Sgber} 113