FreeBSD/usr.sbin/camdd/camdd.c
/*
 * Assumes caller holds the lock for this device.
 */
Assumes caller holds the lock for this device.
Assumes caller holds the lock for this device .
void
camdd_complete_buf(struct camdd_dev *dev, struct camdd_buf *buf,
		   int *error_count)
{
	int retval = 0;
	if (dev->write_dev == 0) {
		retval = camdd_queue_peer_buf(dev, buf);
		if (retval != 0)
			(*error_count)++;
	} else {
		struct camdd_buf *tmp_buf, *next_buf;
		STAILQ_FOREACH_SAFE(tmp_buf, &buf->src_list, src_links,
				    next_buf) {
			struct camdd_buf *src_buf;
			struct camdd_buf_indirect *indirect;
			STAILQ_REMOVE(&buf->src_list, tmp_buf,
				      camdd_buf, src_links);
			tmp_buf->status = buf->status;
			if (tmp_buf->buf_type == CAMDD_BUF_DATA) {
				camdd_complete_peer_buf(dev, tmp_buf);
				continue;
			}
			indirect = &tmp_buf->buf_type_spec.indirect;
			src_buf = indirect->src_buf;
			src_buf->refcount--;
			src_buf->status = buf->status;
			if (src_buf->refcount <= 0)
				camdd_complete_peer_buf(dev, src_buf);
			STAILQ_INSERT_TAIL(&dev->free_indirect_queue,
					   tmp_buf, links);
		}
		STAILQ_INSERT_TAIL(&dev->free_queue, buf, links);
	}
}
void camdd_complete_buf ( struct camdd_dev * dev , struct camdd_buf * buf , int * error_count ) { int retval = 0 ; if ( dev -> write_dev == 0 ) { retval = camdd_queue_peer_buf ( dev , buf ) ; if ( retval != 0 ) ( * error_count ) ++ ; } else { struct camdd_buf * tmp_buf , * next_buf ; STAILQ_FOREACH_SAFE ( tmp_buf , & buf -> src_list , src_links , next_buf ) { struct camdd_buf * src_buf ; struct camdd_buf_indirect * indirect ; STAILQ_REMOVE ( & buf -> src_list , tmp_buf , camdd_buf , src_links ) ; tmp_buf -> status = buf -> status ; if ( tmp_buf -> buf_type == CAMDD_BUF_DATA ) { camdd_complete_peer_buf ( dev , tmp_buf ) ; continue ; } indirect = & tmp_buf -> buf_type_spec . indirect ; src_buf = indirect -> src_buf ; src_buf -> refcount -- ; src_buf -> status = buf -> status ; if ( src_buf -> refcount <= 0 ) camdd_complete_peer_buf ( dev , src_buf ) ; STAILQ_INSERT_TAIL ( & dev -> free_indirect_queue , tmp_buf , links ) ; } STAILQ_INSERT_TAIL ( & dev -> free_queue , buf , links ) ; } }
Assumes caller holds the lock for this device.
Assumes caller holds the lock for this device .
/*
	 * If we're the reader, we need to send the completed I/O
	 * to the writer.  If we're the writer, we need to just
	 * free up resources, or let the reader know if we've
	 * encountered an error.
	 */ /*
			 * XXX KDM we probably need to account for
			 * exactly how many bytes we were able to
			 * write.  Allocate the residual to the
			 * first N buffers?  Or just track the
			 * number of bytes written?  Right now the reader
			 * doesn't do anything with a residual.
			 */