fdt_slicer.c revision 235778
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: head/sys/dev/fdt/fdt_slicer.c 235778 2012-05-22 08:33:14Z gber $"); 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#define DEBUG 39235778Sgber#undef DEBUG 40235778Sgber 41235778Sgber#ifdef DEBUG 42235778Sgber#define debugf(fmt, args...) do { printf("%s(): ", __func__); \ 43235778Sgber printf(fmt,##args); } while (0) 44235778Sgber#else 45235778Sgber#define debugf(fmt, args...) 46235778Sgber#endif 47235778Sgber 48235778Sgberint 49235778Sgberflash_fill_slices(device_t dev, struct flash_slice *slices, int *slices_num) 50235778Sgber{ 51235778Sgber char *slice_name; 52235778Sgber phandle_t dt_node, dt_child; 53235778Sgber u_long base, size; 54235778Sgber int i; 55235778Sgber ssize_t name_len; 56235778Sgber 57235778Sgber /* 58235778Sgber * We assume the caller provides buffer for FLASH_SLICES_MAX_NUM 59235778Sgber * flash_slice structures. 60235778Sgber */ 61235778Sgber if (slices == NULL) { 62235778Sgber *slices_num = 0; 63235778Sgber return (ENOMEM); 64235778Sgber } 65235778Sgber 66235778Sgber dt_node = ofw_bus_get_node(dev); 67235778Sgber for (dt_child = OF_child(dt_node), i = 0; dt_child != 0; 68235778Sgber dt_child = OF_peer(dt_child)) { 69235778Sgber 70235778Sgber if (i == FLASH_SLICES_MAX_NUM) { 71235778Sgber debugf("not enough buffer for slice i=%d\n", i); 72235778Sgber break; 73235778Sgber } 74235778Sgber 75235778Sgber /* 76235778Sgber * Retrieve start and size of the slice. 77235778Sgber */ 78235778Sgber if (fdt_regsize(dt_child, &base, &size) != 0) { 79235778Sgber debugf("error during processing reg property, i=%d\n", 80235778Sgber i); 81235778Sgber continue; 82235778Sgber } 83235778Sgber 84235778Sgber if (size == 0) { 85235778Sgber debugf("slice i=%d with no size\n", i); 86235778Sgber continue; 87235778Sgber } 88235778Sgber 89235778Sgber /* 90235778Sgber * Retrieve label. 91235778Sgber */ 92235778Sgber name_len = OF_getprop_alloc(dt_child, "label", sizeof(char), 93235778Sgber (void **)&slice_name); 94235778Sgber if (name_len <= 0) { 95235778Sgber /* Use node name if no label defined */ 96235778Sgber name_len = OF_getprop_alloc(dt_child, "name", sizeof(char), 97235778Sgber (void **)&slice_name); 98235778Sgber if (name_len <= 0) { 99235778Sgber debugf("slice i=%d with no name\n", i); 100235778Sgber slice_name = NULL; 101235778Sgber } 102235778Sgber } 103235778Sgber 104235778Sgber /* 105235778Sgber * Fill slice entry data. 106235778Sgber */ 107235778Sgber slices[i].base = base; 108235778Sgber slices[i].size = size; 109235778Sgber slices[i].label = slice_name; 110235778Sgber i++; 111235778Sgber } 112235778Sgber 113235778Sgber *slices_num = i; 114235778Sgber return (0); 115235778Sgber} 116