Esempio n. 1
0
/*
 *				SMBUS API FUNCTIONS
 *
 * Called from ig4iic_pci_attach/detach()
 */
int
ig4iic_attach(ig4iic_softc_t *sc)
{
	int error;
	uint32_t v;

	v = reg_read(sc, IG4_REG_COMP_TYPE);
	v = reg_read(sc, IG4_REG_COMP_PARAM1);
	v = reg_read(sc, IG4_REG_GENERAL);
	if ((v & IG4_GENERAL_SWMODE) == 0) {
		v |= IG4_GENERAL_SWMODE;
		reg_write(sc, IG4_REG_GENERAL, v);
		v = reg_read(sc, IG4_REG_GENERAL);
	}

	v = reg_read(sc, IG4_REG_SW_LTR_VALUE);
	v = reg_read(sc, IG4_REG_AUTO_LTR_VALUE);

	v = reg_read(sc, IG4_REG_COMP_VER);
	if (v != IG4_COMP_VER) {
		error = ENXIO;
		goto done;
	}
	v = reg_read(sc, IG4_REG_SS_SCL_HCNT);
	v = reg_read(sc, IG4_REG_SS_SCL_LCNT);
	v = reg_read(sc, IG4_REG_FS_SCL_HCNT);
	v = reg_read(sc, IG4_REG_FS_SCL_LCNT);
	v = reg_read(sc, IG4_REG_SDA_HOLD);

	v = reg_read(sc, IG4_REG_SS_SCL_HCNT);
	reg_write(sc, IG4_REG_FS_SCL_HCNT, v);
	v = reg_read(sc, IG4_REG_SS_SCL_LCNT);
	reg_write(sc, IG4_REG_FS_SCL_LCNT, v);

	/*
	 * Program based on a 25000 Hz clock.  This is a bit of a
	 * hack (obviously).  The defaults are 400 and 470 for standard
	 * and 60 and 130 for fast.  The defaults for standard fail
	 * utterly (presumably cause an abort) because the clock time
	 * is ~18.8ms by default.  This brings it down to ~4ms (for now).
	 */
	reg_write(sc, IG4_REG_SS_SCL_HCNT, 100);
	reg_write(sc, IG4_REG_SS_SCL_LCNT, 125);
	reg_write(sc, IG4_REG_FS_SCL_HCNT, 100);
	reg_write(sc, IG4_REG_FS_SCL_LCNT, 125);

	/*
	 * Use a threshold of 1 so we get interrupted on each character,
	 * allowing us to use mtx_sleep() in our poll code.  Not perfect
	 * but this is better than using DELAY() for receiving data.
	 *
	 * See ig4_var.h for details on interrupt handler synchronization.
	 */
	reg_write(sc, IG4_REG_RX_TL, 1);

	reg_write(sc, IG4_REG_CTL,
		  IG4_CTL_MASTER |
		  IG4_CTL_SLAVE_DISABLE |
		  IG4_CTL_RESTARTEN |
		  IG4_CTL_SPEED_STD);

	sc->smb = device_add_child(sc->dev, "smbus", -1);
	if (sc->smb == NULL) {
		device_printf(sc->dev, "smbus driver not found\n");
		error = ENXIO;
		goto done;
	}

#if 0
	/*
	 * Don't do this, it blows up the PCI config
	 */
	reg_write(sc, IG4_REG_RESETS, IG4_RESETS_ASSERT);
	reg_write(sc, IG4_REG_RESETS, IG4_RESETS_DEASSERT);
#endif

	/*
	 * Interrupt on STOP detect or receive character ready
	 */
	reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET |
					 IG4_INTR_RX_FULL);
	mtx_lock(&sc->io_lock);
	if (set_controller(sc, 0))
		device_printf(sc->dev, "controller error during attach-1\n");
	if (set_controller(sc, IG4_I2C_ENABLE))
		device_printf(sc->dev, "controller error during attach-2\n");
	mtx_unlock(&sc->io_lock);
	error = bus_setup_intr(sc->dev, sc->intr_res, INTR_TYPE_MISC | INTR_MPSAFE,
			       NULL, ig4iic_intr, sc, &sc->intr_handle);
	if (error) {
		device_printf(sc->dev,
			      "Unable to setup irq: error %d\n", error);
	}

	sc->enum_hook.ich_func = ig4iic_start;
	sc->enum_hook.ich_arg = sc->dev;

	/* We have to wait until interrupts are enabled. I2C read and write
	 * only works if the interrupts are available.
	 */
	if (config_intrhook_establish(&sc->enum_hook) != 0)
		error = ENOMEM;
	else
		error = 0;

