aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/line6/midibuf.c106
1 files changed, 51 insertions, 55 deletions
diff --git a/drivers/staging/line6/midibuf.c b/drivers/staging/line6/midibuf.c
index 5726bb148a5a..ab0a5f30fbca 100644
--- a/drivers/staging/line6/midibuf.c
+++ b/drivers/staging/line6/midibuf.c
@@ -18,18 +18,19 @@
18 18
19static int midibuf_message_length(unsigned char code) 19static int midibuf_message_length(unsigned char code)
20{ 20{
21 if(code < 0x80) 21 if (code < 0x80)
22 return -1; 22 return -1;
23 else if(code < 0xf0) { 23 else if (code < 0xf0) {
24 static const int length[] = { 3, 3, 3, 3, 2, 2, 3 }; 24 static const int length[] = { 3, 3, 3, 3, 2, 2, 3 };
25 return length[(code >> 4) - 8]; 25 return length[(code >> 4) - 8];
26 } 26 } else {
27 else {
28 /* 27 /*
29 Note that according to the MIDI specification 0xf2 is the "Song Position 28 Note that according to the MIDI specification 0xf2 is
30 Pointer", but this is used by Line6 to send sysex messages to the host. 29 the "Song Position Pointer", but this is used by Line6
30 to send sysex messages to the host.
31 */ 31 */
32 static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1 }; 32 static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
33 1, 1, 1, -1, 1, 1 };
33 return length[code & 0x0f]; 34 return length[code & 0x0f];
34 } 35 }
35} 36}
@@ -42,7 +43,7 @@ void midibuf_reset(struct MidiBuffer *this)
42 43
43int midibuf_init(struct MidiBuffer *this, int size, int split) 44int midibuf_init(struct MidiBuffer *this, int size, int split)
44{ 45{
45 this->buf = (unsigned char *)kmalloc(size, GFP_KERNEL); 46 this->buf = kmalloc(size, GFP_KERNEL);
46 47
47 if (this->buf == NULL) 48 if (this->buf == NULL)
48 return -ENOMEM; 49 return -ENOMEM;
@@ -55,8 +56,9 @@ int midibuf_init(struct MidiBuffer *this, int size, int split)
55 56
56void midibuf_status(struct MidiBuffer *this) 57void midibuf_status(struct MidiBuffer *this)
57{ 58{
58 printk("midibuf size=%d split=%d pos_read=%d pos_write=%d full=%d command_prev=%02x\n", 59 printk(KERN_DEBUG "midibuf size=%d split=%d pos_read=%d pos_write=%d "
59 this->size, this->split, this->pos_read, this->pos_write, this->full, this->command_prev); 60 "full=%d command_prev=%02x\n", this->size, this->split,
61 this->pos_read, this->pos_write, this->full, this->command_prev);
60} 62}
61 63
62static int midibuf_is_empty(struct MidiBuffer *this) 64static int midibuf_is_empty(struct MidiBuffer *this)
@@ -91,29 +93,28 @@ int midibuf_write(struct MidiBuffer *this, unsigned char *data, int length)
91 int length1, length2; 93 int length1, length2;
92 int skip_active_sense = 0; 94 int skip_active_sense = 0;
93 95
94 if(midibuf_is_full(this) || (length <= 0)) 96 if (midibuf_is_full(this) || (length <= 0))
95 return 0; 97 return 0;
96 98
97 /* skip trailing active sense */ 99 /* skip trailing active sense */
98 if(data[length - 1] == 0xfe) { 100 if (data[length - 1] == 0xfe) {
99 --length; 101 --length;
100 skip_active_sense = 1; 102 skip_active_sense = 1;
101 } 103 }
102 104
103 bytes_free = midibuf_bytes_free(this); 105 bytes_free = midibuf_bytes_free(this);
104 106
105 if(length > bytes_free) 107 if (length > bytes_free)
106 length = bytes_free; 108 length = bytes_free;
107 109
108 if(length > 0) { 110 if (length > 0) {
109 length1 = this->size - this->pos_write; 111 length1 = this->size - this->pos_write;
110 112
111 if(length < length1) { 113 if (length < length1) {
112 /* no buffer wraparound */ 114 /* no buffer wraparound */
113 memcpy(this->buf + this->pos_write, data, length); 115 memcpy(this->buf + this->pos_write, data, length);
114 this->pos_write += length; 116 this->pos_write += length;
115 } 117 } else {
116 else {
117 /* buffer wraparound */ 118 /* buffer wraparound */
118 length2 = length - length1; 119 length2 = length - length1;
119 memcpy(this->buf + this->pos_write, data, length1); 120 memcpy(this->buf + this->pos_write, data, length1);
@@ -121,7 +122,7 @@ int midibuf_write(struct MidiBuffer *this, unsigned char *data, int length)
121 this->pos_write = length2; 122 this->pos_write = length2;
122 } 123 }
123 124
124 if(this->pos_write == this->pos_read) 125 if (this->pos_write == this->pos_read)
125 this->full = 1; 126 this->full = 1;
126 } 127 }
127 128
@@ -137,15 +138,16 @@ int midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)
137 int repeat = 0; 138 int repeat = 0;
138 int i; 139 int i;
139 140
140 if(length < 3) 141 /* we need to be able to store at least a 3 byte MIDI message */
141 return -EINVAL; /* we need to be able to store at least a 3 byte MIDI message */ 142 if (length < 3)
143 return -EINVAL;
142 144
143 if(midibuf_is_empty(this)) 145 if (midibuf_is_empty(this))
144 return 0; 146 return 0;
145 147
146 bytes_used = midibuf_bytes_used(this); 148 bytes_used = midibuf_bytes_used(this);
147 149
148 if(length > bytes_used) 150 if (length > bytes_used)
149 length = bytes_used; 151 length = bytes_used;
150 152
151 length1 = this->size - this->pos_read; 153 length1 = this->size - this->pos_read;
@@ -153,75 +155,69 @@ int midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)
153 /* check MIDI command length */ 155 /* check MIDI command length */
154 command = this->buf[this->pos_read]; 156 command = this->buf[this->pos_read];
155 157
156 if(command & 0x80) { 158 if (command & 0x80) {
157 midi_length = midibuf_message_length(command); 159 midi_length = midibuf_message_length(command);
158 this->command_prev = command; 160 this->command_prev = command;
159 } 161 } else {
160 else { 162 if (this->command_prev > 0) {
161 if(this->command_prev > 0) {
162 int midi_length_prev = midibuf_message_length(this->command_prev); 163 int midi_length_prev = midibuf_message_length(this->command_prev);
163 164
164 if(midi_length_prev > 0) { 165 if (midi_length_prev > 0) {
165 midi_length = midi_length_prev - 1; 166 midi_length = midi_length_prev - 1;
166 repeat = 1; 167 repeat = 1;
167 } 168 } else
168 else
169 midi_length = -1; 169 midi_length = -1;
170 } 170 } else
171 else
172 midi_length = -1; 171 midi_length = -1;
173 } 172 }
174 173
175 if(midi_length < 0) { 174 if (midi_length < 0) {
176 /* search for end of message */ 175 /* search for end of message */
177 if(length < length1) { 176 if (length < length1) {
178 /* no buffer wraparound */ 177 /* no buffer wraparound */
179 for(i = 1; i < length; ++i) 178 for (i = 1; i < length; ++i)
180 if(this->buf[this->pos_read + i] & 0x80) 179 if (this->buf[this->pos_read + i] & 0x80)
181 break; 180 break;
182 181
183 midi_length = i; 182 midi_length = i;
184 } 183 } else {
185 else {
186 /* buffer wraparound */ 184 /* buffer wraparound */
187 length2 = length - length1; 185 length2 = length - length1;
188 186
189 for(i = 1; i < length1; ++i) 187 for (i = 1; i < length1; ++i)
190 if(this->buf[this->pos_read + i] & 0x80) 188 if (this->buf[this->pos_read + i] & 0x80)
191 break; 189 break;
192 190
193 if(i < length1) 191 if (i < length1)
194 midi_length = i; 192 midi_length = i;
195 else { 193 else {
196 for(i = 0; i < length2; ++i) 194 for (i = 0; i < length2; ++i)
197 if(this->buf[i] & 0x80) 195 if (this->buf[i] & 0x80)
198 break; 196 break;
199 197
200 midi_length = length1 + i; 198 midi_length = length1 + i;
201 } 199 }
202 } 200 }
203 201
204 if(midi_length == length) 202 if (midi_length == length)
205 midi_length = -1; /* end of message not found */ 203 midi_length = -1; /* end of message not found */
206 } 204 }
207 205
208 if(midi_length < 0) { 206 if (midi_length < 0) {
209 if(!this->split) 207 if (!this->split)
210 return 0; /* command is not yet complete */ 208 return 0; /* command is not yet complete */
211 } 209 } else {
212 else { 210 if (length < midi_length)
213 if(length < midi_length)
214 return 0; /* command is not yet complete */ 211 return 0; /* command is not yet complete */
215 212
216 length = midi_length; 213 length = midi_length;
217 } 214 }
218 215
219 if(length < length1) { 216 if (length < length1) {
220 /* no buffer wraparound */ 217 /* no buffer wraparound */
221 memcpy(data + repeat, this->buf + this->pos_read, length); 218 memcpy(data + repeat, this->buf + this->pos_read, length);
222 this->pos_read += length; 219 this->pos_read += length;
223 } 220 } else {
224 else {
225 /* buffer wraparound */ 221 /* buffer wraparound */
226 length2 = length - length1; 222 length2 = length - length1;
227 memcpy(data + repeat, this->buf + this->pos_read, length1); 223 memcpy(data + repeat, this->buf + this->pos_read, length1);
@@ -229,7 +225,7 @@ int midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)
229 this->pos_read = length2; 225 this->pos_read = length2;
230 } 226 }
231 227
232 if(repeat) 228 if (repeat)
233 data[0] = this->command_prev; 229 data[0] = this->command_prev;
234 230
235 this->full = 0; 231 this->full = 0;
@@ -240,7 +236,7 @@ int midibuf_ignore(struct MidiBuffer *this, int length)
240{ 236{
241 int bytes_used = midibuf_bytes_used(this); 237 int bytes_used = midibuf_bytes_used(this);
242 238
243 if(length > bytes_used) 239 if (length > bytes_used)
244 length = bytes_used; 240 length = bytes_used;
245 241
246 this->pos_read = (this->pos_read + length) % this->size; 242 this->pos_read = (this->pos_read + length) % this->size;
@@ -252,8 +248,8 @@ int midibuf_skip_message(struct MidiBuffer *this, unsigned short mask)
252{ 248{
253 int cmd = this->command_prev; 249 int cmd = this->command_prev;
254 250
255 if((cmd >= 0x80) && (cmd < 0xf0)) 251 if ((cmd >= 0x80) && (cmd < 0xf0))
256 if((mask & (1 << (cmd & 0x0f))) == 0) 252 if ((mask & (1 << (cmd & 0x0f))) == 0)
257 return 1; 253 return 1;
258 254
259 return 0; 255 return 0;