Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 105087
b: refs/heads/master
c: 2ff1fa6
h: refs/heads/master
i:
  105085: 4bd5a0f
  105083: 2c78b0d
  105079: 4723edf
  105071: ab9c340
  105055: 2adbe94
  105023: 810b4c9
  104959: d71e945
v: v3
  • Loading branch information
Pierre Ossman committed Jul 23, 2008
1 parent 3d4ab88 commit 5cb3272
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 67 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 719a61b452ff74cf81a96e4212748d9d63bcc924
refs/heads/master: 2ff1fa679115e3c8c78ad74ad8fd2d7fd87ae4e7
97 changes: 31 additions & 66 deletions trunk/drivers/mmc/card/queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
printk(KERN_WARNING "%s: unable to allocate "
"bounce buffer\n", mmc_card_name(card));
} else {
blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_HIGH);
blk_queue_bounce_limit(mq->queue, BLK_BOUNCE_ANY);
blk_queue_max_sectors(mq->queue, bouncesz / 512);
blk_queue_max_phys_segments(mq->queue, bouncesz / 512);
blk_queue_max_hw_segments(mq->queue, bouncesz / 512);
Expand Down Expand Up @@ -290,55 +290,15 @@ void mmc_queue_resume(struct mmc_queue *mq)
}
}

static void copy_sg(struct scatterlist *dst, unsigned int dst_len,
struct scatterlist *src, unsigned int src_len)
{
unsigned int chunk;
char *dst_buf, *src_buf;
unsigned int dst_size, src_size;

dst_buf = NULL;
src_buf = NULL;
dst_size = 0;
src_size = 0;

while (src_len) {
BUG_ON(dst_len == 0);

if (dst_size == 0) {
dst_buf = sg_virt(dst);
dst_size = dst->length;
}

if (src_size == 0) {
src_buf = sg_virt(src);
src_size = src->length;
}

chunk = min(dst_size, src_size);

memcpy(dst_buf, src_buf, chunk);

dst_buf += chunk;
src_buf += chunk;
dst_size -= chunk;
src_size -= chunk;

if (dst_size == 0) {
dst++;
dst_len--;
}

if (src_size == 0) {
src++;
src_len--;
}
}
}

/*
* Prepare the sg list(s) to be handed of to the host driver
*/
unsigned int mmc_queue_map_sg(struct mmc_queue *mq)
{
unsigned int sg_len;
size_t buflen;
struct scatterlist *sg;
int i;

if (!mq->bounce_buf)
return blk_rq_map_sg(mq->queue, mq->req, mq->sg);
Expand All @@ -349,47 +309,52 @@ unsigned int mmc_queue_map_sg(struct mmc_queue *mq)

mq->bounce_sg_len = sg_len;

/*
* Shortcut in the event we only get a single entry.
*/
if (sg_len == 1) {
memcpy(mq->sg, mq->bounce_sg, sizeof(struct scatterlist));
return 1;
}
buflen = 0;
for_each_sg(mq->bounce_sg, sg, sg_len, i)
buflen += sg->length;

sg_init_one(mq->sg, mq->bounce_buf, 0);

while (sg_len) {
mq->sg[0].length += mq->bounce_sg[sg_len - 1].length;
sg_len--;
}
sg_init_one(mq->sg, mq->bounce_buf, buflen);

return 1;
}

/*
* If writing, bounce the data to the buffer before the request
* is sent to the host driver
*/
void mmc_queue_bounce_pre(struct mmc_queue *mq)
{
unsigned long flags;

if (!mq->bounce_buf)
return;

if (mq->bounce_sg_len == 1)
return;
if (rq_data_dir(mq->req) != WRITE)
return;

copy_sg(mq->sg, 1, mq->bounce_sg, mq->bounce_sg_len);
local_irq_save(flags);
sg_copy_to_buffer(mq->bounce_sg, mq->bounce_sg_len,
mq->bounce_buf, mq->sg[0].length);
local_irq_restore(flags);
}

/*
* If reading, bounce the data from the buffer after the request
* has been handled by the host driver
*/
void mmc_queue_bounce_post(struct mmc_queue *mq)
{
unsigned long flags;

if (!mq->bounce_buf)
return;

if (mq->bounce_sg_len == 1)
return;
if (rq_data_dir(mq->req) != READ)
return;

copy_sg(mq->bounce_sg, mq->bounce_sg_len, mq->sg, 1);
local_irq_save(flags);
sg_copy_from_buffer(mq->bounce_sg, mq->bounce_sg_len,
mq->bounce_buf, mq->sg[0].length);
local_irq_restore(flags);
}

0 comments on commit 5cb3272

Please sign in to comment.