done:
	return (error);
}
Esempio n. 2
0
/**
 * Tests the cgroup_compare_cgroup() api under different scenarios
 * @param ctl1 controller 1 to be used for testing
 * @param ctl2 controller 1 to be used for testing
 * @param the test number
 */
void test_cgroup_compare_cgroup(int ctl1, int ctl2, int i)
{
	int retval;

	struct cntl_val_t cval;
	cval.val_int64 = 0;
	cval.val_uint64 = 0;
	cval.val_bool = 0;
	strcpy(cval.val_string, "5000");

	struct cgroup *cgroup1 = NULL, *cgroup2 = NULL;
	struct cgroup_controller *controller = NULL;
	char controller_name[FILENAME_MAX], control_file[FILENAME_MAX];
	char wr[SIZE], extra[] = "in cgroup_compare_cgroup";

	retval = cgroup_compare_cgroup(NULL, NULL);
	if (retval)
		message(i++, PASS, "compare_cgroup()", retval, info[NULLGRP]);
	else
		message(i++, FAIL, "compare_cgroup()", retval, info[NULLGRP]);

	cgroup1 = cgroup_new_cgroup("testgroup");
	cgroup2 = cgroup_new_cgroup("testgroup");
	cgroup_set_uid_gid(cgroup1, 0, 0, 0, 0);
	cgroup_set_uid_gid(cgroup2, 0, 0, 0, 0);

	retval = set_controller(ctl1, controller_name, control_file);

	controller = cgroup_add_controller(cgroup1, controller_name);
	if (controller) {
		retval =  add_control_value(controller,
					 control_file, wr, STRING, cval);
		if (retval)
			message(i++, FAIL, wr, retval, extra);
	}

	controller = cgroup_add_controller(cgroup2, controller_name);
	if (controller) {
		retval =  add_control_value(controller,
					 control_file, wr, STRING, cval);
		if (retval)
			message(i++, FAIL, wr, retval, extra);
	}

	retval = cgroup_compare_cgroup(cgroup1, cgroup2);
	if (retval)
		message(i++, FAIL, "compare_cgroup()", retval, info[NOMESSAGE]);
	else
		message(i++, PASS, "compare_cgroup()", retval, info[NOMESSAGE]);

	/* Test the api by putting diff number of controllers in cgroups */
	retval = set_controller(ctl2, controller_name, control_file);
	controller = cgroup_add_controller(cgroup2, controller_name);
	if (controller) {
		retval =  add_control_value(controller,
					 control_file, wr, STRING, cval);
		if (retval)
			message(i++, FAIL, wr, retval, extra);
	}

	retval = cgroup_compare_cgroup(cgroup1, cgroup2);
	if (retval == ECGROUPNOTEQUAL)
		message(i++, PASS, "compare_cgroup()", retval, info[NOMESSAGE]);
	else
		message(i++, FAIL, "compare_cgroup()", retval, info[NOMESSAGE]);

	cgroup_free(&cgroup1);
	cgroup_free(&cgroup2);
}
Esempio n. 3
0
/**
 * Tests the cgroup_get_cgroup() api under different scenarios
 * @param ctl1 controller 1 to be used for testing
 * @param ctl2 controller 1 to be used for testing
 * @param struct ids the permissions struct
 * @param the test number
 */
