xref: /OK3568_Linux_fs/kernel/drivers/block/aoe/aoe.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* Copyright (c) 2013 Coraid, Inc.  See COPYING for GPL terms. */
2*4882a593Smuzhiyun #include <linux/blk-mq.h>
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun #define VERSION "85"
5*4882a593Smuzhiyun #define AOE_MAJOR 152
6*4882a593Smuzhiyun #define DEVICE_NAME "aoe"
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun /* set AOE_PARTITIONS to 1 to use whole-disks only
9*4882a593Smuzhiyun  * default is 16, which is 15 partitions plus the whole disk
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun #ifndef AOE_PARTITIONS
12*4882a593Smuzhiyun #define AOE_PARTITIONS (16)
13*4882a593Smuzhiyun #endif
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun #define WHITESPACE " \t\v\f\n,"
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun enum {
18*4882a593Smuzhiyun 	AOECMD_ATA,
19*4882a593Smuzhiyun 	AOECMD_CFG,
20*4882a593Smuzhiyun 	AOECMD_VEND_MIN = 0xf0,
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun 	AOEFL_RSP = (1<<3),
23*4882a593Smuzhiyun 	AOEFL_ERR = (1<<2),
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun 	AOEAFL_EXT = (1<<6),
26*4882a593Smuzhiyun 	AOEAFL_DEV = (1<<4),
27*4882a593Smuzhiyun 	AOEAFL_ASYNC = (1<<1),
28*4882a593Smuzhiyun 	AOEAFL_WRITE = (1<<0),
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun 	AOECCMD_READ = 0,
31*4882a593Smuzhiyun 	AOECCMD_TEST,
32*4882a593Smuzhiyun 	AOECCMD_PTEST,
33*4882a593Smuzhiyun 	AOECCMD_SET,
34*4882a593Smuzhiyun 	AOECCMD_FSET,
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 	AOE_HVER = 0x10,
37*4882a593Smuzhiyun };
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun struct aoe_hdr {
40*4882a593Smuzhiyun 	unsigned char dst[6];
41*4882a593Smuzhiyun 	unsigned char src[6];
42*4882a593Smuzhiyun 	__be16 type;
43*4882a593Smuzhiyun 	unsigned char verfl;
44*4882a593Smuzhiyun 	unsigned char err;
45*4882a593Smuzhiyun 	__be16 major;
46*4882a593Smuzhiyun 	unsigned char minor;
47*4882a593Smuzhiyun 	unsigned char cmd;
48*4882a593Smuzhiyun 	__be32 tag;
49*4882a593Smuzhiyun };
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun struct aoe_atahdr {
52*4882a593Smuzhiyun 	unsigned char aflags;
53*4882a593Smuzhiyun 	unsigned char errfeat;
54*4882a593Smuzhiyun 	unsigned char scnt;
55*4882a593Smuzhiyun 	unsigned char cmdstat;
56*4882a593Smuzhiyun 	unsigned char lba0;
57*4882a593Smuzhiyun 	unsigned char lba1;
58*4882a593Smuzhiyun 	unsigned char lba2;
59*4882a593Smuzhiyun 	unsigned char lba3;
60*4882a593Smuzhiyun 	unsigned char lba4;
61*4882a593Smuzhiyun 	unsigned char lba5;
62*4882a593Smuzhiyun 	unsigned char res[2];
63*4882a593Smuzhiyun };
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun struct aoe_cfghdr {
66*4882a593Smuzhiyun 	__be16 bufcnt;
67*4882a593Smuzhiyun 	__be16 fwver;
68*4882a593Smuzhiyun 	unsigned char scnt;
69*4882a593Smuzhiyun 	unsigned char aoeccmd;
70*4882a593Smuzhiyun 	unsigned char cslen[2];
71*4882a593Smuzhiyun };
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun enum {
74*4882a593Smuzhiyun 	DEVFL_UP = 1,	/* device is installed in system and ready for AoE->ATA commands */
75*4882a593Smuzhiyun 	DEVFL_TKILL = (1<<1),	/* flag for timer to know when to kill self */
76*4882a593Smuzhiyun 	DEVFL_EXT = (1<<2),	/* device accepts lba48 commands */
77*4882a593Smuzhiyun 	DEVFL_GDALLOC = (1<<3),	/* need to alloc gendisk */
78*4882a593Smuzhiyun 	DEVFL_GD_NOW = (1<<4),	/* allocating gendisk */
79*4882a593Smuzhiyun 	DEVFL_KICKME = (1<<5),	/* slow polling network card catch */
80*4882a593Smuzhiyun 	DEVFL_NEWSIZE = (1<<6),	/* need to update dev size in block layer */
81*4882a593Smuzhiyun 	DEVFL_FREEING = (1<<7),	/* set when device is being cleaned up */
82*4882a593Smuzhiyun 	DEVFL_FREED = (1<<8),	/* device has been cleaned up */
83*4882a593Smuzhiyun };
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun enum {
86*4882a593Smuzhiyun 	DEFAULTBCNT = 2 * 512,	/* 2 sectors */
87*4882a593Smuzhiyun 	MIN_BUFS = 16,
88*4882a593Smuzhiyun 	NTARGETS = 4,
89*4882a593Smuzhiyun 	NAOEIFS = 8,
90*4882a593Smuzhiyun 	NSKBPOOLMAX = 256,
91*4882a593Smuzhiyun 	NFACTIVE = 61,
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	TIMERTICK = HZ / 10,
94*4882a593Smuzhiyun 	RTTSCALE = 8,
95*4882a593Smuzhiyun 	RTTDSCALE = 3,
96*4882a593Smuzhiyun 	RTTAVG_INIT = USEC_PER_SEC / 4 << RTTSCALE,
97*4882a593Smuzhiyun 	RTTDEV_INIT = RTTAVG_INIT / 4,
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	HARD_SCORN_SECS = 10,	/* try another remote port after this */
100*4882a593Smuzhiyun 	MAX_TAINT = 1000,	/* cap on aoetgt taint */
101*4882a593Smuzhiyun };
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun struct aoe_req {
104*4882a593Smuzhiyun 	unsigned long nr_bios;
105*4882a593Smuzhiyun };
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun struct buf {
108*4882a593Smuzhiyun 	ulong nframesout;
109*4882a593Smuzhiyun 	struct bio *bio;
110*4882a593Smuzhiyun 	struct bvec_iter iter;
111*4882a593Smuzhiyun 	struct request *rq;
112*4882a593Smuzhiyun };
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun enum frame_flags {
115*4882a593Smuzhiyun 	FFL_PROBE = 1,
116*4882a593Smuzhiyun };
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun struct frame {
119*4882a593Smuzhiyun 	struct list_head head;
120*4882a593Smuzhiyun 	u32 tag;
121*4882a593Smuzhiyun 	ktime_t sent;			/* high-res time packet was sent */
122*4882a593Smuzhiyun 	ulong waited;
123*4882a593Smuzhiyun 	ulong waited_total;
124*4882a593Smuzhiyun 	struct aoetgt *t;		/* parent target I belong to */
125*4882a593Smuzhiyun 	struct sk_buff *skb;		/* command skb freed on module exit */
126*4882a593Smuzhiyun 	struct sk_buff *r_skb;		/* response skb for async processing */
127*4882a593Smuzhiyun 	struct buf *buf;
128*4882a593Smuzhiyun 	struct bvec_iter iter;
129*4882a593Smuzhiyun 	char flags;
130*4882a593Smuzhiyun };
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun struct aoeif {
133*4882a593Smuzhiyun 	struct net_device *nd;
134*4882a593Smuzhiyun 	ulong lost;
135*4882a593Smuzhiyun 	int bcnt;
136*4882a593Smuzhiyun };
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun struct aoetgt {
139*4882a593Smuzhiyun 	unsigned char addr[6];
140*4882a593Smuzhiyun 	ushort nframes;		/* cap on frames to use */
141*4882a593Smuzhiyun 	struct aoedev *d;			/* parent device I belong to */
142*4882a593Smuzhiyun 	struct list_head ffree;			/* list of free frames */
143*4882a593Smuzhiyun 	struct aoeif ifs[NAOEIFS];
144*4882a593Smuzhiyun 	struct aoeif *ifp;	/* current aoeif in use */
145*4882a593Smuzhiyun 	ushort nout;		/* number of AoE commands outstanding */
146*4882a593Smuzhiyun 	ushort maxout;		/* current value for max outstanding */
147*4882a593Smuzhiyun 	ushort next_cwnd;	/* incr maxout after decrementing to zero */
148*4882a593Smuzhiyun 	ushort ssthresh;	/* slow start threshold */
149*4882a593Smuzhiyun 	ulong falloc;		/* number of allocated frames */
150*4882a593Smuzhiyun 	int taint;		/* how much we want to avoid this aoetgt */
151*4882a593Smuzhiyun 	int minbcnt;
152*4882a593Smuzhiyun 	int wpkts, rpkts;
153*4882a593Smuzhiyun 	char nout_probes;
154*4882a593Smuzhiyun };
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun struct aoedev {
157*4882a593Smuzhiyun 	struct aoedev *next;
158*4882a593Smuzhiyun 	ulong sysminor;
159*4882a593Smuzhiyun 	ulong aoemajor;
160*4882a593Smuzhiyun 	u32 rttavg;		/* scaled AoE round trip time average */
161*4882a593Smuzhiyun 	u32 rttdev;		/* scaled round trip time mean deviation */
162*4882a593Smuzhiyun 	u16 aoeminor;
163*4882a593Smuzhiyun 	u16 flags;
164*4882a593Smuzhiyun 	u16 nopen;		/* (bd_openers isn't available without sleeping) */
165*4882a593Smuzhiyun 	u16 fw_ver;		/* version of blade's firmware */
166*4882a593Smuzhiyun 	u16 lasttag;		/* last tag sent */
167*4882a593Smuzhiyun 	u16 useme;
168*4882a593Smuzhiyun 	ulong ref;
169*4882a593Smuzhiyun 	struct work_struct work;/* disk create work struct */
170*4882a593Smuzhiyun 	struct gendisk *gd;
171*4882a593Smuzhiyun 	struct dentry *debugfs;
172*4882a593Smuzhiyun 	struct request_queue *blkq;
173*4882a593Smuzhiyun 	struct list_head rq_list;
174*4882a593Smuzhiyun 	struct blk_mq_tag_set tag_set;
175*4882a593Smuzhiyun 	struct hd_geometry geo;
176*4882a593Smuzhiyun 	sector_t ssize;
177*4882a593Smuzhiyun 	struct timer_list timer;
178*4882a593Smuzhiyun 	spinlock_t lock;
179*4882a593Smuzhiyun 	struct sk_buff_head skbpool;
180*4882a593Smuzhiyun 	mempool_t *bufpool;	/* for deadlock-free Buf allocation */
181*4882a593Smuzhiyun 	struct {		/* pointers to work in progress */
182*4882a593Smuzhiyun 		struct buf *buf;
183*4882a593Smuzhiyun 		struct bio *nxbio;
184*4882a593Smuzhiyun 		struct request *rq;
185*4882a593Smuzhiyun 	} ip;
186*4882a593Smuzhiyun 	ulong maxbcnt;
187*4882a593Smuzhiyun 	struct list_head factive[NFACTIVE];	/* hash of active frames */
188*4882a593Smuzhiyun 	struct list_head rexmitq; /* deferred retransmissions */
189*4882a593Smuzhiyun 	struct aoetgt **targets;
190*4882a593Smuzhiyun 	ulong ntargets;		/* number of allocated aoetgt pointers */
191*4882a593Smuzhiyun 	struct aoetgt **tgt;	/* target in use when working */
192*4882a593Smuzhiyun 	ulong kicked;
193*4882a593Smuzhiyun 	char ident[512];
194*4882a593Smuzhiyun };
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun /* kthread tracking */
197*4882a593Smuzhiyun struct ktstate {
198*4882a593Smuzhiyun 	struct completion rendez;
199*4882a593Smuzhiyun 	struct task_struct *task;
200*4882a593Smuzhiyun 	wait_queue_head_t *waitq;
201*4882a593Smuzhiyun 	int (*fn) (int);
202*4882a593Smuzhiyun 	char name[12];
203*4882a593Smuzhiyun 	spinlock_t *lock;
204*4882a593Smuzhiyun 	int id;
205*4882a593Smuzhiyun 	int active;
206*4882a593Smuzhiyun };
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun int aoeblk_init(void);
209*4882a593Smuzhiyun void aoeblk_exit(void);
210*4882a593Smuzhiyun void aoeblk_gdalloc(void *);
211*4882a593Smuzhiyun void aoedisk_rm_debugfs(struct aoedev *d);
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun int aoechr_init(void);
214*4882a593Smuzhiyun void aoechr_exit(void);
215*4882a593Smuzhiyun void aoechr_error(char *);
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun void aoecmd_work(struct aoedev *d);
218*4882a593Smuzhiyun void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor);
219*4882a593Smuzhiyun struct sk_buff *aoecmd_ata_rsp(struct sk_buff *);
220*4882a593Smuzhiyun void aoecmd_cfg_rsp(struct sk_buff *);
221*4882a593Smuzhiyun void aoecmd_sleepwork(struct work_struct *);
222*4882a593Smuzhiyun void aoecmd_wreset(struct aoetgt *t);
223*4882a593Smuzhiyun void aoecmd_cleanslate(struct aoedev *);
224*4882a593Smuzhiyun void aoecmd_exit(void);
225*4882a593Smuzhiyun int aoecmd_init(void);
226*4882a593Smuzhiyun struct sk_buff *aoecmd_ata_id(struct aoedev *);
227*4882a593Smuzhiyun void aoe_freetframe(struct frame *);
228*4882a593Smuzhiyun void aoe_flush_iocq(void);
229*4882a593Smuzhiyun void aoe_flush_iocq_by_index(int);
230*4882a593Smuzhiyun void aoe_end_request(struct aoedev *, struct request *, int);
231*4882a593Smuzhiyun int aoe_ktstart(struct ktstate *k);
232*4882a593Smuzhiyun void aoe_ktstop(struct ktstate *k);
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun int aoedev_init(void);
235*4882a593Smuzhiyun void aoedev_exit(void);
236*4882a593Smuzhiyun struct aoedev *aoedev_by_aoeaddr(ulong maj, int min, int do_alloc);
237*4882a593Smuzhiyun void aoedev_downdev(struct aoedev *d);
238*4882a593Smuzhiyun int aoedev_flush(const char __user *str, size_t size);
239*4882a593Smuzhiyun void aoe_failbuf(struct aoedev *, struct buf *);
240*4882a593Smuzhiyun void aoedev_put(struct aoedev *);
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun int aoenet_init(void);
243*4882a593Smuzhiyun void aoenet_exit(void);
244*4882a593Smuzhiyun void aoenet_xmit(struct sk_buff_head *);
245*4882a593Smuzhiyun int is_aoe_netif(struct net_device *ifp);
246*4882a593Smuzhiyun int set_aoe_iflist(const char __user *str, size_t size);
247