]> git.karo-electronics.de Git - linux-beck.git/commitdiff
[SCSI] st: retry enlarge_buffer allocation
authorKai Makisara <Kai.Makisara@kolumbus.fi>
Thu, 18 Dec 2008 05:49:51 +0000 (14:49 +0900)
committerJames Bottomley <James.Bottomley@HansenPartnership.com>
Fri, 2 Jan 2009 18:06:52 +0000 (12:06 -0600)
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>
drivers/scsi/st.c

index ddf2630b347970673242ae09df84705c5de146a2..c6f19ee8f2cbc8e75218cb651a0ea0ffbc7ee72f 100644 (file)
@@ -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;) {