linux/drivers/block/aoe/aoecmd.c
<<
>>
Prefs
   1/* Copyright (c) 2007 Coraid, Inc.  See COPYING for GPL terms. */
   2/*
   3 * aoecmd.c
   4 * Filesystem request handling methods
   5 */
   6
   7#include <linux/hdreg.h>
   8#include <linux/blkdev.h>
   9#include <linux/skbuff.h>
  10#include <linux/netdevice.h>
  11#include <linux/genhd.h>
  12#include <linux/moduleparam.h>
  13#include <net/net_namespace.h>
  14#include <asm/unaligned.h>
  15#include "aoe.h"
  16
  17static int aoe_deadsecs = 60 * 3;
  18module_param(aoe_deadsecs, int, 0644);
  19MODULE_PARM_DESC(aoe_deadsecs, "After aoe_deadsecs seconds, give up and fail dev.");
  20
  21static int aoe_maxout = 16;
  22module_param(aoe_maxout, int, 0644);
  23MODULE_PARM_DESC(aoe_maxout,
  24        "Only aoe_maxout outstanding packets for every MAC on eX.Y.");
  25
  26static struct sk_buff *
  27new_skb(ulong len)
  28{
  29        struct sk_buff *skb;
  30
  31        skb = alloc_skb(len, GFP_ATOMIC);
  32        if (skb) {
  33                skb_reset_mac_header(skb);
  34                skb_reset_network_header(skb);
  35                skb->protocol = __constant_htons(ETH_P_AOE);
  36                skb->priority = 0;
  37                skb->next = skb->prev = NULL;
  38
  39                /* tell the network layer not to perform IP checksums
  40                 * or to get the NIC to do it
  41                 */
  42                skb->ip_summed = CHECKSUM_NONE;
  43        }
  44        return skb;
  45}
  46
  47static struct frame *
  48getframe(struct aoetgt *t, int tag)
  49{
  50        struct frame *f, *e;
  51
  52        f = t->frames;
  53        e = f + t->nframes;
  54        for (; f<e; f++)
  55                if (f->tag == tag)
  56                        return f;
  57        return NULL;
  58}
  59
  60/*
  61 * Leave the top bit clear so we have tagspace for userland.
  62 * The bottom 16 bits are the xmit tick for rexmit/rttavg processing.
  63 * This driver reserves tag -1 to mean "unused frame."
  64 */
  65static int
  66newtag(struct aoetgt *t)
  67{
  68        register ulong n;
  69
  70        n = jiffies & 0xffff;
  71        return n |= (++t->lasttag & 0x7fff) << 16;
  72}
  73
  74static int
  75aoehdr_atainit(struct aoedev *d, struct aoetgt *t, struct aoe_hdr *h)
  76{
  77        u32 host_tag = newtag(t);
  78
  79        memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
  80        memcpy(h->dst, t->addr, sizeof h->dst);
  81        h->type = __constant_cpu_to_be16(ETH_P_AOE);
  82        h->verfl = AOE_HVER;
  83        h->major = cpu_to_be16(d->aoemajor);
  84        h->minor = d->aoeminor;
  85        h->cmd = AOECMD_ATA;
  86        h->tag = cpu_to_be32(host_tag);
  87
  88        return host_tag;
  89}
  90
  91static inline void
  92put_lba(struct aoe_atahdr *ah, sector_t lba)
  93{
  94        ah->lba0 = lba;
  95        ah->lba1 = lba >>= 8;
  96        ah->lba2 = lba >>= 8;
  97        ah->lba3 = lba >>= 8;
  98        ah->lba4 = lba >>= 8;
  99        ah->lba5 = lba >>= 8;
 100}
 101
 102static void
 103ifrotate(struct aoetgt *t)
 104{
 105        t->ifp++;
 106        if (t->ifp >= &t->ifs[NAOEIFS] || t->ifp->nd == NULL)
 107                t->ifp = t->ifs;
 108        if (t->ifp->nd == NULL) {
 109                printk(KERN_INFO "aoe: no interface to rotate to\n");
 110                BUG();
 111        }
 112}
 113
 114static void
 115skb_pool_put(struct aoedev *d, struct sk_buff *skb)
 116{
 117        if (!d->skbpool_hd)
 118                d->skbpool_hd = skb;
 119        else
 120                d->skbpool_tl->next = skb;
 121        d->skbpool_tl = skb;
 122}
 123
 124static struct sk_buff *
 125skb_pool_get(struct aoedev *d)
 126{
 127        struct sk_buff *skb;
 128
 129        skb = d->skbpool_hd;
 130        if (skb && atomic_read(&skb_shinfo(skb)->dataref) == 1) {
 131                d->skbpool_hd = skb->next;
 132                skb->next = NULL;
 133                return skb;
 134        }
 135        if (d->nskbpool < NSKBPOOLMAX
 136        && (skb = new_skb(ETH_ZLEN))) {
 137                d->nskbpool++;
 138                return skb;
 139        }
 140        return NULL;
 141}
 142
 143/* freeframe is where we do our load balancing so it's a little hairy. */
 144static struct frame *
 145freeframe(struct aoedev *d)
 146{
 147        struct frame *f, *e, *rf;
 148        struct aoetgt **t;
 149        struct sk_buff *skb;
 150
 151        if (d->targets[0] == NULL) {    /* shouldn't happen, but I'm paranoid */
 152                printk(KERN_ERR "aoe: NULL TARGETS!\n");
 153                return NULL;
 154        }
 155        t = d->tgt;
 156        t++;
 157        if (t >= &d->targets[NTARGETS] || !*t)
 158                t = d->targets;
 159        for (;;) {
 160                if ((*t)->nout < (*t)->maxout
 161                && t != d->htgt
 162                && (*t)->ifp->nd) {
 163                        rf = NULL;
 164                        f = (*t)->frames;
 165                        e = f + (*t)->nframes;
 166                        for (; f < e; f++) {
 167                                if (f->tag != FREETAG)
 168                                        continue;
 169                                skb = f->skb;
 170                                if (!skb
 171                                && !(f->skb = skb = new_skb(ETH_ZLEN)))
 172                                        continue;
 173                                if (atomic_read(&skb_shinfo(skb)->dataref)
 174                                        != 1) {
 175                                        if (!rf)
 176                                                rf = f;
 177                                        continue;
 178                                }
 179gotone:                         skb_shinfo(skb)->nr_frags = skb->data_len = 0;
 180                                skb_trim(skb, 0);
 181                                d->tgt = t;
 182                                ifrotate(*t);
 183                                return f;
 184                        }
 185                        /* Work can be done, but the network layer is
 186                           holding our precious packets.  Try to grab
 187                           one from the pool. */
 188                        f = rf;
 189                        if (f == NULL) {        /* more paranoia */
 190                                printk(KERN_ERR
 191                                        "aoe: freeframe: %s.\n",
 192                                        "unexpected null rf");
 193                                d->flags |= DEVFL_KICKME;
 194                                return NULL;
 195                        }
 196                        skb = skb_pool_get(d);
 197                        if (skb) {
 198                                skb_pool_put(d, f->skb);
 199                                f->skb = skb;
 200                                goto gotone;
 201                        }
 202                        (*t)->dataref++;
 203                        if ((*t)->nout == 0)
 204                                d->flags |= DEVFL_KICKME;
 205                }
 206                if (t == d->tgt)        /* we've looped and found nada */
 207                        break;
 208                t++;
 209                if (t >= &d->targets[NTARGETS] || !*t)
 210                        t = d->targets;
 211        }
 212        return NULL;
 213}
 214
 215static int
 216aoecmd_ata_rw(struct aoedev *d)
 217{
 218        struct frame *f;
 219        struct aoe_hdr *h;
 220        struct aoe_atahdr *ah;
 221        struct buf *buf;
 222        struct bio_vec *bv;
 223        struct aoetgt *t;
 224        struct sk_buff *skb;
 225        ulong bcnt;
 226        char writebit, extbit;
 227
 228        writebit = 0x10;
 229        extbit = 0x4;
 230
 231        f = freeframe(d);
 232        if (f == NULL)
 233                return 0;
 234        t = *d->tgt;
 235        buf = d->inprocess;
 236        bv = buf->bv;
 237        bcnt = t->ifp->maxbcnt;
 238        if (bcnt == 0)
 239                bcnt = DEFAULTBCNT;
 240        if (bcnt > buf->bv_resid)
 241                bcnt = buf->bv_resid;
 242        /* initialize the headers & frame */
 243        skb = f->skb;
 244        h = (struct aoe_hdr *) skb_mac_header(skb);
 245        ah = (struct aoe_atahdr *) (h+1);
 246        skb_put(skb, sizeof *h + sizeof *ah);
 247        memset(h, 0, skb->len);
 248        f->tag = aoehdr_atainit(d, t, h);
 249        t->nout++;
 250        f->waited = 0;
 251        f->buf = buf;
 252        f->bufaddr = page_address(bv->bv_page) + buf->bv_off;
 253        f->bcnt = bcnt;
 254        f->lba = buf->sector;
 255
 256        /* set up ata header */
 257        ah->scnt = bcnt >> 9;
 258        put_lba(ah, buf->sector);
 259        if (d->flags & DEVFL_EXT) {
 260                ah->aflags |= AOEAFL_EXT;
 261        } else {
 262                extbit = 0;
 263                ah->lba3 &= 0x0f;
 264                ah->lba3 |= 0xe0;       /* LBA bit + obsolete 0xa0 */
 265        }
 266        if (bio_data_dir(buf->bio) == WRITE) {
 267                skb_fill_page_desc(skb, 0, bv->bv_page, buf->bv_off, bcnt);
 268                ah->aflags |= AOEAFL_WRITE;
 269                skb->len += bcnt;
 270                skb->data_len = bcnt;
 271                t->wpkts++;
 272        } else {
 273                t->rpkts++;
 274                writebit = 0;
 275        }
 276
 277        ah->cmdstat = WIN_READ | writebit | extbit;
 278
 279        /* mark all tracking fields and load out */
 280        buf->nframesout += 1;
 281        buf->bv_off += bcnt;
 282        buf->bv_resid -= bcnt;
 283        buf->resid -= bcnt;
 284        buf->sector += bcnt >> 9;
 285        if (buf->resid == 0) {
 286                d->inprocess = NULL;
 287        } else if (buf->bv_resid == 0) {
 288                buf->bv = ++bv;
 289                buf->bv_resid = bv->bv_len;
 290                WARN_ON(buf->bv_resid == 0);
 291                buf->bv_off = bv->bv_offset;
 292        }
 293
 294        skb->dev = t->ifp->nd;
 295        skb = skb_clone(skb, GFP_ATOMIC);
 296        if (skb) {
 297                if (d->sendq_hd)
 298                        d->sendq_tl->next = skb;
 299                else
 300                        d->sendq_hd = skb;
 301                d->sendq_tl = skb;
 302        }
 303        return 1;
 304}
 305
 306/* some callers cannot sleep, and they can call this function,
 307 * transmitting the packets later, when interrupts are on
 308 */
 309static struct sk_buff *
 310aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
 311{
 312        struct aoe_hdr *h;
 313        struct aoe_cfghdr *ch;
 314        struct sk_buff *skb, *sl, *sl_tail;
 315        struct net_device *ifp;
 316
 317        sl = sl_tail = NULL;
 318
 319        read_lock(&dev_base_lock);
 320        for_each_netdev(&init_net, ifp) {
 321                dev_hold(ifp);
 322                if (!is_aoe_netif(ifp))
 323                        goto cont;
 324
 325                skb = new_skb(sizeof *h + sizeof *ch);
 326                if (skb == NULL) {
 327                        printk(KERN_INFO "aoe: skb alloc failure\n");
 328                        goto cont;
 329                }
 330                skb_put(skb, sizeof *h + sizeof *ch);
 331                skb->dev = ifp;
 332                if (sl_tail == NULL)
 333                        sl_tail = skb;
 334                h = (struct aoe_hdr *) skb_mac_header(skb);
 335                memset(h, 0, sizeof *h + sizeof *ch);
 336
 337                memset(h->dst, 0xff, sizeof h->dst);
 338                memcpy(h->src, ifp->dev_addr, sizeof h->src);
 339                h->type = __constant_cpu_to_be16(ETH_P_AOE);
 340                h->verfl = AOE_HVER;
 341                h->major = cpu_to_be16(aoemajor);
 342                h->minor = aoeminor;
 343                h->cmd = AOECMD_CFG;
 344
 345                skb->next = sl;
 346                sl = skb;
 347cont:
 348                dev_put(ifp);
 349        }
 350        read_unlock(&dev_base_lock);
 351
 352        if (tail != NULL)
 353                *tail = sl_tail;
 354        return sl;
 355}
 356
 357static void
 358resend(struct aoedev *d, struct aoetgt *t, struct frame *f)
 359{
 360        struct sk_buff *skb;
 361        struct aoe_hdr *h;
 362        struct aoe_atahdr *ah;
 363        char buf[128];
 364        u32 n;
 365
 366        ifrotate(t);
 367        n = newtag(t);
 368        skb = f->skb;
 369        h = (struct aoe_hdr *) skb_mac_header(skb);
 370        ah = (struct aoe_atahdr *) (h+1);
 371
 372        snprintf(buf, sizeof buf,
 373                "%15s e%ld.%d oldtag=%08x@%08lx newtag=%08x "
 374                "s=%012llx d=%012llx nout=%d\n",
 375                "retransmit", d->aoemajor, d->aoeminor, f->tag, jiffies, n,
 376                mac_addr(h->src),
 377                mac_addr(h->dst), t->nout);
 378        aoechr_error(buf);
 379
 380        f->tag = n;
 381        h->tag = cpu_to_be32(n);
 382        memcpy(h->dst, t->addr, sizeof h->dst);
 383        memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
 384
 385        switch (ah->cmdstat) {
 386        default:
 387                break;
 388        case WIN_READ:
 389        case WIN_READ_EXT:
 390        case WIN_WRITE:
 391        case WIN_WRITE_EXT:
 392                put_lba(ah, f->lba);
 393
 394                n = f->bcnt;
 395                if (n > DEFAULTBCNT)
 396                        n = DEFAULTBCNT;
 397                ah->scnt = n >> 9;
 398                if (ah->aflags & AOEAFL_WRITE) {
 399                        skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr),
 400                                offset_in_page(f->bufaddr), n);
 401                        skb->len = sizeof *h + sizeof *ah + n;
 402                        skb->data_len = n;
 403                }
 404        }
 405        skb->dev = t->ifp->nd;
 406        skb = skb_clone(skb, GFP_ATOMIC);
 407        if (skb == NULL)
 408                return;
 409        if (d->sendq_hd)
 410                d->sendq_tl->next = skb;
 411        else
 412                d->sendq_hd = skb;
 413        d->sendq_tl = skb;
 414}
 415
 416static int
 417tsince(int tag)
 418{
 419        int n;
 420
 421        n = jiffies & 0xffff;
 422        n -= tag & 0xffff;
 423        if (n < 0)
 424                n += 1<<16;
 425        return n;
 426}
 427
 428static struct aoeif *
 429getif(struct aoetgt *t, struct net_device *nd)
 430{
 431        struct aoeif *p, *e;
 432
 433        p = t->ifs;
 434        e = p + NAOEIFS;
 435        for (; p < e; p++)
 436                if (p->nd == nd)
 437                        return p;
 438        return NULL;
 439}
 440
 441static struct aoeif *
 442addif(struct aoetgt *t, struct net_device *nd)
 443{
 444        struct aoeif *p;
 445
 446        p = getif(t, NULL);
 447        if (!p)
 448                return NULL;
 449        p->nd = nd;
 450        p->maxbcnt = DEFAULTBCNT;
 451        p->lost = 0;
 452        p->lostjumbo = 0;
 453        return p;
 454}
 455
 456static void
 457ejectif(struct aoetgt *t, struct aoeif *ifp)
 458{
 459        struct aoeif *e;
 460        ulong n;
 461
 462        e = t->ifs + NAOEIFS - 1;
 463        n = (e - ifp) * sizeof *ifp;
 464        memmove(ifp, ifp+1, n);
 465        e->nd = NULL;
 466}
 467
 468static int
 469sthtith(struct aoedev *d)
 470{
 471        struct frame *f, *e, *nf;
 472        struct sk_buff *skb;
 473        struct aoetgt *ht = *d->htgt;
 474
 475        f = ht->frames;
 476        e = f + ht->nframes;
 477        for (; f < e; f++) {
 478                if (f->tag == FREETAG)
 479                        continue;
 480                nf = freeframe(d);
 481                if (!nf)
 482                        return 0;
 483                skb = nf->skb;
 484                *nf = *f;
 485                f->skb = skb;
 486                f->tag = FREETAG;
 487                nf->waited = 0;
 488                ht->nout--;
 489                (*d->tgt)->nout++;
 490                resend(d, *d->tgt, nf);
 491        }
 492        /* he's clean, he's useless.  take away his interfaces */
 493        memset(ht->ifs, 0, sizeof ht->ifs);
 494        d->htgt = NULL;
 495        return 1;
 496}
 497
 498static inline unsigned char
 499ata_scnt(unsigned char *packet) {
 500        struct aoe_hdr *h;
 501        struct aoe_atahdr *ah;
 502
 503        h = (struct aoe_hdr *) packet;
 504        ah = (struct aoe_atahdr *) (h+1);
 505        return ah->scnt;
 506}
 507
 508static void
 509rexmit_timer(ulong vp)
 510{
 511        struct aoedev *d;
 512        struct aoetgt *t, **tt, **te;
 513        struct aoeif *ifp;
 514        struct frame *f, *e;
 515        struct sk_buff *sl;
 516        register long timeout;
 517        ulong flags, n;
 518
 519        d = (struct aoedev *) vp;
 520        sl = NULL;
 521
 522        /* timeout is always ~150% of the moving average */
 523        timeout = d->rttavg;
 524        timeout += timeout >> 1;
 525
 526        spin_lock_irqsave(&d->lock, flags);
 527
 528        if (d->flags & DEVFL_TKILL) {
 529                spin_unlock_irqrestore(&d->lock, flags);
 530                return;
 531        }
 532        tt = d->targets;
 533        te = tt + NTARGETS;
 534        for (; tt < te && *tt; tt++) {
 535                t = *tt;
 536                f = t->frames;
 537                e = f + t->nframes;
 538                for (; f < e; f++) {
 539                        if (f->tag == FREETAG
 540                        || tsince(f->tag) < timeout)
 541                                continue;
 542                        n = f->waited += timeout;
 543                        n /= HZ;
 544                        if (n > aoe_deadsecs) {
 545                                /* waited too long.  device failure. */
 546                                aoedev_downdev(d);
 547                                break;
 548                        }
 549
 550                        if (n > HELPWAIT /* see if another target can help */
 551                        && (tt != d->targets || d->targets[1]))
 552                                d->htgt = tt;
 553
 554                        if (t->nout == t->maxout) {
 555                                if (t->maxout > 1)
 556                                        t->maxout--;
 557                                t->lastwadj = jiffies;
 558                        }
 559
 560                        ifp = getif(t, f->skb->dev);
 561                        if (ifp && ++ifp->lost > (t->nframes << 1)
 562                        && (ifp != t->ifs || t->ifs[1].nd)) {
 563                                ejectif(t, ifp);
 564                                ifp = NULL;
 565                        }
 566
 567                        if (ata_scnt(skb_mac_header(f->skb)) > DEFAULTBCNT / 512
 568                        && ifp && ++ifp->lostjumbo > (t->nframes << 1)
 569                        && ifp->maxbcnt != DEFAULTBCNT) {
 570                                printk(KERN_INFO
 571                                        "aoe: e%ld.%d: "
 572                                        "too many lost jumbo on "
 573                                        "%s:%012llx - "
 574                                        "falling back to %d frames.\n",
 575                                        d->aoemajor, d->aoeminor,
 576                                        ifp->nd->name, mac_addr(t->addr),
 577                                        DEFAULTBCNT);
 578                                ifp->maxbcnt = 0;
 579                        }
 580                        resend(d, t, f);
 581                }
 582
 583                /* window check */
 584                if (t->nout == t->maxout
 585                && t->maxout < t->nframes
 586                && (jiffies - t->lastwadj)/HZ > 10) {
 587                        t->maxout++;
 588                        t->lastwadj = jiffies;
 589                }
 590        }
 591
 592        if (d->sendq_hd) {
 593                n = d->rttavg <<= 1;
 594                if (n > MAXTIMER)
 595                        d->rttavg = MAXTIMER;
 596        }
 597
 598        if (d->flags & DEVFL_KICKME || d->htgt) {
 599                d->flags &= ~DEVFL_KICKME;
 600                aoecmd_work(d);
 601        }
 602
 603        sl = d->sendq_hd;
 604        d->sendq_hd = d->sendq_tl = NULL;
 605
 606        d->timer.expires = jiffies + TIMERTICK;
 607        add_timer(&d->timer);
 608
 609        spin_unlock_irqrestore(&d->lock, flags);
 610
 611        aoenet_xmit(sl);
 612}
 613
 614/* enters with d->lock held */
 615void
 616aoecmd_work(struct aoedev *d)
 617{
 618        struct buf *buf;
 619loop:
 620        if (d->htgt && !sthtith(d))
 621                return;
 622        if (d->inprocess == NULL) {
 623                if (list_empty(&d->bufq))
 624                        return;
 625                buf = container_of(d->bufq.next, struct buf, bufs);
 626                list_del(d->bufq.next);
 627                d->inprocess = buf;
 628        }
 629        if (aoecmd_ata_rw(d))
 630                goto loop;
 631}
 632
 633/* this function performs work that has been deferred until sleeping is OK
 634 */
 635void
 636aoecmd_sleepwork(struct work_struct *work)
 637{
 638        struct aoedev *d = container_of(work, struct aoedev, work);
 639
 640        if (d->flags & DEVFL_GDALLOC)
 641                aoeblk_gdalloc(d);
 642
 643        if (d->flags & DEVFL_NEWSIZE) {
 644                struct block_device *bd;
 645                unsigned long flags;
 646                u64 ssize;
 647
 648                ssize = d->gd->capacity;
 649                bd = bdget_disk(d->gd, 0);
 650
 651                if (bd) {
 652                        mutex_lock(&bd->bd_inode->i_mutex);
 653                        i_size_write(bd->bd_inode, (loff_t)ssize<<9);
 654                        mutex_unlock(&bd->bd_inode->i_mutex);
 655                        bdput(bd);
 656                }
 657                spin_lock_irqsave(&d->lock, flags);
 658                d->flags |= DEVFL_UP;
 659                d->flags &= ~DEVFL_NEWSIZE;
 660                spin_unlock_irqrestore(&d->lock, flags);
 661        }
 662}
 663
 664static void
 665ataid_complete(struct aoedev *d, struct aoetgt *t, unsigned char *id)
 666{
 667        u64 ssize;
 668        u16 n;
 669
 670        /* word 83: command set supported */
 671        n = get_unaligned_le16(&id[83 << 1]);
 672
 673        /* word 86: command set/feature enabled */
 674        n |= get_unaligned_le16(&id[86 << 1]);
 675
 676        if (n & (1<<10)) {      /* bit 10: LBA 48 */
 677                d->flags |= DEVFL_EXT;
 678
 679                /* word 100: number lba48 sectors */
 680                ssize = get_unaligned_le64(&id[100 << 1]);
 681
 682                /* set as in ide-disk.c:init_idedisk_capacity */
 683                d->geo.cylinders = ssize;
 684                d->geo.cylinders /= (255 * 63);
 685                d->geo.heads = 255;
 686                d->geo.sectors = 63;
 687        } else {
 688                d->flags &= ~DEVFL_EXT;
 689
 690                /* number lba28 sectors */
 691                ssize = get_unaligned_le32(&id[60 << 1]);
 692
 693                /* NOTE: obsolete in ATA 6 */
 694                d->geo.cylinders = get_unaligned_le16(&id[54 << 1]);
 695                d->geo.heads = get_unaligned_le16(&id[55 << 1]);
 696                d->geo.sectors = get_unaligned_le16(&id[56 << 1]);
 697        }
 698
 699        if (d->ssize != ssize)
 700                printk(KERN_INFO
 701                        "aoe: %012llx e%ld.%d v%04x has %llu sectors\n",
 702                        mac_addr(t->addr),
 703                        d->aoemajor, d->aoeminor,
 704                        d->fw_ver, (long long)ssize);
 705        d->ssize = ssize;
 706        d->geo.start = 0;
 707        if (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE))
 708                return;
 709        if (d->gd != NULL) {
 710                d->gd->capacity = ssize;
 711                d->flags |= DEVFL_NEWSIZE;
 712        } else
 713                d->flags |= DEVFL_GDALLOC;
 714        schedule_work(&d->work);
 715}
 716
 717static void
 718calc_rttavg(struct aoedev *d, int rtt)
 719{
 720        register long n;
 721
 722        n = rtt;
 723        if (n < 0) {
 724                n = -rtt;
 725                if (n < MINTIMER)
 726                        n = MINTIMER;
 727                else if (n > MAXTIMER)
 728                        n = MAXTIMER;
 729                d->mintimer += (n - d->mintimer) >> 1;
 730        } else if (n < d->mintimer)
 731                n = d->mintimer;
 732        else if (n > MAXTIMER)
 733                n = MAXTIMER;
 734
 735        /* g == .25; cf. Congestion Avoidance and Control, Jacobson & Karels; 1988 */
 736        n -= d->rttavg;
 737        d->rttavg += n >> 2;
 738}
 739
 740static struct aoetgt *
 741gettgt(struct aoedev *d, char *addr)
 742{
 743        struct aoetgt **t, **e;
 744
 745        t = d->targets;
 746        e = t + NTARGETS;
 747        for (; t < e && *t; t++)
 748                if (memcmp((*t)->addr, addr, sizeof((*t)->addr)) == 0)
 749                        return *t;
 750        return NULL;
 751}
 752
 753static inline void
 754diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector)
 755{
 756        unsigned long n_sect = bio->bi_size >> 9;
 757        const int rw = bio_data_dir(bio);
 758        struct hd_struct *part;
 759
 760        part = get_part(disk, sector);
 761        all_stat_inc(disk, part, ios[rw], sector);
 762        all_stat_add(disk, part, ticks[rw], duration, sector);
 763        all_stat_add(disk, part, sectors[rw], n_sect, sector);
 764        all_stat_add(disk, part, io_ticks, duration, sector);
 765}
 766
 767void
 768aoecmd_ata_rsp(struct sk_buff *skb)
 769{
 770        struct aoedev *d;
 771        struct aoe_hdr *hin, *hout;
 772        struct aoe_atahdr *ahin, *ahout;
 773        struct frame *f;
 774        struct buf *buf;
 775        struct sk_buff *sl;
 776        struct aoetgt *t;
 777        struct aoeif *ifp;
 778        register long n;
 779        ulong flags;
 780        char ebuf[128];
 781        u16 aoemajor;
 782
 783        hin = (struct aoe_hdr *) skb_mac_header(skb);
 784        aoemajor = get_unaligned_be16(&hin->major);
 785        d = aoedev_by_aoeaddr(aoemajor, hin->minor);
 786        if (d == NULL) {
 787                snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response "
 788                        "for unknown device %d.%d\n",
 789                         aoemajor, hin->minor);
 790                aoechr_error(ebuf);
 791                return;
 792        }
 793
 794        spin_lock_irqsave(&d->lock, flags);
 795
 796        n = get_unaligned_be32(&hin->tag);
 797        t = gettgt(d, hin->src);
 798        if (t == NULL) {
 799                printk(KERN_INFO "aoe: can't find target e%ld.%d:%012llx\n",
 800                        d->aoemajor, d->aoeminor, mac_addr(hin->src));
 801                spin_unlock_irqrestore(&d->lock, flags);
 802                return;
 803        }
 804        f = getframe(t, n);
 805        if (f == NULL) {
 806                calc_rttavg(d, -tsince(n));
 807                spin_unlock_irqrestore(&d->lock, flags);
 808                snprintf(ebuf, sizeof ebuf,
 809                        "%15s e%d.%d    tag=%08x@%08lx\n",
 810                        "unexpected rsp",
 811                        get_unaligned_be16(&hin->major),
 812                        hin->minor,
 813                        get_unaligned_be32(&hin->tag),
 814                        jiffies);
 815                aoechr_error(ebuf);
 816                return;
 817        }
 818
 819        calc_rttavg(d, tsince(f->tag));
 820
 821        ahin = (struct aoe_atahdr *) (hin+1);
 822        hout = (struct aoe_hdr *) skb_mac_header(f->skb);
 823        ahout = (struct aoe_atahdr *) (hout+1);
 824        buf = f->buf;
 825
 826        if (ahin->cmdstat & 0xa9) {     /* these bits cleared on success */
 827                printk(KERN_ERR
 828                        "aoe: ata error cmd=%2.2Xh stat=%2.2Xh from e%ld.%d\n",
 829                        ahout->cmdstat, ahin->cmdstat,
 830                        d->aoemajor, d->aoeminor);
 831                if (buf)
 832                        buf->flags |= BUFFL_FAIL;
 833        } else {
 834                if (d->htgt && t == *d->htgt) /* I'll help myself, thank you. */
 835                        d->htgt = NULL;
 836                n = ahout->scnt << 9;
 837                switch (ahout->cmdstat) {
 838                case WIN_READ:
 839                case WIN_READ_EXT:
 840                        if (skb->len - sizeof *hin - sizeof *ahin < n) {
 841                                printk(KERN_ERR
 842                                        "aoe: %s.  skb->len=%d need=%ld\n",
 843                                        "runt data size in read", skb->len, n);
 844                                /* fail frame f?  just returning will rexmit. */
 845                                spin_unlock_irqrestore(&d->lock, flags);
 846                                return;
 847                        }
 848                        memcpy(f->bufaddr, ahin+1, n);
 849                case WIN_WRITE:
 850                case WIN_WRITE_EXT:
 851                        ifp = getif(t, skb->dev);
 852                        if (ifp) {
 853                                ifp->lost = 0;
 854                                if (n > DEFAULTBCNT)
 855                                        ifp->lostjumbo = 0;
 856                        }
 857                        if (f->bcnt -= n) {
 858                                f->lba += n >> 9;
 859                                f->bufaddr += n;
 860                                resend(d, t, f);
 861                                goto xmit;
 862                        }
 863                        break;
 864                case WIN_IDENTIFY:
 865                        if (skb->len - sizeof *hin - sizeof *ahin < 512) {
 866                                printk(KERN_INFO
 867                                        "aoe: runt data size in ataid.  skb->len=%d\n",
 868                                        skb->len);
 869                                spin_unlock_irqrestore(&d->lock, flags);
 870                                return;
 871                        }
 872                        ataid_complete(d, t, (char *) (ahin+1));
 873                        break;
 874                default:
 875                        printk(KERN_INFO
 876                                "aoe: unrecognized ata command %2.2Xh for %d.%d\n",
 877                                ahout->cmdstat,
 878                                get_unaligned_be16(&hin->major),
 879                                hin->minor);
 880                }
 881        }
 882
 883        if (buf && --buf->nframesout == 0 && buf->resid == 0) {
 884                diskstats(d->gd, buf->bio, jiffies - buf->stime, buf->sector);
 885                n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
 886                bio_endio(buf->bio, n);
 887                mempool_free(buf, d->bufpool);
 888        }
 889
 890        f->buf = NULL;
 891        f->tag = FREETAG;
 892        t->nout--;
 893
 894        aoecmd_work(d);
 895xmit:
 896        sl = d->sendq_hd;
 897        d->sendq_hd = d->sendq_tl = NULL;
 898
 899        spin_unlock_irqrestore(&d->lock, flags);
 900        aoenet_xmit(sl);
 901}
 902
 903void
 904aoecmd_cfg(ushort aoemajor, unsigned char aoeminor)
 905{
 906        struct sk_buff *sl;
 907
 908        sl = aoecmd_cfg_pkts(aoemajor, aoeminor, NULL);
 909
 910        aoenet_xmit(sl);
 911}
 912 
 913struct sk_buff *
 914aoecmd_ata_id(struct aoedev *d)
 915{
 916        struct aoe_hdr *h;
 917        struct aoe_atahdr *ah;
 918        struct frame *f;
 919        struct sk_buff *skb;
 920        struct aoetgt *t;
 921
 922        f = freeframe(d);
 923        if (f == NULL)
 924                return NULL;
 925
 926        t = *d->tgt;
 927
 928        /* initialize the headers & frame */
 929        skb = f->skb;
 930        h = (struct aoe_hdr *) skb_mac_header(skb);
 931        ah = (struct aoe_atahdr *) (h+1);
 932        skb_put(skb, sizeof *h + sizeof *ah);
 933        memset(h, 0, skb->len);
 934        f->tag = aoehdr_atainit(d, t, h);
 935        t->nout++;
 936        f->waited = 0;
 937
 938        /* set up ata header */
 939        ah->scnt = 1;
 940        ah->cmdstat = WIN_IDENTIFY;
 941        ah->lba3 = 0xa0;
 942
 943        skb->dev = t->ifp->nd;
 944
 945        d->rttavg = MAXTIMER;
 946        d->timer.function = rexmit_timer;
 947
 948        return skb_clone(skb, GFP_ATOMIC);
 949}
 950 
 951static struct aoetgt *
 952addtgt(struct aoedev *d, char *addr, ulong nframes)
 953{
 954        struct aoetgt *t, **tt, **te;
 955        struct frame *f, *e;
 956
 957        tt = d->targets;
 958        te = tt + NTARGETS;
 959        for (; tt < te && *tt; tt++)
 960                ;
 961
 962        if (tt == te) {
 963                printk(KERN_INFO
 964                        "aoe: device addtgt failure; too many targets\n");
 965                return NULL;
 966        }
 967        t = kcalloc(1, sizeof *t, GFP_ATOMIC);
 968        f = kcalloc(nframes, sizeof *f, GFP_ATOMIC);
 969        if (!t || !f) {
 970                kfree(f);
 971                kfree(t);
 972                printk(KERN_INFO "aoe: cannot allocate memory to add target\n");
 973                return NULL;
 974        }
 975
 976        t->nframes = nframes;
 977        t->frames = f;
 978        e = f + nframes;
 979        for (; f < e; f++)
 980                f->tag = FREETAG;
 981        memcpy(t->addr, addr, sizeof t->addr);
 982        t->ifp = t->ifs;
 983        t->maxout = t->nframes;
 984        return *tt = t;
 985}
 986
 987void
 988aoecmd_cfg_rsp(struct sk_buff *skb)
 989{
 990        struct aoedev *d;
 991        struct aoe_hdr *h;
 992        struct aoe_cfghdr *ch;
 993        struct aoetgt *t;
 994        struct aoeif *ifp;
 995        ulong flags, sysminor, aoemajor;
 996        struct sk_buff *sl;
 997        u16 n;
 998
 999        h = (struct aoe_hdr *) skb_mac_header(skb);
1000        ch = (struct aoe_cfghdr *) (h+1);
1001
1002        /*
1003         * Enough people have their dip switches set backwards to
1004         * warrant a loud message for this special case.
1005         */
1006        aoemajor = be16_to_cpu(get_unaligned(&h->major));
1007        if (aoemajor == 0xfff) {
1008                printk(KERN_ERR "aoe: Warning: shelf address is all ones.  "
1009                        "Check shelf dip switches.\n");
1010                return;
1011        }
1012
1013        sysminor = SYSMINOR(aoemajor, h->minor);
1014        if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) {
1015                printk(KERN_INFO "aoe: e%ld.%d: minor number too large\n",
1016                        aoemajor, (int) h->minor);
1017                return;
1018        }
1019
1020        n = be16_to_cpu(ch->bufcnt);
1021        if (n > aoe_maxout)     /* keep it reasonable */
1022                n = aoe_maxout;
1023
1024        d = aoedev_by_sysminor_m(sysminor);
1025        if (d == NULL) {
1026                printk(KERN_INFO "aoe: device sysminor_m failure\n");
1027                return;
1028        }
1029
1030        spin_lock_irqsave(&d->lock, flags);
1031
1032        t = gettgt(d, h->src);
1033        if (!t) {
1034                t = addtgt(d, h->src, n);
1035                if (!t) {
1036                        spin_unlock_irqrestore(&d->lock, flags);
1037                        return;
1038                }
1039        }
1040        ifp = getif(t, skb->dev);
1041        if (!ifp) {
1042                ifp = addif(t, skb->dev);
1043                if (!ifp) {
1044                        printk(KERN_INFO
1045                                "aoe: device addif failure; "
1046                                "too many interfaces?\n");
1047                        spin_unlock_irqrestore(&d->lock, flags);
1048                        return;
1049                }
1050        }
1051        if (ifp->maxbcnt) {
1052                n = ifp->nd->mtu;
1053                n -= sizeof (struct aoe_hdr) + sizeof (struct aoe_atahdr);
1054                n /= 512;
1055                if (n > ch->scnt)
1056                        n = ch->scnt;
1057                n = n ? n * 512 : DEFAULTBCNT;
1058                if (n != ifp->maxbcnt) {
1059                        printk(KERN_INFO
1060                                "aoe: e%ld.%d: setting %d%s%s:%012llx\n",
1061                                d->aoemajor, d->aoeminor, n,
1062                                " byte data frames on ", ifp->nd->name,
1063                                mac_addr(t->addr));
1064                        ifp->maxbcnt = n;
1065                }
1066        }
1067
1068        /* don't change users' perspective */
1069        if (d->nopen) {
1070                spin_unlock_irqrestore(&d->lock, flags);
1071                return;
1072        }
1073        d->fw_ver = be16_to_cpu(ch->fwver);
1074
1075        sl = aoecmd_ata_id(d);
1076
1077        spin_unlock_irqrestore(&d->lock, flags);
1078
1079        aoenet_xmit(sl);
1080}
1081
1082void
1083aoecmd_cleanslate(struct aoedev *d)
1084{
1085        struct aoetgt **t, **te;
1086        struct aoeif *p, *e;
1087
1088        d->mintimer = MINTIMER;
1089
1090        t = d->targets;
1091        te = t + NTARGETS;
1092        for (; t < te && *t; t++) {
1093                (*t)->maxout = (*t)->nframes;
1094                p = (*t)->ifs;
1095                e = p + NAOEIFS;
1096                for (; p < e; p++) {
1097                        p->lostjumbo = 0;
1098                        p->lost = 0;
1099                        p->maxbcnt = DEFAULTBCNT;
1100                }
1101        }
1102}
1103
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.