aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/umem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/umem.c')
-rw-r--r--drivers/block/umem.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 6b7c02d6360d..c378e285d708 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -113,6 +113,8 @@ struct cardinfo {
113 * have been written 113 * have been written
114 */ 114 */
115 struct bio *bio, *currentbio, **biotail; 115 struct bio *bio, *currentbio, **biotail;
116 int current_idx;
117 sector_t current_sector;
116 118
117 struct request_queue *queue; 119 struct request_queue *queue;
118 120
@@ -121,6 +123,7 @@ struct cardinfo {
121 struct mm_dma_desc *desc; 123 struct mm_dma_desc *desc;
122 int cnt, headcnt; 124 int cnt, headcnt;
123 struct bio *bio, **biotail; 125 struct bio *bio, **biotail;
126 int idx;
124 } mm_pages[2]; 127 } mm_pages[2];
125#define DESC_PER_PAGE ((PAGE_SIZE*2)/sizeof(struct mm_dma_desc)) 128#define DESC_PER_PAGE ((PAGE_SIZE*2)/sizeof(struct mm_dma_desc))
126 129
@@ -380,12 +383,16 @@ static int add_bio(struct cardinfo *card)
380 dma_addr_t dma_handle; 383 dma_addr_t dma_handle;
381 int offset; 384 int offset;
382 struct bio *bio; 385 struct bio *bio;
386 struct bio_vec *vec;
387 int idx;
383 int rw; 388 int rw;
384 int len; 389 int len;
385 390
386 bio = card->currentbio; 391 bio = card->currentbio;
387 if (!bio && card->bio) { 392 if (!bio && card->bio) {
388 card->currentbio = card->bio; 393 card->currentbio = card->bio;
394 card->current_idx = card->bio->bi_idx;
395 card->current_sector = card->bio->bi_sector;
389 card->bio = card->bio->bi_next; 396 card->bio = card->bio->bi_next;
390 if (card->bio == NULL) 397 if (card->bio == NULL)
391 card->biotail = &card->bio; 398 card->biotail = &card->bio;
@@ -394,15 +401,17 @@ static int add_bio(struct cardinfo *card)
394 } 401 }
395 if (!bio) 402 if (!bio)
396 return 0; 403 return 0;
404 idx = card->current_idx;
397 405
398 rw = bio_rw(bio); 406 rw = bio_rw(bio);
399 if (card->mm_pages[card->Ready].cnt >= DESC_PER_PAGE) 407 if (card->mm_pages[card->Ready].cnt >= DESC_PER_PAGE)
400 return 0; 408 return 0;
401 409
402 len = bio_iovec(bio)->bv_len; 410 vec = bio_iovec_idx(bio, idx);
403 dma_handle = pci_map_page(card->dev, 411 len = vec->bv_len;
404 bio_page(bio), 412 dma_handle = pci_map_page(card->dev,
405 bio_offset(bio), 413 vec->bv_page,
414 vec->bv_offset,
406 len, 415 len,
407 (rw==READ) ? 416 (rw==READ) ?
408 PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); 417 PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
@@ -410,6 +419,8 @@ static int add_bio(struct cardinfo *card)
410 p = &card->mm_pages[card->Ready]; 419 p = &card->mm_pages[card->Ready];
411 desc = &p->desc[p->cnt]; 420 desc = &p->desc[p->cnt];
412 p->cnt++; 421 p->cnt++;
422 if (p->bio == NULL)
423 p->idx = idx;
413 if ((p->biotail) != &bio->bi_next) { 424 if ((p->biotail) != &bio->bi_next) {
414 *(p->biotail) = bio; 425 *(p->biotail) = bio;
415 p->biotail = &(bio->bi_next); 426 p->biotail = &(bio->bi_next);
@@ -419,7 +430,7 @@ static int add_bio(struct cardinfo *card)
419 desc->data_dma_handle = dma_handle; 430 desc->data_dma_handle = dma_handle;
420 431
421 desc->pci_addr = cpu_to_le64((u64)desc->data_dma_handle); 432 desc->pci_addr = cpu_to_le64((u64)desc->data_dma_handle);
422 desc->local_addr= cpu_to_le64(bio->bi_sector << 9); 433 desc->local_addr = cpu_to_le64(card->current_sector << 9);
423 desc->transfer_size = cpu_to_le32(len); 434 desc->transfer_size = cpu_to_le32(len);
424 offset = ( ((char*)&desc->sem_control_bits) - ((char*)p->desc)); 435 offset = ( ((char*)&desc->sem_control_bits) - ((char*)p->desc));
425 desc->sem_addr = cpu_to_le64((u64)(p->page_dma+offset)); 436 desc->sem_addr = cpu_to_le64((u64)(p->page_dma+offset));
@@ -435,10 +446,10 @@ static int add_bio(struct cardinfo *card)
435 desc->control_bits |= cpu_to_le32(DMASCR_TRANSFER_READ); 446 desc->control_bits |= cpu_to_le32(DMASCR_TRANSFER_READ);
436 desc->sem_control_bits = desc->control_bits; 447 desc->sem_control_bits = desc->control_bits;
437 448
438 bio->bi_sector += (len>>9); 449 card->current_sector += (len >> 9);
439 bio->bi_size -= len; 450 idx++;
440 bio->bi_idx++; 451 card->current_idx = idx;
441 if (bio->bi_idx >= bio->bi_vcnt) 452 if (idx >= bio->bi_vcnt)
442 card->currentbio = NULL; 453 card->currentbio = NULL;
443 454
444 return 1; 455 return 1;
@@ -474,10 +485,12 @@ static void process_page(unsigned long data)
474 last=1; 485 last=1;
475 } 486 }
476 page->headcnt++; 487 page->headcnt++;
477 idx = bio->bi_phys_segments; 488 idx = page->idx;
478 bio->bi_phys_segments++; 489 page->idx++;
479 if (bio->bi_phys_segments >= bio->bi_vcnt) 490 if (page->idx >= bio->bi_vcnt) {
480 page->bio = bio->bi_next; 491 page->bio = bio->bi_next;
492 page->idx = page->bio->bi_idx;
493 }
481 494
482 pci_unmap_page(card->dev, desc->data_dma_handle, 495 pci_unmap_page(card->dev, desc->data_dma_handle,
483 bio_iovec_idx(bio,idx)->bv_len, 496 bio_iovec_idx(bio,idx)->bv_len,
@@ -547,7 +560,6 @@ static int mm_make_request(struct request_queue *q, struct bio *bio)
547 pr_debug("mm_make_request %llu %u\n", 560 pr_debug("mm_make_request %llu %u\n",
548 (unsigned long long)bio->bi_sector, bio->bi_size); 561 (unsigned long long)bio->bi_sector, bio->bi_size);
549 562
550 bio->bi_phys_segments = bio->bi_idx; /* count of completed segments*/
551 spin_lock_irq(&card->lock); 563 spin_lock_irq(&card->lock);
552 *card->biotail = bio; 564 *card->biotail = bio;
553 bio->bi_next = NULL; 565 bio->bi_next = NULL;