示例#1
0
/*
 *
 * edac_pci_create_sysfs
 *
 *	Create the controls/attributes for the specified EDAC PCI device
 */
int edac_pci_create_sysfs(struct edac_pci_ctl_info *pci)
{
	int err;
	struct kobject *edac_kobj = &pci->kobj;

	debugf0("%s() idx=%d\n", __func__, pci->pci_idx);

	/* create the top main EDAC PCI kobject, IF needed */
	err = edac_pci_main_kobj_setup();
	if (err)
		return err;

	/* Create this instance's kobject under the MAIN kobject */
	err = edac_pci_create_instance_kobj(pci, pci->pci_idx);
	if (err)
		goto unregister_cleanup;

	err = sysfs_create_link(edac_kobj, &pci->dev->kobj, EDAC_PCI_SYMLINK);
	if (err) {
		debugf0("%s() sysfs_create_link() returned err= %d\n",
			__func__, err);
		goto symlink_fail;
	}

	return 0;

	/* Error unwind stack */
symlink_fail:
	edac_pci_unregister_sysfs_instance_kobj(pci);

unregister_cleanup:
	edac_pci_main_kobj_teardown();

	return err;
}
示例#2
0
/*
 * edac_device_create_sysfs() Constructor
 *
 * accept a created edac_device control structure
 * and 'export' it to sysfs. The 'main' kobj should already have been
 * created. 'instance' and 'block' kobjects should be registered
 * along with any 'block' attributes from the low driver. In addition,
 * the main attributes (if any) are connected to the main kobject of
 * the control structure.
 *
 * Return:
 *	0	Success
 *	!0	Failure
 */
int edac_device_create_sysfs(struct edac_device_ctl_info *edac_dev)
{
	int err;
	struct kobject *edac_kobj = &edac_dev->kobj;

	debugf0("%s() idx=%d\n", __func__, edac_dev->dev_idx);

	/*  go create any main attributes callers wants */
	err = edac_device_add_main_sysfs_attributes(edac_dev);
	if (err) {
		debugf0("%s() failed to add sysfs attribs\n", __func__);
		goto err_out;
	}

	/* create a symlink from the edac device
	 * to the platform 'device' being used for this
	 */
	err = sysfs_create_link(edac_kobj,
				&edac_dev->dev->kobj, EDAC_DEVICE_SYMLINK);
	if (err) {
		debugf0("%s() sysfs_create_link() returned err= %d\n",
			__func__, err);
		goto err_remove_main_attribs;
	}

	/* Create the first level instance directories
	 * In turn, the nested blocks beneath the instances will
	 * be registered as well
	 */
	err = edac_device_create_instances(edac_dev);
	if (err) {
		debugf0("%s() edac_device_create_instances() "
			"returned err= %d\n", __func__, err);
		goto err_remove_link;
	}


	debugf4("%s() create-instances done, idx=%d\n",
		__func__, edac_dev->dev_idx);

	return 0;

	/* Error unwind stack */
err_remove_link:
	/* remove the sym link */
	sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK);

err_remove_main_attribs:
	edac_device_remove_main_sysfs_attributes(edac_dev);

err_out:
	return err;
}
示例#3
0
static int how_many_channels(struct pci_dev *pdev)
{
	unsigned char capid0_8b; 

	pci_read_config_byte(pdev, I3200_CAPID0 + 8, &capid0_8b);
	if (capid0_8b & 0x20) { 
		debugf0("In single channel mode.\n");
		return 1;
	} else {
		debugf0("In dual channel mode.\n");
		return 2;
	}
}
示例#4
0
static int how_many_channels(struct pci_dev *pdev)
{
	unsigned char capid0_8b; /* 8th byte of CAPID0 */

	pci_read_config_byte(pdev, I3200_CAPID0 + 8, &capid0_8b);
	if (capid0_8b & 0x20) { /* check DCD: Dual Channel Disable */
		debugf0("In single channel mode.\n");
		return 1;
	} else {
		debugf0("In dual channel mode.\n");
		return 2;
	}
}
示例#5
0
/*
 * edac_pci_main_kobj_teardown()
 *
 *	if no longer linked (needed) remove the top level EDAC PCI
 *	kobject with its controls and attributes
 */
