diff options
author | Bjørn Mork <bjorn@mork.no> | 2012-06-18 20:41:59 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-06-19 18:04:14 -0400 |
commit | 853c24f79dd6f4a3d6d7b52f235fe121aee08b45 (patch) | |
tree | 082552914cade08c19da13e6c83c317eebc51f5d /drivers/net/usb/qmi_wwan.c | |
parent | d1904fbd881e43cde2ec024117efaba83f8d9996 (diff) |
net: qmi_wwan: define a structure for driver specific state
usbnet allocates a fixed size array for minidriver specific
state. Naming the fields and taking advantage of type checking
is a bit more failsafe than casting array elements each time
they are referenced.
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb/qmi_wwan.c')
-rw-r--r-- | drivers/net/usb/qmi_wwan.c | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 3b206786b5e7..c7b9be81ad08 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -54,6 +54,13 @@ | |||
54 | * corresponding management interface | 54 | * corresponding management interface |
55 | */ | 55 | */ |
56 | 56 | ||
57 | /* driver specific data */ | ||
58 | struct qmi_wwan_state { | ||
59 | struct usb_driver *subdriver; | ||
60 | atomic_t pmcount; | ||
61 | unsigned long unused[3]; | ||
62 | }; | ||
63 | |||
57 | static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) | 64 | static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) |
58 | { | 65 | { |
59 | int status = -1; | 66 | int status = -1; |
@@ -65,9 +72,11 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) | |||
65 | struct usb_cdc_ether_desc *cdc_ether = NULL; | 72 | struct usb_cdc_ether_desc *cdc_ether = NULL; |
66 | u32 required = 1 << USB_CDC_HEADER_TYPE | 1 << USB_CDC_UNION_TYPE; | 73 | u32 required = 1 << USB_CDC_HEADER_TYPE | 1 << USB_CDC_UNION_TYPE; |
67 | u32 found = 0; | 74 | u32 found = 0; |
68 | atomic_t *pmcount = (void *)&dev->data[1]; | 75 | struct qmi_wwan_state *info = (void *)&dev->data; |
76 | |||
77 | BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct qmi_wwan_state))); | ||
69 | 78 | ||
70 | atomic_set(pmcount, 0); | 79 | atomic_set(&info->pmcount, 0); |
71 | 80 | ||
72 | /* | 81 | /* |
73 | * assume a data interface has no additional descriptors and | 82 | * assume a data interface has no additional descriptors and |
@@ -177,12 +186,12 @@ err: | |||
177 | /* using a counter to merge subdriver requests with our own into a combined state */ | 186 | /* using a counter to merge subdriver requests with our own into a combined state */ |
178 | static int qmi_wwan_manage_power(struct usbnet *dev, int on) | 187 | static int qmi_wwan_manage_power(struct usbnet *dev, int on) |
179 | { | 188 | { |
180 | atomic_t *pmcount = (void *)&dev->data[1]; | 189 | struct qmi_wwan_state *info = (void *)&dev->data; |
181 | int rv = 0; | 190 | int rv = 0; |
182 | 191 | ||
183 | dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, atomic_read(pmcount), on); | 192 | dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, atomic_read(&info->pmcount), on); |
184 | 193 | ||
185 | if ((on && atomic_add_return(1, pmcount) == 1) || (!on && atomic_dec_and_test(pmcount))) { | 194 | if ((on && atomic_add_return(1, &info->pmcount) == 1) || (!on && atomic_dec_and_test(&info->pmcount))) { |
186 | /* need autopm_get/put here to ensure the usbcore sees the new value */ | 195 | /* need autopm_get/put here to ensure the usbcore sees the new value */ |
187 | rv = usb_autopm_get_interface(dev->intf); | 196 | rv = usb_autopm_get_interface(dev->intf); |
188 | if (rv < 0) | 197 | if (rv < 0) |
@@ -212,7 +221,7 @@ static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) | |||
212 | { | 221 | { |
213 | int rv; | 222 | int rv; |
214 | struct usb_driver *subdriver = NULL; | 223 | struct usb_driver *subdriver = NULL; |
215 | atomic_t *pmcount = (void *)&dev->data[1]; | 224 | struct qmi_wwan_state *info = (void *)&dev->data; |
216 | 225 | ||
217 | /* ZTE makes devices where the interface descriptors and endpoint | 226 | /* ZTE makes devices where the interface descriptors and endpoint |
218 | * configurations of two or more interfaces are identical, even | 227 | * configurations of two or more interfaces are identical, even |
@@ -228,7 +237,7 @@ static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) | |||
228 | goto err; | 237 | goto err; |
229 | } | 238 | } |
230 | 239 | ||
231 | atomic_set(pmcount, 0); | 240 | atomic_set(&info->pmcount, 0); |
232 | 241 | ||
233 | /* collect all three endpoints */ | 242 | /* collect all three endpoints */ |
234 | rv = usbnet_get_endpoints(dev, intf); | 243 | rv = usbnet_get_endpoints(dev, intf); |
@@ -251,7 +260,7 @@ static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) | |||
251 | dev->status = NULL; | 260 | dev->status = NULL; |
252 | 261 | ||
253 | /* save subdriver struct for suspend/resume wrappers */ | 262 | /* save subdriver struct for suspend/resume wrappers */ |
254 | dev->data[0] = (unsigned long)subdriver; | 263 | info->subdriver = subdriver; |
255 | 264 | ||
256 | err: | 265 | err: |
257 | return rv; | 266 | return rv; |
@@ -282,12 +291,12 @@ err: | |||
282 | 291 | ||
283 | static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *intf) | 292 | static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *intf) |
284 | { | 293 | { |
285 | struct usb_driver *subdriver = (void *)dev->data[0]; | 294 | struct qmi_wwan_state *info = (void *)&dev->data; |
286 | 295 | ||
287 | if (subdriver && subdriver->disconnect) | 296 | if (info->subdriver && info->subdriver->disconnect) |
288 | subdriver->disconnect(intf); | 297 | info->subdriver->disconnect(intf); |
289 | 298 | ||
290 | dev->data[0] = (unsigned long)NULL; | 299 | info->subdriver = NULL; |
291 | } | 300 | } |
292 | 301 | ||
293 | /* suspend/resume wrappers calling both usbnet and the cdc-wdm | 302 | /* suspend/resume wrappers calling both usbnet and the cdc-wdm |
@@ -299,15 +308,15 @@ static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *int | |||
299 | static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message) | 308 | static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message) |
300 | { | 309 | { |
301 | struct usbnet *dev = usb_get_intfdata(intf); | 310 | struct usbnet *dev = usb_get_intfdata(intf); |
302 | struct usb_driver *subdriver = (void *)dev->data[0]; | 311 | struct qmi_wwan_state *info = (void *)&dev->data; |
303 | int ret; | 312 | int ret; |
304 | 313 | ||
305 | ret = usbnet_suspend(intf, message); | 314 | ret = usbnet_suspend(intf, message); |
306 | if (ret < 0) | 315 | if (ret < 0) |
307 | goto err; | 316 | goto err; |
308 | 317 | ||
309 | if (subdriver && subdriver->suspend) | 318 | if (info->subdriver && info->subdriver->suspend) |
310 | ret = subdriver->suspend(intf, message); | 319 | ret = info->subdriver->suspend(intf, message); |
311 | if (ret < 0) | 320 | if (ret < 0) |
312 | usbnet_resume(intf); | 321 | usbnet_resume(intf); |
313 | err: | 322 | err: |
@@ -317,16 +326,16 @@ err: | |||
317 | static int qmi_wwan_resume(struct usb_interface *intf) | 326 | static int qmi_wwan_resume(struct usb_interface *intf) |
318 | { | 327 | { |
319 | struct usbnet *dev = usb_get_intfdata(intf); | 328 | struct usbnet *dev = usb_get_intfdata(intf); |
320 | struct usb_driver *subdriver = (void *)dev->data[0]; | 329 | struct qmi_wwan_state *info = (void *)&dev->data; |
321 | int ret = 0; | 330 | int ret = 0; |
322 | 331 | ||
323 | if (subdriver && subdriver->resume) | 332 | if (info->subdriver && info->subdriver->resume) |
324 | ret = subdriver->resume(intf); | 333 | ret = info->subdriver->resume(intf); |
325 | if (ret < 0) | 334 | if (ret < 0) |
326 | goto err; | 335 | goto err; |
327 | ret = usbnet_resume(intf); | 336 | ret = usbnet_resume(intf); |
328 | if (ret < 0 && subdriver && subdriver->resume && subdriver->suspend) | 337 | if (ret < 0 && info->subdriver && info->subdriver->resume && info->subdriver->suspend) |
329 | subdriver->suspend(intf, PMSG_SUSPEND); | 338 | info->subdriver->suspend(intf, PMSG_SUSPEND); |
330 | err: | 339 | err: |
331 | return ret; | 340 | return ret; |
332 | } | 341 | } |