iPXE
aoe.c File Reference

AoE protocol. More...

#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/list.h>
#include <ipxe/if_ether.h>
#include <ipxe/iobuf.h>
#include <ipxe/netdevice.h>
#include <ipxe/features.h>
#include <ipxe/interface.h>
#include <ipxe/xfer.h>
#include <ipxe/uri.h>
#include <ipxe/open.h>
#include <ipxe/ata.h>
#include <ipxe/device.h>
#include <ipxe/efi/efi_path.h>
#include <ipxe/aoe.h>

Go to the source code of this file.

Data Structures

struct  aoe_command
 An AoE command. More...
struct  aoe_command_type
 An AoE command type. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
 FEATURE (FEATURE_PROTOCOL, "AoE", DHCP_EB_FEATURE_AOE, 1)
static LIST_HEAD (aoe_devices)
 List of all AoE devices.
static LIST_HEAD (aoe_commands)
 List of active AoE commands.
static struct aoe_deviceaoedev_get (struct aoe_device *aoedev)
 Get reference to AoE device.
static void aoedev_put (struct aoe_device *aoedev)
 Drop reference to AoE device.
static struct aoe_commandaoecmd_get (struct aoe_command *aoecmd)
 Get reference to AoE command.
static void aoecmd_put (struct aoe_command *aoecmd)
 Drop reference to AoE command.
static const char * aoedev_name (struct aoe_device *aoedev)
 Name AoE device.
static void aoecmd_free (struct refcnt *refcnt)
 Free AoE command.
static void aoecmd_close (struct aoe_command *aoecmd, int rc)
 Close AoE command.
static int aoecmd_tx (struct aoe_command *aoecmd)
 Transmit AoE command request.
static int aoecmd_rx (struct aoe_command *aoecmd, struct io_buffer *iobuf, const void *ll_source)
 Receive AoE command response.
static void aoecmd_expired (struct retry_timer *timer, int fail)
 Handle AoE retry timer expiry.
static size_t aoecmd_ata_cmd_len (struct aoe_command *aoecmd)
 Calculate length of AoE ATA command IU.
static void aoecmd_ata_cmd (struct aoe_command *aoecmd, void *data, size_t len)
 Build AoE ATA command IU.
static int aoecmd_ata_rsp (struct aoe_command *aoecmd, const void *data, size_t len, const void *ll_source __unused)
 Handle AoE ATA response IU.
static size_t aoecmd_cfg_cmd_len (struct aoe_command *aoecmd __unused)
 Calculate length of AoE configuration command IU.
static void aoecmd_cfg_cmd (struct aoe_command *aoecmd, void *data, size_t len)
 Build AoE configuration command IU.
static int aoecmd_cfg_rsp (struct aoe_command *aoecmd, const void *data, size_t len, const void *ll_source)
 Handle AoE configuration response IU.
static struct aoe_commandaoecmd_find_tag (uint32_t tag)
 Identify AoE command by tag.
static int aoecmd_new_tag (void)
 Choose an AoE command tag.
static struct aoe_commandaoecmd_create (struct aoe_device *aoedev, struct aoe_command_type *type)
 Create AoE command.
static int aoedev_ata_command (struct aoe_device *aoedev, struct interface *parent, struct ata_cmd *command)
 Issue AoE ATA command.
static int aoedev_cfg_command (struct aoe_device *aoedev, struct interface *parent)
 Issue AoE configuration command.
static void aoedev_free (struct refcnt *refcnt)
 Free AoE device.
static void aoedev_close (struct aoe_device *aoedev, int rc)
 Close AoE device.
static size_t aoedev_window (struct aoe_device *aoedev)
 Check AoE device flow-control window.
static void aoedev_config_done (struct aoe_device *aoedev, int rc)
 Handle AoE device configuration completion.
static struct deviceaoedev_identify_device (struct aoe_device *aoedev)
 Identify device underlying AoE device.
static struct acpi_descriptoraoedev_describe (struct aoe_device *aoedev)
 Get AoE ACPI descriptor.
static int aoedev_open (struct interface *parent, struct net_device *netdev, unsigned int major, unsigned int minor)
 Open AoE device.
static int aoe_rx (struct io_buffer *iobuf, struct net_device *netdev __unused, const void *ll_dest __unused, const void *ll_source, unsigned int flags __unused)
 Process incoming AoE packets.
static int aoe_parse_uri (struct uri *uri, unsigned int *major, unsigned int *minor)
 Parse AoE URI.
static int aoe_open (struct interface *parent, struct uri *uri)
 Open AoE URI.
static int abft_complete (struct acpi_descriptor *desc __unused)
 Check if AoE boot firmware table descriptor is complete.
static int abft_install (int(*install)(struct acpi_header *acpi))
 Install AoE boot firmware table(s)

Variables

struct net_protocol aoe_protocol __net_protocol
 AoE protocol.
struct acpi_model abft_model __acpi_model
 aBFT model
static struct aoe_command_type aoecmd_ata
 AoE ATA command.
static struct aoe_command_type aoecmd_cfg
 AoE configuration command.
static struct interface_operation aoecmd_ata_op []
 AoE command ATA interface operations.
static struct interface_descriptor aoecmd_ata_desc
 AoE command ATA interface descriptor.
static struct interface_operation aoedev_ata_op []
 AoE device ATA interface operations.
static struct interface_descriptor aoedev_ata_desc
 AoE device ATA interface descriptor.
static struct interface_operation aoedev_config_op []
 AoE device configuration interface operations.
static struct interface_descriptor aoedev_config_desc
 AoE device configuration interface descriptor.
struct uri_opener aoe_uri_opener __uri_opener
 AoE URI opener.

Detailed Description

AoE protocol.

Definition in file aoe.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ FEATURE()

FEATURE ( FEATURE_PROTOCOL ,
"AoE" ,
DHCP_EB_FEATURE_AOE ,
1  )

◆ LIST_HEAD() [1/2]

LIST_HEAD ( aoe_devices )
static

List of all AoE devices.

◆ LIST_HEAD() [2/2]

LIST_HEAD ( aoe_commands )
static

List of active AoE commands.

◆ aoedev_get()

struct aoe_device * aoedev_get ( struct aoe_device * aoedev)
inlinestatic

Get reference to AoE device.

Parameters
aoedevAoE device
Return values
aoedevAoE device

Definition at line 132 of file aoe.c.

132 {
133 ref_get ( &aoedev->refcnt );
134 return aoedev;
135}
#define ref_get(refcnt)
Get additional reference to object.
Definition refcnt.h:93
struct refcnt refcnt
Reference counter.
Definition aoe.h:118

References ref_get, and aoe_device::refcnt.

Referenced by aoecmd_create().

◆ aoedev_put()

void aoedev_put ( struct aoe_device * aoedev)
inlinestatic

Drop reference to AoE device.

Parameters
aoedevAoE device

Definition at line 143 of file aoe.c.

143 {
144 ref_put ( &aoedev->refcnt );
145}
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107

References ref_put, and aoe_device::refcnt.

Referenced by aoecmd_free().

◆ aoecmd_get()

struct aoe_command * aoecmd_get ( struct aoe_command * aoecmd)
inlinestatic

Get reference to AoE command.

Parameters
aoecmdAoE command
Return values
aoecmdAoE command

Definition at line 154 of file aoe.c.

154 {
155 ref_get ( &aoecmd->refcnt );
156 return aoecmd;
157}
An AoE command.
Definition aoe.h:63

References ref_get.

Referenced by aoe_rx(), and aoedev_close().

◆ aoecmd_put()

