Pull asus into release branch
[pandora-kernel.git] / block / ll_rw_blk.c
index a66ec30..3de0695 100644 (file)
@@ -1221,7 +1221,7 @@ void blk_recount_segments(request_queue_t *q, struct bio *bio)
                 * considered part of another segment, since that might
                 * change with the bounce page.
                 */
-               high = page_to_pfn(bv->bv_page) >= q->bounce_pfn;
+               high = page_to_pfn(bv->bv_page) > q->bounce_pfn;
                if (high || highprv)
                        goto new_hw_segment;
                if (cluster) {
@@ -1264,7 +1264,7 @@ new_hw_segment:
        bio->bi_hw_segments = nr_hw_segs;
        bio->bi_flags |= (1 << BIO_SEG_VALID);
 }
-
+EXPORT_SYMBOL(blk_recount_segments);
 
 static int blk_phys_contig_segment(request_queue_t *q, struct bio *bio,
                                   struct bio *nxt)
@@ -2405,6 +2405,7 @@ int blk_rq_map_user(request_queue_t *q, struct request *rq, void __user *ubuf,
                    unsigned long len)
 {
        unsigned long bytes_read = 0;
+       struct bio *bio = NULL;
        int ret;
 
        if (len > (q->max_hw_sectors << 9))
@@ -2431,6 +2432,8 @@ int blk_rq_map_user(request_queue_t *q, struct request *rq, void __user *ubuf,
                ret = __blk_rq_map_user(q, rq, ubuf, map_len);
                if (ret < 0)
                        goto unmap_rq;
+               if (!bio)
+                       bio = rq->bio;
                bytes_read += ret;
                ubuf += ret;
        }
@@ -2438,7 +2441,7 @@ int blk_rq_map_user(request_queue_t *q, struct request *rq, void __user *ubuf,
        rq->buffer = rq->data = NULL;
        return 0;
 unmap_rq:
-       blk_rq_unmap_user(rq);
+       blk_rq_unmap_user(bio);
        return ret;
 }
 
@@ -2450,6 +2453,7 @@ EXPORT_SYMBOL(blk_rq_map_user);
  * @rq:                request to map data to
  * @iov:       pointer to the iovec
  * @iov_count: number of elements in the iovec
+ * @len:       I/O byte count
  *
  * Description:
  *    Data will be mapped directly for zero copy io, if possible. Otherwise
@@ -2495,29 +2499,30 @@ EXPORT_SYMBOL(blk_rq_map_user_iov);
 
 /**
  * blk_rq_unmap_user - unmap a request with user data
- * @rq:                rq to be unmapped
+ * @bio:              start of bio list
  *
  * Description:
- *    Unmap a rq previously mapped by blk_rq_map_user().
- *    rq->bio must be set to the original head of the request.
+ *    Unmap a rq previously mapped by blk_rq_map_user(). The caller must
+ *    supply the original rq->bio from the blk_rq_map_user() return, since
+ *    the io completion may have changed rq->bio.
  */
-int blk_rq_unmap_user(struct request *rq)
+int blk_rq_unmap_user(struct bio *bio)
 {
-       struct bio *bio, *mapped_bio;
+       struct bio *mapped_bio;
        int ret = 0, ret2;
 
-       while ((bio = rq->bio)) {
-               if (bio_flagged(bio, BIO_BOUNCED))
+       while (bio) {
+               mapped_bio = bio;
+               if (unlikely(bio_flagged(bio, BIO_BOUNCED)))
                        mapped_bio = bio->bi_private;
-               else
-                       mapped_bio = bio;
 
                ret2 = __blk_rq_unmap_user(mapped_bio);
                if (ret2 && !ret)
                        ret = ret2;
 
-               rq->bio = bio->bi_next;
-               bio_put(bio);
+               mapped_bio = bio;
+               bio = bio->bi_next;
+               bio_put(mapped_bio);
        }
 
        return ret;
@@ -3653,8 +3658,8 @@ int __init blk_dev_init(void)
        open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL);
        register_hotcpu_notifier(&blk_cpu_notifier);
 
-       blk_max_low_pfn = max_low_pfn;
-       blk_max_pfn = max_pfn;
+       blk_max_low_pfn = max_low_pfn - 1;
+       blk_max_pfn = max_pfn - 1;
 
        return 0;
 }