u8 *diag_cmd_buffer;
u8 *diag_resp_buffer;
struct ath6kl *ar;
+ struct workqueue_struct *wq;
};
/* usb urb object */
* Flushing any pending I/O may schedule work this call will block
* until all scheduled work runs to completion.
*/
- flush_scheduled_work();
+ flush_workqueue(ar_usb->wq);
}
static void ath6kl_usb_start_recv_pipes(struct ath6kl_usb *ar_usb)
/* note: queue implements a lock */
skb_queue_tail(&pipe->io_comp_queue, skb);
- schedule_work(&pipe->io_complete_work);
+ queue_work(pipe->ar_usb->wq, &pipe->io_complete_work);
cleanup_recv_urb:
ath6kl_usb_cleanup_recv_urb(urb_context);
/* note: queue implements a lock */
skb_queue_tail(&pipe->io_comp_queue, skb);
- schedule_work(&pipe->io_complete_work);
+ queue_work(pipe->ar_usb->wq, &pipe->io_complete_work);
}
static void ath6kl_usb_io_comp_work(struct work_struct *work)
kfree(ar_usb->diag_cmd_buffer);
kfree(ar_usb->diag_resp_buffer);
+ destroy_workqueue(ar_usb->wq);
kfree(ar_usb);
}
int status = 0;
int i;
+ /* ath6kl_usb_destroy() needs ar_usb != NULL && ar_usb->wq != NULL. */
ar_usb = kzalloc(sizeof(struct ath6kl_usb), GFP_KERNEL);
if (ar_usb == NULL)
- goto fail_ath6kl_usb_create;
+ return NULL;
+ ar_usb->wq = alloc_workqueue("ath6kl_wq", 0, 0);
+ if (!ar_usb->wq) {
+ kfree(ar_usb);
+ return NULL;
+ }
usb_set_intfdata(interface, ar_usb);
spin_lock_init(&(ar_usb->cs_lock));