Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 420edbcc authored by Carsten Otte's avatar Carsten Otte Committed by Linus Torvalds
Browse files

[PATCH] xip: bdev: execute in place



This is the block device related part.  The block device operation
direct_access now has a struct block_device as first parameter.

Signed-off-by: default avatarCarsten Otte <cotte@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 3d41088f
Loading
Loading
Loading
Loading
+40 −4
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@
static int dcssblk_open(struct inode *inode, struct file *filp);
static int dcssblk_release(struct inode *inode, struct file *filp);
static int dcssblk_make_request(struct request_queue *q, struct bio *bio);
static int dcssblk_direct_access(struct block_device *bdev, sector_t secnum,
				 unsigned long *data);

static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0";

@@ -43,6 +45,7 @@ static struct block_device_operations dcssblk_devops = {
	.owner   	= THIS_MODULE,
	.open    	= dcssblk_open,
	.release 	= dcssblk_release,
	.direct_access 	= dcssblk_direct_access,
};

static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *attr, const char * buf,
@@ -641,6 +644,20 @@ dcssblk_make_request(request_queue_t *q, struct bio *bio)
		/* Request beyond end of DCSS segment. */
		goto fail;
	}
	/* verify data transfer direction */
	if (dev_info->is_shared) {
		switch (dev_info->segment_type) {
		case SEG_TYPE_SR:
		case SEG_TYPE_ER:
		case SEG_TYPE_SC:
			/* cannot write to these segments */
			if (bio_data_dir(bio) == WRITE) {
				PRINT_WARN("rejecting write to ro segment %s\n", dev_info->dev.bus_id);
				goto fail;
			}
		}
	}

	index = (bio->bi_sector >> 3);
	bio_for_each_segment(bvec, bio, i) {
		page_addr = (unsigned long)
@@ -661,7 +678,26 @@ dcssblk_make_request(request_queue_t *q, struct bio *bio)
	bio_endio(bio, bytes_done, 0);
	return 0;
fail:
	bio_io_error(bio, bytes_done);
	bio_io_error(bio, bio->bi_size);
	return 0;
}

static int
dcssblk_direct_access (struct block_device *bdev, sector_t secnum,
			unsigned long *data)
{
	struct dcssblk_dev_info *dev_info;
	unsigned long pgoff;

	dev_info = bdev->bd_disk->private_data;
	if (!dev_info)
		return -ENODEV;
	if (secnum % (PAGE_SIZE/512))
		return -EINVAL;
	pgoff = secnum / (PAGE_SIZE / 512);
	if ((pgoff+1)*PAGE_SIZE-1 > dev_info->end - dev_info->start)
		return -ERANGE;
	*data = (unsigned long) (dev_info->start+pgoff*PAGE_SIZE);
	return 0;
}

+1 −0
Original line number Diff line number Diff line
@@ -885,6 +885,7 @@ struct block_device_operations {
	int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long);
	long (*unlocked_ioctl) (struct file *, unsigned, unsigned long);
	long (*compat_ioctl) (struct file *, unsigned, unsigned long);
	int (*direct_access) (struct block_device *, sector_t, unsigned long *);
	int (*media_changed) (struct gendisk *);
	int (*revalidate_disk) (struct gendisk *);
	struct module *owner;