aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorInaky Perez-Gonzalez <inaky@linux.intel.com>2009-09-16 20:53:57 -0400
committerInaky Perez-Gonzalez <inaky@linux.intel.com>2009-10-19 02:56:06 -0400
commit8f90f3ee83dc54e182d6a7548727cbae4b523e6e (patch)
tree8a81fd0076562a5c6e30a652c63fa25343783dc6
parentac53aed9349242095a780f57ac0c995fb170c950 (diff)
wimax/i2400m: cleanup initialization/destruction flow
Currently the i2400m driver was starting in a weird way: registering a network device, setting the device up and then registering a WiMAX device. This is an historic artifact, and was causing issues, a some early reports the device sends were getting lost by issue of the wimax_dev not being registered. Fix said situation by doing the wimax device registration in i2400m_setup() after network device registration and before starting thed device. As well, removed spurious setting of the state to UNINITIALIZED; i2400m.dev_start() does that already. Signed-off-by: Inaky Perez-Gonzalez <inaky@linux.intel.com>
-rw-r--r--drivers/net/wimax/i2400m/driver.c32
-rw-r--r--drivers/net/wimax/i2400m/i2400m.h30
-rw-r--r--drivers/net/wimax/i2400m/netdev.c10
3 files changed, 41 insertions, 31 deletions
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index a33df0431020..a0ae19966c0c 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -754,13 +754,9 @@ EXPORT_SYMBOL_GPL(i2400m_bm_buf_free
754 * 754 *
755 * Returns: 0 if ok, < 0 errno code on error. 755 * Returns: 0 if ok, < 0 errno code on error.
756 * 756 *
757 * Initializes the bus-generic parts of the i2400m driver; the 757 * Sets up basic device comunication infrastructure, boots the ROM to
758 * bus-specific parts have been initialized, function pointers filled 758 * read the MAC address, registers with the WiMAX and network stacks
759 * out by the bus-specific probe function. 759 * and then brings up the device.
760 *
761 * As well, this registers the WiMAX and net device nodes. Once this
762 * function returns, the device is operative and has to be ready to
763 * receive and send network traffic and WiMAX control operations.
764 */ 760 */
765int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags) 761int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
766{ 762{
@@ -796,18 +792,13 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
796 } 792 }
797 netif_carrier_off(net_dev); 793 netif_carrier_off(net_dev);
798 794
799 result = i2400m_dev_start(i2400m, bm_flags);
800 if (result < 0)
801 goto error_dev_start;
802
803 i2400m->wimax_dev.op_msg_from_user = i2400m_op_msg_from_user; 795 i2400m->wimax_dev.op_msg_from_user = i2400m_op_msg_from_user;
804 i2400m->wimax_dev.op_rfkill_sw_toggle = i2400m_op_rfkill_sw_toggle; 796 i2400m->wimax_dev.op_rfkill_sw_toggle = i2400m_op_rfkill_sw_toggle;
805 i2400m->wimax_dev.op_reset = i2400m_op_reset; 797 i2400m->wimax_dev.op_reset = i2400m_op_reset;
798
806 result = wimax_dev_add(&i2400m->wimax_dev, net_dev); 799 result = wimax_dev_add(&i2400m->wimax_dev, net_dev);
807 if (result < 0) 800 if (result < 0)
808 goto error_wimax_dev_add; 801 goto error_wimax_dev_add;
809 /* User space needs to do some init stuff */
810 wimax_state_change(wimax_dev, WIMAX_ST_UNINITIALIZED);
811 802
812 /* Now setup all that requires a registered net and wimax device. */ 803 /* Now setup all that requires a registered net and wimax device. */
813 result = sysfs_create_group(&net_dev->dev.kobj, &i2400m_dev_attr_group); 804 result = sysfs_create_group(&net_dev->dev.kobj, &i2400m_dev_attr_group);
@@ -815,22 +806,27 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
815 dev_err(dev, "cannot setup i2400m's sysfs: %d\n", result); 806 dev_err(dev, "cannot setup i2400m's sysfs: %d\n", result);
816 goto error_sysfs_setup; 807 goto error_sysfs_setup;
817 } 808 }
809
818 result = i2400m_debugfs_add(i2400m); 810 result = i2400m_debugfs_add(i2400m);
819 if (result < 0) { 811 if (result < 0) {
820 dev_err(dev, "cannot setup i2400m's debugfs: %d\n", result); 812 dev_err(dev, "cannot setup i2400m's debugfs: %d\n", result);
821 goto error_debugfs_setup; 813 goto error_debugfs_setup;
822 } 814 }
815
816 result = i2400m_dev_start(i2400m, bm_flags);
817 if (result < 0)
818 goto error_dev_start;
823 d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result); 819 d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
824 return result; 820 return result;
825 821
822error_dev_start:
823 i2400m_debugfs_rm(i2400m);
826error_debugfs_setup: 824error_debugfs_setup:
827 sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj, 825 sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj,
828 &i2400m_dev_attr_group); 826 &i2400m_dev_attr_group);
829error_sysfs_setup: 827error_sysfs_setup:
830 wimax_dev_rm(&i2400m->wimax_dev); 828 wimax_dev_rm(&i2400m->wimax_dev);
831error_wimax_dev_add: 829error_wimax_dev_add:
832 i2400m_dev_stop(i2400m);
833error_dev_start:
834 unregister_netdev(net_dev); 830 unregister_netdev(net_dev);
835error_register_netdev: 831error_register_netdev:
836 unregister_pm_notifier(&i2400m->pm_notifier); 832 unregister_pm_notifier(&i2400m->pm_notifier);
@@ -854,15 +850,15 @@ void i2400m_release(struct i2400m *i2400m)
854 d_fnstart(3, dev, "(i2400m %p)\n", i2400m); 850 d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
855 netif_stop_queue(i2400m->wimax_dev.net_dev); 851 netif_stop_queue(i2400m->wimax_dev.net_dev);
856 852
853 i2400m_dev_stop(i2400m);
854
857 i2400m_debugfs_rm(i2400m); 855 i2400m_debugfs_rm(i2400m);
858 sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj, 856 sysfs_remove_group(&i2400m->wimax_dev.net_dev->dev.kobj,
859 &i2400m_dev_attr_group); 857 &i2400m_dev_attr_group);
860 wimax_dev_rm(&i2400m->wimax_dev); 858 wimax_dev_rm(&i2400m->wimax_dev);
861 i2400m_dev_stop(i2400m);
862 unregister_netdev(i2400m->wimax_dev.net_dev); 859 unregister_netdev(i2400m->wimax_dev.net_dev);
863 unregister_pm_notifier(&i2400m->pm_notifier); 860 unregister_pm_notifier(&i2400m->pm_notifier);
864 kfree(i2400m->bm_ack_buf); 861 i2400m_bm_buf_free(i2400m);
865 kfree(i2400m->bm_cmd_buf);
866 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m); 862 d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
867} 863}
868EXPORT_SYMBOL_GPL(i2400m_release); 864EXPORT_SYMBOL_GPL(i2400m_release);
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index 303eb78bce32..2b9c400810b5 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -117,16 +117,28 @@
117 * well as i2400m->wimax_dev.net_dev and call i2400m_setup(). The 117 * well as i2400m->wimax_dev.net_dev and call i2400m_setup(). The
118 * i2400m driver will only register with the WiMAX and network stacks; 118 * i2400m driver will only register with the WiMAX and network stacks;
119 * the only access done to the device is to read the MAC address so we 119 * the only access done to the device is to read the MAC address so we
120 * can register a network device. This calls i2400m_dev_start() to 120 * can register a network device.
121 * load firmware, setup communication with the device and configure it
122 * for operation.
123 * 121 *
124 * At this point, control and data communications are possible. 122 * The high-level call flow is:
123 *
124 * bus_probe()
125 * i2400m_setup()
126 * boot rom initialization / read mac addr
127 * network / WiMAX stacks registration
128 * i2400m_dev_start()
129 * i2400m->bus_dev_start()
130 * i2400m_dev_initialize()
131 *
132 * The reverse applies for a disconnect() call:
125 * 133 *
126 * On disconnect/driver unload, the bus-specific disconnect function 134 * bus_disconnect()
127 * calls i2400m_release() to undo i2400m_setup(). i2400m_dev_stop() 135 * i2400m_release()
128 * shuts the firmware down and releases resources uses to communicate 136 * i2400m_dev_stop()
129 * with the device. 137 * i2400m_dev_shutdown()
138 * i2400m->bus_dev_stop()
139 * network / WiMAX stack unregistration
140 *
141 * At this point, control and data communications are possible.
130 * 142 *
131 * While the device is up, it might reset. The bus-specific driver has 143 * While the device is up, it might reset. The bus-specific driver has
132 * to catch that situation and call i2400m_dev_reset_handle() to deal 144 * to catch that situation and call i2400m_dev_reset_handle() to deal
@@ -706,7 +718,7 @@ static inline int i2400m_debugfs_add(struct i2400m *i2400m)
706static inline void i2400m_debugfs_rm(struct i2400m *i2400m) {} 718static inline void i2400m_debugfs_rm(struct i2400m *i2400m) {}
707#endif 719#endif
708 720
709/* Called by _dev_start()/_dev_stop() to initialize the device itself */ 721/* Initialize/shutdown the device */
710extern int i2400m_dev_initialize(struct i2400m *); 722extern int i2400m_dev_initialize(struct i2400m *);
711extern void i2400m_dev_shutdown(struct i2400m *); 723extern void i2400m_dev_shutdown(struct i2400m *);
712 724
diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c
index 0e8f6a046b9b..fefd794087ad 100644
--- a/drivers/net/wimax/i2400m/netdev.c
+++ b/drivers/net/wimax/i2400m/netdev.c
@@ -102,11 +102,13 @@ int i2400m_open(struct net_device *net_dev)
102 struct device *dev = i2400m_dev(i2400m); 102 struct device *dev = i2400m_dev(i2400m);
103 103
104 d_fnstart(3, dev, "(net_dev %p [i2400m %p])\n", net_dev, i2400m); 104 d_fnstart(3, dev, "(net_dev %p [i2400m %p])\n", net_dev, i2400m);
105 if (i2400m->ready == 0) { 105 /* Make sure we wait until init is complete... */
106 dev_err(dev, "Device is still initializing\n"); 106 mutex_lock(&i2400m->init_mutex);
107 result = -EBUSY; 107 if (i2400m->updown)
108 } else
109 result = 0; 108 result = 0;
109 else
110 result = -EBUSY;
111 mutex_unlock(&i2400m->init_mutex);
110 d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n", 112 d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n",
111 net_dev, i2400m, result); 113 net_dev, i2400m, result);
112 return result; 114 return result;