diff options
-rw-r--r-- | drivers/scsi/st.c | 11 | ||||
-rw-r--r-- | drivers/scsi/st.h | 2 |
2 files changed, 13 insertions, 0 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 3984cd82fe10..9d9e4b90f23b 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -3723,6 +3723,12 @@ static struct st_buffer * | |||
3723 | tb->buffer_size = got; | 3723 | tb->buffer_size = got; |
3724 | sg_init_table(tb->sg, max_sg); | 3724 | sg_init_table(tb->sg, max_sg); |
3725 | 3725 | ||
3726 | tb->reserved_pages = kzalloc(max_sg * sizeof(struct page *), priority); | ||
3727 | if (!tb->reserved_pages) { | ||
3728 | kfree(tb); | ||
3729 | return NULL; | ||
3730 | } | ||
3731 | |||
3726 | return tb; | 3732 | return tb; |
3727 | } | 3733 | } |
3728 | 3734 | ||
@@ -3771,9 +3777,11 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm | |||
3771 | STbuffer->buffer_size = got; | 3777 | STbuffer->buffer_size = got; |
3772 | if (STbuffer->cleared) | 3778 | if (STbuffer->cleared) |
3773 | memset(page_address(STbuffer->frp[segs].page), 0, b_size); | 3779 | memset(page_address(STbuffer->frp[segs].page), 0, b_size); |
3780 | STbuffer->reserved_pages[segs] = STbuffer->frp[segs].page; | ||
3774 | segs++; | 3781 | segs++; |
3775 | } | 3782 | } |
3776 | STbuffer->b_data = page_address(STbuffer->frp[0].page); | 3783 | STbuffer->b_data = page_address(STbuffer->frp[0].page); |
3784 | STbuffer->map_data.page_order = order; | ||
3777 | 3785 | ||
3778 | return 1; | 3786 | return 1; |
3779 | } | 3787 | } |
@@ -3803,6 +3811,8 @@ static void normalize_buffer(struct st_buffer * STbuffer) | |||
3803 | STbuffer->frp_segs = STbuffer->orig_frp_segs; | 3811 | STbuffer->frp_segs = STbuffer->orig_frp_segs; |
3804 | STbuffer->frp_sg_current = 0; | 3812 | STbuffer->frp_sg_current = 0; |
3805 | STbuffer->sg_segs = 0; | 3813 | STbuffer->sg_segs = 0; |
3814 | STbuffer->map_data.page_order = 0; | ||
3815 | STbuffer->map_data.offset = 0; | ||
3806 | } | 3816 | } |
3807 | 3817 | ||
3808 | 3818 | ||
@@ -4282,6 +4292,7 @@ static void scsi_tape_release(struct kref *kref) | |||
4282 | if (tpnt->buffer) { | 4292 | if (tpnt->buffer) { |
4283 | tpnt->buffer->orig_frp_segs = 0; | 4293 | tpnt->buffer->orig_frp_segs = 0; |
4284 | normalize_buffer(tpnt->buffer); | 4294 | normalize_buffer(tpnt->buffer); |
4295 | kfree(tpnt->buffer->reserved_pages); | ||
4285 | kfree(tpnt->buffer); | 4296 | kfree(tpnt->buffer); |
4286 | } | 4297 | } |
4287 | 4298 | ||
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index b92712f95931..74748abe8246 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h | |||
@@ -44,6 +44,8 @@ struct st_buffer { | |||
44 | int syscall_result; | 44 | int syscall_result; |
45 | struct st_request *last_SRpnt; | 45 | struct st_request *last_SRpnt; |
46 | struct st_cmdstatus cmdstat; | 46 | struct st_cmdstatus cmdstat; |
47 | struct page **reserved_pages; | ||
48 | struct rq_map_data map_data; | ||
47 | unsigned char *b_data; | 49 | unsigned char *b_data; |
48 | unsigned short use_sg; /* zero or max number of s/g segments for this adapter */ | 50 | unsigned short use_sg; /* zero or max number of s/g segments for this adapter */ |
49 | unsigned short sg_segs; /* number of segments in s/g list */ | 51 | unsigned short sg_segs; /* number of segments in s/g list */ |