Skip to content

Commit

Permalink
[SCSI] st: kill struct st_buff_fragment
Browse files Browse the repository at this point in the history
This removes struct st_buff_fragment and use reserved_pages array to
store fragment buffer.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: Kai Makisara <Kai.Makisara@kolumbus.fi>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
  • Loading branch information
FUJITA Tomonori authored and James Bottomley committed Jan 2, 2009
1 parent b3376b4 commit 08c9583
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 42 deletions.
78 changes: 43 additions & 35 deletions drivers/scsi/st.c
Original file line number Diff line number Diff line change
Expand Up @@ -3753,16 +3753,16 @@ 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");
return NULL;
}
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;
Expand Down Expand Up @@ -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)
Expand All @@ -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;
Expand All @@ -3838,20 +3841,20 @@ 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;
}


/* 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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -3929,31 +3934,34 @@ 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;

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;
}
Expand Down
7 changes: 0 additions & 7 deletions drivers/scsi/st.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 08c9583

Please sign in to comment.