/*
 * sysfs based topology -- gathers topology information from Linux sysfs
 *
 * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 *
 * For more information see Linux kernel Documentation/ABI/testing/sysfs-block.
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>

#include "sysfs.h"
#include "topology.h"

/*
 * Sysfs topology values (since 2.6.31, May 2009).
 */
static struct topology_val {

	/* /sys/dev/block/<maj>:<min>/<ATTR> */
	const char *attr;

	/* functions to set probing resut */
	int (*set_ulong)(blkid_probe, unsigned long);
	int (*set_int)(blkid_probe, int);

} topology_vals[] = {
	{ "alignment_offset", NULL, blkid_topology_set_alignment_offset },
	{ "queue/minimum_io_size", blkid_topology_set_minimum_io_size },
	{ "queue/optimal_io_size", blkid_topology_set_optimal_io_size },
	{ "queue/physical_block_size", blkid_topology_set_physical_sector_size },
};

static int probe_sysfs_tp(blkid_probe pr,
		const struct blkid_idmag *mag __attribute__((__unused__)))
{
	dev_t dev, disk = 0;
	int rc;
	struct sysfs_cxt sysfs = UL_SYSFSCXT_EMPTY,
			 parent = UL_SYSFSCXT_EMPTY;
	size_t i, count = 0;

	dev = blkid_probe_get_devno(pr);
	if (!dev || sysfs_init(&sysfs, dev, NULL) != 0)
		return 1;

	rc = 1;		/* nothing (default) */

	for (i = 0; i < ARRAY_SIZE(topology_vals); i++) {
		struct topology_val *val = &topology_vals[i];
		int ok = sysfs_has_attribute(&sysfs, val->attr);

		rc = 1;	/* nothing */

		if (!ok) {
			if (!disk) {
				/*
				 * Read atrributes from "disk" if the current
				 * device is a partition.
				 */
				disk = blkid_probe_get_wholedisk_devno(pr);
				if (disk && disk != dev) {
					if (sysfs_init(&parent, disk, NULL) != 0)
						goto done;

					sysfs.parent = &parent;
					ok = sysfs_has_attribute(&sysfs,
								 val->attr);
				}
			}
			if (!ok)
				continue;	/* attribute does not exist */
		}

		if (val->set_ulong) {
			uint64_t data;

			if (sysfs_read_u64(&sysfs, val->attr, &data) != 0)
				continue;
			rc = val->set_ulong(pr, (unsigned long) data);

		} else if (val->set_int) {
			int64_t data;

			if (sysfs_read_s64(&sysfs, val->attr, &data) != 0)
				continue;
			rc = val->set_int(pr, (int) data);
		}

		if (rc < 0)
			goto done;	/* error */
		if (rc == 0)
			count++;
	}

done:
	sysfs_deinit(&sysfs);
	sysfs_deinit(&parent);

	if (count)
		return 0;		/* success */
	return rc;			/* error or nothing */
}

const struct blkid_idinfo sysfs_tp_idinfo =
{
	.name		= "sysfs",
	.probefunc	= probe_sysfs_tp,
	.magics		= BLKID_NONE_MAGIC
};

