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

Commit 08c95832 authored by FUJITA Tomonori's avatar FUJITA Tomonori Committed by James Bottomley
Browse files

[SCSI] st: kill struct st_buff_fragment



This removes struct st_buff_fragment and use reserved_pages array to
store fragment buffer.

Signed-off-by: default avatarFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: default avatarKai Makisara <Kai.Makisara@kolumbus.fi>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent b3376b4a
Loading
Loading
Loading
Loading
+43 −35
Original line number Diff line number Diff line
@@ -3753,8 +3753,9 @@ static struct st_buffer *
	else
		priority = GFP_KERNEL;

	i = sizeof(struct st_buffer) + (max_sg - 1) * sizeof(struct scatterlist) +
		max_sg * sizeof(struct st_buf_fragment);
	i = sizeof(struct st_buffer) +
		(max_sg - 1) * sizeof(struct scatterlist);

	tb = kzalloc(i, priority);
	if (!tb) {
		printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
@@ -3762,7 +3763,6 @@ static struct st_buffer *
	}
	tb->frp_segs = tb->orig_frp_segs = 0;
	tb->use_sg = max_sg;
	tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg);

	tb->dma = need_dma;
	tb->buffer_size = got;
@@ -3799,9 +3799,12 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm
	if (need_dma)
		priority |= GFP_DMA;

	if (STbuffer->cleared)
		priority |= __GFP_ZERO;

	if (STbuffer->frp_segs) {
		b_size = STbuffer->frp[0].length;
		order = get_order(b_size);
		order = STbuffer->map_data.page_order;
		b_size = PAGE_SIZE << order;
	} else {
		for (b_size = PAGE_SIZE, order = 0;
		     order <= 6 && b_size < new_size; order++, b_size *= 2)
@@ -3810,22 +3813,22 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm

	for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
	     segs < max_segs && got < new_size;) {
		STbuffer->frp[segs].page = alloc_pages(priority, order);
		if (STbuffer->frp[segs].page == NULL) {
		struct page *page;

		page = alloc_pages(priority, order);
		if (!page) {
			DEB(STbuffer->buffer_size = got);
			normalize_buffer(STbuffer);
			return 0;
		}
		STbuffer->frp[segs].length = b_size;

		STbuffer->frp_segs += 1;
		got += b_size;
		STbuffer->buffer_size = got;
		if (STbuffer->cleared)
			memset(page_address(STbuffer->frp[segs].page), 0, b_size);
		STbuffer->reserved_pages[segs] = STbuffer->frp[segs].page;
		STbuffer->reserved_pages[segs] = page;
		segs++;
	}
	STbuffer->b_data = page_address(STbuffer->frp[0].page);
	STbuffer->b_data = page_address(STbuffer->reserved_pages[0]);
	STbuffer->map_data.page_order = order;

	return 1;
@@ -3838,7 +3841,8 @@ static void clear_buffer(struct st_buffer * st_bp)
	int i;

	for (i=0; i < st_bp->frp_segs; i++)
		memset(page_address(st_bp->frp[i].page), 0, st_bp->frp[i].length);
		memset(page_address(st_bp->reserved_pages[i]), 0,
		       PAGE_SIZE << st_bp->map_data.page_order);
	st_bp->cleared = 1;
}

