Esempio n. 1
0
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);
	}
Esempio n. 2
0
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;
	}
Esempio n. 3
0
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;
}