func: int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes)
  
  {
  
      unsigned int idx;
  
      unsigned int total_bufs, in_total, out_total;
  
  
  
      idx = vq->last_avail_idx;
  
  
  
      total_bufs = in_total = out_total = 0;
  
      while (virtqueue_num_heads(vq, idx)) {
  
          unsigned int max, num_bufs, indirect = 0;
  
          target_phys_addr_t desc_pa;
  
          int i;
  
  
  
          max = vq->vring.num;
  
          num_bufs = total_bufs;
  
          i = virtqueue_get_head(vq, idx++);
  
          desc_pa = vq->vring.desc;
  
  
  
          if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) {
  
              if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) {
  
                  error_report("Invalid size for indirect buffer table");
  
                  exit(1);
  
              }
  
  
  
              /* If we've got too many, that implies a descriptor loop. */
  
              if (num_bufs >= max) {
  
                  error_report("Looped descriptor");
  
                  exit(1);
  
              }
  
  
  
              /* loop over the indirect descriptor table */
  
              indirect = 1;
  
              max = vring_desc_len(desc_pa, i) / sizeof(VRingDesc);
  
              num_bufs = i = 0;
  
              desc_pa = vring_desc_addr(desc_pa, i);
  
          }
  
  
  
          do {
  
              /* If we've got too many, that implies a descriptor loop. */
  
              if (++num_bufs > max) {
  
                  error_report("Looped descriptor");
  
                  exit(1);
  
              }
  
  
  
              if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) {
  
                  if (in_bytes > 0 &&
  
                      (in_total += vring_desc_len(desc_pa, i)) >= in_bytes)
  
                      return 1;
  
              } else {
  
                  if (out_bytes > 0 &&
  
                      (out_total += vring_desc_len(desc_pa, i)) >= out_bytes)
  
                      return 1;
  
              }
  
          } while ((i = virtqueue_next_desc(desc_pa, i, max)) != max);
  
  
  
          if (!indirect)
  
              total_bufs = num_bufs;
  
          else
  
              total_bufs++;
  
      }
  
  
  
      return 0;
  
  }
  