aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/aoe/aoedev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/aoe/aoedev.c')
-rw-r--r--drivers/block/aoe/aoedev.c69
1 files changed, 48 insertions, 21 deletions
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index ded33ba31acc..ed4258a62df5 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -12,6 +12,24 @@
12static struct aoedev *devlist; 12static struct aoedev *devlist;
13static spinlock_t devlist_lock; 13static spinlock_t devlist_lock;
14 14
15int
16aoedev_isbusy(struct aoedev *d)
17{
18 struct frame *f, *e;
19
20 f = d->frames;
21 e = f + d->nframes;
22 do {
23 if (f->tag != FREETAG) {
24 printk(KERN_DEBUG "aoe: %ld.%ld isbusy\n",
25 d->aoemajor, d->aoeminor);
26 return 1;
27 }
28 } while (++f < e);
29
30 return 0;
31}
32
15struct aoedev * 33struct aoedev *
16aoedev_by_aoeaddr(int maj, int min) 34aoedev_by_aoeaddr(int maj, int min)
17{ 35{
@@ -28,6 +46,18 @@ aoedev_by_aoeaddr(int maj, int min)
28 return d; 46 return d;
29} 47}
30 48
49static void
50dummy_timer(ulong vp)
51{
52 struct aoedev *d;
53
54 d = (struct aoedev *)vp;
55 if (d->flags & DEVFL_TKILL)
56 return;
57 d->timer.expires = jiffies + HZ;
58 add_timer(&d->timer);
59}
60
31/* called with devlist lock held */ 61/* called with devlist lock held */
32static struct aoedev * 62static struct aoedev *
33aoedev_newdev(ulong nframes) 63aoedev_newdev(ulong nframes)
@@ -44,6 +74,8 @@ aoedev_newdev(ulong nframes)
44 return NULL; 74 return NULL;
45 } 75 }
46 76
77 INIT_WORK(&d->work, aoecmd_sleepwork, d);
78
47 d->nframes = nframes; 79 d->nframes = nframes;
48 d->frames = f; 80 d->frames = f;
49 e = f + nframes; 81 e = f + nframes;
@@ -52,6 +84,10 @@ aoedev_newdev(ulong nframes)
52 84
53 spin_lock_init(&d->lock); 85 spin_lock_init(&d->lock);
54 init_timer(&d->timer); 86 init_timer(&d->timer);
87 d->timer.data = (ulong) d;
88 d->timer.function = dummy_timer;
89 d->timer.expires = jiffies + HZ;
90 add_timer(&d->timer);
55 d->bufpool = NULL; /* defer to aoeblk_gdalloc */ 91 d->bufpool = NULL; /* defer to aoeblk_gdalloc */
56 INIT_LIST_HEAD(&d->bufq); 92 INIT_LIST_HEAD(&d->bufq);
57 d->next = devlist; 93 d->next = devlist;
@@ -67,9 +103,6 @@ aoedev_downdev(struct aoedev *d)
67 struct buf *buf; 103 struct buf *buf;
68 struct bio *bio; 104 struct bio *bio;
69 105
70 d->flags |= DEVFL_TKILL;
71 del_timer(&d->timer);
72
73 f = d->frames; 106 f = d->frames;
74 e = f + d->nframes; 107 e = f + d->nframes;
75 for (; f<e; f->tag = FREETAG, f->buf = NULL, f++) { 108 for (; f<e; f->tag = FREETAG, f->buf = NULL, f++) {
@@ -92,16 +125,15 @@ aoedev_downdev(struct aoedev *d)
92 bio_endio(bio, bio->bi_size, -EIO); 125 bio_endio(bio, bio->bi_size, -EIO);
93 } 126 }
94 127
95 if (d->nopen)
96 d->flags |= DEVFL_CLOSEWAIT;
97 if (d->gd) 128 if (d->gd)
98 d->gd->capacity = 0; 129 d->gd->capacity = 0;
99 130
100 d->flags &= ~DEVFL_UP; 131 d->flags &= ~(DEVFL_UP | DEVFL_PAUSE);
101} 132}
102 133
134/* find it or malloc it */
103struct aoedev * 135struct aoedev *
104aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bufcnt) 136aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt)
105{ 137{
106 struct aoedev *d; 138 struct aoedev *d;
107 ulong flags; 139 ulong flags;
@@ -112,25 +144,19 @@ aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bu
112 if (d->sysminor == sysminor) 144 if (d->sysminor == sysminor)
113 break; 145 break;
114 146
115 if (d == NULL && (d = aoedev_newdev(bufcnt)) == NULL) { 147 if (d == NULL) {
116 spin_unlock_irqrestore(&devlist_lock, flags); 148 d = aoedev_newdev(bufcnt);
117 printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n"); 149 if (d == NULL) {
118 return NULL; 150 spin_unlock_irqrestore(&devlist_lock, flags);
119 } /* if newdev, (d->flags & DEVFL_UP) == 0 for below */ 151 printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n");
120 152 return NULL;
121 spin_unlock_irqrestore(&devlist_lock, flags); 153 }
122 spin_lock_irqsave(&d->lock, flags);
123
124 d->ifp = ifp;
125 memcpy(d->addr, addr, sizeof d->addr);
126 if ((d->flags & DEVFL_UP) == 0) {
127 aoedev_downdev(d); /* flushes outstanding frames */
128 d->sysminor = sysminor; 154 d->sysminor = sysminor;
129 d->aoemajor = AOEMAJOR(sysminor); 155 d->aoemajor = AOEMAJOR(sysminor);
130 d->aoeminor = AOEMINOR(sysminor); 156 d->aoeminor = AOEMINOR(sysminor);
131 } 157 }
132 158
133 spin_unlock_irqrestore(&d->lock, flags); 159 spin_unlock_irqrestore(&devlist_lock, flags);
134 return d; 160 return d;
135} 161}
136 162
@@ -161,6 +187,7 @@ aoedev_exit(void)
161 187
162 spin_lock_irqsave(&d->lock, flags); 188 spin_lock_irqsave(&d->lock, flags);
163 aoedev_downdev(d); 189 aoedev_downdev(d);
190 d->flags |= DEVFL_TKILL;
164 spin_unlock_irqrestore(&d->lock, flags); 191 spin_unlock_irqrestore(&d->lock, flags);
165 192
166 del_timer_sync(&d->timer); 193 del_timer_sync(&d->timer);