static void aoecmd_ata_rw(struct aoedev *d, struct frame *f) { struct aoe_hdr *h; struct aoe_atahdr *ah; struct buf *buf; struct sk_buff *skb; ulong bcnt; register sector_t sector; char writebit, extbit; writebit = 0x10; extbit = 0x4; buf = d->inprocess; sector = buf->sector; bcnt = buf->bv_resid; if (bcnt > MAXATADATA) bcnt = MAXATADATA; /* initialize the headers & frame */ h = (struct aoe_hdr *) f->data; ah = (struct aoe_atahdr *) (h+1); f->ndata = sizeof *h + sizeof *ah; memset(h, 0, f->ndata); f->tag = aoehdr_atainit(d, h); f->waited = 0; f->buf = buf; f->bufaddr = buf->bufaddr; /* set up ata header */ ah->scnt = bcnt >> 9; ah->lba0 = sector; ah->lba1 = sector >>= 8; ah->lba2 = sector >>= 8; ah->lba3 = sector >>= 8; if (d->flags & DEVFL_EXT) { ah->aflags |= AOEAFL_EXT; ah->lba4 = sector >>= 8; ah->lba5 = sector >>= 8; } else {
static void aoecmd_ata_rw(struct aoedev *d, struct frame *f) { struct aoe_hdr *h; struct aoe_atahdr *ah; struct buf *buf; struct sk_buff *skb; ulong bcnt; register sector_t sector; char writebit, extbit; writebit = 0x10; extbit = 0x4; buf = d->inprocess; sector = buf->sector; bcnt = buf->bv_resid; if (bcnt > d->maxbcnt) bcnt = d->maxbcnt; /* initialize the headers & frame */ skb = f->skb; h = (struct aoe_hdr *) skb->mac.raw; ah = (struct aoe_atahdr *) (h+1); skb_put(skb, sizeof *h + sizeof *ah); memset(h, 0, skb->len); f->tag = aoehdr_atainit(d, h); f->waited = 0; f->buf = buf; f->bufaddr = buf->bufaddr; f->bcnt = bcnt; f->lba = sector; /* set up ata header */ ah->scnt = bcnt >> 9; put_lba(ah, sector); if (d->flags & DEVFL_EXT) { ah->aflags |= AOEAFL_EXT; } else { extbit = 0; ah->lba3 &= 0x0f; ah->lba3 |= 0xe0; /* LBA bit + obsolete 0xa0 */ } if (bio_data_dir(buf->bio) == WRITE) { skb_fill_page_desc(skb, 0, virt_to_page(f->bufaddr), offset_in_page(f->bufaddr), bcnt); ah->aflags |= AOEAFL_WRITE; skb->len += bcnt; skb->data_len = bcnt; } else { writebit = 0; } ah->cmdstat = WIN_READ | writebit | extbit; /* mark all tracking fields and load out */ buf->nframesout += 1; buf->bufaddr += bcnt; buf->bv_resid -= bcnt; /* printk(KERN_DEBUG "aoe: bv_resid=%ld\n", buf->bv_resid); */ buf->resid -= bcnt; buf->sector += bcnt >> 9; if (buf->resid == 0) { d->inprocess = NULL; } else if (buf->bv_resid == 0) { buf->bv++; WARN_ON(buf->bv->bv_len == 0); buf->bv_resid = buf->bv->bv_len; buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset; } skb->dev = d->ifp; skb = skb_clone(skb, GFP_ATOMIC); if (skb == NULL) return; if (d->sendq_hd) d->sendq_tl->next = skb; else d->sendq_hd = skb; d->sendq_tl = skb; }