static void edac_pci_main_kobj_teardown(void)
{
	debugf0("%s()\n", __func__);

	/* Decrement the count and only if no more controller instances
	 * are connected perform the unregisteration of the top level
	 * main kobj
	 */
	if (atomic_dec_return(&edac_pci_sysfs_refcount) == 0) {
		debugf0("%s() called kobject_put on main kobj\n",
			__func__);
		kobject_put(edac_pci_top_main_kobj);
	}
}
示例#6
0
/*
 * Do a DRAM ECC write. Assemble staged values in the pvt area and format into
 * fields needed by the injection registers.
 */
static ssize_t amd64_inject_write_store(struct mem_ctl_info *mci,
					const char *data, size_t count)
{
	struct amd64_pvt *pvt = mci->pvt_info;
	unsigned long value;
	u32 section, word_bits;
	int ret = 0;

	ret = strict_strtoul(data, 10, &value);
	if (ret != -EINVAL) {

		/* Form value to choose 16-byte section of cacheline */
		section = F10_NB_ARRAY_DRAM_ECC |
				SET_NB_ARRAY_ADDRESS(pvt->injection.section);
		pci_write_config_dword(pvt->misc_f3_ctl,
					F10_NB_ARRAY_ADDR, section);

		word_bits = SET_NB_DRAM_INJECTION_WRITE(pvt->injection.word,
						pvt->injection.bit_map);

		/* Issue 'word' and 'bit' along with the READ request */
		pci_write_config_dword(pvt->misc_f3_ctl,
					F10_NB_ARRAY_DATA, word_bits);

		debugf0("section=0x%x word_bits=0x%x\n", section, word_bits);

		return count;
	}
	return ret;
}
示例#7
0
static void edac_sysfs_pci_teardown(void)
{
	debugf0("%s()\n", __func__);
	init_completion(&edac_pci_kobj_complete);
	kobject_unregister(&edac_pci_kobj);
	wait_for_completion(&edac_pci_kobj_complete);
}
示例#8
0
/*
 * edac_pci_remove_sysfs
 *
 *	remove the controls and attributes for this EDAC PCI device
 */
void edac_pci_remove_sysfs(struct edac_pci_ctl_info *pci)
{
	debugf0("%s() index=%d\n", __func__, pci->pci_idx);

	/* Remove the symlink */
	sysfs_remove_link(&pci->kobj, EDAC_PCI_SYMLINK);

	/* remove this PCI instance's sysfs entries */
	edac_pci_unregister_sysfs_instance_kobj(pci);

	/* Call the main unregister function, which will determine
	 * if this 'pci' is the last instance.
	 * If it is, the main kobject will be unregistered as a result
	 */
	debugf0("%s() calling edac_pci_main_kobj_teardown()\n", __func__);
	edac_pci_main_kobj_teardown();
}
示例#9
0
/* returns count (>= 0), or negative on error */
static int __devinit r82600_init_one(struct pci_dev *pdev,
				const struct pci_device_id *ent)
{
	debugf0("%s()\n", __func__);

	/* don't need to call pci_enable_device() */
	return r82600_probe1(pdev, ent->driver_data);
}
示例#10
0
文件: edac_module.c 项目: 08opt/linux
/*
 * edac_exit()
 *      module exit/termination function
 */
static void __exit edac_exit(void)
{
	debugf0("%s()\n", __func__);

	/* tear down the various subsystems */
	edac_workqueue_teardown();
	edac_sysfs_teardown_mc_kset();
}
int edac_device_create_sysfs(struct edac_device_ctl_info *edac_dev)
{
	int err;
	struct kobject *edac_kobj = &edac_dev->kobj;

	debugf0("%s() idx=%d\n", __func__, edac_dev->dev_idx);

	
	err = edac_device_add_main_sysfs_attributes(edac_dev);
	if (err) {
		debugf0("%s() failed to add sysfs attribs\n", __func__);
		goto err_out;
	}

	err = sysfs_create_link(edac_kobj,
				&edac_dev->dev->kobj, EDAC_DEVICE_SYMLINK);
	if (err) {
		debugf0("%s() sysfs_create_link() returned err= %d\n",
			__func__, err);
		goto err_remove_main_attribs;
	}

	err = edac_device_create_instances(edac_dev);
	if (err) {
		debugf0("%s() edac_device_create_instances() "
			"returned err= %d\n", __func__, err);
		goto err_remove_link;
	}


	debugf4("%s() create-instances done, idx=%d\n",
		__func__, edac_dev->dev_idx);

	return 0;

	
err_remove_link:
	
	sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK);