@@ -3846,12 +3850,11 @@ static void clear_buffer(struct st_buffer * st_bp)
/* Release the extra buffer */
static void normalize_buffer(struct st_buffer * STbuffer)
{
	int i, order;
	int i, order = STbuffer->map_data.page_order;

	for (i = STbuffer->orig_frp_segs; i < STbuffer->frp_segs; i++) {
		order = get_order(STbuffer->frp[i].length);
		__free_pages(STbuffer->frp[i].page, order);
		STbuffer->buffer_size -= STbuffer->frp[i].length;
		__free_pages(STbuffer->reserved_pages[i], order);
		STbuffer->buffer_size -= (PAGE_SIZE << order);
	}
	STbuffer->frp_segs = STbuffer->orig_frp_segs;
	STbuffer->frp_sg_current = 0;
@@ -3866,18 +3869,19 @@ static void normalize_buffer(struct st_buffer * STbuffer)
static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
{
	int i, cnt, res, offset;
	int length = PAGE_SIZE << st_bp->map_data.page_order;

	for (i = 0, offset = st_bp->buffer_bytes;
	     i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
		offset -= st_bp->frp[i].length;
	     i < st_bp->frp_segs && offset >= length; i++)
		offset -= length;
	if (i == st_bp->frp_segs) {	/* Should never happen */
		printk(KERN_WARNING "st: append_to_buffer offset overflow.\n");
		return (-EIO);
	}
	for (; i < st_bp->frp_segs && do_count > 0; i++) {
		cnt = st_bp->frp[i].length - offset < do_count ?
		    st_bp->frp[i].length - offset : do_count;
		res = copy_from_user(page_address(st_bp->frp[i].page) + offset, ubp, cnt);
		struct page *page = st_bp->reserved_pages[i];
		cnt = length - offset < do_count ? length - offset : do_count;
		res = copy_from_user(page_address(page) + offset, ubp, cnt);
		if (res)
			return (-EFAULT);
		do_count -= cnt;
@@ -3897,18 +3901,19 @@ static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, in
static int from_buffer(struct st_buffer * st_bp, char __user *ubp, int do_count)
{
	int i, cnt, res, offset;
	int length = PAGE_SIZE << st_bp->map_data.page_order;

	for (i = 0, offset = st_bp->read_pointer;
	     i < st_bp->frp_segs && offset >= st_bp->frp[i].length; i++)
		offset -= st_bp->frp[i].length;
	     i < st_bp->frp_segs && offset >= length; i++)
		offset -= length;
	if (i == st_bp->frp_segs) {	/* Should never happen */
		printk(KERN_WARNING "st: from_buffer offset overflow.\n");
		return (-EIO);
	}
	for (; i < st_bp->frp_segs && do_count > 0; i++) {
		cnt = st_bp->frp[i].length - offset < do_count ?
		    st_bp->frp[i].length - offset : do_count;
		res = copy_to_user(ubp, page_address(st_bp->frp[i].page) + offset, cnt);
		struct page *page = st_bp->reserved_pages[i];
		cnt = length - offset < do_count ? length - offset : do_count;
		res = copy_to_user(ubp, page_address(page) + offset, cnt);
		if (res)
			return (-EFAULT);
		do_count -= cnt;
@@ -3929,6 +3934,7 @@ static void move_buffer_data(struct st_buffer * st_bp, int offset)
{
	int src_seg, dst_seg, src_offset = 0, dst_offset;
	int count, total;
	int length = PAGE_SIZE << st_bp->map_data.page_order;

	if (offset == 0)
		return;
@@ -3936,24 +3942,26 @@ static void move_buffer_data(struct st_buffer * st_bp, int offset)
	total=st_bp->buffer_bytes - offset;
	for (src_seg=0; src_seg < st_bp->frp_segs; src_seg++) {
		src_offset = offset;
		if (src_offset < st_bp->frp[src_seg].length)
		if (src_offset < length)
			break;
		offset -= st_bp->frp[src_seg].length;
		offset -= length;
	}

	st_bp->buffer_bytes = st_bp->read_pointer = total;
	for (dst_seg=dst_offset=0; total > 0; ) {
		count = min(st_bp->frp[dst_seg].length - dst_offset,
			    st_bp->frp[src_seg].length - src_offset);
		memmove(page_address(st_bp->frp[dst_seg].page) + dst_offset,
			page_address(st_bp->frp[src_seg].page) + src_offset, count);
		struct page *dpage = st_bp->reserved_pages[dst_seg];
		struct page *spage = st_bp->reserved_pages[src_seg];

		count = min(length - dst_offset, length - src_offset);
		memmove(page_address(dpage) + dst_offset,
			page_address(spage) + src_offset, count);
		src_offset += count;
		if (src_offset >= st_bp->frp[src_seg].length) {
		if (src_offset >= length) {
			src_seg++;
			src_offset = 0;
		}
		dst_offset += count;
		if (dst_offset >= st_bp->frp[dst_seg].length) {
		if (dst_offset >= length) {
			dst_seg++;
			dst_offset = 0;
		}
+0 −7
Original line number Diff line number Diff line
@@ -54,16 +54,9 @@ struct st_buffer {
	unsigned short orig_frp_segs;	/* number of segments allocated at first try */
	unsigned short frp_segs;	/* number of buffer segments */
	unsigned int frp_sg_current;	/* driver buffer length currently in s/g list */
	struct st_buf_fragment *frp;	/* the allocated buffer fragment list */
	struct scatterlist sg[1];	/* MUST BE last item */
};

/* The tape buffer fragment descriptor */
struct st_buf_fragment {
	struct page *page;
	unsigned int length;
};

/* The tape mode definition */
struct st_modedef {
	unsigned char defined;