void zero_fill_bio(struct bio *bio) { unsigned long flags; struct bio_vec *bv; int i; bio_for_each_segment(bv, bio, i) { char *data = bvec_kmap_irq(bv, &flags); memset(data, 0, bv->bv_len); flush_dcache_page(bv->bv_page); bvec_kunmap_irq(data, &flags); }
static int tbio_transfer(struct request *req, struct tbio_device *dev) { unsigned int i = 0, offset = 0; char *buf; unsigned long flags; size_t size; struct bio_vec *bv; struct req_iterator iter; size = blk_rq_cur_bytes(req); prk_info("bio req of size %zu:", size); offset = blk_rq_pos(req) * 512; rq_for_each_segment(bv, req, iter) { size = bv->bv_len; prk_info("%s bio(%u), segs(%u) sect(%u) pos(%lu) off(%u)", (bio_data_dir(iter.bio) == READ) ? "READ" : "WRITE", i, bio_segments(iter.bio), bio_sectors(iter.bio), iter.bio->bi_sector, offset); if (get_capacity(req->rq_disk) * 512 < offset) { prk_info("Error, small capacity %zu, offset %u", get_capacity(req->rq_disk) * 512, offset); continue; } buf = bvec_kmap_irq(bv, &flags); if (bio_data_dir(iter.bio) == WRITE) memcpy(dev->data + offset, buf, size); else memcpy(buf, dev->data + offset, size); offset += size; flush_kernel_dcache_page(bv->bv_page); bvec_kunmap_irq(buf, &flags); ++i; }
static int drct_set_sg_entry(spd_dev_t *dev, int n, struct bio *bio, u32 count) { spd_scatterlist_t *sg = dev->sg; spd_bdev_t *bdev = dev->bdev; struct bio_vec *bvec = bio_iovec_idx(bio, bdev->rmw_bio_idx); u32 bus_addr = 0; u32 size = 0; int i = bdev->rmw_bio_idx; PINFO("idx=%d n=%d count=%lx", bdev->rmw_bio_idx, n, (unsigned long)count); while(count > 0){ bvec = bio_iovec_idx(bio, i); #if defined(CONFIG_P2FAT_FS) if(bio_drct(bio)){ /* Cannot touch bvec->bv_page(=NULL)!! * bvec->bv_private(append new) = bus address!? * bvec->bv_len = data size * maybe offset == 0 */ bus_addr = bvec->bv_private + bdev->rmw_bvec_offset; size = bvec->bv_len - bdev->rmw_bvec_offset; PRINT_BVEC(i, bus_addr, size, bdev->rmw_bvec_offset, n, 1); if(size > count){ PINFO("size=%lx count=%lx", (unsigned long)size, (unsigned long)count); n = set_sg_entry(sg, n, bus_addr, count); bdev->rmw_bvec_offset += count; bdev->rmw_bio_idx = i; break; } n = set_sg_entry(sg, n, bus_addr, size); #else /* ! CONFIG_P2FAT_FS */ if (0) { ; #endif /* CONFIG_P2FAT_FS */ } else { /* Use bvec->bv_page (nomal style) */ unsigned long flags = 0; char *buffer = bvec_kmap_irq(bvec, &flags); bus_addr = virt_to_bus((void *)buffer) + bdev->rmw_bvec_offset; size = bvec->bv_len - bdev->rmw_bvec_offset; PRINT_BVEC(i, bus_addr, size, bdev->rmw_bvec_offset, n, 0); if(size > count){ PINFO("size=%lx count=%lx", (unsigned long)size, (unsigned long)count); n = set_sg_entry(sg, n, bus_addr, count); bdev->rmw_bvec_offset += count; bdev->rmw_bio_idx = i; bvec_kunmap_irq(buffer, &flags); break; } n = set_sg_entry(sg, n, bus_addr, size); bvec_kunmap_irq(buffer, &flags); } if(n < 0){ return n; } i++; count -= size; bdev->rmw_bvec_offset = 0; bdev->rmw_bio_idx = i; } return n; }