void aoecmd_put ( struct aoe_command * aoecmd)
inlinestatic

Drop reference to AoE command.

Parameters
aoecmdAoE command

Definition at line 165 of file aoe.c.

165 {
166 ref_put ( &aoecmd->refcnt );
167}

References ref_put.

Referenced by aoe_rx(), aoecmd_close(), and aoedev_close().

◆ aoedev_name()

const char * aoedev_name ( struct aoe_device * aoedev)
static

Name AoE device.

Parameters
aoedevAoE device
Return values
nameAoE device name

Definition at line 175 of file aoe.c.

175 {
176 static char buf[16];
177
178 snprintf ( buf, sizeof ( buf ), "%s/e%d.%d", aoedev->netdev->name,
179 aoedev->major, aoedev->minor );
180 return buf;
181}
uint8_t minor
Minor number.
Definition aoe.h:128
struct net_device * netdev
Network device.
Definition aoe.h:121
uint16_t major
Major number.
Definition aoe.h:126
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition netdevice.h:363
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

References aoe_command::aoedev, aoe_device::major, aoe_device::minor, net_device::name, aoe_device::netdev, and snprintf().

Referenced by abft_install(), aoecmd_ata_cmd(), aoecmd_ata_rsp(), aoecmd_cfg_cmd(), aoecmd_cfg_rsp(), aoecmd_rx(), aoecmd_tx(), aoedev_ata_command(), and aoedev_open().

◆ aoecmd_free()

void aoecmd_free ( struct refcnt * refcnt)
static

Free AoE command.

Parameters
refcntReference counter

Definition at line 188 of file aoe.c.

188 {
189 struct aoe_command *aoecmd =
191
192 assert ( ! timer_running ( &aoecmd->timer ) );
193 assert ( list_empty ( &aoecmd->list ) );
194
195 aoedev_put ( aoecmd->aoedev );
196 free ( aoecmd );
197}
static void aoedev_put(struct aoe_device *aoedev)
Drop reference to AoE device.
Definition aoe.c:143
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define list_empty(list)
Test whether a list is empty.
Definition list.h:137
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
An AoE command.
Definition aoe.c:73
A reference counter.
Definition refcnt.h:27

References aoedev_put(), assert, container_of, free, and list_empty.

Referenced by aoecmd_create().

◆ aoecmd_close()

void aoecmd_close ( struct aoe_command * aoecmd,
int rc )
static

Close AoE command.

Parameters
aoecmdAoE command
rcReason for close

Definition at line 205 of file aoe.c.

205 {
206 struct aoe_device *aoedev = aoecmd->aoedev;
207
208 /* Stop timer */
209 stop_timer ( &aoecmd->timer );
210
211 /* Preserve the timeout value for subsequent commands */
212 aoedev->timeout = aoecmd->timer.timeout;
213
214 /* Remove from list of commands */
215 if ( ! list_empty ( &aoecmd->list ) ) {
216 list_del ( &aoecmd->list );
217 INIT_LIST_HEAD ( &aoecmd->list );
218 aoecmd_put ( aoecmd );
219 }
220
221 /* Shut down interfaces */
222 intf_shutdown ( &aoecmd->ata, rc );
223}
static void aoecmd_put(struct aoe_command *aoecmd)
Drop reference to AoE command.
Definition aoe.c:165
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition retry.c:118
An AoE device.
Definition aoe.h:116
unsigned long timeout
Saved timeout value.
Definition aoe.h:133
struct aoeata ata
ATA command.
Definition aoe.h:67

References aoecmd_put(), aoecmd::ata, INIT_LIST_HEAD, intf_shutdown(), list_del, list_empty, rc, stop_timer(), and aoe_device::timeout.

Referenced by aoecmd_expired(), aoecmd_rx(), and aoedev_close().

◆ aoecmd_tx()

int aoecmd_tx ( struct aoe_command * aoecmd)
static

Transmit AoE command request.

Parameters
aoecmdAoE command
Return values
rcReturn status code

Definition at line 231 of file aoe.c.

231 {
232 struct aoe_device *aoedev = aoecmd->aoedev;
233 struct net_device *netdev = aoedev->netdev;
234 struct io_buffer *iobuf;
235 struct aoehdr *aoehdr;
236 size_t cmd_len;
237 int rc;
238
239 /* Sanity check */
240 assert ( netdev != NULL );
241
242 /* If we are transmitting anything that requires a response,
243 * start the retransmission timer. Do this before attempting
244 * to allocate the I/O buffer, in case allocation itself
245 * fails.
246 */
247 start_timer ( &aoecmd->timer );
248
249 /* Create outgoing I/O buffer */
250 cmd_len = aoecmd->type->cmd_len ( aoecmd );
251 iobuf = alloc_iob ( MAX_LL_HEADER_LEN + cmd_len );
252 if ( ! iobuf )
253 return -ENOMEM;
255 aoehdr = iob_put ( iobuf, cmd_len );
256
257 /* Fill AoE header */
258 memset ( aoehdr, 0, sizeof ( *aoehdr ) );
260 aoehdr->major = htons ( aoedev->major );
261 aoehdr->minor = aoedev->minor;
262 aoehdr->tag = htonl ( aoecmd->tag );
263 aoecmd->type->cmd ( aoecmd, iobuf->data, iob_len ( iobuf ) );
264
265 /* Send packet */
266 if ( ( rc = net_tx ( iobuf, netdev, &aoe_protocol, aoedev->target,
267 netdev->ll_addr ) ) != 0 ) {
268 DBGC ( aoedev, "AoE %s/%08x could not transmit: %s\n",
269 aoedev_name ( aoedev ), aoecmd->tag,
270 strerror ( rc ) );
271 return rc;
272 }
273
274 return 0;
275}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
static const char * aoedev_name(struct aoe_device *aoedev)
Name AoE device.
Definition aoe.c:175
#define AOE_VERSION
Version 1.
Definition aoe.h:88
static struct net_device * netdev
Definition gdbudp.c:53
#define DBGC(...)
Definition compiler.h:505
#define ENOMEM
Not enough space.
Definition errno.h:535
#define htonl(value)
Definition byteswap.h:134
#define htons(value)
Definition byteswap.h:136
void * memset(void *dest, int character, size_t len) __nonnull
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
#define iob_put(iobuf, len)
Definition iobuf.h:125
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define iob_reserve(iobuf, len)
Definition iobuf.h:72
int net_tx(struct io_buffer *iobuf, struct net_device *netdev, struct net_protocol *net_protocol, const void *ll_dest, const void *ll_source)
Transmit network-layer packet.
Definition netdevice.c:1074
#define MAX_LL_HEADER_LEN
Maximum length of a link-layer header.
Definition netdevice.h:46
void start_timer(struct retry_timer *timer)
Start timer.
Definition retry.c:94
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
uint8_t target[MAX_LL_ADDR_LEN]
Target MAC address.
Definition aoe.h:130
An AoE header.
Definition aoe.h:71
uint16_t major
Major device number, in network byte order.
Definition aoe.h:77
uint32_t tag
Tag, in network byte order.
Definition aoe.h:83
uint8_t ver_flags
Protocol version number and flags.
Definition aoe.h:73
uint8_t minor
Minor device number.
Definition aoe.h:79
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
A network device.
Definition netdevice.h:353

References alloc_iob(), AOE_VERSION, aoedev_name(), assert, io_buffer::data, DBGC, ENOMEM, htonl, htons, iob_len(), iob_put, iob_reserve, aoe_device::major, aoehdr::major, MAX_LL_HEADER_LEN, memset(), aoe_device::minor, aoehdr::minor, net_tx(), aoe_device::netdev, netdev, NULL, rc, start_timer(), strerror(), aoehdr::tag, aoe_device::target, and aoehdr::ver_flags.

