xref: /openbmc/linux/drivers/block/aoe/aoe.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1ca47bbd9SEd Cashin /* Copyright (c) 2013 Coraid, Inc.  See COPYING for GPL terms. */
23582dd29SJens Axboe #include <linux/blk-mq.h>
33582dd29SJens Axboe 
4896dcd9aSEd Cashin #define VERSION "85"
51da177e4SLinus Torvalds #define AOE_MAJOR 152
61da177e4SLinus Torvalds #define DEVICE_NAME "aoe"
7fc458dcdSecashin@coraid.com 
8fc458dcdSecashin@coraid.com /* set AOE_PARTITIONS to 1 to use whole-disks only
9fc458dcdSecashin@coraid.com  * default is 16, which is 15 partitions plus the whole disk
10fc458dcdSecashin@coraid.com  */
111da177e4SLinus Torvalds #ifndef AOE_PARTITIONS
12e39526e6SEd L Cashin #define AOE_PARTITIONS (16)
131da177e4SLinus Torvalds #endif
14fc458dcdSecashin@coraid.com 
154a6c9ee9SEd Cashin #define WHITESPACE " \t\v\f\n,"
161da177e4SLinus Torvalds 
171da177e4SLinus Torvalds enum {
181da177e4SLinus Torvalds 	AOECMD_ATA,
191da177e4SLinus Torvalds 	AOECMD_CFG,
20b6d6c517SEd Cashin 	AOECMD_VEND_MIN = 0xf0,
211da177e4SLinus Torvalds 
221da177e4SLinus Torvalds 	AOEFL_RSP = (1<<3),
231da177e4SLinus Torvalds 	AOEFL_ERR = (1<<2),
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds 	AOEAFL_EXT = (1<<6),
261da177e4SLinus Torvalds 	AOEAFL_DEV = (1<<4),
271da177e4SLinus Torvalds 	AOEAFL_ASYNC = (1<<1),
281da177e4SLinus Torvalds 	AOEAFL_WRITE = (1<<0),
291da177e4SLinus Torvalds 
301da177e4SLinus Torvalds 	AOECCMD_READ = 0,
311da177e4SLinus Torvalds 	AOECCMD_TEST,
321da177e4SLinus Torvalds 	AOECCMD_PTEST,
331da177e4SLinus Torvalds 	AOECCMD_SET,
341da177e4SLinus Torvalds 	AOECCMD_FSET,
351da177e4SLinus Torvalds 
361da177e4SLinus Torvalds 	AOE_HVER = 0x10,
371da177e4SLinus Torvalds };
381da177e4SLinus Torvalds 
391da177e4SLinus Torvalds struct aoe_hdr {
401da177e4SLinus Torvalds 	unsigned char dst[6];
411da177e4SLinus Torvalds 	unsigned char src[6];
4263e9cc5dSecashin@coraid.com 	__be16 type;
431da177e4SLinus Torvalds 	unsigned char verfl;
441da177e4SLinus Torvalds 	unsigned char err;
4563e9cc5dSecashin@coraid.com 	__be16 major;
461da177e4SLinus Torvalds 	unsigned char minor;
471da177e4SLinus Torvalds 	unsigned char cmd;
4863e9cc5dSecashin@coraid.com 	__be32 tag;
491da177e4SLinus Torvalds };
501da177e4SLinus Torvalds 
511da177e4SLinus Torvalds struct aoe_atahdr {
521da177e4SLinus Torvalds 	unsigned char aflags;
531da177e4SLinus Torvalds 	unsigned char errfeat;
541da177e4SLinus Torvalds 	unsigned char scnt;
551da177e4SLinus Torvalds 	unsigned char cmdstat;
561da177e4SLinus Torvalds 	unsigned char lba0;
571da177e4SLinus Torvalds 	unsigned char lba1;
581da177e4SLinus Torvalds 	unsigned char lba2;
591da177e4SLinus Torvalds 	unsigned char lba3;
601da177e4SLinus Torvalds 	unsigned char lba4;
611da177e4SLinus Torvalds 	unsigned char lba5;
621da177e4SLinus Torvalds 	unsigned char res[2];
631da177e4SLinus Torvalds };
641da177e4SLinus Torvalds 
651da177e4SLinus Torvalds struct aoe_cfghdr {
6663e9cc5dSecashin@coraid.com 	__be16 bufcnt;
6763e9cc5dSecashin@coraid.com 	__be16 fwver;
6819bf2635SEd L. Cashin 	unsigned char scnt;
691da177e4SLinus Torvalds 	unsigned char aoeccmd;
701da177e4SLinus Torvalds 	unsigned char cslen[2];
711da177e4SLinus Torvalds };
721da177e4SLinus Torvalds 
731da177e4SLinus Torvalds enum {
741da177e4SLinus Torvalds 	DEVFL_UP = 1,	/* device is installed in system and ready for AoE->ATA commands */
751da177e4SLinus Torvalds 	DEVFL_TKILL = (1<<1),	/* flag for timer to know when to kill self */
761da177e4SLinus Torvalds 	DEVFL_EXT = (1<<2),	/* device accepts lba48 commands */
77b21faa25SEd Cashin 	DEVFL_GDALLOC = (1<<3),	/* need to alloc gendisk */
78e52a2932SEd Cashin 	DEVFL_GD_NOW = (1<<4),	/* allocating gendisk */
79e52a2932SEd Cashin 	DEVFL_KICKME = (1<<5),	/* slow polling network card catch */
80e52a2932SEd Cashin 	DEVFL_NEWSIZE = (1<<6),	/* need to update dev size in block layer */
81e52a2932SEd Cashin 	DEVFL_FREEING = (1<<7),	/* set when device is being cleaned up */
82e52a2932SEd Cashin 	DEVFL_FREED = (1<<8),	/* device has been cleaned up */
831da177e4SLinus Torvalds };
841da177e4SLinus Torvalds 
851da177e4SLinus Torvalds enum {
8619bf2635SEd L. Cashin 	DEFAULTBCNT = 2 * 512,	/* 2 sectors */
8768e0d42fSEd L. Cashin 	MIN_BUFS = 16,
8871114ec4SEd Cashin 	NTARGETS = 4,
8968e0d42fSEd L. Cashin 	NAOEIFS = 8,
9069cf2d85SEd Cashin 	NSKBPOOLMAX = 256,
9164a80f5aSEd Cashin 	NFACTIVE = 61,
9268e0d42fSEd L. Cashin 
9368e0d42fSEd L. Cashin 	TIMERTICK = HZ / 10,
943a0c40d2SEd Cashin 	RTTSCALE = 8,
953a0c40d2SEd Cashin 	RTTDSCALE = 3,
965f0c9c48SEd Cashin 	RTTAVG_INIT = USEC_PER_SEC / 4 << RTTSCALE,
973a0c40d2SEd Cashin 	RTTDEV_INIT = RTTAVG_INIT / 4,
98bbb44e30SEd Cashin 
99bbb44e30SEd Cashin 	HARD_SCORN_SECS = 10,	/* try another remote port after this */
100bbb44e30SEd Cashin 	MAX_TAINT = 1000,	/* cap on aoetgt taint */
1011da177e4SLinus Torvalds };
1021da177e4SLinus Torvalds 
10361e7712eSChristoph Hellwig struct aoe_req {
10461e7712eSChristoph Hellwig 	unsigned long nr_bios;
10561e7712eSChristoph Hellwig };
10661e7712eSChristoph Hellwig 
1071da177e4SLinus Torvalds struct buf {
1081da177e4SLinus Torvalds 	ulong nframesout;
1091da177e4SLinus Torvalds 	struct bio *bio;
110feb261e2SKent Overstreet 	struct bvec_iter iter;
11169cf2d85SEd Cashin 	struct request *rq;
1121da177e4SLinus Torvalds };
1131da177e4SLinus Torvalds 
114bbb44e30SEd Cashin enum frame_flags {
115bbb44e30SEd Cashin 	FFL_PROBE = 1,
116bbb44e30SEd Cashin };
117bbb44e30SEd Cashin 
1181da177e4SLinus Torvalds struct frame {
119896831f5SEd Cashin 	struct list_head head;
120896831f5SEd Cashin 	u32 tag;
12185cf955dSTina Ruchandani 	ktime_t sent;			/* high-res time packet was sent */
1221da177e4SLinus Torvalds 	ulong waited;
1233fc9b032SEd Cashin 	ulong waited_total;
124896831f5SEd Cashin 	struct aoetgt *t;		/* parent target I belong to */
125896831f5SEd Cashin 	struct sk_buff *skb;		/* command skb freed on module exit */
126896831f5SEd Cashin 	struct sk_buff *r_skb;		/* response skb for async processing */
12769cf2d85SEd Cashin 	struct buf *buf;
128feb261e2SKent Overstreet 	struct bvec_iter iter;
129bbb44e30SEd Cashin 	char flags;
1301da177e4SLinus Torvalds };
1311da177e4SLinus Torvalds 
13268e0d42fSEd L. Cashin struct aoeif {
13368e0d42fSEd L. Cashin 	struct net_device *nd;
1343f0f0133SEd Cashin 	ulong lost;
1353f0f0133SEd Cashin 	int bcnt;
13668e0d42fSEd L. Cashin };
13768e0d42fSEd L. Cashin 
13868e0d42fSEd L. Cashin struct aoetgt {
13968e0d42fSEd L. Cashin 	unsigned char addr[6];
1401b8a1636SEd Cashin 	ushort nframes;		/* cap on frames to use */
141896831f5SEd Cashin 	struct aoedev *d;			/* parent device I belong to */
142896831f5SEd Cashin 	struct list_head ffree;			/* list of free frames */
14368e0d42fSEd L. Cashin 	struct aoeif ifs[NAOEIFS];
14468e0d42fSEd L. Cashin 	struct aoeif *ifp;	/* current aoeif in use */
14572837600SEd Cashin 	ushort nout;		/* number of AoE commands outstanding */
1461b8a1636SEd Cashin 	ushort maxout;		/* current value for max outstanding */
1473a0c40d2SEd Cashin 	ushort next_cwnd;	/* incr maxout after decrementing to zero */
1483a0c40d2SEd Cashin 	ushort ssthresh;	/* slow start threshold */
1491b8a1636SEd Cashin 	ulong falloc;		/* number of allocated frames */
150bbb44e30SEd Cashin 	int taint;		/* how much we want to avoid this aoetgt */
1513f0f0133SEd Cashin 	int minbcnt;
15268e0d42fSEd L. Cashin 	int wpkts, rpkts;
153bbb44e30SEd Cashin 	char nout_probes;
15468e0d42fSEd L. Cashin };
15568e0d42fSEd L. Cashin 
1561da177e4SLinus Torvalds struct aoedev {
1571da177e4SLinus Torvalds 	struct aoedev *next;
1581da177e4SLinus Torvalds 	ulong sysminor;
1591da177e4SLinus Torvalds 	ulong aoemajor;
1605f0c9c48SEd Cashin 	u32 rttavg;		/* scaled AoE round trip time average */
1615f0c9c48SEd Cashin 	u32 rttdev;		/* scaled round trip time mean deviation */
16268e0d42fSEd L. Cashin 	u16 aoeminor;
16368e0d42fSEd L. Cashin 	u16 flags;
164dced3a05SEd L. Cashin 	u16 nopen;		/* (bd_openers isn't available without sleeping) */
1651da177e4SLinus Torvalds 	u16 fw_ver;		/* version of blade's firmware */
16664a80f5aSEd Cashin 	u16 lasttag;		/* last tag sent */
16764a80f5aSEd Cashin 	u16 useme;
16869cf2d85SEd Cashin 	ulong ref;
1691da177e4SLinus Torvalds 	struct work_struct work;/* disk create work struct */
1701da177e4SLinus Torvalds 	struct gendisk *gd;
171e8866cf2SEd Cashin 	struct dentry *debugfs;
1727135a71bSEd Cashin 	struct request_queue *blkq;
1733582dd29SJens Axboe 	struct list_head rq_list;
1743582dd29SJens Axboe 	struct blk_mq_tag_set tag_set;
1751da177e4SLinus Torvalds 	struct hd_geometry geo;
1761da177e4SLinus Torvalds 	sector_t ssize;
1771da177e4SLinus Torvalds 	struct timer_list timer;
1781da177e4SLinus Torvalds 	spinlock_t lock;
179e9bb8fb0SDavid S. Miller 	struct sk_buff_head skbpool;
1801da177e4SLinus Torvalds 	mempool_t *bufpool;	/* for deadlock-free Buf allocation */
18169cf2d85SEd Cashin 	struct {		/* pointers to work in progress */
18269cf2d85SEd Cashin 		struct buf *buf;
18369cf2d85SEd Cashin 		struct bio *nxbio;
18469cf2d85SEd Cashin 		struct request *rq;
18569cf2d85SEd Cashin 	} ip;
1863f0f0133SEd Cashin 	ulong maxbcnt;
18764a80f5aSEd Cashin 	struct list_head factive[NFACTIVE];	/* hash of active frames */
1883a0c40d2SEd Cashin 	struct list_head rexmitq; /* deferred retransmissions */
18971114ec4SEd Cashin 	struct aoetgt **targets;
19071114ec4SEd Cashin 	ulong ntargets;		/* number of allocated aoetgt pointers */
19168e0d42fSEd L. Cashin 	struct aoetgt **tgt;	/* target in use when working */
192896831f5SEd Cashin 	ulong kicked;
193667be1e7SEd Cashin 	char ident[512];
1941da177e4SLinus Torvalds };
1951da177e4SLinus Torvalds 
196896831f5SEd Cashin /* kthread tracking */
197896831f5SEd Cashin struct ktstate {
198896831f5SEd Cashin 	struct completion rendez;
199896831f5SEd Cashin 	struct task_struct *task;
200896831f5SEd Cashin 	wait_queue_head_t *waitq;
2018030d343SEd Cashin 	int (*fn) (int);
2028030d343SEd Cashin 	char name[12];
203896831f5SEd Cashin 	spinlock_t *lock;
2048030d343SEd Cashin 	int id;
2058030d343SEd Cashin 	int active;
206896831f5SEd Cashin };
2071da177e4SLinus Torvalds 
2081da177e4SLinus Torvalds int aoeblk_init(void);
2091da177e4SLinus Torvalds void aoeblk_exit(void);
2101da177e4SLinus Torvalds void aoeblk_gdalloc(void *);
211e8866cf2SEd Cashin void aoedisk_rm_debugfs(struct aoedev *d);
2121da177e4SLinus Torvalds 
2131da177e4SLinus Torvalds int aoechr_init(void);
2141da177e4SLinus Torvalds void aoechr_exit(void);
2151da177e4SLinus Torvalds void aoechr_error(char *);
2161da177e4SLinus Torvalds 
2171da177e4SLinus Torvalds void aoecmd_work(struct aoedev *d);
2183ae1c24eSEd L. Cashin void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor);
219896831f5SEd Cashin struct sk_buff *aoecmd_ata_rsp(struct sk_buff *);
2201da177e4SLinus Torvalds void aoecmd_cfg_rsp(struct sk_buff *);
221c4028958SDavid Howells void aoecmd_sleepwork(struct work_struct *);
2223a0c40d2SEd Cashin void aoecmd_wreset(struct aoetgt *t);
22368e0d42fSEd L. Cashin void aoecmd_cleanslate(struct aoedev *);
224896831f5SEd Cashin void aoecmd_exit(void);
225896831f5SEd Cashin int aoecmd_init(void);
22668e0d42fSEd L. Cashin struct sk_buff *aoecmd_ata_id(struct aoedev *);
227896831f5SEd Cashin void aoe_freetframe(struct frame *);
22869cf2d85SEd Cashin void aoe_flush_iocq(void);
2298030d343SEd Cashin void aoe_flush_iocq_by_index(int);
23069cf2d85SEd Cashin void aoe_end_request(struct aoedev *, struct request *, int);
231eb086ec5SEd Cashin int aoe_ktstart(struct ktstate *k);
232eb086ec5SEd Cashin void aoe_ktstop(struct ktstate *k);
2331da177e4SLinus Torvalds 
2341da177e4SLinus Torvalds int aoedev_init(void);
2351da177e4SLinus Torvalds void aoedev_exit(void);
2360c966214SEd Cashin struct aoedev *aoedev_by_aoeaddr(ulong maj, int min, int do_alloc);
2371da177e4SLinus Torvalds void aoedev_downdev(struct aoedev *d);
238262bf541SEd L. Cashin int aoedev_flush(const char __user *str, size_t size);
23969cf2d85SEd Cashin void aoe_failbuf(struct aoedev *, struct buf *);
24069cf2d85SEd Cashin void aoedev_put(struct aoedev *);
2411da177e4SLinus Torvalds 
2421da177e4SLinus Torvalds int aoenet_init(void);
2431da177e4SLinus Torvalds void aoenet_exit(void);
244e9bb8fb0SDavid S. Miller void aoenet_xmit(struct sk_buff_head *);
2451da177e4SLinus Torvalds int is_aoe_netif(struct net_device *ifp);
2461da177e4SLinus Torvalds int set_aoe_iflist(const char __user *str, size_t size);
247*0b8d7622STetsuo Handa 
248*0b8d7622STetsuo Handa extern struct workqueue_struct *aoe_wq;
249