From ecf0ba70c65bb385c39ff7a4e17bff477382f31c Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Fri, 8 May 2009 13:02:41 -0700 Subject: [PATCH] --- yaml --- r: 150869 b: refs/heads/master c: e9a6b45be580d648ed2f21646214733504bd4d6f h: refs/heads/master i: 150867: 2c2c63adb44bc332384fb4c0094bf2264f6d6712 v: v3 --- [refs] | 2 +- trunk/drivers/net/wimax/i2400m/driver.c | 21 ++++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/[refs] b/[refs] index c1a132b4889a..3a0a9a5c7393 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: fff1068559a2ae00a036b80c5df3c564fc6c6305 +refs/heads/master: e9a6b45be580d648ed2f21646214733504bd4d6f diff --git a/trunk/drivers/net/wimax/i2400m/driver.c b/trunk/drivers/net/wimax/i2400m/driver.c index 86dd18a48358..006eb1233a8b 100644 --- a/trunk/drivers/net/wimax/i2400m/driver.c +++ b/trunk/drivers/net/wimax/i2400m/driver.c @@ -385,6 +385,11 @@ int i2400m_check_mac_addr(struct i2400m *i2400m) * Uploads firmware and brings up all the resources needed to be able * to communicate with the device. * + * The workqueue has to be setup early, at least before RX handling + * (it's only real user for now) so it can process reports as they + * arrive. We also want to destroy it if we retry, to make sure it is + * flushed...easier like this. + * * TX needs to be setup before the bus-specific code (otherwise on * shutdown, the bus-tx code could try to access it). */ @@ -410,15 +415,15 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags) result = i2400m_rx_setup(i2400m); if (result < 0) goto error_rx_setup; - result = i2400m->bus_dev_start(i2400m); - if (result < 0) - goto error_bus_dev_start; i2400m->work_queue = create_singlethread_workqueue(wimax_dev->name); if (i2400m->work_queue == NULL) { result = -ENOMEM; dev_err(dev, "cannot create workqueue\n"); goto error_create_workqueue; } + result = i2400m->bus_dev_start(i2400m); + if (result < 0) + goto error_bus_dev_start; result = i2400m_firmware_check(i2400m); /* fw versions ok? */ if (result < 0) goto error_fw_check; @@ -440,10 +445,10 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags) error_dev_initialize: error_check_mac_addr: error_fw_check: - destroy_workqueue(i2400m->work_queue); -error_create_workqueue: i2400m->bus_dev_stop(i2400m); error_bus_dev_start: + destroy_workqueue(i2400m->work_queue); +error_create_workqueue: i2400m_rx_release(i2400m); error_rx_setup: i2400m_tx_release(i2400m); @@ -479,7 +484,9 @@ int i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri bm_flags) * * Returns: 0 if ok, < 0 errno code on error. * - * Releases all the resources allocated to communicate with the device. + * Releases all the resources allocated to communicate with the + * device. Note we cannot destroy the workqueue earlier as until RX is + * fully destroyed, it could still try to schedule jobs. */ static void __i2400m_dev_stop(struct i2400m *i2400m) @@ -491,8 +498,8 @@ void __i2400m_dev_stop(struct i2400m *i2400m) wimax_state_change(wimax_dev, __WIMAX_ST_QUIESCING); i2400m_dev_shutdown(i2400m); i2400m->ready = 0; - destroy_workqueue(i2400m->work_queue); i2400m->bus_dev_stop(i2400m); + destroy_workqueue(i2400m->work_queue); i2400m_rx_release(i2400m); i2400m_tx_release(i2400m); wimax_state_change(wimax_dev, WIMAX_ST_DOWN);