Referenced by aoecmd_expired(), aoedev_ata_command(), and aoedev_cfg_command().

◆ aoecmd_rx()

int aoecmd_rx ( struct aoe_command * aoecmd,
struct io_buffer * iobuf,
const void * ll_source )
static

Receive AoE command response.

Parameters
aoecmdAoE command
iobufI/O buffer
ll_sourceLink-layer source address
Return values
rcReturn status code

Definition at line 285 of file aoe.c.

286 {
287 struct aoe_device *aoedev = aoecmd->aoedev;
288 struct aoehdr *aoehdr = iobuf->data;
289 int rc;
290
291 /* Sanity check */
292 if ( iob_len ( iobuf ) < sizeof ( *aoehdr ) ) {
293 DBGC ( aoedev, "AoE %s/%08x received underlength response "
294 "(%zd bytes)\n", aoedev_name ( aoedev ),
295 aoecmd->tag, iob_len ( iobuf ) );
296 rc = -EINVAL;
297 goto done;
298 }
299 if ( ( ntohs ( aoehdr->major ) != aoedev->major ) ||
300 ( aoehdr->minor != aoedev->minor ) ) {
301 DBGC ( aoedev, "AoE %s/%08x received response for incorrect "
302 "device e%d.%d\n", aoedev_name ( aoedev ), aoecmd->tag,
303 ntohs ( aoehdr->major ), aoehdr->minor );
304 rc = -EINVAL;
305 goto done;
306 }
307
308 /* Catch command failures */
309 if ( aoehdr->ver_flags & AOE_FL_ERROR ) {
310 DBGC ( aoedev, "AoE %s/%08x terminated in error\n",
311 aoedev_name ( aoedev ), aoecmd->tag );
312 aoecmd_close ( aoecmd, -EIO );
313 rc = -EIO;
314 goto done;
315 }
316
317 /* Hand off to command completion handler */
318 if ( ( rc = aoecmd->type->rsp ( aoecmd, iobuf->data, iob_len ( iobuf ),
319 ll_source ) ) != 0 )
320 goto done;
321
322 done:
323 /* Free I/O buffer */
324 free_iob ( iobuf );
325
326 /* Terminate command */
328
329 return rc;
330}
static void aoecmd_close(struct aoe_command *aoecmd, int rc)
Close AoE command.
Definition aoe.c:205
#define AOE_FL_ERROR
Command generated an error.
Definition aoe.h:92
struct bofm_section_header done
Definition bofm_test.c:46
#define EINVAL
Invalid argument.
Definition errno.h:429
#define EIO
Input/output error.
Definition errno.h:434
#define ntohs(value)
Definition byteswap.h:137
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153

References AOE_FL_ERROR, aoecmd_close(), aoedev_name(), io_buffer::data, DBGC, done, EINVAL, EIO, free_iob(), iob_len(), aoe_device::major, aoehdr::major, aoe_device::minor, aoehdr::minor, ntohs, rc, and aoehdr::ver_flags.

Referenced by aoe_rx().

◆ aoecmd_expired()

void aoecmd_expired ( struct retry_timer * timer,
int fail )
static

Handle AoE retry timer expiry.

Parameters
timerAoE retry timer
failFailure indicator

Definition at line 338 of file aoe.c.

338 {
339 struct aoe_command *aoecmd =
340 container_of ( timer, struct aoe_command, timer );
341
342 if ( fail ) {
344 } else {
345 aoecmd_tx ( aoecmd );
346 }
347}
static int aoecmd_tx(struct aoe_command *aoecmd)
Transmit AoE command request.
Definition aoe.c:231
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
A timer.
Definition timer.h:29

References aoecmd_close(), aoecmd_tx(), container_of, and ETIMEDOUT.

Referenced by aoecmd_create().

◆ aoecmd_ata_cmd_len()

size_t aoecmd_ata_cmd_len ( struct aoe_command * aoecmd)
static

Calculate length of AoE ATA command IU.

Parameters
aoecmdAoE command
Return values
lenLength of command IU

Definition at line 355 of file aoe.c.

355 {
356 struct ata_cmd *command = &aoecmd->command;
357
358 return ( sizeof ( struct aoehdr ) + sizeof ( struct aoeata ) +
359 command->data_out_len );
360}
An AoE ATA command.
Definition aoe.h:39
An ATA command information unit.
Definition ata.h:168
A command-line command.
Definition command.h:10

◆ aoecmd_ata_cmd()

void aoecmd_ata_cmd ( struct aoe_command * aoecmd,
void * data,
size_t len )
static

Build AoE ATA command IU.

Parameters
aoecmdAoE command
dataCommand IU
lenLength of command IU

Definition at line 369 of file aoe.c.

370 {
371 struct aoe_device *aoedev = aoecmd->aoedev;
372 struct ata_cmd *command = &aoecmd->command;
373 struct aoehdr *aoehdr = data;
374 struct aoeata *aoeata = &aoehdr->payload[0].ata;
375
376 /* Sanity check */
377 static_assert ( AOE_FL_DEV_HEAD == ATA_DEV_SLAVE );
378 assert ( len == ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) +
379 command->data_out_len ) );
380
381 /* Build IU */
383 memset ( aoeata, 0, sizeof ( *aoeata ) );
384 aoeata->aflags = ( ( command->cb.lba48 ? AOE_FL_EXTENDED : 0 ) |
385 ( command->cb.device & ATA_DEV_SLAVE ) |
386 ( command->data_out_len ? AOE_FL_WRITE : 0 ) );
387 aoeata->err_feat = command->cb.err_feat.bytes.cur;
388 aoeata->count = command->cb.count.native;
389 aoeata->cmd_stat = command->cb.cmd_stat;
390 aoeata->lba.u64 = cpu_to_le64 ( command->cb.lba.native );
391 if ( ! command->cb.lba48 )
392 aoeata->lba.bytes[3] |=
393 ( command->cb.device & ATA_DEV_MASK );
394 memcpy ( aoeata->data, command->data_out, command->data_out_len );
395
396 DBGC2 ( aoedev, "AoE %s/%08x ATA cmd %02x:%02x:%02x:%02x:%08llx",
397 aoedev_name ( aoedev ), aoecmd->tag, aoeata->aflags,
399 aoeata->lba.u64 );
400 if ( command->data_out_len )
401 DBGC2 ( aoedev, " out %04zx", command->data_out_len );
402 if ( command->data_in_len )
403 DBGC2 ( aoedev, " in %04zx", command->data_in_len );
404 DBGC2 ( aoedev, "\n" );
405}
#define AOE_FL_WRITE
Write command.
Definition aoe.h:60
#define AOE_FL_DEV_HEAD
Device/head flag.
Definition aoe.h:58
#define AOE_CMD_ATA
Issue ATA command.
Definition aoe.h:97
#define AOE_FL_EXTENDED
LBA48 extended addressing.
Definition aoe.h:57
#define ATA_DEV_SLAVE
Slave ("device 1") flag in the ATA device register.
Definition ata.h:117
#define ATA_DEV_MASK
Mask of non-LBA portion of device register.
Definition ata.h:123
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define DBGC2(...)
Definition compiler.h:522
#define cpu_to_le64(value)
Definition byteswap.h:109
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint8_t cmd_stat
ATA command/status register.
Definition aoe.h:47
uint8_t bytes[6]
Definition aoe.h:51
uint8_t data[0]
Data payload.
Definition aoe.h:54
uint8_t count
ATA sector count register.
Definition aoe.h:45
uint8_t aflags
AoE command flags.
Definition aoe.h:41
uint64_t u64
Definition aoe.h:50
uint8_t err_feat
ATA error/feature register.
Definition aoe.h:43
union aoeata::@075054160020220033235346100236214147067212322041 lba
Logical block address, in little-endian order.
uint8_t command
Command number.
Definition aoe.h:81
union aoecmd payload[0]
Payload.
Definition aoe.h:85

