diff options
author | Inaky Perez-Gonzalez <inaky@linux.intel.com> | 2009-05-08 16:02:41 -0400 |
---|---|---|
committer | Inaky Perez-Gonzalez <inaky@linux.intel.com> | 2009-06-11 06:30:18 -0400 |
commit | e9a6b45be580d648ed2f21646214733504bd4d6f (patch) | |
tree | e8dccd2ef276a4725ee9f1bfaad8b3ce5d0f6cf1 /drivers/net/wimax/i2400m/driver.c | |
parent | fff1068559a2ae00a036b80c5df3c564fc6c6305 (diff) |
wimax/i2400m: i2400m's work queue should be initialized before RX support
RX support is the only user of the work-queue, to process
reports/notifications from the device. Thus, it needs the work queue
to be initialized first.
Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
Diffstat (limited to 'drivers/net/wimax/i2400m/driver.c')
-rw-r--r-- | drivers/net/wimax/i2400m/driver.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c index 86dd18a48358..006eb1233a8b 100644 --- a/drivers/net/wimax/i2400m/driver.c +++ b/drivers/net/wimax/i2400m/driver.c | |||
@@ -385,6 +385,11 @@ error: | |||
385 | * Uploads firmware and brings up all the resources needed to be able | 385 | * Uploads firmware and brings up all the resources needed to be able |
386 | * to communicate with the device. | 386 | * to communicate with the device. |
387 | * | 387 | * |
388 | * The workqueue has to be setup early, at least before RX handling | ||
389 | * (it's only real user for now) so it can process reports as they | ||
390 | * arrive. We also want to destroy it if we retry, to make sure it is | ||
391 | * flushed...easier like this. | ||
392 | * | ||
388 | * TX needs to be setup before the bus-specific code (otherwise on | 393 | * TX needs to be setup before the bus-specific code (otherwise on |
389 | * shutdown, the bus-tx code could try to access it). | 394 | * shutdown, the bus-tx code could try to access it). |
390 | */ | 395 | */ |
@@ -410,15 +415,15 @@ retry: | |||
410 | result = i2400m_rx_setup(i2400m); | 415 | result = i2400m_rx_setup(i2400m); |
411 | if (result < 0) | 416 | if (result < 0) |
412 | goto error_rx_setup; | 417 | goto error_rx_setup; |
413 | result = i2400m->bus_dev_start(i2400m); | ||
414 | if (result < 0) | ||
415 | goto error_bus_dev_start; | ||
416 | i2400m->work_queue = create_singlethread_workqueue(wimax_dev->name); | 418 | i2400m->work_queue = create_singlethread_workqueue(wimax_dev->name); |
417 | if (i2400m->work_queue == NULL) { | 419 | if (i2400m->work_queue == NULL) { |
418 | result = -ENOMEM; | 420 | result = -ENOMEM; |
419 | dev_err(dev, "cannot create workqueue\n"); | 421 | dev_err(dev, "cannot create workqueue\n"); |
420 | goto error_create_workqueue; | 422 | goto error_create_workqueue; |
421 | } | 423 | } |
424 | result = i2400m->bus_dev_start(i2400m); | ||
425 | if (result < 0) | ||
426 | goto error_bus_dev_start; | ||
422 | result = i2400m_firmware_check(i2400m); /* fw versions ok? */ | 427 | result = i2400m_firmware_check(i2400m); /* fw versions ok? */ |
423 | if (result < 0) | 428 | if (result < 0) |
424 | goto error_fw_check; | 429 | goto error_fw_check; |
@@ -440,10 +445,10 @@ retry: | |||
440 | error_dev_initialize: | 445 | error_dev_initialize: |
441 | error_check_mac_addr: | 446 | error_check_mac_addr: |
442 | error_fw_check: | 447 | error_fw_check: |
443 | destroy_workqueue(i2400m->work_queue); | ||
444 | error_create_workqueue: | ||
445 | i2400m->bus_dev_stop(i2400m); | 448 | i2400m->bus_dev_stop(i2400m); |
446 | error_bus_dev_start: | 449 | error_bus_dev_start: |
450 | destroy_workqueue(i2400m->work_queue); | ||
451 | error_create_workqueue: | ||
447 | i2400m_rx_release(i2400m); | 452 | i2400m_rx_release(i2400m); |
448 | error_rx_setup: | 453 | error_rx_setup: |
449 | i2400m_tx_release(i2400m); | 454 | i2400m_tx_release(i2400m); |
@@ -479,7 +484,9 @@ int i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri bm_flags) | |||
479 | * | 484 | * |
480 | * Returns: 0 if ok, < 0 errno code on error. | 485 | * Returns: 0 if ok, < 0 errno code on error. |
481 | * | 486 | * |
482 | * Releases all the resources allocated to communicate with the device. | 487 | * Releases all the resources allocated to communicate with the |
488 | * device. Note we cannot destroy the workqueue earlier as until RX is | ||
489 | * fully destroyed, it could still try to schedule jobs. | ||
483 | */ | 490 | */ |
484 | static | 491 | static |
485 | void __i2400m_dev_stop(struct i2400m *i2400m) | 492 | void __i2400m_dev_stop(struct i2400m *i2400m) |
@@ -491,8 +498,8 @@ void __i2400m_dev_stop(struct i2400m *i2400m) | |||
491 | wimax_state_change(wimax_dev, __WIMAX_ST_QUIESCING); | 498 | wimax_state_change(wimax_dev, __WIMAX_ST_QUIESCING); |
492 | i2400m_dev_shutdown(i2400m); | 499 | i2400m_dev_shutdown(i2400m); |
493 | i2400m->ready = 0; | 500 | i2400m->ready = 0; |
494 | destroy_workqueue(i2400m->work_queue); | ||
495 | i2400m->bus_dev_stop(i2400m); | 501 | i2400m->bus_dev_stop(i2400m); |
502 | destroy_workqueue(i2400m->work_queue); | ||
496 | i2400m_rx_release(i2400m); | 503 | i2400m_rx_release(i2400m); |
497 | i2400m_tx_release(i2400m); | 504 | i2400m_tx_release(i2400m); |
498 | wimax_state_change(wimax_dev, WIMAX_ST_DOWN); | 505 | wimax_state_change(wimax_dev, WIMAX_ST_DOWN); |