err_remove_main_attribs:
	edac_device_remove_main_sysfs_attributes(edac_dev);

err_out:
	return err;
}
void edac_device_unregister_sysfs_main_kobj(struct edac_device_ctl_info *dev)
{
	debugf0("%s()\n", __func__);
	debugf4("%s() name of kobject is: %s\n",
		__func__, kobject_name(&dev->kobj));

	kobject_put(&dev->kobj);
	edac_put_sysfs_subsys();
}
示例#13
0
/*
 * edac_pci_unregister_sysfs_instance_kobj
 *
 *	unregister the kobj for the EDAC PCI instance
 */
static void edac_pci_unregister_sysfs_instance_kobj(
			struct edac_pci_ctl_info *pci)
{
	debugf0("%s()\n", __func__);

	/* Unregister the instance kobject and allow its release
	 * function release the main reference count and then
	 * kfree the memory
	 */
	kobject_put(&pci->kobj);
}
示例#14
0
/*
 * edac_pci_release_main_kobj
 *
 *	This release function is called when the reference count to the
 *	passed kobj goes to zero.
 *
 *	This kobj is the 'main' kobject that EDAC PCI instances
 *	link to, and thus provide for proper nesting counts
 */
static void edac_pci_release_main_kobj(struct kobject *kobj)
{
	debugf0("%s() here to module_put(THIS_MODULE)\n", __func__);

	kfree(kobj);

	/* last reference to top EDAC PCI kobject has been removed,
	 * NOW release our ref count on the core module
	 */
	module_put(THIS_MODULE);
}
示例#15
0
static void __devexit r82600_remove_one(struct pci_dev *pdev)
{
	struct mem_ctl_info *mci;

	debugf0("%s()\n", __func__);

	if ((mci = edac_mc_del_mc(&pdev->dev)) == NULL)
		return;

	edac_mc_free(mci);
}
示例#16
0
/*
 * edac_device_remove_sysfs() destructor
 *
 * given an edac_device struct, tear down the kobject resources
 */
void edac_device_remove_sysfs(struct edac_device_ctl_info *edac_dev)
{
	debugf0("%s()\n", __func__);

	/* remove any main attributes for this device */
	edac_device_remove_main_sysfs_attributes(edac_dev);

	/* remove the device sym link */
	sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK);

	/* walk the instance/block kobject tree, deconstructing it */
	edac_device_delete_instances(edac_dev);
}
void edac_device_remove_sysfs(struct edac_device_ctl_info *edac_dev)
{
	debugf0("%s()\n", __func__);

	
	edac_device_remove_main_sysfs_attributes(edac_dev);

	
	sysfs_remove_link(&edac_dev->kobj, EDAC_DEVICE_SYMLINK);

	
	edac_device_delete_instances(edac_dev);
}
示例#18
0
static int __init i3000_init(void)
{
	int pci_rc;

	debugf3("MC: %s()\n", __func__);
	pci_rc = pci_register_driver(&i3000_driver);
	if (pci_rc < 0)
		goto fail0;

	if (mci_pdev == NULL) {
		i3000_registered = 0;
		mci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
					PCI_DEVICE_ID_INTEL_3000_HB, NULL);
		if (!mci_pdev) {
			debugf0("i3000 pci_get_device fail\n");
			pci_rc = -ENODEV;
			goto fail1;
		}

		pci_rc = i3000_init_one(mci_pdev, i3000_pci_tbl);
		if (pci_rc < 0) {
			debugf0("i3000 init fail\n");
			pci_rc = -ENODEV;
			goto fail1;
		}
	}

	return 0;

fail1:
	pci_unregister_driver(&i3000_driver);

