示例#1
0
/**
 * pdcspath_store - This function writes a path to stable storage.
 * @entry: A pointer to an allocated pdcspath_entry.
 * 
 * It can be used in two ways: either by passing it a preset devpath struct
 * containing an already computed hardware path, or by passing it a device
 * pointer, from which it'll find out the corresponding hardware path.
 * For now we do not handle the case where there's an error in writing to the
 * Stable Storage area, so you'd better not mess up the data :P
 *
 * This function expects to be called with @entry->rw_lock write-hold.
 */
static void
pdcspath_store(struct pdcspath_entry *entry)
{
	struct device_path *devpath;

	BUG_ON(!entry);

	devpath = &entry->devpath;
	
	/* We expect the caller to set the ready flag to 0 if the hardware
	   path struct provided is invalid, so that we know we have to fill it.
	   First case, we don't have a preset hwpath... */
	if (!entry->ready) {
		/* ...but we have a device, map it */
		BUG_ON(!entry->dev);
		device_to_hwpath(entry->dev, (struct hardware_path *)devpath);
	}
	/* else, we expect the provided hwpath to be valid. */
	
	DPRINTK("%s: store: 0x%p, 0x%p, addr: 0x%lx\n", __func__,
			entry, devpath, entry->addr);

	/* addr, devpath and count must be word aligned */
	if (pdc_stable_write(entry->addr, devpath, sizeof(*devpath)) != PDC_OK) {
		printk(KERN_ERR "%s: an error occured when writing to PDC.\n"
				"It is likely that the Stable Storage data has been corrupted.\n"
				"Please check it carefully upon next reboot.\n", __func__);
		WARN_ON(1);
	}
		
	/* kobject is already registered */
	entry->ready = 2;
	
	DPRINTK("%s: device: 0x%p\n", __func__, entry->dev);
}
示例#2
0
/**
 * pdcs_osdep1_write - Stable Storage OS-Dependent data area 1 input.
 * @buf: The input buffer to read from.
 * @count: The number of bytes to be read.
 *
 * This can store 16 bytes of OS-Dependent data. We use a byte-by-byte
 * write approach. It's up to userspace to deal with it when constructing
 * its input buffer.
 */
static ssize_t pdcs_osdep1_write(struct kobject *kobj,
				 struct kobj_attribute *attr,
				 const char *buf, size_t count)
{
	u8 in[16];

	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;

	if (!buf || !count)
		return -EINVAL;

	if (unlikely(pdcs_osid != OS_ID_LINUX))
		return -EPERM;

	if (count > 16)
		return -EMSGSIZE;

	/* We'll use a local copy of buf */
	memset(in, 0, 16);
	memcpy(in, buf, count);

	if (pdc_stable_write(PDCS_ADDR_OSD1, &in, sizeof(in)) != PDC_OK)
		return -EIO;

	return count;
}
static void
pdcspath_store(struct pdcspath_entry *entry)
{
	struct device_path *devpath;

	BUG_ON(!entry);

	devpath = &entry->devpath;
	
	if (!entry->ready) {
		
		BUG_ON(!entry->dev);
		device_to_hwpath(entry->dev, (struct hardware_path *)devpath);
	}
	
	
	DPRINTK("%s: store: 0x%p, 0x%p, addr: 0x%lx\n", __func__,
			entry, devpath, entry->addr);

	
	if (pdc_stable_write(entry->addr, devpath, sizeof(*devpath)) != PDC_OK) {
		printk(KERN_ERR "%s: an error occurred when writing to PDC.\n"
				"It is likely that the Stable Storage data has been corrupted.\n"
				"Please check it carefully upon next reboot.\n", __func__);
		WARN_ON(1);
	}
		
	
	entry->ready = 2;
	
	DPRINTK("%s: device: 0x%p\n", __func__, entry->dev);
}
示例#4
0
/**
 * pdcs_osdep2_write - Stable Storage OS-Dependent data area 2 input.
 * @buf: The input buffer to read from.
 * @count: The number of bytes to be read.
 *
 * This can store pdcs_size - 224 bytes of OS-Dependent data. We use a
 * byte-by-byte write approach. It's up to userspace to deal with it when
 * constructing its input buffer.
 */
static ssize_t pdcs_osdep2_write(struct kobject *kobj,
				 struct kobj_attribute *attr,
				 const char *buf, size_t count)
{
	unsigned long size;
	unsigned short i;
	u8 in[4];

	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;

	if (!buf || !count)
		return -EINVAL;

	if (unlikely(pdcs_size <= 224))
		return -ENOSYS;

	if (unlikely(pdcs_osid != OS_ID_LINUX))
		return -EPERM;

	size = pdcs_size - 224;

	if (count > size)
		return -EMSGSIZE;

	/* We'll use a local copy of buf */

	for (i=0; i<count; i+=4) {
		memset(in, 0, 4);
		memcpy(in, buf+i, (count-i < 4) ? count-i : 4);
		if (unlikely(pdc_stable_write(PDCS_ADDR_OSD2 + i, &in,
					sizeof(in)) != PDC_OK))
			return -EIO;
	}

	return count;
}
示例#5
0
文件: setup.c 项目: Broadcom/stblinux
static int __init parisc_init(void)
{
	u32 osid = (OS_ID_LINUX << 16);

	parisc_proc_mkdir();
	parisc_init_resources();
	do_device_inventory();                  /* probe for hardware */

	parisc_pdc_chassis_init();
	
	/* set up a new led state on systems shipped LED State panel */
	pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART);

	/* tell PDC we're Linux. Nevermind failure. */
	pdc_stable_write(0x40, &osid, sizeof(osid));
	
	/* start with known state */
	flush_cache_all_local();
	flush_tlb_all_local(NULL);

	processor_init();
#ifdef CONFIG_SMP
	pr_info("CPU(s): %d out of %d %s at %d.%06d MHz online\n",
		num_online_cpus(), num_present_cpus(),
#else
	pr_info("CPU(s): 1 x %s at %d.%06d MHz\n",
#endif
			boot_cpu_data.cpu_name,
			boot_cpu_data.cpu_hz / 1000000,
			boot_cpu_data.cpu_hz % 1000000	);

	apply_alternatives_all();
	parisc_setup_cache_timing();

	/* These are in a non-obvious order, will fix when we have an iotree */
#if defined(CONFIG_IOSAPIC)
	iosapic_init();
#endif
#if defined(CONFIG_IOMMU_SBA)
	sba_init();
#endif
#if defined(CONFIG_PCI_LBA)
	lba_init();
#endif

	/* CCIO before any potential subdevices */
#if defined(CONFIG_IOMMU_CCIO)
	ccio_init();
#endif

	/*
	 * Need to register Asp & Wax before the EISA adapters for the IRQ
	 * regions.  EISA must come before PCI to be sure it gets IRQ region
	 * 0.
	 */
#if defined(CONFIG_GSC_LASI) || defined(CONFIG_GSC_WAX)
	gsc_init();
#endif
#ifdef CONFIG_EISA
	eisa_init();
#endif

#if defined(CONFIG_HPPB)
	hppb_init();
#endif

#if defined(CONFIG_GSC_DINO)
	dino_init();
#endif

#ifdef CONFIG_CHASSIS_LCD_LED
	register_led_regions();	/* register LED port info in procfs */
#endif

	return 0;
}