References aoeata::aflags, AOE_CMD_ATA, AOE_FL_DEV_HEAD, AOE_FL_EXTENDED, AOE_FL_WRITE, aoedev_name(), assert, aoecmd::ata, ATA_DEV_MASK, ATA_DEV_SLAVE, aoeata::bytes, aoeata::cmd_stat, aoehdr::command, aoeata::count, cpu_to_le64, aoeata::data, data, DBGC2, aoeata::err_feat, aoeata::lba, len, memcpy(), memset(), aoehdr::payload, and aoeata::u64.

◆ aoecmd_ata_rsp()

int aoecmd_ata_rsp ( struct aoe_command * aoecmd,
const void * data,
size_t len,
const void *ll_source __unused )
static

Handle AoE ATA response IU.

Parameters
aoecmdAoE command
dataResponse IU
lenLength of response IU
ll_sourceLink-layer source address
Return values
rcReturn status code

Definition at line 416 of file aoe.c.

417 {
418 struct aoe_device *aoedev = aoecmd->aoedev;
419 struct ata_cmd *command = &aoecmd->command;
420 const struct aoehdr *aoehdr = data;
421 const struct aoeata *aoeata = &aoehdr->payload[0].ata;
422 size_t data_len;
423
424 /* Sanity check */
425 if ( len < ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) ) ) {
426 DBGC ( aoedev, "AoE %s/%08x received underlength ATA response "
427 "(%zd bytes)\n", aoedev_name ( aoedev ),
428 aoecmd->tag, len );
429 return -EINVAL;
430 }
431 data_len = ( len - ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) ) );
432 DBGC2 ( aoedev, "AoE %s/%08x ATA rsp %02x in %04zx\n",
433 aoedev_name ( aoedev ), aoecmd->tag, aoeata->cmd_stat,
434 data_len );
435
436 /* Check for command failure */
437 if ( aoeata->cmd_stat & ATA_STAT_ERR ) {
438 DBGC ( aoedev, "AoE %s/%08x status %02x\n",
439 aoedev_name ( aoedev ), aoecmd->tag, aoeata->cmd_stat );
440 return -EIO;
441 }
442
443 /* Check data-in length is sufficient. (There may be trailing
444 * garbage due to Ethernet minimum-frame-size padding.)
445 */
446 if ( data_len < command->data_in_len ) {
447 DBGC ( aoedev, "AoE %s/%08x data-in underrun (received %zd, "
448 "expected %zd)\n", aoedev_name ( aoedev ), aoecmd->tag,
449 data_len, command->data_in_len );
450 return -ERANGE;
451 }
452
453 /* Copy out data payload */
454 memcpy ( command->data_in, aoeata->data, command->data_in_len );
455
456 return 0;
457}
#define ATA_STAT_ERR
Command completed in error.
Definition ata.h:141
#define ERANGE
Result too large.
Definition errno.h:640
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition ucode.h:15

References __unused, aoedev_name(), aoecmd::ata, ATA_STAT_ERR, aoeata::cmd_stat, aoeata::data, data, data_len, DBGC, DBGC2, EINVAL, EIO, ERANGE, len, memcpy(), and aoehdr::payload.

◆ aoecmd_cfg_cmd_len()

size_t aoecmd_cfg_cmd_len ( struct aoe_command *aoecmd __unused)
static

Calculate length of AoE configuration command IU.

Parameters
aoecmdAoE command
Return values
lenLength of command IU

Definition at line 472 of file aoe.c.

472 {
473 return ( sizeof ( struct aoehdr ) + sizeof ( struct aoecfg ) );
474}
An AoE config command.
Definition aoe.h:23

References __unused.

◆ aoecmd_cfg_cmd()

void aoecmd_cfg_cmd ( struct aoe_command * aoecmd,
void * data,
size_t len )
static

Build AoE configuration command IU.

Parameters
aoecmdAoE command
dataCommand IU
lenLength of command IU

Definition at line 483 of file aoe.c.

484 {
485 struct aoe_device *aoedev = aoecmd->aoedev;
486 struct aoehdr *aoehdr = data;
487 struct aoecfg *aoecfg = &aoehdr->payload[0].cfg;
488
489 /* Sanity check */
490 assert ( len == ( sizeof ( *aoehdr ) + sizeof ( *aoecfg ) ) );
491
492 /* Build IU */
494 memset ( aoecfg, 0, sizeof ( *aoecfg ) );
495
496 DBGC ( aoedev, "AoE %s/%08x CONFIG cmd\n",
497 aoedev_name ( aoedev ), aoecmd->tag );
498}
#define AOE_CMD_CONFIG
Query Config Information.
Definition aoe.h:98
struct aoecfg cfg
Config command.
Definition aoe.h:65

References AOE_CMD_CONFIG, aoedev_name(), assert, aoecmd::cfg, aoehdr::command, data, DBGC, len, memset(), and aoehdr::payload.

◆ aoecmd_cfg_rsp()

int aoecmd_cfg_rsp ( struct aoe_command * aoecmd,
const void * data,
size_t len,
const void * ll_source )
static

Handle AoE configuration response IU.

Parameters
aoecmdAoE command
dataResponse IU
lenLength of response IU
ll_sourceLink-layer source address
Return values
rcReturn status code

Definition at line 509 of file aoe.c.

510 {
511 struct aoe_device *aoedev = aoecmd->aoedev;
512 struct ll_protocol *ll_protocol = aoedev->netdev->ll_protocol;
513 const struct aoehdr *aoehdr = data;
514 const struct aoecfg *aoecfg = &aoehdr->payload[0].cfg;
515
516 /* Sanity check */
517 if ( len < ( sizeof ( *aoehdr ) + sizeof ( *aoecfg ) ) ) {
518 DBGC ( aoedev, "AoE %s/%08x received underlength "
519 "configuration response (%zd bytes)\n",
520 aoedev_name ( aoedev ), aoecmd->tag, len );
521 return -EINVAL;
522 }
523 DBGC ( aoedev, "AoE %s/%08x CONFIG rsp buf %04x fw %04x scnt %02x\n",
524 aoedev_name ( aoedev ), aoecmd->tag, ntohs ( aoecfg->bufcnt ),
525 aoecfg->fwver, aoecfg->scnt );
526
527 /* Record target MAC address */
528 memcpy ( aoedev->target, ll_source, ll_protocol->ll_addr_len );
529 DBGC ( aoedev, "AoE %s has MAC address %s\n",
530 aoedev_name ( aoedev ), ll_protocol->ntoa ( aoedev->target ) );
531
532 return 0;
533}
uint8_t scnt
ATA target sector count.
Definition aoe.h:29
uint16_t bufcnt
AoE queue depth.
Definition aoe.h:25
uint16_t fwver
ATA target firmware version.
Definition aoe.h:27
A link-layer protocol.
Definition netdevice.h:115
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition netdevice.h:164
uint8_t ll_addr_len
Link-layer address length.
Definition netdevice.h:199
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition netdevice.h:373