fail0:
	if (mci_pdev)
		pci_dev_put(mci_pdev);

	return pci_rc;
}
示例#19
0
/* DEVICE instance kobject release() function */
static void edac_pci_instance_release(struct kobject *kobj)
{
	struct edac_pci_ctl_info *pci;

	debugf0("%s()\n", __func__);

	/* Form pointer to containing struct, the pci control struct */
	pci = to_instance(kobj);

	/* decrement reference count on top main kobj */
	kobject_put(edac_pci_top_main_kobj);

	kfree(pci);	/* Free the control struct */
}
示例#20
0
/*
 * MC teardown:
 *	the '..../edac/mc' kobject followed by '..../edac' itself
 */
static void edac_sysfs_memctrl_teardown(void)
{
	debugf0("MC: " __FILE__ ": %s()\n", __func__);

	/* Unregister the MC's kobject and wait for reference count to reach
	 * 0.
	 */
	init_completion(&edac_memctrl_kobj_complete);
	kobject_unregister(&edac_memctrl_kobj);
	wait_for_completion(&edac_memctrl_kobj_complete);

	/* Unregister the 'edac' object */
	sysdev_class_unregister(&edac_class);
}
示例#21
0
/* Clear any PCI parity errors logged by this device. */
static void edac_pci_dev_parity_clear(struct pci_dev *dev)
{
	u8 header_type;

	debugf0("%s()\n", __func__);

	get_pci_parity_status(dev, 0);

	/* read the device TYPE, looking for bridges */
	pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type);

	if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE)
		get_pci_parity_status(dev, 1);
}
示例#22
0
/* returns count (>= 0), or negative on error */
static int __devinit i3000_init_one(struct pci_dev *pdev,
				const struct pci_device_id *ent)
{
	int rc;

	debugf0("MC: %s()\n", __func__);

	if (pci_enable_device(pdev) < 0)
		return -EIO;

	rc = i3000_probe1(pdev, ent->driver_data);
	if (mci_pdev == NULL)
		mci_pdev = pci_dev_get(pdev);

	return rc;
}
示例#23
0
/*
 * edac_device_unregister_sysfs_main_kobj:
 *	the '..../edac/<name>' kobject
 */
void edac_device_unregister_sysfs_main_kobj(struct edac_device_ctl_info *dev)
{
	debugf0("%s()\n", __func__);
	debugf4("%s() name of kobject is: %s\n",
		__func__, kobject_name(&dev->kobj));

	/*
	 * Unregister the edac device's kobject and
	 * allow for reference count to reach 0 at which point
	 * the callback will be called to:
	 *   a) module_put() this module
	 *   b) 'kfree' the memory
	 */
	kobject_put(&dev->kobj);
	edac_put_sysfs_class();
}
示例#24
0
文件: mpc85xx_edac.c 项目: E-LLP/n900
static int mpc85xx_l2_err_remove(struct of_device *op)
{
	struct edac_device_ctl_info *edac_dev = dev_get_drvdata(&op->dev);
	struct mpc85xx_l2_pdata *pdata = edac_dev->pvt_info;

	debugf0("%s()\n", __func__);

	if (edac_op_state == EDAC_OPSTATE_INT) {
		out_be32(pdata->l2_vbase + MPC85XX_L2_ERRINTEN, 0);
		irq_dispose_mapping(pdata->irq);
	}

	out_be32(pdata->l2_vbase + MPC85XX_L2_ERRDIS, orig_l2_err_disable);
	edac_device_del_device(&op->dev);
	edac_device_free_ctl_info(edac_dev);
	return 0;
}
示例#25
0
文件: mpc85xx_edac.c 项目: E-LLP/n900
static int mpc85xx_mc_err_remove(struct of_device *op)
{
	struct mem_ctl_info *mci = dev_get_drvdata(&op->dev);
	struct mpc85xx_mc_pdata *pdata = mci->pvt_info;

	debugf0("%s()\n", __func__);

	if (edac_op_state == EDAC_OPSTATE_INT) {
		out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_INT_EN, 0);
		irq_dispose_mapping(pdata->irq);
	}

	out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_DISABLE,
		 orig_ddr_err_disable);
	out_be32(pdata->mc_vbase + MPC85XX_MC_ERR_SBE, orig_ddr_err_sbe);

	edac_mc_del_mc(&op->dev);
	edac_mc_free(mci);
	return 0;
}
static int edac_device_create_instances(struct edac_device_ctl_info *edac_dev)
{
	int i, j;
	int err;

	debugf0("%s()\n", __func__);

	
	for (i = 0; i < edac_dev->nr_instances; i++) {
		err = edac_device_create_instance(edac_dev, i);
		if (err) {
			
			for (j = 0; j < i; j++)
				edac_device_delete_instance(edac_dev, j);
			return err;
		}
	}

	return 0;
}
示例#27
0
/*
 * edac_device_create_instances
 *	create the first level of 'instances' for this device
 *	(ie  'cache' might have 'cache0', 'cache1', 'cache2', etc
 */
