drivers/staging/media/atomisp/pci/hmm/hmm_bo.c

Source file repositories/reference/linux-study-clean/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c

File Facts

System
Linux kernel
Corpus path
drivers/staging/media/atomisp/pci/hmm/hmm_bo.c
Extension
.c
Size
25647 bytes
Lines
1083
Domain
Driver Families
Bucket
drivers/staging
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (this->pgnr < pgnr) {
			if (!this->node.rb_right)
				return NULL;
			ret_bo = __bo_search_and_remove_from_free_rbtree(
				     this->node.rb_right, pgnr);
		} else {
			ret_bo = __bo_search_and_remove_from_free_rbtree(
				     this->node.rb_left, pgnr);
		}
		if (!ret_bo) {
			if (this->pgnr > pgnr)
				goto remove_bo_and_return;
			else
				return NULL;
		}
		return ret_bo;
	}

remove_bo_and_return:
	/* NOTE: All nodes on free rbtree have a 'prev' that points to NULL.
	 * 1. check if 'this->next' is NULL:
	 *	yes: erase 'this' node and rebalance rbtree, return 'this'.
	 */
	if (!this->next) {
		rb_erase(&this->node, &this->bdev->free_rbtree);
		return this;
	}
	/* NOTE: if 'this->next' is not NULL, always return 'this->next' bo.
	 * 2. check if 'this->next->next' is NULL:
	 *	yes: change the related 'next/prev' pointer,
	 *		return 'this->next' but the rbtree stays unchanged.
	 */
	temp_bo = this->next;
	this->next = temp_bo->next;
	if (temp_bo->next)
		temp_bo->next->prev = this;
	temp_bo->next = NULL;
	temp_bo->prev = NULL;
	return temp_bo;
}

static struct hmm_buffer_object *__bo_search_by_addr(struct rb_root *root,
	ia_css_ptr start)
{
	struct rb_node *n = root->rb_node;
	struct hmm_buffer_object *bo;

	do {
		bo = rb_entry(n, struct hmm_buffer_object, node);

		if (bo->start > start) {
			if (!n->rb_left)
				return NULL;
			n = n->rb_left;
		} else if (bo->start < start) {
			if (!n->rb_right)
				return NULL;
			n = n->rb_right;
		} else {
			return bo;
		}
	} while (n);

	return NULL;
}

static struct hmm_buffer_object *__bo_search_by_addr_in_range(
    struct rb_root *root, unsigned int start)
{
	struct rb_node *n = root->rb_node;
	struct hmm_buffer_object *bo;

	do {
		bo = rb_entry(n, struct hmm_buffer_object, node);

		if (bo->start > start) {
			if (!n->rb_left)
				return NULL;
			n = n->rb_left;
		} else {
			if (bo->end > start)
				return bo;
			if (!n->rb_right)
				return NULL;
			n = n->rb_right;
		}
	} while (n);

	return NULL;
}

Annotation

Implementation Notes