at v3.4 3.0 kB view raw
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}