152e112b3ab6b2b35a144565c8ea3bdda1e2845f2Ed L. Cashin/* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */ 28911ef4dc97f77797f297318010a7424300d2d50Ed L. Cashin#define VERSION "47" 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define AOE_MAJOR 152 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEVICE_NAME "aoe" 5fc458dcda27c6d26cb11ef9ee9c1c3599711be94Ed L. Cashin 6fc458dcda27c6d26cb11ef9ee9c1c3599711be94Ed L. Cashin/* set AOE_PARTITIONS to 1 to use whole-disks only 7fc458dcda27c6d26cb11ef9ee9c1c3599711be94Ed L. Cashin * default is 16, which is 15 partitions plus the whole disk 8fc458dcda27c6d26cb11ef9ee9c1c3599711be94Ed L. Cashin */ 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef AOE_PARTITIONS 10e39526e6e7a96904c9f1c85375d49ff437c18c44Ed L. Cashin#define AOE_PARTITIONS (16) 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 12fc458dcda27c6d26cb11ef9ee9c1c3599711be94Ed L. Cashin 13e39526e6e7a96904c9f1c85375d49ff437c18c44Ed L. Cashin#define SYSMINOR(aoemajor, aoeminor) ((aoemajor) * NPERSHELF + (aoeminor)) 14e39526e6e7a96904c9f1c85375d49ff437c18c44Ed L. Cashin#define AOEMAJOR(sysminor) ((sysminor) / NPERSHELF) 15e39526e6e7a96904c9f1c85375d49ff437c18c44Ed L. Cashin#define AOEMINOR(sysminor) ((sysminor) % NPERSHELF) 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WHITESPACE " \t\v\f\n" 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenum { 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AOECMD_ATA, 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AOECMD_CFG, 21b6d6c5175809934e04a606d9193ef04924a7a7d9Ed L. Cashin AOECMD_VEND_MIN = 0xf0, 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AOEFL_RSP = (1<<3), 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AOEFL_ERR = (1<<2), 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AOEAFL_EXT = (1<<6), 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AOEAFL_DEV = (1<<4), 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AOEAFL_ASYNC = (1<<1), 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AOEAFL_WRITE = (1<<0), 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AOECCMD_READ = 0, 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AOECCMD_TEST, 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AOECCMD_PTEST, 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AOECCMD_SET, 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AOECCMD_FSET, 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds AOE_HVER = 0x10, 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct aoe_hdr { 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char dst[6]; 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char src[6]; 4363e9cc5d6fbe8b58ea1ee96439d356cbf726fbc0Ed L. Cashin __be16 type; 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char verfl; 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char err; 4663e9cc5d6fbe8b58ea1ee96439d356cbf726fbc0Ed L. Cashin __be16 major; 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char minor; 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char cmd; 4963e9cc5d6fbe8b58ea1ee96439d356cbf726fbc0Ed L. Cashin __be32 tag; 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct aoe_atahdr { 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char aflags; 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char errfeat; 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char scnt; 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char cmdstat; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char lba0; 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char lba1; 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char lba2; 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char lba3; 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char lba4; 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char lba5; 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char res[2]; 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct aoe_cfghdr { 6763e9cc5d6fbe8b58ea1ee96439d356cbf726fbc0Ed L. Cashin __be16 bufcnt; 6863e9cc5d6fbe8b58ea1ee96439d356cbf726fbc0Ed L. Cashin __be16 fwver; 6919bf26353c50bc2be375109ec73f2f0bbd616ed1Ed L. Cashin unsigned char scnt; 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char aoeccmd; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char cslen[2]; 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenum { 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEVFL_UP = 1, /* device is installed in system and ready for AoE->ATA commands */ 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEVFL_TKILL = (1<<1), /* flag for timer to know when to kill self */ 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEVFL_EXT = (1<<2), /* device accepts lba48 commands */ 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEVFL_CLOSEWAIT = (1<<3), /* device is waiting for all closes to revalidate */ 793ae1c24e395b2b65326439622223d88d92bfa03aEd L. Cashin DEVFL_GDALLOC = (1<<4), /* need to alloc gendisk */ 8068e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin DEVFL_KICKME = (1<<5), /* slow polling network card catch */ 813ae1c24e395b2b65326439622223d88d92bfa03aEd L. Cashin DEVFL_NEWSIZE = (1<<6), /* need to update dev size in block layer */ 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BUFFL_FAIL = 1, 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenum { 8719bf26353c50bc2be375109ec73f2f0bbd616ed1Ed L. Cashin DEFAULTBCNT = 2 * 512, /* 2 sectors */ 88e39526e6e7a96904c9f1c85375d49ff437c18c44Ed L. Cashin NPERSHELF = 16, /* number of slots per shelf address */ 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FREETAG = -1, 9068e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin MIN_BUFS = 16, 9168e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin NTARGETS = 8, 9268e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin NAOEIFS = 8, 939bb237b6a670fa7a6af3adc65231b1f6fda44510Ed L. Cashin NSKBPOOLMAX = 128, 9468e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin 9568e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin TIMERTICK = HZ / 10, 9668e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin MINTIMER = HZ >> 2, 9768e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin MAXTIMER = HZ << 1, 9868e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin HELPWAIT = 20, 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct buf { 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct list_head bufs; 10368e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin ulong stime; /* for disk stats */ 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ulong flags; 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ulong nframesout; 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ulong resid; 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ulong bv_resid; 10868e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin ulong bv_off; 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sector_t sector; 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bio *bio; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bio_vec *bv; 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct frame { 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int tag; 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ulong waited; 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct buf *buf; 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *bufaddr; 11919bf26353c50bc2be375109ec73f2f0bbd616ed1Ed L. Cashin ulong bcnt; 12019bf26353c50bc2be375109ec73f2f0bbd616ed1Ed L. Cashin sector_t lba; 121e407a7f6cd143b3ab4eb3d7e1cf882e96b710eb5Ed L. Cashin struct sk_buff *skb; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12468e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashinstruct aoeif { 12568e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin struct net_device *nd; 12668e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin unsigned char lost; 12768e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin unsigned char lostjumbo; 12868e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin ushort maxbcnt; 12968e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin}; 13068e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin 13168e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashinstruct aoetgt { 13268e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin unsigned char addr[6]; 13368e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin ushort nframes; 13468e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin struct frame *frames; 13568e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin struct aoeif ifs[NAOEIFS]; 13668e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin struct aoeif *ifp; /* current aoeif in use */ 13768e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin ushort nout; 13868e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin ushort maxout; 13968e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin u16 lasttag; /* last tag sent */ 14068e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin u16 useme; 14168e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin ulong lastwadj; /* last window adjustment */ 14268e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin int wpkts, rpkts; 1439bb237b6a670fa7a6af3adc65231b1f6fda44510Ed L. Cashin int dataref; 14468e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin}; 14568e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct aoedev { 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct aoedev *next; 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ulong sysminor; 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ulong aoemajor; 15068e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin u16 aoeminor; 15168e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin u16 flags; 152dced3a053dd5415a7321e1ae153c96dea644da4eEd L. Cashin u16 nopen; /* (bd_openers isn't available without sleeping) */ 153dced3a053dd5415a7321e1ae153c96dea644da4eEd L. Cashin u16 rttavg; /* round trip average of requests/responses */ 154dced3a053dd5415a7321e1ae153c96dea644da4eEd L. Cashin u16 mintimer; 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 fw_ver; /* version of blade's firmware */ 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct work_struct work;/* disk create work struct */ 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct gendisk *gd; 1587135a71b19be1faf48b7148d77844d03bc0717d6Ed L. Cashin struct request_queue *blkq; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct hd_geometry geo; 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sector_t ssize; 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct timer_list timer; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spinlock_t lock; 163e9bb8fb0b6d61a822201537b25206a0ca34b9d1dDavid S. Miller struct sk_buff_head sendq; 164e9bb8fb0b6d61a822201537b25206a0ca34b9d1dDavid S. Miller struct sk_buff_head skbpool; 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mempool_t *bufpool; /* for deadlock-free Buf allocation */ 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct list_head bufq; /* queue of bios to work on */ 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct buf *inprocess; /* the one we're currently working on */ 16868e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin struct aoetgt *targets[NTARGETS]; 16968e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin struct aoetgt **tgt; /* target in use when working */ 17068e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashin struct aoetgt **htgt; /* target needing rexmit assistance */ 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint aoeblk_init(void); 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid aoeblk_exit(void); 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid aoeblk_gdalloc(void *); 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid aoedisk_rm_sysfs(struct aoedev *d); 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint aoechr_init(void); 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid aoechr_exit(void); 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid aoechr_error(char *); 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid aoecmd_work(struct aoedev *d); 1843ae1c24e395b2b65326439622223d88d92bfa03aEd L. Cashinvoid aoecmd_cfg(ushort aoemajor, unsigned char aoeminor); 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid aoecmd_ata_rsp(struct sk_buff *); 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid aoecmd_cfg_rsp(struct sk_buff *); 187c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howellsvoid aoecmd_sleepwork(struct work_struct *); 18868e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashinvoid aoecmd_cleanslate(struct aoedev *); 18968e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashinstruct sk_buff *aoecmd_ata_id(struct aoedev *); 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint aoedev_init(void); 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid aoedev_exit(void); 19332465c650670c7499548d70fdeed57fab44ee679Ed L. Cashinstruct aoedev *aoedev_by_aoeaddr(int maj, int min); 19468e0d42f39d85b334d3867a4e5fc2e0e775c1a6cEd L. Cashinstruct aoedev *aoedev_by_sysminor_m(ulong sysminor); 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid aoedev_downdev(struct aoedev *d); 196262bf54144ebcb78cd0d057d2705dc5fb7bba7acEd L. Cashinint aoedev_flush(const char __user *str, size_t size); 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint aoenet_init(void); 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid aoenet_exit(void); 200e9bb8fb0b6d61a822201537b25206a0ca34b9d1dDavid S. Millervoid aoenet_xmit(struct sk_buff_head *); 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint is_aoe_netif(struct net_device *ifp); 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint set_aoe_iflist(const char __user *str, size_t size); 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 204