static void calc_order(void)
{
	int diff;
	int order;

	order = get_bitmask_order(SUSPEND_PD_PAGES(pmdisk_pages));
	pmdisk_pages += 1 << order;
	do {
		diff = get_bitmask_order(SUSPEND_PD_PAGES(pmdisk_pages)) - order;
		if (diff) {
			order += diff;
			pmdisk_pages += 1 << diff;
		}
	} while(diff);
	pagedir_order = order;
}
static int __init read_pagedir(void)
{
	unsigned long addr;
	int i, n = pmdisk_info.pagedir_pages;
	int error = 0;

	pagedir_order = get_bitmask_order(n);

	addr =__get_free_pages(GFP_ATOMIC, pagedir_order);
	if (!addr)
		return -ENOMEM;
	pm_pagedir_nosave = (struct pbe *)addr;

	pr_debug("pmdisk: Reading pagedir (%d Pages)\n",n);

	for (i = 0; i < n && !error; i++, addr += PAGE_SIZE) {
		unsigned long offset = swp_offset(pmdisk_info.pagedir[i]);
		if (offset)
			error = read_page(offset, (void *)addr);
		else
			error = -EFAULT;
	}
	if (error)
		free_pages((unsigned long)pm_pagedir_nosave,pagedir_order);
	return error;
}
示例#3
0
文件: swsusp.c 项目: xricson/knoppix
static suspend_pagedir_t *create_suspend_pagedir(int nr_copy_pages)
{
	int i;
	suspend_pagedir_t *pagedir;
	struct pbe *p;
	struct page *page;

	pagedir_order = get_bitmask_order(SUSPEND_PD_PAGES(nr_copy_pages));

	p = pagedir = (suspend_pagedir_t *)__get_free_pages(GFP_ATOMIC | __GFP_COLD, pagedir_order);
	if(!pagedir)
		return NULL;

	page = virt_to_page(pagedir);
	for(i=0; i < 1<<pagedir_order; i++)
		SetPageNosave(page++);
		
	while(nr_copy_pages--) {
		p->address = get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
		if(!p->address) {
			free_suspend_pagedir((unsigned long) pagedir);
			return NULL;
		}
		SetPageNosave(virt_to_page(p->address));
		p->orig_address = 0;
		p++;
	}
	return pagedir;
}
示例#4
0
static void calc_order(void)
{
	int diff = 0;
	int order = 0;

	do {
		diff = get_bitmask_order(SUSPEND_PD_PAGES(nr_copy_pages)) - order;
		if (diff) {
			order += diff;
			nr_copy_pages += 1 << diff;
		}
	} while(diff);
	pagedir_order = order;
}
int escore_write(struct snd_soc_codec *codec, unsigned int reg,
		       unsigned int value)
{
	struct escore_priv *escore = &escore_priv;
	struct escore_api_access *api_access;
	u32 api_word[2] = {0};
	int msg_len;
	unsigned int val_mask;
	int i;
	int rc = 0;

	if (reg > escore->api_addr_max) {
		pr_err("%s(): invalid address = 0x%04x\n", __func__, reg);
		return -EINVAL;
	}

	pr_debug("%s(): reg=%08x val=%d\n", __func__, reg, value);

	api_access = &escore->escore_api_access[reg];
	msg_len = api_access->write_msg_len;
	val_mask = (1 << get_bitmask_order(api_access->val_max)) - 1;
	memcpy((char *)api_word, (char *)api_access->write_msg, msg_len);

	switch (msg_len) {
	case 8:
		api_word[1] |= (val_mask & value);
		break;
	case 4:
		api_word[0] |= (val_mask & value);
		break;
	}

	pr_debug("%s(): mutex lock\n", __func__);
	mutex_lock(&escore->api_mutex);
	for (i = 0; i < msg_len / 4; i++) {
		rc = escore_cmd(escore, api_word[i]);
		if (rc < 0) {
			pr_err("%s(): escore_cmd()", __func__);
			pr_info("%s(): mutex unlock\n", __func__);
			mutex_unlock(&escore->api_mutex);
			return rc;
		}
	}
	pr_debug("%s(): mutex unlock\n", __func__);
	mutex_unlock(&escore->api_mutex);

	return rc;
}
示例#6
0
static int __init check_header(void)
{
	const char * reason = NULL;
	int error;

	if ((error = bio_read_page(swp_offset(swsusp_header.swsusp_info), &swsusp_info)))
		return error;

 	/* Is this same machine? */
	if ((reason = sanity_check())) {
		printk(KERN_ERR "swsusp: Resume mismatch: %s\n",reason);
		return -EPERM;
	}
	nr_copy_pages = swsusp_info.image_pages;
	pagedir_order = get_bitmask_order(SUSPEND_PD_PAGES(nr_copy_pages));
	return error;
}
示例#7
0
static int omfs_fill_super(struct super_block *sb, void *data, int silent)
{
	struct buffer_head *bh, *bh2;
	struct omfs_super_block *omfs_sb;
	struct omfs_root_block *omfs_rb;
	struct omfs_sb_info *sbi;
	struct inode *root;
	int ret = -EINVAL;

	sbi = kzalloc(sizeof(struct omfs_sb_info), GFP_KERNEL);
	if (!sbi)
		return -ENOMEM;

	sb->s_fs_info = sbi;

	sbi->s_uid = current_uid();
	sbi->s_gid = current_gid();
	sbi->s_dmask = sbi->s_fmask = current_umask();

	if (!parse_options((char *) data, sbi))
		goto end;

	sb->s_maxbytes = 0xffffffff;

	sb_set_blocksize(sb, 0x200);

	bh = sb_bread(sb, 0);
	if (!bh)
		goto end;

	omfs_sb = (struct omfs_super_block *)bh->b_data;

	if (omfs_sb->s_magic != cpu_to_be32(OMFS_MAGIC)) {
		if (!silent)
			printk(KERN_ERR "omfs: Invalid superblock (%x)\n",
				   omfs_sb->s_magic);
		goto out_brelse_bh;
	}
	sb->s_magic = OMFS_MAGIC;

	sbi->s_num_blocks = be64_to_cpu(omfs_sb->s_num_blocks);
	sbi->s_blocksize = be32_to_cpu(omfs_sb->s_blocksize);
	sbi->s_mirrors = be32_to_cpu(omfs_sb->s_mirrors);
	sbi->s_root_ino = be64_to_cpu(omfs_sb->s_root_block);
	sbi->s_sys_blocksize = be32_to_cpu(omfs_sb->s_sys_blocksize);
	mutex_init(&sbi->s_bitmap_lock);

	if (sbi->s_num_blocks > OMFS_MAX_BLOCKS) {
		printk(KERN_ERR "omfs: sysblock number (%llx) is out of range\n",
		       (unsigned long long)sbi->s_num_blocks);
		goto out_brelse_bh;
	}

	if (sbi->s_sys_blocksize > PAGE_SIZE) {
		printk(KERN_ERR "omfs: sysblock size (%d) is out of range\n",
			sbi->s_sys_blocksize);
		goto out_brelse_bh;
	}

	if (sbi->s_blocksize < sbi->s_sys_blocksize ||
	    sbi->s_blocksize > OMFS_MAX_BLOCK_SIZE) {
		printk(KERN_ERR "omfs: block size (%d) is out of range\n",
			sbi->s_blocksize);
		goto out_brelse_bh;
	}

	/*
	 * Use sys_blocksize as the fs block since it is smaller than a
	 * page while the fs blocksize can be larger.
	 */
	sb_set_blocksize(sb, sbi->s_sys_blocksize);

	/*
	 * ...and the difference goes into a shift.  sys_blocksize is always
	 * a power of two factor of blocksize.
	 */
	sbi->s_block_shift = get_bitmask_order(sbi->s_blocksize) -
		get_bitmask_order(sbi->s_sys_blocksize);

	bh2 = omfs_bread(sb, be64_to_cpu(omfs_sb->s_root_block));
	if (!bh2)
		goto out_brelse_bh;

	omfs_rb = (struct omfs_root_block *)bh2->b_data;

	sbi->s_bitmap_ino = be64_to_cpu(omfs_rb->r_bitmap);
	sbi->s_clustersize = be32_to_cpu(omfs_rb->r_clustersize);

	if (sbi->s_num_blocks != be64_to_cpu(omfs_rb->r_num_blocks)) {
		printk(KERN_ERR "omfs: block count discrepancy between "
			"super and root blocks (%llx, %llx)\n",
			(unsigned long long)sbi->s_num_blocks,
			(unsigned long long)be64_to_cpu(omfs_rb->r_num_blocks));
		goto out_brelse_bh2;
	}

	if (sbi->s_bitmap_ino != ~0ULL &&
	    sbi->s_bitmap_ino > sbi->s_num_blocks) {
		printk(KERN_ERR "omfs: free space bitmap location is corrupt "
			"(%llx, total blocks %llx)\n",
			(unsigned long long) sbi->s_bitmap_ino,
			(unsigned long long) sbi->s_num_blocks);
		goto out_brelse_bh2;
	}
	if (sbi->s_clustersize < 1 ||
	    sbi->s_clustersize > OMFS_MAX_CLUSTER_SIZE) {
		printk(KERN_ERR "omfs: cluster size out of range (%d)",
			sbi->s_clustersize);
		goto out_brelse_bh2;
	}

	ret = omfs_get_imap(sb);
	if (ret)
		goto out_brelse_bh2;

	sb->s_op = &omfs_sops;

	root = omfs_iget(sb, be64_to_cpu(omfs_rb->r_root_dir));
	if (IS_ERR(root)) {
		ret = PTR_ERR(root);
		goto out_brelse_bh2;
	}

	sb->s_root = d_make_root(root);
	if (!sb->s_root) {
		ret = -ENOMEM;
		goto out_brelse_bh2;
	}
	printk(KERN_DEBUG "omfs: Mounted volume %s\n", omfs_rb->r_name);

	ret = 0;
out_brelse_bh2:
	brelse(bh2);
out_brelse_bh:
	brelse(bh);
end:
	if (ret)
		kfree(sbi);
	return ret;
}
示例#8
0
文件: swsusp.c 项目: xricson/knoppix
static int __read_suspend_image(struct block_device *bdev, union diskpage *cur, int noresume)
{
	swp_entry_t next;
	int i, nr_pgdir_pages;

#define PREPARENEXT \
	{	next = cur->link.next; \
		next.val = swp_offset(next) * PAGE_SIZE; \
        }

	if (bdev_read_page(bdev, 0, cur)) return -EIO;

	if ((!memcmp("SWAP-SPACE",cur->swh.magic.magic,10)) ||
	    (!memcmp("SWAPSPACE2",cur->swh.magic.magic,10))) {
		printk(KERN_ERR "%sThis is normal swap space\n", name_resume );
		return -EINVAL;
	}

	PREPARENEXT; /* We have to read next position before we overwrite it */

	if (!memcmp("S1",cur->swh.magic.magic,2))
		memcpy(cur->swh.magic.magic,"SWAP-SPACE",10);
	else if (!memcmp("S2",cur->swh.magic.magic,2))
		memcpy(cur->swh.magic.magic,"SWAPSPACE2",10);
	else {
		if (noresume)
			return -EINVAL;
		panic("%sUnable to find suspended-data signature (%.10s - misspelled?\n", 
			name_resume, cur->swh.magic.magic);
	}
	if (noresume) {
		/* We don't do a sanity check here: we want to restore the swap
		   whatever version of kernel made the suspend image;
		   We need to write swap, but swap is *not* enabled so
		   we must write the device directly */
		printk("%s: Fixing swap signatures %s...\n", name_resume, resume_file);
		bdev_write_page(bdev, 0, cur);
	}

	printk( "%sSignature found, resuming\n", name_resume );
	MDELAY(1000);

	if (bdev_read_page(bdev, next.val, cur)) return -EIO;
	if (sanity_check(&cur->sh)) 	/* Is this same machine? */	
		return -EPERM;
	PREPARENEXT;

	pagedir_save = cur->sh.suspend_pagedir;
	nr_copy_pages = cur->sh.num_pbes;
	nr_pgdir_pages = SUSPEND_PD_PAGES(nr_copy_pages);
	pagedir_order = get_bitmask_order(nr_pgdir_pages);

	pagedir_nosave = (suspend_pagedir_t *)__get_free_pages(GFP_ATOMIC, pagedir_order);
	if (!pagedir_nosave)
		return -ENOMEM;

	PRINTK( "%sReading pagedir, ", name_resume );

	/* We get pages in reverse order of saving! */
	for (i=nr_pgdir_pages-1; i>=0; i--) {
		BUG_ON (!next.val);
		cur = (union diskpage *)((char *) pagedir_nosave)+i;
		if (bdev_read_page(bdev, next.val, cur)) return -EIO;
		PREPARENEXT;
	}
	BUG_ON (next.val);

	if (relocate_pagedir())
		return -ENOMEM;
	if (check_pagedir())
		return -ENOMEM;

	printk( "Reading image data (%d pages): ", nr_copy_pages );
	for(i=0; i < nr_copy_pages; i++) {
		swp_entry_t swap_address = (pagedir_nosave+i)->swap_address;
		if (!(i%100))
			printk( "." );
		/* You do not need to check for overlaps...
		   ... check_pagedir already did this work */
		if (bdev_read_page(bdev, swp_offset(swap_address) * PAGE_SIZE, (char *)((pagedir_nosave+i)->address)))
			return -EIO;
	}
	printk( "|\n" );
	return 0;
}