static void oz_pd_free(struct work_struct *work) { struct oz_pd *pd; struct list_head *e; struct oz_tx_frame *f; struct oz_isoc_stream *st; struct oz_farewell *fwell; pd = container_of(work, struct oz_pd, workitem); oz_trace_msg(M, "Destroying PD:%p\n", pd); tasklet_kill(&pd->heartbeat_tasklet); tasklet_kill(&pd->timeout_tasklet); /* Finish scheduled uevent work, uevent might be rescheduled by * oz timeout tasklet again */ cancel_work_sync(&pd->uevent_workitem); /* Delete any streams. */ e = pd->stream_list.next; while (e != &pd->stream_list) { st = container_of(e, struct oz_isoc_stream, link); e = e->next; oz_isoc_stream_free(st); } /* Free any queued tx frames. */ e = pd->tx_queue.next; while (e != &pd->tx_queue) { f = container_of(e, struct oz_tx_frame, link); e = e->next; if (f->skb != NULL) kfree_skb(f->skb); oz_retire_frame(pd, f); } oz_elt_buf_term(&pd->elt_buff); /* Free any farewells. */ e = pd->farewell_list.next; while (e != &pd->farewell_list) { fwell = container_of(e, struct oz_farewell, link); e = e->next; kfree(fwell); } /* Deallocate all frames in tx pool. */ while (pd->tx_pool) { e = pd->tx_pool; pd->tx_pool = e->next; kfree(container_of(e, struct oz_tx_frame, link)); } if (pd->net_dev) { oz_trace_msg(M, "%s: dev_put(%p)\n", __func__, pd->net_dev); dev_put(pd->net_dev); } kfree(pd); complete(&oz_pd_done); }
/* * Context: softirq or process */ static void oz_pd_free(struct work_struct *work) { struct list_head *e; struct oz_tx_frame *f; struct oz_isoc_stream *st; struct oz_farewell *fwell; struct oz_pd *pd; oz_pd_dbg(pd, ON, "Destroying PD\n"); pd = container_of(work, struct oz_pd, workitem); /*Disable timer tasklets*/ tasklet_kill(&pd->heartbeat_tasklet); tasklet_kill(&pd->timeout_tasklet); /* Delete any streams. */ e = pd->stream_list.next; while (e != &pd->stream_list) { st = container_of(e, struct oz_isoc_stream, link); e = e->next; oz_isoc_stream_free(st); } /* Free any queued tx frames. */ e = pd->tx_queue.next; while (e != &pd->tx_queue) { f = container_of(e, struct oz_tx_frame, link); e = e->next; if (f->skb != NULL) kfree_skb(f->skb); oz_retire_frame(pd, f); } oz_elt_buf_term(&pd->elt_buff); /* Free any farewells. */ e = pd->farewell_list.next; while (e != &pd->farewell_list) { fwell = container_of(e, struct oz_farewell, link); e = e->next; kfree(fwell); } /* Deallocate all frames in tx pool. */ while (pd->tx_pool) { e = pd->tx_pool; pd->tx_pool = e->next; kfree(container_of(e, struct oz_tx_frame, link)); } if (pd->net_dev) dev_put(pd->net_dev); kfree(pd); }
/*------------------------------------------------------------------------------ * Context: softirq or process */ void oz_pd_destroy(struct oz_pd *pd) { struct list_head *e; struct oz_tx_frame *f; struct oz_isoc_stream *st; struct oz_farewell *fwell; oz_trace("Destroying PD\n"); /* Delete any streams. */ e = pd->stream_list.next; while (e != &pd->stream_list) { st = container_of(e, struct oz_isoc_stream, link); e = e->next; oz_isoc_stream_free(st); } /* Free any queued tx frames. */ e = pd->tx_queue.next; while (e != &pd->tx_queue) { f = container_of(e, struct oz_tx_frame, link); e = e->next; if (f->skb != NULL) kfree_skb(f->skb); oz_retire_frame(pd, f); } oz_elt_buf_term(&pd->elt_buff); /* Free any farewells. */ e = pd->farewell_list.next; while (e != &pd->farewell_list) { fwell = container_of(e, struct oz_farewell, link); e = e->next; kfree(fwell); } /* Deallocate all frames in tx pool. */ while (pd->tx_pool) { e = pd->tx_pool; pd->tx_pool = e->next; kfree(container_of(e, struct oz_tx_frame, link)); } if (pd->net_dev) dev_put(pd->net_dev); kfree(pd); }