123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- /*
- * Line6 Linux USB driver - 0.9.1beta
- *
- * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- */
- #include <linux/slab.h>
- #include "driver.h"
- #include "dumprequest.h"
- /*
- Set "dump in progress" flag.
- */
- void line6_dump_started(struct line6_dump_request *l6dr, int dest)
- {
- l6dr->in_progress = dest;
- }
- /*
- Invalidate current channel, i.e., set "dump in progress" flag.
- Reading from the "dump" special file blocks until dump is completed.
- */
- void line6_invalidate_current(struct line6_dump_request *l6dr)
- {
- line6_dump_started(l6dr, LINE6_DUMP_CURRENT);
- }
- /*
- Clear "dump in progress" flag and notify waiting processes.
- */
- void line6_dump_finished(struct line6_dump_request *l6dr)
- {
- l6dr->in_progress = LINE6_DUMP_NONE;
- wake_up(&l6dr->wait);
- }
- /*
- Send an asynchronous channel dump request.
- */
- int line6_dump_request_async(struct line6_dump_request *l6dr,
- struct usb_line6 *line6, int num, int dest)
- {
- int ret;
- line6_dump_started(l6dr, dest);
- ret = line6_send_raw_message_async(line6, l6dr->reqbufs[num].buffer,
- l6dr->reqbufs[num].length);
- if (ret < 0)
- line6_dump_finished(l6dr);
- return ret;
- }
- /*
- Wait for completion (interruptible).
- */
- int line6_dump_wait_interruptible(struct line6_dump_request *l6dr)
- {
- return wait_event_interruptible(l6dr->wait,
- l6dr->in_progress == LINE6_DUMP_NONE);
- }
- /*
- Wait for completion.
- */
- void line6_dump_wait(struct line6_dump_request *l6dr)
- {
- wait_event(l6dr->wait, l6dr->in_progress == LINE6_DUMP_NONE);
- }
- /*
- Wait for completion (with timeout).
- */
- int line6_dump_wait_timeout(struct line6_dump_request *l6dr, long timeout)
- {
- return wait_event_timeout(l6dr->wait,
- l6dr->in_progress == LINE6_DUMP_NONE,
- timeout);
- }
- /*
- Initialize dump request buffer.
- */
- int line6_dumpreq_initbuf(struct line6_dump_request *l6dr, const void *buf,
- size_t len, int num)
- {
- l6dr->reqbufs[num].buffer = kmemdup(buf, len, GFP_KERNEL);
- if (l6dr->reqbufs[num].buffer == NULL)
- return -ENOMEM;
- l6dr->reqbufs[num].length = len;
- return 0;
- }
- /*
- Initialize dump request data structure (including one buffer).
- */
- int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf,
- size_t len)
- {
- int ret;
- ret = line6_dumpreq_initbuf(l6dr, buf, len, 0);
- if (ret < 0)
- return ret;
- init_waitqueue_head(&l6dr->wait);
- return 0;
- }
- /*
- Destruct dump request data structure.
- */
- void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num)
- {
- if (l6dr == NULL)
- return;
- if (l6dr->reqbufs[num].buffer == NULL)
- return;
- kfree(l6dr->reqbufs[num].buffer);
- l6dr->reqbufs[num].buffer = NULL;
- }
- /*
- Destruct dump request data structure.
- */
- void line6_dumpreq_destruct(struct line6_dump_request *l6dr)
- {
- if (l6dr->reqbufs[0].buffer == NULL)
- return;
- line6_dumpreq_destructbuf(l6dr, 0);
- }
|