drivers/comedi/drivers/usbduxsigma.c

Source file repositories/reference/linux-study-clean/drivers/comedi/drivers/usbduxsigma.c

File Facts

System
Linux kernel
Corpus path
drivers/comedi/drivers/usbduxsigma.c
Extension
.c
Size
41419 bytes
Lines
1616
Domain
Driver Families
Bucket
drivers/comedi
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 usbduxsigma_private {
	/* actual number of in-buffers */
	int n_ai_urbs;
	/* actual number of out-buffers */
	int n_ao_urbs;
	/* ISO-transfer handling: buffers */
	struct urb **ai_urbs;
	struct urb **ao_urbs;
	/* pwm-transfer handling */
	struct urb *pwm_urb;
	/* PWM period */
	unsigned int pwm_period;
	/* PWM internal delay for the GPIF in the FX2 */
	u8 pwm_delay;
	/* size of the PWM buffer which holds the bit pattern */
	int pwm_buf_sz;
	/* input buffer for the ISO-transfer */
	__be32 *in_buf;
	/* input buffer for single insn */
	u8 *insn_buf;

	unsigned high_speed:1;
	unsigned ai_cmd_running:1;
	unsigned ao_cmd_running:1;
	unsigned pwm_cmd_running:1;

	/* time between samples in units of the timer */
	unsigned int ai_timer;
	unsigned int ao_timer;
	/* counter between acquisitions */
	unsigned int ai_counter;
	unsigned int ao_counter;
	/* interval in frames/uframes */
	unsigned int ai_interval;
	/* commands */
	u8 *dux_commands;
	struct mutex mut;
};

static void usbduxsigma_unlink_urbs(struct urb **urbs, int num_urbs)
{
	int i;

	for (i = 0; i < num_urbs; i++)
		usb_kill_urb(urbs[i]);
}

static void usbduxsigma_ai_stop(struct comedi_device *dev, int do_unlink)
{
	struct usbduxsigma_private *devpriv = dev->private;

	if (do_unlink && devpriv->ai_urbs)
		usbduxsigma_unlink_urbs(devpriv->ai_urbs, devpriv->n_ai_urbs);

	devpriv->ai_cmd_running = 0;
}

static int usbduxsigma_ai_cancel(struct comedi_device *dev,
				 struct comedi_subdevice *s)
{
	struct usbduxsigma_private *devpriv = dev->private;

	mutex_lock(&devpriv->mut);
	/* unlink only if it is really running */
	usbduxsigma_ai_stop(dev, devpriv->ai_cmd_running);
	mutex_unlock(&devpriv->mut);

	return 0;
}

static void usbduxsigma_ai_handle_urb(struct comedi_device *dev,
				      struct comedi_subdevice *s,
				      struct urb *urb)
{
	struct usbduxsigma_private *devpriv = dev->private;
	struct comedi_async *async = s->async;
	struct comedi_cmd *cmd = &async->cmd;
	u32 val;
	int ret;
	int i;

	if ((urb->actual_length > 0) && (urb->status != -EXDEV)) {
		devpriv->ai_counter--;
		if (devpriv->ai_counter == 0) {
			devpriv->ai_counter = devpriv->ai_timer;

			/*
			 * Get the data from the USB bus and hand it over
			 * to comedi. Note, first byte is the DIO state.
			 */

Annotation

Implementation Notes