diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index cef1a41..839b506 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -198,8 +199,13 @@ static void mmc_urgent_request(struct request_queue *q) static struct scatterlist *mmc_alloc_sg(int sg_len, int *err) { struct scatterlist *sg; + size_t size = sizeof(struct scatterlist)*sg_len; + + if (size > PAGE_SIZE) + sg = vmalloc(size); + else + sg = kmalloc(size, GFP_KERNEL); - sg = kmalloc(sizeof(struct scatterlist)*sg_len, GFP_KERNEL); if (!sg) *err = -ENOMEM; else { @@ -210,6 +216,14 @@ static struct scatterlist *mmc_alloc_sg(int sg_len, int *err) return sg; } +static void mmc_alloc_free(const void *addr) +{ + if (is_vmalloc_addr(addr)) + vfree(addr); + else + kfree(addr); +} + static void mmc_queue_setup_discard(struct request_queue *q, struct mmc_card *card) { @@ -397,20 +411,20 @@ success: return 0; free_bounce_sg: - kfree(mqrq_cur->bounce_sg); + mmc_alloc_free(mqrq_cur->bounce_sg); mqrq_cur->bounce_sg = NULL; - kfree(mqrq_prev->bounce_sg); + mmc_alloc_free(mqrq_prev->bounce_sg); mqrq_prev->bounce_sg = NULL; cleanup_queue: - kfree(mqrq_cur->sg); + mmc_alloc_free(mqrq_cur->sg); mqrq_cur->sg = NULL; - kfree(mqrq_cur->bounce_buf); + mmc_alloc_free(mqrq_cur->bounce_buf); mqrq_cur->bounce_buf = NULL; - kfree(mqrq_prev->sg); + mmc_alloc_free(mqrq_prev->sg); mqrq_prev->sg = NULL; - kfree(mqrq_prev->bounce_buf); + mmc_alloc_free(mqrq_prev->bounce_buf); mqrq_prev->bounce_buf = NULL; blk_cleanup_queue(mq->queue); @@ -436,22 +450,22 @@ void mmc_cleanup_queue(struct mmc_queue *mq) blk_start_queue(q); spin_unlock_irqrestore(q->queue_lock, flags); - kfree(mqrq_cur->bounce_sg); + mmc_alloc_free(mqrq_cur->bounce_sg); mqrq_cur->bounce_sg = NULL; - kfree(mqrq_cur->sg); + mmc_alloc_free(mqrq_cur->sg); mqrq_cur->sg = NULL; - kfree(mqrq_cur->bounce_buf); + mmc_alloc_free(mqrq_cur->bounce_buf); mqrq_cur->bounce_buf = NULL; - kfree(mqrq_prev->bounce_sg); + mmc_alloc_free(mqrq_prev->bounce_sg); mqrq_prev->bounce_sg = NULL; - kfree(mqrq_prev->sg); + mmc_alloc_free(mqrq_prev->sg); mqrq_prev->sg = NULL; - kfree(mqrq_prev->bounce_buf); + mmc_alloc_free(mqrq_prev->bounce_buf); mqrq_prev->bounce_buf = NULL; mq->card = NULL;