References aoedev_name(), aoecfg::bufcnt, aoecmd::cfg, data, DBGC, EINVAL, aoecfg::fwver, len, ll_protocol::ll_addr_len, net_device::ll_protocol, memcpy(), aoe_device::netdev, ll_protocol::ntoa, ntohs, aoehdr::payload, aoecfg::scnt, and aoe_device::target.

◆ aoecmd_find_tag()

struct aoe_command * aoecmd_find_tag ( uint32_t tag)
static

Identify AoE command by tag.

Parameters
tagCommand tag
Return values
aoecmdAoE command, or NULL

Definition at line 557 of file aoe.c.

557 {
558 struct aoe_command *aoecmd;
559
560 list_for_each_entry ( aoecmd, &aoe_commands, list ) {
561 if ( aoecmd->tag == tag )
562 return aoecmd;
563 }
564 return NULL;
565}
uint64_t tag
Identity tag.
Definition edd.h:1
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
struct list_head list
List of active commands.
Definition aoe.c:79

References aoe_command::list, list_for_each_entry, NULL, and tag.

Referenced by aoe_rx(), and aoecmd_new_tag().

◆ aoecmd_new_tag()

int aoecmd_new_tag ( void )
static

Choose an AoE command tag.

Return values
tagNew tag, or negative error

Definition at line 572 of file aoe.c.

572 {
573 static uint16_t tag_idx;
574 unsigned int i;
575
576 for ( i = 0 ; i < 65536 ; i++ ) {
577 tag_idx++;
578 if ( aoecmd_find_tag ( tag_idx ) == NULL )
579 return ( AOE_TAG_MAGIC | tag_idx );
580 }
581 return -EADDRINUSE;
582}
static struct aoe_command * aoecmd_find_tag(uint32_t tag)
Identify AoE command by tag.
Definition aoe.c:557
#define AOE_TAG_MAGIC
AoE tag magic marker.
Definition aoe.h:110
unsigned short uint16_t
Definition stdint.h:11
#define EADDRINUSE
Address already in use.
Definition errno.h:304

References AOE_TAG_MAGIC, aoecmd_find_tag(), EADDRINUSE, and NULL.

Referenced by aoecmd_create().

◆ aoecmd_create()

struct aoe_command * aoecmd_create ( struct aoe_device * aoedev,
struct aoe_command_type * type )
static

Create AoE command.

Parameters
aoedevAoE device
typeAoE command type
Return values
aoecmdAoE command

Definition at line 591 of file aoe.c.

592 {
593 struct aoe_command *aoecmd;
594 int tag;
595
596 /* Allocate command tag */
598 if ( tag < 0 )
599 return NULL;
600
601 /* Allocate and initialise structure */
602 aoecmd = zalloc ( sizeof ( *aoecmd ) );
603 if ( ! aoecmd )
604 return NULL;
605 ref_init ( &aoecmd->refcnt, aoecmd_free );
606 list_add ( &aoecmd->list, &aoe_commands );
607 intf_init ( &aoecmd->ata, &aoecmd_ata_desc, &aoecmd->refcnt );
608 timer_init ( &aoecmd->timer, aoecmd_expired, &aoecmd->refcnt );
609 aoecmd->aoedev = aoedev_get ( aoedev );
610 aoecmd->type = type;
611 aoecmd->tag = tag;
612
613 /* Preserve timeout from last completed command */
614 aoecmd->timer.timeout = aoedev->timeout;
615
616 /* Return already mortalised. (Reference is held by command list.) */
617 return aoecmd;
618}
static void aoecmd_free(struct refcnt *refcnt)
Free AoE command.
Definition aoe.c:188
static struct interface_descriptor aoecmd_ata_desc
AoE command ATA interface descriptor.
Definition aoe.c:548
static void aoecmd_expired(struct retry_timer *timer, int fail)
Handle AoE retry timer expiry.
Definition aoe.c:338
static struct aoe_device * aoedev_get(struct aoe_device *aoedev)
Get reference to AoE device.
Definition aoe.c:132
static int aoecmd_new_tag(void)
Choose an AoE command tag.
Definition aoe.c:572
uint32_t type
Operating system type.
Definition ena.h:1
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
struct aoe_device * aoedev
AOE device.
Definition aoe.c:77

References aoecmd_ata_desc, aoecmd_expired(), aoecmd_free(), aoecmd_new_tag(), aoe_command::aoedev, aoedev_get(), aoecmd::ata, intf_init(), list_add, NULL, ref_init, tag, aoe_device::timeout, type, and zalloc().

Referenced by aoedev_ata_command(), and aoedev_cfg_command().

◆ aoedev_ata_command()

int aoedev_ata_command ( struct aoe_device * aoedev,
struct interface * parent,
struct ata_cmd * command )
static

Issue AoE ATA command.

Parameters
aoedevAoE device
parentParent interface
commandATA command
Return values
tagCommand tag, or negative error

Definition at line 628 of file aoe.c.

630 {
631 struct net_device *netdev = aoedev->netdev;
632 struct aoe_command *aoecmd;
633
634 /* Fail immediately if net device is closed */
635 if ( ! netdev_is_open ( netdev ) ) {
636 DBGC ( aoedev, "AoE %s cannot issue command while net device "
637 "is closed\n", aoedev_name ( aoedev ) );
638 return -EWOULDBLOCK;
639 }
640
641 /* Create command */
643 if ( ! aoecmd )
644 return -ENOMEM;
645 memcpy ( &aoecmd->command, command, sizeof ( aoecmd->command ) );
646
647 /* Attempt to send command. Allow failures to be handled by
648 * the retry timer.
649 */
650 aoecmd_tx ( aoecmd );
651
652 /* Attach to parent interface, leave reference with command
653 * list, and return.
654 */
655 intf_plug_plug ( &aoecmd->ata, parent );
656 return aoecmd->tag;
657}
static struct aoe_command_type aoecmd_ata
AoE ATA command.
Definition aoe.c:460
static struct aoe_command * aoecmd_create(struct aoe_device *aoedev, struct aoe_command_type *type)
Create AoE command.
Definition aoe.c:591
#define EWOULDBLOCK
Operation would block.
Definition errno.h:680
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:662

References aoecmd_ata, aoecmd_create(), aoecmd_tx(), aoe_command::aoedev, aoedev_name(), aoecmd::ata, DBGC, ENOMEM, EWOULDBLOCK, intf_plug_plug(), memcpy(), aoe_device::netdev, netdev, and netdev_is_open().

◆ aoedev_cfg_command()

int aoedev_cfg_command ( struct aoe_device * aoedev,
struct interface * parent )
static

Issue AoE configuration command.

Parameters
aoedevAoE device
parentParent interface
Return values
tagCommand tag, or negative error

Definition at line 666 of file aoe.c.

667 {
668 struct aoe_command *aoecmd;
669
670 /* Create command */
672 if ( ! aoecmd )
673 return -ENOMEM;
674
675 /* Attempt to send command. Allow failures to be handled by
676 * the retry timer.
677 */
678 aoecmd_tx ( aoecmd );
679
680 /* Attach to parent interface, leave reference with command
681 * list, and return.
682 */
683 intf_plug_plug ( &aoecmd->ata, parent );
684 return aoecmd->tag;
685}
static struct aoe_command_type aoecmd_cfg
AoE configuration command.
Definition aoe.c:536

References aoecmd_cfg, aoecmd_create(), aoecmd_tx(), aoe_command::aoedev, aoecmd::ata, ENOMEM, and intf_plug_plug().

Referenced by aoedev_open().

◆ aoedev_free()

void aoedev_free ( struct refcnt * refcnt)
static

Free AoE device.

Parameters
refcntReference count

Definition at line 692 of file aoe.c.

