1/* Copyright (c) 2007 Coraid, Inc.  See COPYING for GPL terms. */
2#define VERSION "47"
3#define AOE_MAJOR 152
4#define DEVICE_NAME "aoe"
5
6/* set AOE_PARTITIONS to 1 to use whole-disks only
7 * default is 16, which is 15 partitions plus the whole disk
8 */
9#ifndef AOE_PARTITIONS
10#define AOE_PARTITIONS (16)
11#endif
12
13#define SYSMINOR(aoemajor, aoeminor) ((aoemajor) * NPERSHELF + (aoeminor))
14#define AOEMAJOR(sysminor) ((sysminor) / NPERSHELF)
15#define AOEMINOR(sysminor) ((sysminor) % NPERSHELF)
16#define WHITESPACE " \t\v\f\n"
17
18enum {
19	AOECMD_ATA,
20	AOECMD_CFG,
21	AOECMD_VEND_MIN = 0xf0,
22
23	AOEFL_RSP = (1<<3),
24	AOEFL_ERR = (1<<2),
25
26	AOEAFL_EXT = (1<<6),
27	AOEAFL_DEV = (1<<4),
28	AOEAFL_ASYNC = (1<<1),
29	AOEAFL_WRITE = (1<<0),
30
31	AOECCMD_READ = 0,
32	AOECCMD_TEST,
33	AOECCMD_PTEST,
34	AOECCMD_SET,
35	AOECCMD_FSET,
36
37	AOE_HVER = 0x10,
38};
39
40struct aoe_hdr {
41	unsigned char dst[6];
42	unsigned char src[6];
43	__be16 type;
44	unsigned char verfl;
45	unsigned char err;
46	__be16 major;
47	unsigned char minor;
48	unsigned char cmd;
49	__be32 tag;
50};
51
52struct aoe_atahdr {
53	unsigned char aflags;
54	unsigned char errfeat;
55	unsigned char scnt;
56	unsigned char cmdstat;
57	unsigned char lba0;
58	unsigned char lba1;
59	unsigned char lba2;
60	unsigned char lba3;
61	unsigned char lba4;
62	unsigned char lba5;
63	unsigned char res[2];
64};
65
66struct aoe_cfghdr {
67	__be16 bufcnt;
68	__be16 fwver;
69	unsigned char scnt;
70	unsigned char aoeccmd;
71	unsigned char cslen[2];
72};
73
74enum {
75	DEVFL_UP = 1,	/* device is installed in system and ready for AoE->ATA commands */
76	DEVFL_TKILL = (1<<1),	/* flag for timer to know when to kill self */
77	DEVFL_EXT = (1<<2),	/* device accepts lba48 commands */
78	DEVFL_CLOSEWAIT = (1<<3), /* device is waiting for all closes to revalidate */
79	DEVFL_GDALLOC = (1<<4),	/* need to alloc gendisk */
80	DEVFL_KICKME = (1<<5),	/* slow polling network card catch */
81	DEVFL_NEWSIZE = (1<<6),	/* need to update dev size in block layer */
82
83	BUFFL_FAIL = 1,
84};
85
86enum {
87	DEFAULTBCNT = 2 * 512,	/* 2 sectors */
88	NPERSHELF = 16,		/* number of slots per shelf address */
89	FREETAG = -1,
90	MIN_BUFS = 16,
91	NTARGETS = 8,
92	NAOEIFS = 8,
93	NSKBPOOLMAX = 128,
94
95	TIMERTICK = HZ / 10,
96	MINTIMER = HZ >> 2,
97	MAXTIMER = HZ << 1,
98	HELPWAIT = 20,
99};
100
101struct buf {
102	struct list_head bufs;
103	ulong stime;	/* for disk stats */
104	ulong flags;
105	ulong nframesout;
106	ulong resid;
107	ulong bv_resid;
108	ulong bv_off;
109	sector_t sector;
110	struct bio *bio;
111	struct bio_vec *bv;
112};
113
114struct frame {
115	int tag;
116	ulong waited;
117	struct buf *buf;
118	char *bufaddr;
119	ulong bcnt;
120	sector_t lba;
121	struct sk_buff *skb;
122};
123
124struct aoeif {
125	struct net_device *nd;
126	unsigned char lost;
127	unsigned char lostjumbo;
128	ushort maxbcnt;
129};
130
131struct aoetgt {
132	unsigned char addr[6];
133	ushort nframes;
134	struct frame *frames;
135	struct aoeif ifs[NAOEIFS];
136	struct aoeif *ifp;	/* current aoeif in use */
137	ushort nout;
138	ushort maxout;
139	u16 lasttag;		/* last tag sent */
140	u16 useme;
141	ulong lastwadj;		/* last window adjustment */
142	int wpkts, rpkts;
143	int dataref;
144};
145
146struct aoedev {
147	struct aoedev *next;
148	ulong sysminor;
149	ulong aoemajor;
150	u16 aoeminor;
151	u16 flags;
152	u16 nopen;		/* (bd_openers isn't available without sleeping) */
153	u16 rttavg;		/* round trip average of requests/responses */
154	u16 mintimer;
155	u16 fw_ver;		/* version of blade's firmware */
156	struct work_struct work;/* disk create work struct */
157	struct gendisk *gd;
158	struct request_queue *blkq;
159	struct hd_geometry geo;
160	sector_t ssize;
161	struct timer_list timer;
162	spinlock_t lock;
163	struct sk_buff_head sendq;
164	struct sk_buff_head skbpool;
165	mempool_t *bufpool;	/* for deadlock-free Buf allocation */
166	struct list_head bufq;	/* queue of bios to work on */
167	struct buf *inprocess;	/* the one we're currently working on */
168	struct aoetgt *targets[NTARGETS];
169	struct aoetgt **tgt;	/* target in use when working */
170	struct aoetgt **htgt;	/* target needing rexmit assistance */
171};
172
173
174int aoeblk_init(void);
175void aoeblk_exit(void);
176void aoeblk_gdalloc(void *);
177void aoedisk_rm_sysfs(struct aoedev *d);
178
179int aoechr_init(void);
180void aoechr_exit(void);
181void aoechr_error(char *);
182
183void aoecmd_work(struct aoedev *d);
184void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor);
185void aoecmd_ata_rsp(struct sk_buff *);
186void aoecmd_cfg_rsp(struct sk_buff *);
187void aoecmd_sleepwork(struct work_struct *);
188void aoecmd_cleanslate(struct aoedev *);
189struct sk_buff *aoecmd_ata_id(struct aoedev *);
190
191int aoedev_init(void);
192void aoedev_exit(void);
193struct aoedev *aoedev_by_aoeaddr(int maj, int min);
194struct aoedev *aoedev_by_sysminor_m(ulong sysminor);
195void aoedev_downdev(struct aoedev *d);
196int aoedev_flush(const char __user *str, size_t size);
197
198int aoenet_init(void);
199void aoenet_exit(void);
200void aoenet_xmit(struct sk_buff_head *);
201int is_aoe_netif(struct net_device *ifp);
202int set_aoe_iflist(const char __user *str, size_t size);
203
204