linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / block / aoe / aoedev.c
index ed4258a..ded33ba 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)
 {
@@ -46,18 +28,6 @@ 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)
@@ -74,8 +44,6 @@ aoedev_newdev(ulong nframes)
                return NULL;
        }
 
-       INIT_WORK(&d->work, aoecmd_sleepwork, d);
-
        d->nframes = nframes;
        d->frames = f;
        e = f + nframes;
@@ -84,10 +52,6 @@ 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;
@@ -103,6 +67,9 @@ 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++) {
@@ -125,15 +92,16 @@ 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 | DEVFL_PAUSE);
+       d->flags &= ~DEVFL_UP;
 }
 
-/* find it or malloc it */
 struct aoedev *
-aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt)
+aoedev_set(ulong sysminor, unsigned char *addr, struct net_device *ifp, ulong bufcnt)
 {
        struct aoedev *d;
        ulong flags;
@@ -144,19 +112,25 @@ aoedev_by_sysminor_m(ulong sysminor, ulong bufcnt)
                if (d->sysminor == sysminor)
                        break;
 
-       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;
-               }
+       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 */
                d->sysminor = sysminor;
                d->aoemajor = AOEMAJOR(sysminor);
                d->aoeminor = AOEMINOR(sysminor);
        }
 
-       spin_unlock_irqrestore(&devlist_lock, flags);
+       spin_unlock_irqrestore(&d->lock, flags);
        return d;
 }
 
@@ -187,7 +161,6 @@ 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);