diff options
Diffstat (limited to 'drivers/block/aoe/aoechr.c')
-rw-r--r-- | drivers/block/aoe/aoechr.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index d5480e34cb22..03c7f4ab5624 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c | |||
@@ -6,6 +6,7 @@ | |||
6 | 6 | ||
7 | #include <linux/hdreg.h> | 7 | #include <linux/hdreg.h> |
8 | #include <linux/blkdev.h> | 8 | #include <linux/blkdev.h> |
9 | #include <linux/delay.h> | ||
9 | #include "aoe.h" | 10 | #include "aoe.h" |
10 | 11 | ||
11 | enum { | 12 | enum { |
@@ -68,6 +69,7 @@ revalidate(const char __user *str, size_t size) | |||
68 | int major, minor, n; | 69 | int major, minor, n; |
69 | ulong flags; | 70 | ulong flags; |
70 | struct aoedev *d; | 71 | struct aoedev *d; |
72 | struct sk_buff *skb; | ||
71 | char buf[16]; | 73 | char buf[16]; |
72 | 74 | ||
73 | if (size >= sizeof buf) | 75 | if (size >= sizeof buf) |
@@ -85,13 +87,20 @@ revalidate(const char __user *str, size_t size) | |||
85 | d = aoedev_by_aoeaddr(major, minor); | 87 | d = aoedev_by_aoeaddr(major, minor); |
86 | if (!d) | 88 | if (!d) |
87 | return -EINVAL; | 89 | return -EINVAL; |
88 | |||
89 | spin_lock_irqsave(&d->lock, flags); | 90 | spin_lock_irqsave(&d->lock, flags); |
90 | d->flags &= ~DEVFL_MAXBCNT; | 91 | aoecmd_cleanslate(d); |
91 | d->flags |= DEVFL_PAUSE; | 92 | loop: |
93 | skb = aoecmd_ata_id(d); | ||
92 | spin_unlock_irqrestore(&d->lock, flags); | 94 | spin_unlock_irqrestore(&d->lock, flags); |
95 | /* try again if we are able to sleep a bit, | ||
96 | * otherwise give up this revalidation | ||
97 | */ | ||
98 | if (!skb && !msleep_interruptible(200)) { | ||
99 | spin_lock_irqsave(&d->lock, flags); | ||
100 | goto loop; | ||
101 | } | ||
102 | aoenet_xmit(skb); | ||
93 | aoecmd_cfg(major, minor); | 103 | aoecmd_cfg(major, minor); |
94 | |||
95 | return 0; | 104 | return 0; |
96 | } | 105 | } |
97 | 106 | ||