692 {
693 struct aoe_device *aoedev =
695
696 netdev_put ( aoedev->netdev );
697 free ( aoedev );
698}
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576

References container_of, free, aoe_device::netdev, and netdev_put().

Referenced by aoedev_open().

◆ aoedev_close()

void aoedev_close ( struct aoe_device * aoedev,
int rc )
static

Close AoE device.

Parameters
aoedevAoE device
rcReason for close

Definition at line 706 of file aoe.c.

706 {
707 struct aoe_command *aoecmd;
708 struct aoe_command *tmp;
709
710 /* Shut down interfaces */
711 intf_shutdown ( &aoedev->ata, rc );
713
714 /* Shut down any active commands */
715 list_for_each_entry_safe ( aoecmd, tmp, &aoe_commands, list ) {
716 if ( aoecmd->aoedev != aoedev )
717 continue;
718 aoecmd_get ( aoecmd );
720 aoecmd_put ( aoecmd );
721 }
722}
static struct aoe_command * aoecmd_get(struct aoe_command *aoecmd)
Get reference to AoE command.
Definition aoe.c:154
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
struct interface ata
ATA command issuing interface.
Definition aoe.h:123
struct interface config
Configuration command interface.
Definition aoe.h:136

References aoecmd_close(), aoecmd_get(), aoecmd_put(), aoe_command::aoedev, aoe_device::ata, aoe_device::config, intf_shutdown(), aoe_command::list, list_for_each_entry_safe, rc, and tmp.

Referenced by aoedev_config_done(), and aoedev_open().

◆ aoedev_window()

size_t aoedev_window ( struct aoe_device * aoedev)
static

Check AoE device flow-control window.

Parameters
aoedevAoE device
Return values
lenLength of window

Definition at line 730 of file aoe.c.

730 {
731 return ( aoedev->configured ? ~( ( size_t ) 0 ) : 0 );
732}
int configured
Device is configued.
Definition aoe.h:138

References aoe_command::aoedev, and aoe_device::configured.

◆ aoedev_config_done()

void aoedev_config_done ( struct aoe_device * aoedev,
int rc )
static

Handle AoE device configuration completion.

Parameters
aoedevAoE device
rcReason for completion

Definition at line 740 of file aoe.c.

740 {
741
742 /* Shut down interface */
743 intf_shutdown ( &aoedev->config, rc );
744
745 /* Close device on failure */
746 if ( rc != 0 ) {
747 aoedev_close ( aoedev, rc );
748 return;
749 }
750
751 /* Mark device as configured */
752 aoedev->configured = 1;
753 xfer_window_changed ( &aoedev->ata );
754}
static void aoedev_close(struct aoe_device *aoedev, int rc)
Close AoE device.
Definition aoe.c:706
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition xfer.c:147

References aoe_command::aoedev, aoedev_close(), aoe_device::ata, aoe_device::config, aoe_device::configured, intf_shutdown(), rc, and xfer_window_changed().

◆ aoedev_identify_device()

struct device * aoedev_identify_device ( struct aoe_device * aoedev)
static

Identify device underlying AoE device.

Parameters
aoedevAoE device
Return values
deviceUnderlying device

Definition at line 762 of file aoe.c.

762 {
763 return aoedev->netdev->dev;
764}
struct device * dev
Underlying hardware device.
Definition netdevice.h:365

References net_device::dev, and aoe_device::netdev.

◆ aoedev_describe()

struct acpi_descriptor * aoedev_describe ( struct aoe_device * aoedev)
static

Get AoE ACPI descriptor.

Parameters
aoedevAoE device
Return values
descACPI descriptor

Definition at line 772 of file aoe.c.

772 {
773 return &aoedev->desc;
774}
struct acpi_descriptor desc
ACPI descriptor.
Definition aoe.h:141

References aoe_device::desc.

◆ aoedev_open()

int aoedev_open ( struct interface * parent,
struct net_device * netdev,
unsigned int major,
unsigned int minor )
static

Open AoE device.

Parameters
parentParent interface
netdevNetwork device
majorDevice major number
minorDevice minor number
Return values
rcReturn status code

Definition at line 809 of file aoe.c.

810 {
811 struct aoe_device *aoedev;
812 int rc;
813
814 /* Allocate and initialise structure */
815 aoedev = zalloc ( sizeof ( *aoedev ) );
816 if ( ! aoedev ) {
817 rc = -ENOMEM;
818 goto err_zalloc;
819 }
820 ref_init ( &aoedev->refcnt, aoedev_free );
821 intf_init ( &aoedev->ata, &aoedev_ata_desc, &aoedev->refcnt );
822 intf_init ( &aoedev->config, &aoedev_config_desc, &aoedev->refcnt );
823 aoedev->netdev = netdev_get ( netdev );
824 aoedev->major = major;
825 aoedev->minor = minor;
826 memcpy ( aoedev->target, netdev->ll_broadcast,
827 netdev->ll_protocol->ll_addr_len );
828 acpi_init ( &aoedev->desc, &abft_model, &aoedev->refcnt );
829
830 /* Initiate configuration */
831 if ( ( rc = aoedev_cfg_command ( aoedev, &aoedev->config ) ) < 0 ) {
832 DBGC ( aoedev, "AoE %s could not initiate configuration: %s\n",
833 aoedev_name ( aoedev ), strerror ( rc ) );
834 goto err_config;
835 }
836
837 /* Attach ATA device to parent interface */
838 if ( ( rc = ata_open ( parent, &aoedev->ata, ATA_DEV_MASTER,
839 AOE_MAX_COUNT ) ) != 0 ) {
840 DBGC ( aoedev, "AoE %s could not create ATA device: %s\n",
841 aoedev_name ( aoedev ), strerror ( rc ) );
842 goto err_ata_open;
843 }
844
845 /* Mortalise self and return */
846 ref_put ( &aoedev->refcnt );
847 return 0;
848
849 err_ata_open:
850 err_config:
851 aoedev_close ( aoedev, rc );
852 ref_put ( &aoedev->refcnt );
853 err_zalloc:
854 return rc;
855}
static void aoedev_free(struct refcnt *refcnt)
Free AoE device.
Definition aoe.c:692
static struct interface_descriptor aoedev_ata_desc
AoE device ATA interface descriptor.
Definition aoe.c:788
static int aoedev_cfg_command(struct aoe_device *aoedev, struct interface *parent)
Issue AoE configuration command.
Definition aoe.c:666
static struct interface_descriptor aoedev_config_desc
AoE device configuration interface descriptor.
Definition aoe.c:797
#define AOE_MAX_COUNT
Maximum number of sectors per packet.
Definition aoe.h:113
int ata_open(struct interface *block, struct interface *ata, unsigned int device, unsigned int max_count)
Open ATA device.
Definition ata.c:663
#define ATA_DEV_MASTER
Master ("device 0") flag in the ATA device register.
Definition ata.h:120
static void acpi_init(struct acpi_descriptor *desc, struct acpi_model *model, struct refcnt *refcnt)
Initialise ACPI descriptor.
Definition acpi.h:312
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition netdevice.h:565
uint32_t major
Major version.
Definition netvsc.h:3
uint32_t minor
Minor version.
Definition netvsc.h:5

References acpi_init(), AOE_MAX_COUNT, aoedev_ata_desc, aoedev_cfg_command(), aoedev_close(), aoedev_config_desc, aoedev_free(), aoedev_name(), aoe_device::ata, ATA_DEV_MASTER, ata_open(), aoe_device::config, DBGC, aoe_device::desc, ENOMEM, intf_init(), aoe_device::major, major, memcpy(), aoe_device::minor, minor, aoe_device::netdev, netdev, netdev_get(), rc, ref_init, ref_put, aoe_device::refcnt, strerror(), aoe_device::target, and zalloc().

