Root/drivers/staging/line6/dumprequest.c

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}
136

Archive Download this file



interactive