Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1/*
  2 * Line6 Linux USB driver - 0.9.1beta
  3 *
  4 * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
  5 *
  6 *	This program is free software; you can redistribute it and/or
  7 *	modify it under the terms of the GNU General Public License as
  8 *	published by the Free Software Foundation, version 2.
  9 *
 10 */
 11
 12#include <linux/slab.h>
 13
 14#include "driver.h"
 15#include "dumprequest.h"
 16
 17/*
 18	Set "dump in progress" flag.
 19*/
 20void line6_dump_started(struct line6_dump_request *l6dr, int dest)
 21{
 22	l6dr->in_progress = dest;
 23}
 24
 25/*
 26	Invalidate current channel, i.e., set "dump in progress" flag.
 27	Reading from the "dump" special file blocks until dump is completed.
 28*/
 29void line6_invalidate_current(struct line6_dump_request *l6dr)
 30{
 31	line6_dump_started(l6dr, LINE6_DUMP_CURRENT);
 32}
 33
 34/*
 35	Clear "dump in progress" flag and notify waiting processes.
 36*/
 37void line6_dump_finished(struct line6_dump_request *l6dr)
 38{
 39	l6dr->in_progress = LINE6_DUMP_NONE;
 40	wake_up(&l6dr->wait);
 41}
 42
 43/*
 44	Send an asynchronous channel dump request.
 45*/
 46int line6_dump_request_async(struct line6_dump_request *l6dr,
 47			     struct usb_line6 *line6, int num, int dest)
 48{
 49	int ret;
 50	line6_dump_started(l6dr, dest);
 51	ret = line6_send_raw_message_async(line6, l6dr->reqbufs[num].buffer,
 52					   l6dr->reqbufs[num].length);
 53
 54	if (ret < 0)
 55		line6_dump_finished(l6dr);
 56
 57	return ret;
 58}
 59
 60/*
 61	Wait for completion (interruptible).
 62*/
 63int line6_dump_wait_interruptible(struct line6_dump_request *l6dr)
 64{
 65	return wait_event_interruptible(l6dr->wait,
 66					l6dr->in_progress == LINE6_DUMP_NONE);
 67}
 68
 69/*
 70	Wait for completion.
 71*/
 72void line6_dump_wait(struct line6_dump_request *l6dr)
 73{
 74	wait_event(l6dr->wait, l6dr->in_progress == LINE6_DUMP_NONE);
 75}
 76
 77/*
 78	Wait for completion (with timeout).
 79*/
 80int line6_dump_wait_timeout(struct line6_dump_request *l6dr, long timeout)
 81{
 82	return wait_event_timeout(l6dr->wait,
 83				  l6dr->in_progress == LINE6_DUMP_NONE,
 84				  timeout);
 85}
 86
 87/*
 88	Initialize dump request buffer.
 89*/
 90int line6_dumpreq_initbuf(struct line6_dump_request *l6dr, const void *buf,
 91			  size_t len, int num)
 92{
 93	l6dr->reqbufs[num].buffer = kmemdup(buf, len, GFP_KERNEL);
 94	if (l6dr->reqbufs[num].buffer == NULL)
 95		return -ENOMEM;
 96	l6dr->reqbufs[num].length = len;
 97	return 0;
 98}
 99
100/*
101	Initialize dump request data structure (including one buffer).
102*/
103int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf,
104		       size_t len)
105{
106	int ret;
107	ret = line6_dumpreq_initbuf(l6dr, buf, len, 0);
108	if (ret < 0)
109		return ret;
110	init_waitqueue_head(&l6dr->wait);
111	return 0;
112}
113
114/*
115	Destruct dump request data structure.
116*/
117void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num)
118{
119	if (l6dr == NULL)
120		return;
121	if (l6dr->reqbufs[num].buffer == NULL)
122		return;
123	kfree(l6dr->reqbufs[num].buffer);
124	l6dr->reqbufs[num].buffer = NULL;
125}
126
127/*
128	Destruct dump request data structure.
129*/
130void line6_dumpreq_destruct(struct line6_dump_request *l6dr)
131{
132	if (l6dr->reqbufs[0].buffer == NULL)
133		return;
134	line6_dumpreq_destructbuf(l6dr, 0);
135}