Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / block / aoe / aoedev.c
index 6e231c5..ed4258a 100644 (file)
 static struct aoedev *devlist;
 static spinlock_t devlist_lock;
 
+int
+aoedev_isbusy(struct aoedev *d)
+{
+       struct frame *f, *e;
+
+       f = d->frames;
+       e = f + d->nframes;
+       do {
+               if (f->tag != FREETAG) {
+                       printk(KERN_DEBUG "aoe: %ld.%ld isbusy\n",
+                               d->aoemajor, d->aoeminor);
+                       return 1;
+               }
+       } while (++f < e);
+
+       return 0;
+}
+
 struct aoedev *
 aoedev_by_aoeaddr(int maj, int min)
 {
@@ -28,6 +46,18 @@ aoedev_by_aoeaddr(int maj, int min)
        return d;
 }
 
+static void
+dummy_timer(ulong vp)
+{
+       struct aoedev *d;
+
+       d = (struct aoedev *)vp;
+       if (d->flags & DEVFL_TKILL)
+               return;
+       d->timer.expires = jiffies + HZ;
+       add_timer(&d->timer);
+}
+
 /* called with devlist lock held */
 static struct aoedev *
 aoedev_newdev(ulong nframes)
@@ -35,7 +65,7 @@ aoedev_newdev(ulong nframes)
        struct aoedev *d;
        struct frame *f, *e;
 
-       d = kcalloc(1, sizeof *d, GFP_ATOMIC);
+       d = kzalloc(sizeof *d, GFP_ATOMIC);
        if (d == NULL)
                return NULL;
        f = kcalloc(nframes, sizeof *f, GFP_ATOMIC);
@@ -44,6 +74,8 @@ aoedev_newdev(ulong nframes)
                return NULL;
        }
 
+       INIT_WORK(&d->work, aoecmd_sleepwork, d);
+
        d->nframes = nframes;
        d->frames = f;
        e = f + nframes;
@@ -52,6 +84,10 @@ aoedev_newdev(ulong nframes)
 
        spin_lock_init(&d->lock);
        init_timer(&d->timer);
+       d->timer.data = (ulong) d;
+       d->timer.function = dummy_timer;
+       d->timer.expires = jiffies + HZ;
+       add_timer(&d->timer);
        d->bufpool = NULL;      /* defer to aoeblk_gdalloc */
        INIT_LIST_HEAD(&d->bufq);
        d->next = devlist;
@@ -67,9 +103,6 @@ aoedev_downdev(struct aoedev *d)
        struct buf *buf;
        struct bio *bio;
 
-       d->flags |= DEVFL_TKILL;
-       del_timer(&d->timer);
-
        f = d->frames;
        e = f + d->nframes;
        for (; f<e; f->tag = FREETAG, f->buf = NULL, f++) {
@@ -92,16 +125,15 @@ aoedev_downdev(struct aoedev *d)
                bio_endio(bio, bio->bi_size, -EIO);
        }
 
-       if (d->nopen)
-               d->flags |= DEVFL_CLOSEWAIT;
        if (d->gd)
                d->gd->capacity = 0;
 
-       d->flags &= ~DEVFL_UP;
+       d->flags &= ~(DEVFL_UP | DEVFL_PAUSE);
 }
 
+/* find it or malloc it */
 struct aoedev *
-aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bufcnt)
+aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt)
 {
        struct aoedev *d;
        ulong flags;
@@ -112,25 +144,19 @@ aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bu
                if (d->sysminor == sysminor)
                        break;
 
-       if (d == NULL && (d = aoedev_newdev(bufcnt)) == NULL) {
-               spin_unlock_irqrestore(&devlist_lock, flags);
-               printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n");
-               return NULL;
-       } /* if newdev, (d->flags & DEVFL_UP) == 0 for below */
-
-       spin_unlock_irqrestore(&devlist_lock, flags);
-       spin_lock_irqsave(&d->lock, flags);
-
-       d->ifp = ifp;
-       memcpy(d->addr, addr, sizeof d->addr);
-       if ((d->flags & DEVFL_UP) == 0) {
-               aoedev_downdev(d); /* flushes outstanding frames */
+       if (d == NULL) {
+               d = aoedev_newdev(bufcnt);
+               if (d == NULL) {
+                       spin_unlock_irqrestore(&devlist_lock, flags);
+                       printk(KERN_INFO "aoe: aoedev_set: aoedev_newdev failure.\n");
+                       return NULL;
+               }
                d->sysminor = sysminor;
                d->aoemajor = AOEMAJOR(sysminor);
                d->aoeminor = AOEMINOR(sysminor);
        }
 
-       spin_unlock_irqrestore(&d->lock, flags);
+       spin_unlock_irqrestore(&devlist_lock, flags);
        return d;
 }
 
@@ -161,6 +187,7 @@ aoedev_exit(void)
 
                spin_lock_irqsave(&d->lock, flags);
                aoedev_downdev(d);
+               d->flags |= DEVFL_TKILL;
                spin_unlock_irqrestore(&d->lock, flags);
 
                del_timer_sync(&d->timer);