iwlwifi: add thermal throttling support to 5150
[pandora-kernel.git] / block / blk-settings.c
index 7541ea4..476d870 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/bio.h>
 #include <linux/blkdev.h>
 #include <linux/bootmem.h>     /* for max_pfn/max_low_pfn */
+#include <linux/gcd.h>
 
 #include "blk.h"
 
@@ -97,7 +98,7 @@ EXPORT_SYMBOL_GPL(blk_queue_lld_busy);
 
 /**
  * blk_set_default_limits - reset limits to default values
- * @limits:  the queue_limits structure to reset
+ * @lim:  the queue_limits structure to reset
  *
  * Description:
  *   Returns a queue_limit struct to its default state.  Can be used by
@@ -112,7 +113,7 @@ void blk_set_default_limits(struct queue_limits *lim)
        lim->max_segment_size = MAX_SEGMENT_SIZE;
        lim->max_sectors = lim->max_hw_sectors = SAFE_MAX_SECTORS;
        lim->logical_block_size = lim->physical_block_size = lim->io_min = 512;
-       lim->bounce_pfn = BLK_BOUNCE_ANY;
+       lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT);
        lim->alignment_offset = 0;
        lim->io_opt = 0;
        lim->misaligned = 0;
@@ -164,6 +165,13 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn)
 
        blk_set_default_limits(&q->limits);
 
+       /*
+        * If the caller didn't supply a lock, fall back to our embedded
+        * per-queue locks
+        */
+       if (!q->queue_lock)
+               q->queue_lock = &q->__queue_lock;
+
        /*
         * by default assume old behaviour and bounce for any highmem page
         */
@@ -377,8 +385,8 @@ void blk_queue_alignment_offset(struct request_queue *q, unsigned int offset)
 EXPORT_SYMBOL(blk_queue_alignment_offset);
 
 /**
- * blk_queue_io_min - set minimum request size for the queue
- * @q: the request queue for the device
+ * blk_limits_io_min - set minimum request size for a device
+ * @limits: the queue limits
  * @min:  smallest I/O size in bytes
  *
  * Description:
@@ -387,15 +395,35 @@ EXPORT_SYMBOL(blk_queue_alignment_offset);
  *   smallest I/O the device can perform without incurring a performance
  *   penalty.
  */
-void blk_queue_io_min(struct request_queue *q, unsigned int min)
+void blk_limits_io_min(struct queue_limits *limits, unsigned int min)
 {
-       q->limits.io_min = min;
+       limits->io_min = min;
 
-       if (q->limits.io_min < q->limits.logical_block_size)
-               q->limits.io_min = q->limits.logical_block_size;
+       if (limits->io_min < limits->logical_block_size)
+               limits->io_min = limits->logical_block_size;
 
-       if (q->limits.io_min < q->limits.physical_block_size)
-               q->limits.io_min = q->limits.physical_block_size;
+       if (limits->io_min < limits->physical_block_size)
+               limits->io_min = limits->physical_block_size;
+}
+EXPORT_SYMBOL(blk_limits_io_min);
+
+/**
+ * blk_queue_io_min - set minimum request size for the queue
+ * @q: the request queue for the device
+ * @min:  smallest I/O size in bytes
+ *
+ * Description:
+ *   Storage devices may report a granularity or preferred minimum I/O
+ *   size which is the smallest request the device can perform without
+ *   incurring a performance penalty.  For disk drives this is often the
+ *   physical block size.  For RAID arrays it is often the stripe chunk
+ *   size.  A properly aligned multiple of minimum_io_size is the
+ *   preferred request size for workloads where a high number of I/O
+ *   operations is desired.
+ */
+void blk_queue_io_min(struct request_queue *q, unsigned int min)
+{
+       blk_limits_io_min(&q->limits, min);
 }
 EXPORT_SYMBOL(blk_queue_io_min);
 
@@ -405,8 +433,12 @@ EXPORT_SYMBOL(blk_queue_io_min);
  * @opt:  optimal request size in bytes
  *
  * Description:
- *   Drivers can call this function to set the preferred I/O request
- *   size for devices that report such a value.
+ *   Storage devices may report an optimal I/O size, which is the
+ *   device's preferred unit for sustained I/O.  This is rarely reported
+ *   for disk drives.  For RAID arrays it is usually the stripe width or
+ *   the internal track size.  A properly aligned multiple of
+ *   optimal_io_size is the preferred request size for workloads where
+ *   sustained throughput is desired.
  */
 void blk_queue_io_opt(struct request_queue *q, unsigned int opt)
 {
@@ -426,27 +458,7 @@ EXPORT_SYMBOL(blk_queue_io_opt);
  **/
 void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
 {
-       /* zero is "infinity" */
-       t->limits.max_sectors = min_not_zero(queue_max_sectors(t),
-                                            queue_max_sectors(b));
-
-       t->limits.max_hw_sectors = min_not_zero(queue_max_hw_sectors(t),
-                                               queue_max_hw_sectors(b));
-
-       t->limits.seg_boundary_mask = min_not_zero(queue_segment_boundary(t),
-                                                  queue_segment_boundary(b));
-
-       t->limits.max_phys_segments = min_not_zero(queue_max_phys_segments(t),
-                                                  queue_max_phys_segments(b));
-
-       t->limits.max_hw_segments = min_not_zero(queue_max_hw_segments(t),
-                                                queue_max_hw_segments(b));
-
-       t->limits.max_segment_size = min_not_zero(queue_max_segment_size(t),
-                                                 queue_max_segment_size(b));
-
-       t->limits.logical_block_size = max(queue_logical_block_size(t),
-                                          queue_logical_block_size(b));
+       blk_stack_limits(&t->limits, &b->limits, 0);
 
        if (!t->queue_lock)
                WARN_ON_ONCE(1);
@@ -516,6 +528,16 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
                return -1;
        }
 
+       /* Find lcm() of optimal I/O size */
+       if (t->io_opt && b->io_opt)
+               t->io_opt = (t->io_opt * b->io_opt) / gcd(t->io_opt, b->io_opt);
+       else if (b->io_opt)
+               t->io_opt = b->io_opt;
+
+       /* Verify that optimal I/O size is a multiple of io_min */
+       if (t->io_min && t->io_opt % t->io_min)
+               return -1;
+
        return 0;
 }
 EXPORT_SYMBOL(blk_stack_limits);