drivers/gpib/common/iblib.c

Source file repositories/reference/linux-study-clean/drivers/gpib/common/iblib.c

File Facts

System
Linux kernel
Corpus path
drivers/gpib/common/iblib.c
Extension
.c
Size
17483 bytes
Lines
717
Domain
Driver Families
Bucket
drivers/gpib
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

struct wait_info {
	struct gpib_board *board;
	struct timer_list timer;
	int timed_out;
	unsigned long usec_timeout;
};

static void wait_timeout(struct timer_list *t)
{
	struct wait_info *winfo = timer_container_of(winfo, t, timer);

	winfo->timed_out = 1;
	wake_up_interruptible(&winfo->board->wait);
}

static void init_wait_info(struct wait_info *winfo)
{
	winfo->board = NULL;
	winfo->timed_out = 0;
	timer_setup_on_stack(&winfo->timer, wait_timeout, 0);
}

static int wait_satisfied(struct wait_info *winfo, struct gpib_status_queue *status_queue,
			  int wait_mask, int *status, struct gpib_descriptor *desc)
{
	struct gpib_board *board = winfo->board;
	int temp_status;

	if (mutex_lock_interruptible(&board->big_gpib_mutex))
		return -ERESTARTSYS;

	temp_status = general_ibstatus(board, status_queue, 0, 0, desc);

	mutex_unlock(&board->big_gpib_mutex);

	if (winfo->timed_out)
		temp_status |= TIMO;
	else
		temp_status &= ~TIMO;
	if (wait_mask & temp_status) {
		*status = temp_status;
		return 1;
	}
// XXX does wait for END work?
	return 0;
}

/* install timer interrupt handler */
static void start_wait_timer(struct wait_info *winfo)
/* Starts the timeout task  */
{
	winfo->timed_out = 0;

	if (winfo->usec_timeout > 0)
		mod_timer(&winfo->timer, jiffies + usec_to_jiffies(winfo->usec_timeout));
}

static void remove_wait_timer(struct wait_info *winfo)
{
	timer_delete_sync(&winfo->timer);
	timer_destroy_on_stack(&winfo->timer);
}

/*
 * IBWAIT
 * Check or wait for a GPIB event to occur.  The mask argument
 * is a bit vector corresponding to the status bit vector.  It
 * has a bit set for each condition which can terminate the wait
 * If the mask is 0 then
 * no condition is waited for.
 */
int ibwait(struct gpib_board *board, int wait_mask, int clear_mask, int set_mask,
	   int *status, unsigned long usec_timeout, struct gpib_descriptor *desc)
{
	int retval = 0;
	struct gpib_status_queue *status_queue;
	struct wait_info winfo;

	if (desc->is_board)
		status_queue = NULL;
	else
		status_queue = get_gpib_status_queue(board, desc->pad, desc->sad);

	if (wait_mask == 0) {
		*status = general_ibstatus(board, status_queue, clear_mask, set_mask, desc);
		return 0;
	}

	mutex_unlock(&board->big_gpib_mutex);

Annotation

Implementation Notes