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 Original line Diff line number Diff line
@@ -3753,8 +3753,9 @@ static struct st_buffer *
	else
	else
		priority = GFP_KERNEL;
		priority = GFP_KERNEL;


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

	tb = kzalloc(i, priority);
	tb = kzalloc(i, priority);
	if (!tb) {
	if (!tb) {
		printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
		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->frp_segs = tb->orig_frp_segs = 0;
	tb->use_sg = max_sg;
	tb->use_sg = max_sg;
	tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg);


	tb->dma = need_dma;
	tb->dma = need_dma;
	tb->buffer_size = got;
	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)
	if (need_dma)
		priority |= GFP_DMA;
		priority |= GFP_DMA;


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

	if (STbuffer->frp_segs) {
	if (STbuffer->frp_segs) {
		b_size = STbuffer->frp[0].length;
		order = STbuffer->map_data.page_order;
		order = get_order(b_size);
		b_size = PAGE_SIZE << order;
	} else {
	} else {
		for (b_size = PAGE_SIZE, order = 0;
		for (b_size = PAGE_SIZE, order = 0;
		     order <= 6 && b_size < new_size; order++, b_size *= 2)
		     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;
	for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
	     segs < max_segs && got < new_size;) {
	     segs < max_segs && got < new_size;) {
		STbuffer->frp[segs].page = alloc_pages(priority, order);
		struct page *page;
		if (STbuffer->frp[segs].page == NULL) {

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

		STbuffer->frp_segs += 1;
		STbuffer->frp_segs += 1;
		got += b_size;
		got += b_size;
		STbuffer->buffer_size = got;
		STbuffer->buffer_size = got;
		if (STbuffer->cleared)
		STbuffer->reserved_pages[segs] = page;
			memset(page_address(STbuffer->frp[segs].page), 0, b_size);
		STbuffer->reserved_pages[segs] = STbuffer->frp[segs].page;
		segs++;
		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;
	STbuffer->map_data.page_order = order;


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


	for (i=0; i < st_bp->frp_segs; 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;
	st_bp->cleared = 1;
}
}


@@ -3846,12 +3850,11 @@ static void clear_buffer(struct st_buffer * st_bp)
/* Release the extra buffer */
/* Release the extra buffer */
static void normalize_buffer(struct st_buffer * STbuffer)
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++) {
	for (i = STbuffer->orig_frp_segs; i < STbuffer->frp_segs; i++) {
		order = get_order(STbuffer->frp[i].length);
		__free_pages(STbuffer->reserved_pages[i], order);
		__free_pages(STbuffer->frp[i].page, order);
		STbuffer->buffer_size -= (PAGE_SIZE << order);
		STbuffer->buffer_size -= STbuffer->frp[i].length;
	}
	}
	STbuffer->frp_segs = STbuffer->orig_frp_segs;
	STbuffer->frp_segs = STbuffer->orig_frp_segs;
	STbuffer->frp_sg_current = 0;
	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)
static int append_to_buffer(const char __user *ubp, struct st_buffer * st_bp, int do_count)
{
{
	int i, cnt, res, offset;
	int i, cnt, res, offset;
	int length = PAGE_SIZE << st_bp->map_data.page_order;


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


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


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


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

			page_address(st_bp->frp[src_seg].page) + src_offset, count);
		count = min(length - dst_offset, length - src_offset);
		memmove(page_address(dpage) + dst_offset,
			page_address(spage) + src_offset, count);
		src_offset += count;
		src_offset += count;
		if (src_offset >= st_bp->frp[src_seg].length) {
		if (src_offset >= length) {
			src_seg++;
			src_seg++;
			src_offset = 0;
			src_offset = 0;
		}
		}
		dst_offset += count;
		dst_offset += count;
		if (dst_offset >= st_bp->frp[dst_seg].length) {
		if (dst_offset >= length) {
			dst_seg++;
			dst_seg++;
			dst_offset = 0;
			dst_offset = 0;
		}
		}
+0 −7
Original line number Original line 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 orig_frp_segs;	/* number of segments allocated at first try */
	unsigned short frp_segs;	/* number of buffer segments */
	unsigned short frp_segs;	/* number of buffer segments */
	unsigned int frp_sg_current;	/* driver buffer length currently in s/g list */
	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 */
	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 */
/* The tape mode definition */
struct st_modedef {
struct st_modedef {
	unsigned char defined;
	unsigned char defined;