Referenced by aoe_open().

◆ aoe_rx()

int aoe_rx ( struct io_buffer * iobuf,
struct net_device *netdev __unused,
const void *ll_dest __unused,
const void * ll_source,
unsigned int flags __unused )
static

Process incoming AoE packets.

Parameters
iobufI/O buffer
netdevNetwork device
ll_destLink-layer destination address
ll_sourceLink-layer source address
flagsPacket flags
Return values
rcReturn status code

Definition at line 874 of file aoe.c.

878 {
879 struct aoehdr *aoehdr = iobuf->data;
880 struct aoe_command *aoecmd;
881 int rc;
882
883 /* Sanity check */
884 if ( iob_len ( iobuf ) < sizeof ( *aoehdr ) ) {
885 DBG ( "AoE received underlength packet (%zd bytes)\n",
886 iob_len ( iobuf ) );
887 rc = -EINVAL;
888 goto err_sanity;
889 }
891 DBG ( "AoE received packet for unsupported protocol version "
892 "%02x\n", ( aoehdr->ver_flags & AOE_VERSION_MASK ) );
894 goto err_sanity;
895 }
896 if ( ! ( aoehdr->ver_flags & AOE_FL_RESPONSE ) ) {
897 DBG ( "AoE received request packet\n" );
898 rc = -EOPNOTSUPP;
899 goto err_sanity;
900 }
901
902 /* Demultiplex amongst active AoE commands */
904 if ( ! aoecmd ) {
905 DBG ( "AoE received packet for unused tag %08x\n",
906 ntohl ( aoehdr->tag ) );
907 rc = -ENOENT;
908 goto err_demux;
909 }
910
911 /* Pass received frame to command */
912 aoecmd_get ( aoecmd );
913 if ( ( rc = aoecmd_rx ( aoecmd, iob_disown ( iobuf ),
914 ll_source ) ) != 0 )
915 goto err_rx;
916
917 err_rx:
918 aoecmd_put ( aoecmd );
919 err_demux:
920 err_sanity:
921 free_iob ( iobuf );
922 return rc;
923}
static int aoecmd_rx(struct aoe_command *aoecmd, struct io_buffer *iobuf, const void *ll_source)
Receive AoE command response.
Definition aoe.c:285
#define AOE_FL_RESPONSE
Message is a response.
Definition aoe.h:91
#define AOE_VERSION_MASK
Version part of ver_flags field.
Definition aoe.h:89
#define DBG(...)
Print a debugging message.
Definition compiler.h:498
#define ENOENT
No such file or directory.
Definition errno.h:515
#define EOPNOTSUPP
Operation not supported on socket.
Definition errno.h:605
#define EPROTONOSUPPORT
Protocol not supported.
Definition errno.h:630
#define ntohl(value)
Definition byteswap.h:135
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217

References __unused, AOE_FL_RESPONSE, AOE_VERSION, AOE_VERSION_MASK, aoecmd_find_tag(), aoecmd_get(), aoecmd_put(), aoecmd_rx(), io_buffer::data, DBG, EINVAL, ENOENT, EOPNOTSUPP, EPROTONOSUPPORT, flags, free_iob(), iob_disown, iob_len(), netdev, ntohl, rc, aoehdr::tag, and aoehdr::ver_flags.

◆ aoe_parse_uri()

int aoe_parse_uri ( struct uri * uri,
unsigned int * major,
unsigned int * minor )
static

Parse AoE URI.

Parameters
uriURI
Return values
majorMajor device number
minorMinor device number
rcReturn status code

An AoE URI has the form "aoe:e<major>.<minor>".

Definition at line 949 of file aoe.c.

950 {
951 const char *ptr;
952 char *end;
953
954 /* Check for URI with opaque portion */
955 if ( ! uri->opaque )
956 return -EINVAL;
957 ptr = uri->opaque;
958
959 /* Check for initial 'e' */
960 if ( *ptr != 'e' )
961 return -EINVAL;
962 ptr++;
963
964 /* Parse major device number */
965 *major = strtoul ( ptr, &end, 10 );
966 if ( *end != '.' )
967 return -EINVAL;
968 ptr = ( end + 1 );
969
970 /* Parse minor device number */
971 *minor = strtoul ( ptr, &end, 10 );
972 if ( *end )
973 return -EINVAL;
974
975 return 0;
976}
uint32_t end
Ending offset.
Definition netvsc.h:7
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition string.c:485
A Uniform Resource Identifier.
Definition uri.h:65
const char * opaque
Opaque part.
Definition uri.h:71

References EINVAL, end, major, minor, uri::opaque, and strtoul().

Referenced by aoe_open().

◆ aoe_open()

int aoe_open ( struct interface * parent,
struct uri * uri )
static

Open AoE URI.

Parameters
parentParent interface
uriURI
Return values
rcReturn status code

Definition at line 985 of file aoe.c.

985 {
986 struct net_device *netdev;
987 unsigned int major;
988 unsigned int minor;
989 int rc;
990
991 /* Identify network device. This is something of a hack, but
992 * the AoE URI scheme that has been in use for some time now
993 * provides no way to specify a particular device.
994 */
996 if ( ! netdev ) {
997 DBG ( "AoE cannot identify network device\n" );
998 return -ENODEV;
999 }
1000
1001 /* Parse URI */
1002 if ( ( rc = aoe_parse_uri ( uri, &major, &minor ) ) != 0 ) {
1003 DBG ( "AoE cannot parse URI\n" );
1004 return rc;
1005 }
1006
1007 /* Open AoE device */
1008 if ( ( rc = aoedev_open ( parent, netdev, major, minor ) ) != 0 )
1009 return rc;
1010
1011 return 0;
1012}
static int aoe_parse_uri(struct uri *uri, unsigned int *major, unsigned int *minor)
Parse AoE URI.
Definition aoe.c:949
static int aoedev_open(struct interface *parent, struct net_device *netdev, unsigned int major, unsigned int minor)
Open AoE device.
Definition aoe.c:809
#define ENODEV
No such device.
Definition errno.h:510
struct net_device * last_opened_netdev(void)
Get most recently opened network device.
Definition netdevice.c:1048

References aoe_parse_uri(), aoedev_open(), DBG, ENODEV, last_opened_netdev(), major, minor, netdev, and rc.

◆ abft_complete()

int abft_complete ( struct acpi_descriptor *desc __unused)
static

Check if AoE boot firmware table descriptor is complete.

Parameters
descACPI descriptor
Return values
rcReturn status code

Definition at line 1033 of file aoe.c.

1033 {
1034 return 0;
1035}

References __unused, and desc.

◆ abft_install()

int abft_install ( int(* install )(struct acpi_header *acpi))
static

Install AoE boot firmware table(s)

Parameters
installInstallation method
Return values
rcReturn status code

Definition at line 1043 of file aoe.c.

