2006-09-20 22:36:48 +04:00
/* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */
2006-02-07 19:37:36 +03:00
# define VERSION "22"
2005-04-17 02:20:36 +04:00
# define AOE_MAJOR 152
# define DEVICE_NAME "aoe"
2005-04-19 09:00:17 +04:00
/* set AOE_PARTITIONS to 1 to use whole-disks only
* default is 16 , which is 15 partitions plus the whole disk
*/
2005-04-17 02:20:36 +04:00
# ifndef AOE_PARTITIONS
2005-08-20 00:54:43 +04:00
# define AOE_PARTITIONS (16)
2005-04-17 02:20:36 +04:00
# endif
2005-04-19 09:00:17 +04:00
2005-08-20 00:54:43 +04:00
# define SYSMINOR(aoemajor, aoeminor) ((aoemajor) * NPERSHELF + (aoeminor))
# define AOEMAJOR(sysminor) ((sysminor) / NPERSHELF)
# define AOEMINOR(sysminor) ((sysminor) % NPERSHELF)
2005-04-17 02:20:36 +04:00
# define WHITESPACE " \t\v\f\n"
enum {
AOECMD_ATA ,
AOECMD_CFG ,
AOEFL_RSP = ( 1 < < 3 ) ,
AOEFL_ERR = ( 1 < < 2 ) ,
AOEAFL_EXT = ( 1 < < 6 ) ,
AOEAFL_DEV = ( 1 < < 4 ) ,
AOEAFL_ASYNC = ( 1 < < 1 ) ,
AOEAFL_WRITE = ( 1 < < 0 ) ,
AOECCMD_READ = 0 ,
AOECCMD_TEST ,
AOECCMD_PTEST ,
AOECCMD_SET ,
AOECCMD_FSET ,
AOE_HVER = 0x10 ,
} ;
struct aoe_hdr {
unsigned char dst [ 6 ] ;
unsigned char src [ 6 ] ;
2005-04-19 09:00:20 +04:00
__be16 type ;
2005-04-17 02:20:36 +04:00
unsigned char verfl ;
unsigned char err ;
2005-04-19 09:00:20 +04:00
__be16 major ;
2005-04-17 02:20:36 +04:00
unsigned char minor ;
unsigned char cmd ;
2005-04-19 09:00:20 +04:00
__be32 tag ;
2005-04-17 02:20:36 +04:00
} ;
struct aoe_atahdr {
unsigned char aflags ;
unsigned char errfeat ;
unsigned char scnt ;
unsigned char cmdstat ;
unsigned char lba0 ;
unsigned char lba1 ;
unsigned char lba2 ;
unsigned char lba3 ;
unsigned char lba4 ;
unsigned char lba5 ;
unsigned char res [ 2 ] ;
} ;
struct aoe_cfghdr {
2005-04-19 09:00:20 +04:00
__be16 bufcnt ;
__be16 fwver ;
2005-04-17 02:20:36 +04:00
unsigned char res ;
unsigned char aoeccmd ;
unsigned char cslen [ 2 ] ;
} ;
enum {
DEVFL_UP = 1 , /* device is installed in system and ready for AoE->ATA commands */
DEVFL_TKILL = ( 1 < < 1 ) , /* flag for timer to know when to kill self */
DEVFL_EXT = ( 1 < < 2 ) , /* device accepts lba48 commands */
DEVFL_CLOSEWAIT = ( 1 < < 3 ) , /* device is waiting for all closes to revalidate */
2006-01-19 21:46:19 +03:00
DEVFL_GDALLOC = ( 1 < < 4 ) , /* need to alloc gendisk */
DEVFL_PAUSE = ( 1 < < 5 ) ,
DEVFL_NEWSIZE = ( 1 < < 6 ) , /* need to update dev size in block layer */
2005-04-17 02:20:36 +04:00
BUFFL_FAIL = 1 ,
} ;
enum {
MAXATADATA = 1024 ,
2005-08-20 00:54:43 +04:00
NPERSHELF = 16 , /* number of slots per shelf address */
2005-04-17 02:20:36 +04:00
FREETAG = - 1 ,
MIN_BUFS = 8 ,
} ;
struct buf {
struct list_head bufs ;
2005-04-19 09:00:22 +04:00
ulong start_time ; /* for disk stats */
2005-04-17 02:20:36 +04:00
ulong flags ;
ulong nframesout ;
char * bufaddr ;
ulong resid ;
ulong bv_resid ;
sector_t sector ;
struct bio * bio ;
struct bio_vec * bv ;
} ;
struct frame {
int tag ;
ulong waited ;
struct buf * buf ;
char * bufaddr ;
int writedatalen ;
int ndata ;
/* largest possible */
unsigned char data [ sizeof ( struct aoe_hdr ) + sizeof ( struct aoe_atahdr ) ] ;
} ;
struct aoedev {
struct aoedev * next ;
unsigned char addr [ 6 ] ; /* remote mac addr */
ushort flags ;
ulong sysminor ;
ulong aoemajor ;
ulong aoeminor ;
ulong nopen ; /* (bd_openers isn't available without sleeping) */
ulong rttavg ; /* round trip average of requests/responses */
u16 fw_ver ; /* version of blade's firmware */
struct work_struct work ; /* disk create work struct */
struct gendisk * gd ;
request_queue_t blkq ;
struct hd_geometry geo ;
sector_t ssize ;
struct timer_list timer ;
spinlock_t lock ;
struct net_device * ifp ; /* interface ed is attached to */
2005-04-19 09:00:22 +04:00
struct sk_buff * sendq_hd ; /* packets needing to be sent, list head */
struct sk_buff * sendq_tl ;
2005-04-17 02:20:36 +04:00
mempool_t * bufpool ; /* for deadlock-free Buf allocation */
struct list_head bufq ; /* queue of bios to work on */
struct buf * inprocess ; /* the one we're currently working on */
ulong lasttag ; /* last tag sent */
ulong nframes ; /* number of frames below */
struct frame * frames ;
} ;
int aoeblk_init ( void ) ;
void aoeblk_exit ( void ) ;
void aoeblk_gdalloc ( void * ) ;
void aoedisk_rm_sysfs ( struct aoedev * d ) ;
int aoechr_init ( void ) ;
void aoechr_exit ( void ) ;
void aoechr_error ( char * ) ;
void aoecmd_work ( struct aoedev * d ) ;
2006-01-19 21:46:19 +03:00
void aoecmd_cfg ( ushort aoemajor , unsigned char aoeminor ) ;
2005-04-17 02:20:36 +04:00
void aoecmd_ata_rsp ( struct sk_buff * ) ;
void aoecmd_cfg_rsp ( struct sk_buff * ) ;
2006-01-19 21:46:19 +03:00
void aoecmd_sleepwork ( void * vp ) ;
2005-04-17 02:20:36 +04:00
int aoedev_init ( void ) ;
void aoedev_exit ( void ) ;
2005-04-19 09:00:18 +04:00
struct aoedev * aoedev_by_aoeaddr ( int maj , int min ) ;
2006-01-19 21:46:19 +03:00
struct aoedev * aoedev_by_sysminor_m ( ulong sysminor , ulong bufcnt ) ;
2005-04-17 02:20:36 +04:00
void aoedev_downdev ( struct aoedev * d ) ;
2006-01-19 21:46:19 +03:00
int aoedev_isbusy ( struct aoedev * d ) ;
2005-04-17 02:20:36 +04:00
int aoenet_init ( void ) ;
void aoenet_exit ( void ) ;
void aoenet_xmit ( struct sk_buff * ) ;
int is_aoe_netif ( struct net_device * ifp ) ;
int set_aoe_iflist ( const char __user * str , size_t size ) ;
u64 mac_addr ( char addr [ 6 ] ) ;