1 /* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */
4 * AoE device utility functions; maintains device list.
7 #include <linux/hdreg.h>
8 #include <linux/blkdev.h>
9 #include <linux/netdevice.h>
12 static struct aoedev *devlist;
13 static spinlock_t devlist_lock;
16 aoedev_isbusy(struct aoedev *d)
18 struct aoetgt **t, **te;
23 for (; t < te && *t; t++) {
25 e = f + (*t)->nframes;
27 if (f->tag != FREETAG)
34 aoedev_by_aoeaddr(int maj, int min)
39 spin_lock_irqsave(&devlist_lock, flags);
41 for (d=devlist; d; d=d->next)
42 if (d->aoemajor == maj && d->aoeminor == min)
45 spin_unlock_irqrestore(&devlist_lock, flags);
54 d = (struct aoedev *)vp;
55 if (d->flags & DEVFL_TKILL)
57 d->timer.expires = jiffies + HZ;
62 aoedev_downdev(struct aoedev *d)
64 struct aoetgt **t, **te;
71 for (; t < te && *t; t++) {
73 e = f + (*t)->nframes;
74 for (; f < e; f->tag = FREETAG, f->buf = NULL, f++) {
75 if (f->tag == FREETAG || f->buf == NULL)
79 if (--buf->nframesout == 0
80 && buf != d->inprocess) {
81 mempool_free(buf, d->bufpool);
85 (*t)->maxout = (*t)->nframes;
91 mempool_free(buf, d->bufpool);
97 while (!list_empty(&d->bufq)) {
98 buf = container_of(d->bufq.next, struct buf, bufs);
99 list_del(d->bufq.next);
101 mempool_free(buf, d->bufpool);
102 bio_endio(bio, -EIO);
108 d->flags &= ~DEVFL_UP;
111 /* find it or malloc it */
113 aoedev_by_sysminor_m(ulong sysminor)
118 spin_lock_irqsave(&devlist_lock, flags);
120 for (d=devlist; d; d=d->next)
121 if (d->sysminor == sysminor)
125 d = kcalloc(1, sizeof *d, GFP_ATOMIC);
128 INIT_WORK(&d->work, aoecmd_sleepwork);
129 spin_lock_init(&d->lock);
130 init_timer(&d->timer);
131 d->timer.data = (ulong) d;
132 d->timer.function = dummy_timer;
133 d->timer.expires = jiffies + HZ;
134 add_timer(&d->timer);
135 d->bufpool = NULL; /* defer to aoeblk_gdalloc */
137 INIT_LIST_HEAD(&d->bufq);
138 d->sysminor = sysminor;
139 d->aoemajor = AOEMAJOR(sysminor);
140 d->aoeminor = AOEMINOR(sysminor);
141 d->mintimer = MINTIMER;
145 spin_unlock_irqrestore(&devlist_lock, flags);
150 freetgt(struct aoetgt *t)
157 skb_shinfo(f->skb)->nr_frags = 0;
158 dev_kfree_skb(f->skb);
165 aoedev_freedev(struct aoedev *d)
167 struct aoetgt **t, **e;
176 for (; t < e && *t; t++)
179 mempool_destroy(d->bufpool);
189 flush_scheduled_work();
191 while ((d = devlist)) {
194 spin_lock_irqsave(&d->lock, flags);
196 d->flags |= DEVFL_TKILL;
197 spin_unlock_irqrestore(&d->lock, flags);
199 del_timer_sync(&d->timer);
207 spin_lock_init(&devlist_lock);