1043 {
1044 struct aoe_device *aoedev;
1045 struct abft_table abft;
1046 int rc;
1047
1048 list_for_each_entry ( aoedev, &abft_model.descs, desc.list ) {
1049
1050 /* Populate table */
1051 memset ( &abft, 0, sizeof ( abft ) );
1052 abft.acpi.signature = cpu_to_le32 ( ABFT_SIG );
1053 abft.acpi.length = cpu_to_le32 ( sizeof ( abft ) );
1054 abft.acpi.revision = 1;
1055 abft.shelf = cpu_to_le16 ( aoedev->major );
1056 abft.slot = aoedev->minor;
1057 memcpy ( abft.mac, aoedev->netdev->ll_addr,
1058 sizeof ( abft.mac ) );
1059
1060 /* Install table */
1061 if ( ( rc = install ( &abft.acpi ) ) != 0 ) {
1062 DBGC ( aoedev, "AoE %s could not install aBFT: %s\n",
1063 aoedev_name ( aoedev ), strerror ( rc ) );
1064 return rc;
1065 }
1066 }
1067
1068 return 0;
1069}
#define ABFT_SIG
AoE boot firmware table signature.
Definition aoe.h:145
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
#define cpu_to_le32(value)
Definition byteswap.h:108
#define cpu_to_le16(value)
Definition byteswap.h:107
AoE Boot Firmware Table (aBFT)
Definition aoe.h:150
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition netdevice.h:388

References ABFT_SIG, abft_table::acpi, acpi, aoedev_name(), cpu_to_le16, cpu_to_le32, DBGC, desc, acpi_header::length, list_for_each_entry, net_device::ll_addr, abft_table::mac, aoe_device::major, memcpy(), memset(), aoe_device::minor, aoe_device::netdev, rc, acpi_header::revision, abft_table::shelf, acpi_header::signature, abft_table::slot, and strerror().

Variable Documentation

◆ __net_protocol

struct net_protocol aoe_protocol __net_protocol
Initial value:
= {
.name = "AoE",
.net_proto = htons ( ETH_P_AOE ),
.rx = aoe_rx,
}
static int aoe_rx(struct io_buffer *iobuf, struct net_device *netdev __unused, const void *ll_dest __unused, const void *ll_source, unsigned int flags __unused)
Process incoming AoE packets.
Definition aoe.c:874
#define ETH_P_AOE
Definition if_ether.h:26

AoE protocol.

Definition at line 56 of file aoe.c.

◆ __acpi_model

struct acpi_model abft_model __acpi_model
Initial value:
= {
.descs = LIST_HEAD_INIT ( abft_model.descs ),
.complete = abft_complete,
.install = abft_install,
}
static int abft_install(int(*install)(struct acpi_header *acpi))
Install AoE boot firmware table(s)
Definition aoe.c:1043
static int abft_complete(struct acpi_descriptor *desc __unused)
Check if AoE boot firmware table descriptor is complete.
Definition aoe.c:1033
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition list.h:31

aBFT model

Definition at line 57 of file aoe.c.

◆ aoecmd_ata

struct aoe_command_type aoecmd_ata
static
Initial value:
= {
.cmd_len = aoecmd_ata_cmd_len,
}
static void aoecmd_ata_cmd(struct aoe_command *aoecmd, void *data, size_t len)
Build AoE ATA command IU.
Definition aoe.c:369
static int aoecmd_ata_rsp(struct aoe_command *aoecmd, const void *data, size_t len, const void *ll_source __unused)
Handle AoE ATA response IU.
Definition aoe.c:416
static size_t aoecmd_ata_cmd_len(struct aoe_command *aoecmd)
Calculate length of AoE ATA command IU.
Definition aoe.c:355

AoE ATA command.

Definition at line 460 of file aoe.c.

460 {
461 .cmd_len = aoecmd_ata_cmd_len,
462 .cmd = aoecmd_ata_cmd,
463 .rsp = aoecmd_ata_rsp,
464};

Referenced by aoedev_ata_command().

◆ aoecmd_cfg

struct aoe_command_type aoecmd_cfg
static
Initial value:
= {
.cmd_len = aoecmd_cfg_cmd_len,
}
static int aoecmd_cfg_rsp(struct aoe_command *aoecmd, const void *data, size_t len, const void *ll_source)
Handle AoE configuration response IU.
Definition aoe.c:509
static size_t aoecmd_cfg_cmd_len(struct aoe_command *aoecmd __unused)
Calculate length of AoE configuration command IU.
Definition aoe.c:472
static void aoecmd_cfg_cmd(struct aoe_command *aoecmd, void *data, size_t len)
Build AoE configuration command IU.
Definition aoe.c:483

AoE configuration command.

Definition at line 536 of file aoe.c.

536 {
537 .cmd_len = aoecmd_cfg_cmd_len,
538 .cmd = aoecmd_cfg_cmd,
539 .rsp = aoecmd_cfg_rsp,
540};

Referenced by aoedev_cfg_command().

◆ aoecmd_ata_op

struct interface_operation aoecmd_ata_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33

AoE command ATA interface operations.

Definition at line 543 of file aoe.c.

543 {
545};

◆ aoecmd_ata_desc

struct interface_descriptor aoecmd_ata_desc
static
Initial value:
=
static struct interface_operation aoecmd_ata_op[]
AoE command ATA interface operations.
Definition aoe.c:543
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81

AoE command ATA interface descriptor.

Definition at line 548 of file aoe.c.

Referenced by aoecmd_create().

◆ aoedev_ata_op

struct interface_operation aoedev_ata_op[]
static
Initial value:
= {
}
struct acpi_descriptor * acpi_describe(struct interface *intf)
Get object's ACPI descriptor.
Definition acpi.c:321
static int aoedev_ata_command(struct aoe_device *aoedev, struct interface *parent, struct ata_cmd *command)
Issue AoE ATA command.
Definition aoe.c:628
static struct device * aoedev_identify_device(struct aoe_device *aoedev)
Identify device underlying AoE device.
Definition aoe.c:762
static size_t aoedev_window(struct aoe_device *aoedev)
Check AoE device flow-control window.
Definition aoe.c:730
static struct acpi_descriptor * aoedev_describe(struct aoe_device *aoedev)
Get AoE ACPI descriptor.
Definition aoe.c:772
struct device * identify_device(struct interface *intf)
Identify a device behind an interface.
Definition device.c:126
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition efi_path.c:920
EFI_DEVICE_PATH_PROTOCOL * efi_aoe_path(struct aoe_device *aoedev)
Construct EFI device path for AoE device.
Definition efi_path.c:572
#define EFI_INTF_OP
Definition efi.h:374
An ATA command.
Definition ata.c:110
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117

AoE device ATA interface operations.

Definition at line 777 of file aoe.c.

◆ aoedev_ata_desc

struct interface_descriptor aoedev_ata_desc
static
Initial value:
=
static struct interface_operation aoedev_ata_op[]
AoE device ATA interface operations.
Definition aoe.c:777

AoE device ATA interface descriptor.

Definition at line 788 of file aoe.c.

Referenced by aoedev_open().

◆ aoedev_config_op

struct interface_operation aoedev_config_op[]
static
Initial value:
= {
}
static void aoedev_config_done(struct aoe_device *aoedev, int rc)
Handle AoE device configuration completion.
Definition aoe.c:740

AoE device configuration interface operations.

Definition at line 792 of file aoe.c.

792 {
794};

◆ aoedev_config_desc

struct interface_descriptor aoedev_config_desc
static
Initial value:
=
static struct interface_operation aoedev_config_op[]
AoE device configuration interface operations.
Definition aoe.c:792

AoE device configuration interface descriptor.

Definition at line 797 of file aoe.c.

Referenced by aoedev_open().

◆ __uri_opener

struct uri_opener aoe_uri_opener __uri_opener
Initial value:
= {
.scheme = "aoe",
.open = aoe_open,
}
static int aoe_open(struct interface *parent, struct uri *uri)
Open AoE URI.
Definition aoe.c:985

AoE URI opener.

Definition at line 1015 of file aoe.c.

1015 {
1016 .scheme = "aoe",
1017 .open = aoe_open,
1018};