diff options
Diffstat (limited to 'drivers/staging/ozwpan/ozeltbuf.c')
-rw-r--r-- | drivers/staging/ozwpan/ozeltbuf.c | 130 |
1 files changed, 22 insertions, 108 deletions
diff --git a/drivers/staging/ozwpan/ozeltbuf.c b/drivers/staging/ozwpan/ozeltbuf.c index bd560c67fc8c..01b25da44241 100644 --- a/drivers/staging/ozwpan/ozeltbuf.c +++ b/drivers/staging/ozwpan/ozeltbuf.c @@ -10,21 +10,16 @@ #include "ozeltbuf.h" #include "ozpd.h" -#define OZ_ELT_INFO_MAGIC_USED 0x35791057 -#define OZ_ELT_INFO_MAGIC_FREE 0x78940102 - /* * Context: softirq-serialized */ -int oz_elt_buf_init(struct oz_elt_buf *buf) +void oz_elt_buf_init(struct oz_elt_buf *buf) { memset(buf, 0, sizeof(struct oz_elt_buf)); INIT_LIST_HEAD(&buf->stream_list); INIT_LIST_HEAD(&buf->order_list); INIT_LIST_HEAD(&buf->isoc_list); - buf->max_free_elts = 32; spin_lock_init(&buf->lock); - return 0; } /* @@ -32,32 +27,12 @@ int oz_elt_buf_init(struct oz_elt_buf *buf) */ void oz_elt_buf_term(struct oz_elt_buf *buf) { - struct list_head *e; - int i; + struct oz_elt_info *ei, *n; - /* Free any elements in the order or isoc lists. */ - for (i = 0; i < 2; i++) { - struct list_head *list; - if (i) - list = &buf->order_list; - else - list = &buf->isoc_list; - e = list->next; - while (e != list) { - struct oz_elt_info *ei = - container_of(e, struct oz_elt_info, link_order); - e = e->next; - kfree(ei); - } - } - /* Free any elelment in the pool. */ - while (buf->elt_pool) { - struct oz_elt_info *ei = - container_of(buf->elt_pool, struct oz_elt_info, link); - buf->elt_pool = buf->elt_pool->next; + list_for_each_entry_safe(ei, n, &buf->isoc_list, link_order) + kfree(ei); + list_for_each_entry_safe(ei, n, &buf->order_list, link_order) kfree(ei); - } - buf->free_elts = 0; } /* @@ -67,27 +42,8 @@ struct oz_elt_info *oz_elt_info_alloc(struct oz_elt_buf *buf) { struct oz_elt_info *ei; - spin_lock_bh(&buf->lock); - if (buf->free_elts && buf->elt_pool) { - ei = container_of(buf->elt_pool, struct oz_elt_info, link); - buf->elt_pool = ei->link.next; - buf->free_elts--; - spin_unlock_bh(&buf->lock); - if (ei->magic != OZ_ELT_INFO_MAGIC_FREE) { - oz_dbg(ON, "%s: ei with bad magic: 0x%x\n", - __func__, ei->magic); - } - } else { - spin_unlock_bh(&buf->lock); - ei = kmalloc(sizeof(struct oz_elt_info), GFP_ATOMIC); - } + ei = kmem_cache_zalloc(oz_elt_info_cache, GFP_ATOMIC); if (ei) { - ei->flags = 0; - ei->app_id = 0; - ei->callback = NULL; - ei->context = 0; - ei->stream = NULL; - ei->magic = OZ_ELT_INFO_MAGIC_USED; INIT_LIST_HEAD(&ei->link); INIT_LIST_HEAD(&ei->link_order); } @@ -100,17 +56,8 @@ struct oz_elt_info *oz_elt_info_alloc(struct oz_elt_buf *buf) */ void oz_elt_info_free(struct oz_elt_buf *buf, struct oz_elt_info *ei) { - if (ei) { - if (ei->magic == OZ_ELT_INFO_MAGIC_USED) { - buf->free_elts++; - ei->link.next = buf->elt_pool; - buf->elt_pool = &ei->link; - ei->magic = OZ_ELT_INFO_MAGIC_FREE; - } else { - oz_dbg(ON, "%s: bad magic ei: %p magic: 0x%x\n", - __func__, ei, ei->magic); - } - } + if (ei) + kmem_cache_free(oz_elt_info_cache, ei); } /*------------------------------------------------------------------------------ @@ -118,16 +65,11 @@ void oz_elt_info_free(struct oz_elt_buf *buf, struct oz_elt_info *ei) */ void oz_elt_info_free_chain(struct oz_elt_buf *buf, struct list_head *list) { - struct list_head *e; + struct oz_elt_info *ei, *n; - e = list->next; spin_lock_bh(&buf->lock); - while (e != list) { - struct oz_elt_info *ei; - ei = container_of(e, struct oz_elt_info, link); - e = e->next; + list_for_each_entry_safe(ei, n, list->next, link) oz_elt_info_free(buf, ei); - } spin_unlock_bh(&buf->lock); } @@ -152,14 +94,13 @@ int oz_elt_stream_create(struct oz_elt_buf *buf, u8 id, int max_buf_count) int oz_elt_stream_delete(struct oz_elt_buf *buf, u8 id) { - struct list_head *e; + struct list_head *e, *n; struct oz_elt_stream *st = NULL; oz_dbg(ON, "%s: (0x%x)\n", __func__, id); spin_lock_bh(&buf->lock); - e = buf->stream_list.next; - while (e != &buf->stream_list) { - st = container_of(e, struct oz_elt_stream, link); + list_for_each(e, &buf->stream_list) { + st = list_entry(e, struct oz_elt_stream, link); if (st->id == id) { list_del(e); break; @@ -170,11 +111,9 @@ int oz_elt_stream_delete(struct oz_elt_buf *buf, u8 id) spin_unlock_bh(&buf->lock); return -1; } - e = st->elt_list.next; - while (e != &st->elt_list) { + list_for_each_safe(e, n, &st->elt_list) { struct oz_elt_info *ei = - container_of(e, struct oz_elt_info, link); - e = e->next; + list_entry(e, struct oz_elt_info, link); list_del_init(&ei->link); list_del_init(&ei->link_order); st->buf_count -= ei->length; @@ -214,7 +153,7 @@ int oz_queue_elt_info(struct oz_elt_buf *buf, u8 isoc, u8 id, if (id) { list_for_each(e, &buf->stream_list) { - st = container_of(e, struct oz_elt_stream, link); + st = list_entry(e, struct oz_elt_stream, link); if (st->id == id) break; } @@ -235,6 +174,7 @@ int oz_queue_elt_info(struct oz_elt_buf *buf, u8 isoc, u8 id, == OZ_USB_ENDPOINT_DATA) && (body->format == OZ_DATA_F_ISOC_FIXED)) { u8 unit_count = body->frame_number; + body->frame_number = st->frame_number; st->frame_number += unit_count; } @@ -269,22 +209,18 @@ int oz_select_elts_for_tx(struct oz_elt_buf *buf, u8 isoc, unsigned *len, unsigned max_len, struct list_head *list) { int count = 0; - struct list_head *e; struct list_head *el; - struct oz_elt_info *ei; + struct oz_elt_info *ei, *n; spin_lock_bh(&buf->lock); if (isoc) el = &buf->isoc_list; else el = &buf->order_list; - e = el->next; - while (e != el) { - struct oz_app_hdr *app_hdr; - ei = container_of(e, struct oz_elt_info, link_order); - e = e->next; + + list_for_each_entry_safe(ei, n, el, link_order) { if ((*len + ei->length) <= max_len) { - app_hdr = (struct oz_app_hdr *) + struct oz_app_hdr *app_hdr = (struct oz_app_hdr *) &ei->data[sizeof(struct oz_elt)]; app_hdr->elt_seq_num = buf->tx_seq_num[ei->app_id]++; if (buf->tx_seq_num[ei->app_id] == 0) @@ -312,27 +248,5 @@ int oz_select_elts_for_tx(struct oz_elt_buf *buf, u8 isoc, unsigned *len, int oz_are_elts_available(struct oz_elt_buf *buf) { - return buf->order_list.next != &buf->order_list; -} - -void oz_trim_elt_pool(struct oz_elt_buf *buf) -{ - struct list_head *free = NULL; - struct list_head *e; - - spin_lock_bh(&buf->lock); - while (buf->free_elts > buf->max_free_elts) { - e = buf->elt_pool; - buf->elt_pool = e->next; - e->next = free; - free = e; - buf->free_elts--; - } - spin_unlock_bh(&buf->lock); - while (free) { - struct oz_elt_info *ei = - container_of(free, struct oz_elt_info, link); - free = free->next; - kfree(ei); - } + return !list_empty(&buf->order_list); } |