static int edac_device_create_instances(struct edac_device_ctl_info *edac_dev)
{
	int i, j;
	int err;

	debugf0("%s()\n", __func__);

	/* iterate over creation of the instances */
	for (i = 0; i < edac_dev->nr_instances; i++) {
		err = edac_device_create_instance(edac_dev, i);
		if (err) {
			/* unwind previous instances on error */
			for (j = 0; j < i; j++)
				edac_device_delete_instance(edac_dev, j);
			return err;
		}
	}

	return 0;
}
示例#28
0
文件: mpc85xx_edac.c 项目: E-LLP/n900
static int mpc85xx_pci_err_remove(struct of_device *op)
{
	struct edac_pci_ctl_info *pci = dev_get_drvdata(&op->dev);
	struct mpc85xx_pci_pdata *pdata = pci->pvt_info;

	debugf0("%s()\n", __func__);

	out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_CAP_DR,
		 orig_pci_err_cap_dr);

	out_be32(pdata->pci_vbase + MPC85XX_PCI_ERR_EN, orig_pci_err_en);

	edac_pci_del_device(pci->dev);

	if (edac_op_state == EDAC_OPSTATE_INT)
		irq_dispose_mapping(pdata->irq);

	edac_pci_free_ctl_info(pci);

	return 0;
}
示例#29
0
/*
 * accept a hex value and store it into the virtual error register file, field:
 * nbeal and nbeah. Assume virtual error values have already been set for: NBSL,
 * NBSH and NBCFG. Then proceed to map the error values to a MC, CSROW and
 * CHANNEL
 */
static ssize_t amd64_nbea_store(struct mem_ctl_info *mci, const char *data,
				size_t count)
{
	struct amd64_pvt *pvt = mci->pvt_info;
	unsigned long long value;
	int ret = 0;

	ret = strict_strtoull(data, 16, &value);
	if (ret != -EINVAL) {
		debugf0("received NBEA= 0x%llx\n", value);

		/* place the value into the virtual error packet */
		pvt->ctl_error_info.nbeal = (u32) value;
		value >>= 32;
		pvt->ctl_error_info.nbeah = (u32) value;

		/* Process the Mapping request */
		/* TODO: Add race prevention */
		amd_decode_nb_mce(pvt->mc_node_id, &pvt->ctl_error_info, 1);

		return count;
	}
示例#30
0
/*
 * edac_pci_create_instance_kobj
 *
 *	construct one EDAC PCI instance's kobject for use
 */
static int edac_pci_create_instance_kobj(struct edac_pci_ctl_info *pci, int idx)
{
	struct kobject *main_kobj;
	int err;

	debugf0("%s()\n", __func__);

	/* First bump the ref count on the top main kobj, which will
	 * track the number of PCI instances we have, and thus nest
	 * properly on keeping the module loaded
	 */
	main_kobj = kobject_get(edac_pci_top_main_kobj);
	if (!main_kobj) {
		err = -ENODEV;
		goto error_out;
	}

	/* And now register this new kobject under the main kobj */
	err = kobject_init_and_add(&pci->kobj, &ktype_pci_instance,
				   edac_pci_top_main_kobj, "pci%d", idx);
	if (err != 0) {
		debugf2("%s() failed to register instance pci%d\n",
			__func__, idx);
		kobject_put(edac_pci_top_main_kobj);
		goto error_out;
	}

	kobject_uevent(&pci->kobj, KOBJ_ADD);
	debugf1("%s() Register instance 'pci%d' kobject\n", __func__, idx);

	return 0;

	/* Error unwind statck */
error_out:
	return err;
}