.. | .. |
---|
300 | 300 | write_unlock(&xen_9pfs_lock); |
---|
301 | 301 | |
---|
302 | 302 | for (i = 0; i < priv->num_rings; i++) { |
---|
| 303 | + struct xen_9pfs_dataring *ring = &priv->rings[i]; |
---|
| 304 | + |
---|
| 305 | + cancel_work_sync(&ring->work); |
---|
| 306 | + |
---|
303 | 307 | if (!priv->rings[i].intf) |
---|
304 | 308 | break; |
---|
305 | 309 | if (priv->rings[i].irq > 0) |
---|
.. | .. |
---|
393 | 397 | return ret; |
---|
394 | 398 | } |
---|
395 | 399 | |
---|
396 | | -static int xen_9pfs_front_probe(struct xenbus_device *dev, |
---|
397 | | - const struct xenbus_device_id *id) |
---|
| 400 | +static int xen_9pfs_front_init(struct xenbus_device *dev) |
---|
398 | 401 | { |
---|
399 | 402 | int ret, i; |
---|
400 | 403 | struct xenbus_transaction xbt; |
---|
401 | | - struct xen_9pfs_front_priv *priv = NULL; |
---|
402 | | - char *versions; |
---|
| 404 | + struct xen_9pfs_front_priv *priv = dev_get_drvdata(&dev->dev); |
---|
| 405 | + char *versions, *v; |
---|
403 | 406 | unsigned int max_rings, max_ring_order, len = 0; |
---|
404 | 407 | |
---|
405 | 408 | versions = xenbus_read(XBT_NIL, dev->otherend, "versions", &len); |
---|
406 | 409 | if (IS_ERR(versions)) |
---|
407 | 410 | return PTR_ERR(versions); |
---|
408 | | - if (strcmp(versions, "1")) { |
---|
| 411 | + for (v = versions; *v; v++) { |
---|
| 412 | + if (simple_strtoul(v, &v, 10) == 1) { |
---|
| 413 | + v = NULL; |
---|
| 414 | + break; |
---|
| 415 | + } |
---|
| 416 | + } |
---|
| 417 | + if (v) { |
---|
409 | 418 | kfree(versions); |
---|
410 | 419 | return -EINVAL; |
---|
411 | 420 | } |
---|
.. | .. |
---|
420 | 429 | if (p9_xen_trans.maxsize > XEN_FLEX_RING_SIZE(max_ring_order)) |
---|
421 | 430 | p9_xen_trans.maxsize = XEN_FLEX_RING_SIZE(max_ring_order) / 2; |
---|
422 | 431 | |
---|
423 | | - priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
---|
424 | | - if (!priv) |
---|
425 | | - return -ENOMEM; |
---|
426 | | - |
---|
427 | | - priv->dev = dev; |
---|
428 | 432 | priv->num_rings = XEN_9PFS_NUM_RINGS; |
---|
429 | 433 | priv->rings = kcalloc(priv->num_rings, sizeof(*priv->rings), |
---|
430 | 434 | GFP_KERNEL); |
---|
.. | .. |
---|
483 | 487 | goto error; |
---|
484 | 488 | } |
---|
485 | 489 | |
---|
486 | | - write_lock(&xen_9pfs_lock); |
---|
487 | | - list_add_tail(&priv->list, &xen_9pfs_devs); |
---|
488 | | - write_unlock(&xen_9pfs_lock); |
---|
489 | | - dev_set_drvdata(&dev->dev, priv); |
---|
490 | | - xenbus_switch_state(dev, XenbusStateInitialised); |
---|
491 | | - |
---|
492 | 490 | return 0; |
---|
493 | 491 | |
---|
494 | 492 | error_xenbus: |
---|
495 | 493 | xenbus_transaction_end(xbt, 1); |
---|
496 | 494 | xenbus_dev_fatal(dev, ret, "writing xenstore"); |
---|
497 | 495 | error: |
---|
498 | | - dev_set_drvdata(&dev->dev, NULL); |
---|
499 | 496 | xen_9pfs_front_free(priv); |
---|
500 | 497 | return ret; |
---|
| 498 | +} |
---|
| 499 | + |
---|
| 500 | +static int xen_9pfs_front_probe(struct xenbus_device *dev, |
---|
| 501 | + const struct xenbus_device_id *id) |
---|
| 502 | +{ |
---|
| 503 | + struct xen_9pfs_front_priv *priv = NULL; |
---|
| 504 | + |
---|
| 505 | + priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
---|
| 506 | + if (!priv) |
---|
| 507 | + return -ENOMEM; |
---|
| 508 | + |
---|
| 509 | + priv->dev = dev; |
---|
| 510 | + dev_set_drvdata(&dev->dev, priv); |
---|
| 511 | + |
---|
| 512 | + write_lock(&xen_9pfs_lock); |
---|
| 513 | + list_add_tail(&priv->list, &xen_9pfs_devs); |
---|
| 514 | + write_unlock(&xen_9pfs_lock); |
---|
| 515 | + |
---|
| 516 | + return 0; |
---|
501 | 517 | } |
---|
502 | 518 | |
---|
503 | 519 | static int xen_9pfs_front_resume(struct xenbus_device *dev) |
---|
.. | .. |
---|
518 | 534 | break; |
---|
519 | 535 | |
---|
520 | 536 | case XenbusStateInitWait: |
---|
| 537 | + if (!xen_9pfs_front_init(dev)) |
---|
| 538 | + xenbus_switch_state(dev, XenbusStateInitialised); |
---|
521 | 539 | break; |
---|
522 | 540 | |
---|
523 | 541 | case XenbusStateConnected: |
---|