Handle multi-sector reads by splitting them into subcommands.
[people/xl0/gpxe.git] / src / include / gpxe / aoe.h
1 #ifndef _GPXE_AOE_H
2 #define _GPXE_AOE_H
3
4 /** @file
5  *
6  * AoE protocol
7  *
8  */
9
10 #include <stdint.h>
11 #include <gpxe/list.h>
12 #include <gpxe/if_ether.h>
13 #include <gpxe/ata.h>
14
15 /** An AoE ATA command */
16 struct aoecmd {
17         /** AoE command flags */
18         uint8_t aflags;
19         /** ATA error/feature register */
20         uint8_t err_feat;
21         /** ATA sector count register */
22         uint8_t count;
23         /** ATA command/status register */
24         uint8_t cmd_stat;
25         /** Logical block address, in little-endian order */
26         union {
27                 uint64_t u64;
28                 uint8_t bytes[6];
29         } lba;
30         /** Data payload */
31         uint8_t data[0];
32 } __attribute__ (( packed ));
33
34 #define AOE_FL_EXTENDED 0x40    /**< LBA48 extended addressing */
35 #define AOE_FL_DEV_HEAD 0x10    /**< Device/head flag */
36 #define AOE_FL_ASYNC    0x02    /**< Asynchronous write */
37 #define AOE_FL_WRITE    0x01    /**< Write command */
38
39 /** An AoE header */
40 struct aoehdr {
41         /** Protocol version number and flags */
42         uint8_t ver_flags;
43         /** Error code */
44         uint8_t error;
45         /** Major device number, in network byte order */
46         uint16_t major;
47         /** Minor device number */
48         uint8_t minor;
49         /** Command number */
50         uint8_t command;
51         /** Tag, in network byte order */
52         uint32_t tag;
53         /** Payload */
54         union {
55                 /** ATA command */
56                 struct aoecmd command[0];
57         } arg;
58 } __attribute__ (( packed ));
59
60 #define AOE_VERSION     0x10    /**< Version 1 */
61 #define AOE_VERSION_MASK 0xf0   /**< Version part of ver_flags field */
62
63 #define AOE_FL_RESPONSE 0x08    /**< Message is a response */
64 #define AOE_FL_ERROR    0x04    /**< Command generated an error */
65
66 #define AOE_MAJOR_BROADCAST 0xffff
67 #define AOE_MINOR_BROADCAST 0xff
68
69 #define AOE_CMD_ATA     0x00    /**< Issue ATA command */
70 #define AOE_CMD_CONFIG  0x01    /**< Query Config Information */
71
72 #define AOE_ERR_BAD_COMMAND     1 /**< Unrecognised command code */
73 #define AOE_ERR_BAD_PARAMETER   2 /**< Bad argument parameter */
74 #define AOE_ERR_UNAVAILABLE     3 /**< Device unavailable */
75 #define AOE_ERR_CONFIG_EXISTS   4 /**< Config string present */
76 #define AOE_ERR_BAD_VERSION     5 /**< Unsupported version */
77
78 /** An AoE session */
79 struct aoe_session {
80         /** List of all AoE sessions */
81         struct list_head list;
82
83         /** Network device */
84         struct net_device *netdev;
85         /** Major number */
86         uint16_t major;
87         /** Minor number */
88         uint8_t minor;
89         /** Target MAC address */
90         uint8_t target[ETH_ALEN];
91
92         /** Tag for current command */
93         uint32_t tag;
94         /** Current ATA command */
95         struct ata_command *command;
96         /** Status of the command */
97         int status;
98         /** Byte offset within command's data buffer */
99         unsigned int command_offset;
100 };
101
102 #define AOE_STATUS_ERR_MASK     0x0f /**< Error portion of status code */ 
103 #define AOE_STATUS_PENDING      0x80 /**< Command pending */
104 #define AOE_STATUS_UNDERRUN     0x40 /**< Buffer overrun */
105 #define AOE_STATUS_OVERRUN      0x20 /**< Buffer underrun */
106
107 /** Maximum number of sectors per packet */
108 #define AOE_MAX_COUNT 2
109
110 extern void aoe_open ( struct aoe_session *aoe );
111 extern void aoe_close ( struct aoe_session *aoe );
112 extern int aoe_issue ( struct aoe_session *aoe, struct ata_command *command );
113 extern int aoe_issue_split ( struct aoe_session *aoe,
114                              struct ata_command *command );
115
116 /** An AoE device */
117 struct aoe_device {
118         /** ATA device interface */
119         struct ata_device ata;
120         /** AoE protocol instance */
121         struct aoe_session aoe;
122 };
123
124 extern int init_aoedev ( struct aoe_device *aoedev );
125
126 #endif /* _GPXE_AOE_H */