void test_cgroup_get_cgroup(int ctl1, int ctl2, struct uid_gid_t ids, int i)
{
	struct cgroup *cgroup_filled = NULL, *cgroup_a = NULL, *cgroup_b = NULL;
	struct cgroup_controller *controller = NULL;
	char controller_name[FILENAME_MAX], control_file[FILENAME_MAX];
	struct cntl_val_t cval = {0, 0, 0, "5000"};
	int ret;

	/*
	 * No need to test the next 3 scenarios separately for Multimnt
	 * so testing them only under single mount
	 */
	if (fs_mounted == FS_MOUNTED) {
		/* 1. Test with nullcgroup first */
		ret = cgroup_get_cgroup(NULL);
		if (ret == ECGROUPNOTALLOWED)
			message(i++, PASS, "get_cgroup()", ret, info[NULLGRP]);
		else
			message(i++, FAIL, "get_cgroup()", ret, info[NULLGRP]);

		/* 2. Test with invalid name filled cgroup(non existing) */
		cgroup_filled = cgroup_new_cgroup("nogroup");
		if (!cgroup_filled)
			message(i++, FAIL, "new_cgroup()", 0, info[NOMESSAGE]);

		ret = cgroup_get_cgroup(cgroup_filled);
		if (ret)
			message(i++, PASS, "get_cgroup()", ret,
							 info[NOTCRTDGRP]);
		else
			message(i++, FAIL, "get_cgroup()", ret,
							 info[NOTCRTDGRP]);
		/* Free the allocated cgroup before reallocation */
		cgroup_free(&cgroup_filled);

		/* 3.
		 * Test with name filled cgroup. Ensure the group group1 exists
		 * in the filesystem before calling this test function
		 */
		cgroup_filled = cgroup_new_cgroup("group1");
		if (!cgroup_filled)
			message(i++, FAIL, "new_cgroup()", 0, info[NOMESSAGE]);

		ret = cgroup_get_cgroup(cgroup_filled);
		if (!ret)
			message(i++, PASS, "get_cgroup()", ret,
							 info[NOMESSAGE]);
		else
			message(i++, FAIL, "get_cgroup()", ret,
							 info[NOMESSAGE]);
	}

	/* SINGLE & MULTI MOUNT: Create, get and compare a cgroup */

	/* get cgroup_a ds and create group_a in filesystem */
	cgroup_a = create_new_cgroup_ds(ctl1, "group_a", STRING, cval, ids, 0);
	if (fs_mounted == FS_MULTI_MOUNTED) {
		/* Create under another controller also */
		ret = set_controller(ctl2, controller_name, control_file);
		controller = cgroup_add_controller(cgroup_a, controller_name);
		if (controller)
			message(i++, PASS, "cgroup_add_controller()",
					0, info[NOMESSAGE]);
		else
			message(i++, FAIL, "cgroup_add_controller()",
					-1, info[NOMESSAGE]);
	}
	test_cgroup_create_cgroup(0, cgroup_a, "group_a", 0, 1, 1, 00);

	/* create group_b ds to be filled by cgroup_get_cgroup */
	cgroup_b = cgroup_new_cgroup("group_a");
	if (!cgroup_b)
		message(i++, FAIL, "new_cgroup()", 0, info[NOMESSAGE]);
	/* Fill the ds and compare the two */
	ret = cgroup_get_cgroup(cgroup_b);
	if (!ret) {
		ret = cgroup_compare_cgroup(cgroup_a, cgroup_b);
		if (ret == 0)
			message(i++, PASS, "get_cgroup()", ret, info[SAMEGRP]);
		else
			message(i++, FAIL, "get_cgroup()", ret,
							 info[NOMESSAGE]);
	} else {
		message(i++, FAIL, "get_cgroup()", ret, info[NOMESSAGE]);
	}

	/* Delete this created group from fs to leave fs clean */
	if (fs_mounted == FS_MULTI_MOUNTED)
		test_cgroup_delete_cgroup(0, cgroup_a, "group_a", 1, 1, 0, 0);
	else
		test_cgroup_delete_cgroup(0, cgroup_a, "group_a", 0, 1, 0, 0);

	cgroup_free(&cgroup_a);
	cgroup_free(&cgroup_b);
	cgroup_free(&cgroup_filled);
}
Esempio n. 4
0
/*
 *				SMBUS API FUNCTIONS
 *
 * Called from ig4iic_pci_attach/detach()
 */
