summaryrefslogtreecommitdiffstats
path: root/drivers/qmimodem
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2012-06-25 10:20:08 -0700
committerMarcel Holtmann <marcel@holtmann.org>2012-06-25 10:20:08 -0700
commita41b7a246b1fdac46afa2d898344ff1fc53e536b (patch)
treeac6d94c9dc30bccb273740db84ccc24cf6ef8dae /drivers/qmimodem
parent5ada27b7c1d99a20789eb2f9032aef8ee9cbdfd9 (diff)
downloadofono-a41b7a246b1fdac46afa2d898344ff1fc53e536b.tar.bz2
qmimodem: Add support for canceling all service requests
Diffstat (limited to 'drivers/qmimodem')
-rw-r--r--drivers/qmimodem/qmi.c79
-rw-r--r--drivers/qmimodem/qmi.h1
2 files changed, 70 insertions, 10 deletions
diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c
index 12a183f8..e34a69b6 100644
--- a/drivers/qmimodem/qmi.c
+++ b/drivers/qmimodem/qmi.c
@@ -89,6 +89,7 @@ struct qmi_result {
struct qmi_request {
uint16_t tid;
+ uint8_t client;
void *buf;
size_t len;
qmi_message_func_t callback;
@@ -165,6 +166,8 @@ static struct qmi_request *__request_alloc(uint8_t service,
return NULL;
}
+ req->client = client;
+
hdr = req->buf;
hdr->frame = 0x01;
@@ -1683,6 +1686,16 @@ struct service_send_data {
qmi_destroy_func_t destroy;
};
+static void service_send_free(struct service_send_data *data)
+{
+ if (data->destroy)
+ data->destroy(data->user_data);
+
+ qmi_param_free(data->param);
+
+ g_free(data);
+}
+
static void service_send_callback(uint16_t message, uint16_t length,
const void *buffer, void *user_data)
{
@@ -1709,11 +1722,7 @@ done:
if (data->func)
data->func(&result, data->user_data);
- if (data->destroy)
- data->destroy(data->user_data);
-
- qmi_param_free(data->param);
- g_free(data);
+ service_send_free(data);
}
uint16_t qmi_service_send(struct qmi_service *service,
@@ -1771,7 +1780,6 @@ bool qmi_service_cancel(struct qmi_service *service, uint16_t id)
{
unsigned int tid = id;
struct qmi_device *device;
- struct service_send_data *data;
struct qmi_request *req;
GList *list;
@@ -1802,16 +1810,67 @@ bool qmi_service_cancel(struct qmi_service *service, uint16_t id)
g_queue_delete_link(device->service_queue, list);
}
- data = req->user_data;
-
- if (data->destroy)
- data->destroy(data->user_data);
+ service_send_free(req->user_data);
__request_free(req, NULL);
return true;
}
+static GQueue *remove_client(GQueue *queue, uint8_t client)
+{
+ GQueue *new_queue;
+ GList *list;
+
+ new_queue = g_queue_new();
+
+ while (1) {
+ struct qmi_request *req;
+
+ list = g_queue_pop_head_link(queue);
+ if (!list)
+ break;
+
+ req = list->data;
+
+ if (!req->client || req->client != client) {
+ g_queue_push_tail_link(new_queue, list);
+ continue;
+ }
+
+ service_send_free(req->user_data);
+
+ __request_free(req, NULL);
+ }
+
+ g_queue_free(queue);
+
+ return new_queue;
+}
+
+bool qmi_service_cancel_all(struct qmi_service *service)
+{
+ struct qmi_device *device;
+
+ if (!service)
+ return false;
+
+ if (!service->client_id)
+ return false;
+
+ device = service->device;
+ if (!device)
+ return false;
+
+ device->req_queue = remove_client(device->req_queue,
+ service->client_id);
+
+ device->service_queue = remove_client(device->service_queue,
+ service->client_id);
+
+ return true;
+}
+
uint16_t qmi_service_register(struct qmi_service *service,
uint16_t message, qmi_result_func_t func,
void *user_data, qmi_destroy_func_t destroy)
diff --git a/drivers/qmimodem/qmi.h b/drivers/qmimodem/qmi.h
index 3e51a829..81cfac91 100644
--- a/drivers/qmimodem/qmi.h
+++ b/drivers/qmimodem/qmi.h
@@ -143,6 +143,7 @@ uint16_t qmi_service_send(struct qmi_service *service,
qmi_result_func_t func,
void *user_data, qmi_destroy_func_t destroy);
bool qmi_service_cancel(struct qmi_service *service, uint16_t id);
+bool qmi_service_cancel_all(struct qmi_service *service);
uint16_t qmi_service_register(struct qmi_service *service,
uint16_t message, qmi_result_func_t func,