summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Makisara <Kai.Makisara@kolumbus.fi>2008-12-18 14:49:51 +0900
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-01-02 12:06:52 -0600
commit8f78fc5eb798426891f99390a61f752aaef9fc39 (patch)
tree4b1f614ed4af572024b3906855ab15f3b7f19ec8
parent02ae2c0e844e2864a877d1da8a92fe5e63778a18 (diff)
downloadlinux-3.10-8f78fc5eb798426891f99390a61f752aaef9fc39.tar.gz
linux-3.10-8f78fc5eb798426891f99390a61f752aaef9fc39.tar.bz2
linux-3.10-8f78fc5eb798426891f99390a61f752aaef9fc39.zip
[SCSI] st: retry enlarge_buffer allocation
Make enlarge_buffer() retry allocation if the previously chosen page order was too small. Really limit the page order to 6. Return error if the maximum order is not large enough for the request. Signed-off-by: Kai Makisara <Kai.Makisara@kolumbus.fi> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/st.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index ddf2630b347..c6f19ee8f2c 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3695,6 +3695,8 @@ static struct st_buffer *new_tape_buffer(int need_dma, int max_sg)
/* Try to allocate enough space in the tape buffer */
+#define ST_MAX_ORDER 6
+
static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dma)
{
int segs, nbr, max_segs, b_size, order, got;
@@ -3723,9 +3725,16 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm
b_size = PAGE_SIZE << order;
} else {
for (b_size = PAGE_SIZE, order = 0;
- order <= 6 && b_size < new_size; order++, b_size *= 2)
+ order < ST_MAX_ORDER && b_size < new_size;
+ order++, b_size *= 2)
; /* empty */
}
+ if (max_segs * (PAGE_SIZE << order) < new_size) {
+ if (order == ST_MAX_ORDER)
+ return 0;
+ normalize_buffer(STbuffer);
+ return enlarge_buffer(STbuffer, new_size, need_dma);
+ }
for (segs = STbuffer->frp_segs, got = STbuffer->buffer_size;
segs < max_segs && got < new_size;) {