示例#1
0
/*
 * Give out the data that's requested from the buffer that we have
 * queued up.
 */
ssize_t fill_readbuf(struct crypto_device *crdev, char *out_buf, 
                     size_t out_count)
{
	struct crypto_vq_buffer *buf;

	debug("Entering\n");
	if (!out_count || !device_has_data(crdev))
		return 0;

	buf = crdev->inbuf;
	out_count = min(out_count, buf->len - buf->offset);

	memcpy(out_buf, buf->buf + buf->offset, out_count);

	buf->offset += out_count;

	if (buf->offset == buf->len) {
		/*
		 * FIXME: We're done using all the data in this buffer.
		 * Re-queue so that the Host can send us more data.
		 */
		crdev->inbuf = NULL;

		if (add_inbuf(crdev->ivq, buf) < 0)
			printk(KERN_WARNING "failed add_buf\n");

	}
	debug("Leaving\n");
	/* Return the number of bytes actually copied */
	return out_count;
}
示例#2
0
/*
 * Host sent us a control message.
 * Called in interrupt context!
 */
static void control_in_intr(struct virtqueue *vq)
{
	struct crypto_device *crdev;
	struct crypto_vq_buffer *buf;
	unsigned int len;

	debug("Entering\n");
	crdev = vq->vdev->priv;

	while ((buf = virtqueue_get_buf(vq, &len))) {
		
		buf->len = len;
		buf->offset = 0;
		
		handle_control_message(crdev, buf);
		
		spin_lock_irq(&crdev->c_lock);
		if (add_inbuf(crdev->c_ivq, buf) < 0) {
			printk(KERN_WARNING "Error adding buffer to queue\n");
			free_buf(buf);
		}
		spin_unlock_irq(&crdev->c_lock);
	}
	debug("Leaving\n");
}
示例#3
0
/*
 * Fill a virtqueue with buffers so Host can send us data.
 */
unsigned int fill_queue(struct virtqueue *vq, spinlock_t *lock)
{
	struct crypto_vq_buffer *buf;
	unsigned int nr_added_bufs;
	int ret;
	
	debug("Entering\n");
	nr_added_bufs = 0;
	do {
		buf = alloc_buf(PAGE_SIZE);
		if (!buf)
		break;
		
		ret = add_inbuf(vq, buf);
		if (ret < 0) {
			free_buf(buf);
			break;
		}
		nr_added_bufs++;
	} while (ret > 0);
	debug("Leaving\n");
	
	return nr_added_bufs;
}