int
ig4iic_attach(ig4iic_softc_t *sc)
{
	int error;
	uint32_t v;


	v = reg_read(sc, IG4_REG_COMP_TYPE);
	printf("type %08x\n", v);
	v = reg_read(sc, IG4_REG_COMP_PARAM1);
	printf("params %08x\n", v);
	v = reg_read(sc, IG4_REG_COMP_VER);
	printf("version %08x\n", v);
	if (v != IG4_COMP_VER) {
		error = ENXIO;
		goto done;
	}
#if 1
	v = reg_read(sc, IG4_REG_SS_SCL_HCNT);
	printf("SS_SCL_HCNT %08x\n", v);
	v = reg_read(sc, IG4_REG_SS_SCL_LCNT);
	printf("SS_SCL_LCNT %08x\n", v);
	v = reg_read(sc, IG4_REG_FS_SCL_HCNT);
	printf("FS_SCL_HCNT %08x\n", v);
	v = reg_read(sc, IG4_REG_FS_SCL_LCNT);
	printf("FS_SCL_LCNT %08x\n", v);
	v = reg_read(sc, IG4_REG_SDA_HOLD);
	printf("HOLD        %08x\n", v);

	v = reg_read(sc, IG4_REG_SS_SCL_HCNT);
	reg_write(sc, IG4_REG_FS_SCL_HCNT, v);
	v = reg_read(sc, IG4_REG_SS_SCL_LCNT);
	reg_write(sc, IG4_REG_FS_SCL_LCNT, v);
#endif
	/*
	 * Program based on a 25000 Hz clock.  This is a bit of a
	 * hack (obviously).  The defaults are 400 and 470 for standard
	 * and 60 and 130 for fast.  The defaults for standard fail
	 * utterly (presumably cause an abort) because the clock time
	 * is ~18.8ms by default.  This brings it down to ~4ms (for now).
	 */
	reg_write(sc, IG4_REG_SS_SCL_HCNT, 100);
	reg_write(sc, IG4_REG_SS_SCL_LCNT, 125);
	reg_write(sc, IG4_REG_FS_SCL_HCNT, 100);
	reg_write(sc, IG4_REG_FS_SCL_LCNT, 125);

	/*
	 * Use a threshold of 1 so we get interrupted on each character,
	 * allowing us to use lksleep() in our poll code.  Not perfect
	 * but this is better than using DELAY() for receiving data.
	 */
	reg_write(sc, IG4_REG_RX_TL, 1);

	reg_write(sc, IG4_REG_CTL,
		  IG4_CTL_MASTER |
		  IG4_CTL_SLAVE_DISABLE |
		  IG4_CTL_RESTARTEN |
		  IG4_CTL_SPEED_STD);

	mtx_lock(&sc->mtx);
	sc->smb = device_add_child(sc->dev, "smbus", -1);
	if (sc->smb == NULL) {
		device_printf(sc->dev, "smbus driver not found\n");
		error = ENXIO;
		goto done;
	}

#if 0
	/*
	 * Don't do this, it blows up the PCI config
	 */
	reg_write(sc, IG4_REG_RESETS, IG4_RESETS_ASSERT);
	reg_write(sc, IG4_REG_RESETS, IG4_RESETS_DEASSERT);
#endif

	/*
	 * Interrupt on STOP detect or receive character ready
	 */
	reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET |
					 IG4_INTR_RX_FULL);
	if (set_controller(sc, 0))
		device_printf(sc->dev, "controller error during attach-1\n");
	if (set_controller(sc, IG4_I2C_ENABLE))
		device_printf(sc->dev, "controller error during attach-2\n");
	mtx_unlock(&sc->mtx);
	error = bus_setup_intr(sc->dev, sc->intr_res,
			       INTR_TYPE_MISC | INTR_MPSAFE, NULL,
			       ig4iic_intr, sc, &sc->intr_handle);
	if (error) {
		device_printf(sc->dev,
			      "Unable to setup irq: error %d\n", error);
		goto done;
	}

	/* Attach us to the smbus */
	error = bus_generic_attach(sc->dev);
	mtx_lock(&sc->mtx);
	if (error) {
		device_printf(sc->dev,
			      "failed to attach child: error %d\n", error);
		goto done;
	}
	sc->generic_attached = 1;

done:
	mtx_unlock(&sc->mtx);
	return error;
}