iPXE
aoe.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stddef.h>
28#include <string.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <errno.h>
32#include <assert.h>
33#include <byteswap.h>
34#include <ipxe/list.h>
35#include <ipxe/if_ether.h>
36#include <ipxe/iobuf.h>
37#include <ipxe/netdevice.h>
38#include <ipxe/features.h>
39#include <ipxe/interface.h>
40#include <ipxe/xfer.h>
41#include <ipxe/uri.h>
42#include <ipxe/open.h>
43#include <ipxe/ata.h>
44#include <ipxe/device.h>
45#include <ipxe/efi/efi_path.h>
46#include <ipxe/aoe.h>
47
48/** @file
49 *
50 * AoE protocol
51 *
52 */
53
55
56struct net_protocol aoe_protocol __net_protocol;
57struct acpi_model abft_model __acpi_model;
58
59/******************************************************************************
60 *
61 * AoE devices and commands
62 *
63 ******************************************************************************
64 */
65
66/** List of all AoE devices */
67static LIST_HEAD ( aoe_devices );
68
69/** List of active AoE commands */
70static LIST_HEAD ( aoe_commands );
71
72/** An AoE command */
74 /** Reference count */
75 struct refcnt refcnt;
76 /** AOE device */
78 /** List of active commands */
80
81 /** ATA command interface */
82 struct interface ata;
83
84 /** ATA command */
86 /** Command type */
88 /** Command tag */
90
91 /** Retransmission timer */
93};
94
95/** An AoE command type */
97 /**
98 * Calculate length of AoE command IU
99 *
100 * @v aoecmd AoE command
101 * @ret len Length of command IU
102 */
103 size_t ( * cmd_len ) ( struct aoe_command *aoecmd );
104 /**
105 * Build AoE command IU
106 *
107 * @v aoecmd AoE command
108 * @v data Command IU
109 * @v len Length of command IU
110 * @ret rc Return status code
111 */
112 int ( * cmd ) ( struct aoe_command *aoecmd, void *data, size_t len );
113 /**
114 * Handle AoE response IU
115 *
116 * @v aoecmd AoE command
117 * @v data Response IU
118 * @v len Length of response IU
119 * @v ll_source Link-layer source address
120 * @ret rc Return status code
121 */
122 int ( * rsp ) ( struct aoe_command *aoecmd, const void *data,
123 size_t len, const void *ll_source );
124};
125
126/**
127 * Get reference to AoE device
128 *
129 * @v aoedev AoE device
130 * @ret aoedev AoE device
131 */
132static inline __attribute__ (( always_inline )) struct aoe_device *
133aoedev_get ( struct aoe_device *aoedev ) {
134 ref_get ( &aoedev->refcnt );
135 return aoedev;
136}
137
138/**
139 * Drop reference to AoE device
140 *
141 * @v aoedev AoE device
142 */
143static inline __attribute__ (( always_inline )) void
144aoedev_put ( struct aoe_device *aoedev ) {
145 ref_put ( &aoedev->refcnt );
146}
147
148/**
149 * Get reference to AoE command
150 *
151 * @v aoecmd AoE command
152 * @ret aoecmd AoE command
153 */
154static inline __attribute__ (( always_inline )) struct aoe_command *
156 ref_get ( &aoecmd->refcnt );
157 return aoecmd;
158}
159
160/**
161 * Drop reference to AoE command
162 *
163 * @v aoecmd AoE command
164 */
165static inline __attribute__ (( always_inline )) void
167 ref_put ( &aoecmd->refcnt );
168}
169
170/**
171 * Name AoE device
172 *
173 * @v aoedev AoE device
174 * @ret name AoE device name
175 */
176static const char * aoedev_name ( struct aoe_device *aoedev ) {
177 static char buf[16];
178
179 snprintf ( buf, sizeof ( buf ), "%s/e%d.%d", aoedev->netdev->name,
181 return buf;
182}
183
184/**
185 * Free AoE command
186 *
187 * @v refcnt Reference counter
188 */
189static void aoecmd_free ( struct refcnt *refcnt ) {
190 struct aoe_command *aoecmd =
192
193 assert ( ! timer_running ( &aoecmd->timer ) );
194 assert ( list_empty ( &aoecmd->list ) );
195
196 aoedev_put ( aoecmd->aoedev );
197 free ( aoecmd );
198}
199
200/**
201 * Close AoE command
202 *
203 * @v aoecmd AoE command
204 * @v rc Reason for close
205 */
206static void aoecmd_close ( struct aoe_command *aoecmd, int rc ) {
207 struct aoe_device *aoedev = aoecmd->aoedev;
208
209 /* Stop timer */
210 stop_timer ( &aoecmd->timer );
211
212 /* Preserve the timeout value for subsequent commands */
213 aoedev->timeout = aoecmd->timer.timeout;
214
215 /* Remove from list of commands */
216 if ( ! list_empty ( &aoecmd->list ) ) {
217 list_del ( &aoecmd->list );
218 INIT_LIST_HEAD ( &aoecmd->list );
219 aoecmd_put ( aoecmd );
220 }
221
222 /* Shut down interfaces */
223 intf_shutdown ( &aoecmd->ata, rc );
224}
225
226/**
227 * Transmit AoE command request
228 *
229 * @v aoecmd AoE command
230 * @ret rc Return status code
231 */
232static int aoecmd_tx ( struct aoe_command *aoecmd ) {
233 struct aoe_device *aoedev = aoecmd->aoedev;
234 struct net_device *netdev = aoedev->netdev;
235 struct io_buffer *iobuf;
236 struct aoehdr *aoehdr;
237 size_t cmd_len;
238 int rc;
239
240 /* Sanity check */
241 assert ( netdev != NULL );
242
243 /* If we are transmitting anything that requires a response,
244 * start the retransmission timer. Do this before attempting
245 * to allocate the I/O buffer, in case allocation itself
246 * fails.
247 */
248 start_timer ( &aoecmd->timer );
249
250 /* Create outgoing I/O buffer */
251 cmd_len = aoecmd->type->cmd_len ( aoecmd );
252 iobuf = alloc_iob ( MAX_LL_HEADER_LEN + cmd_len );
253 if ( ! iobuf ) {
254 rc = -ENOMEM;
255 goto err_alloc;
256 }
258 aoehdr = iob_put ( iobuf, cmd_len );
259
260 /* Fill AoE header */
261 memset ( aoehdr, 0, sizeof ( *aoehdr ) );
263 aoehdr->major = htons ( aoedev->major );
264 aoehdr->minor = aoedev->minor;
265 aoehdr->tag = htonl ( aoecmd->tag );
266 if ( ( rc = aoecmd->type->cmd ( aoecmd, iobuf->data,
267 iob_len ( iobuf ) ) ) != 0 ) {
268 goto err_cmd;
269 }
270
271 /* Send packet */
272 if ( ( rc = net_tx ( iob_disown ( iobuf ), netdev, &aoe_protocol,
273 aoedev->target, netdev->ll_addr ) ) != 0 ) {
274 DBGC ( aoedev, "AoE %s/%08x could not transmit: %s\n",
275 aoedev_name ( aoedev ), aoecmd->tag,
276 strerror ( rc ) );
277 goto err_tx;
278 }
279
280 return 0;
281
282 err_tx:
283 err_cmd:
284 free_iob ( iobuf );
285 err_alloc:
286 return rc;
287}
288
289/**
290 * Receive AoE command response
291 *
292 * @v aoecmd AoE command
293 * @v iobuf I/O buffer
294 * @v ll_source Link-layer source address
295 * @ret rc Return status code
296 */
297static int aoecmd_rx ( struct aoe_command *aoecmd, struct io_buffer *iobuf,
298 const void *ll_source ) {
299 struct aoe_device *aoedev = aoecmd->aoedev;
300 struct aoehdr *aoehdr;
301 int rc;
302
303 /* Sanity check */
304 if ( iob_len ( iobuf ) < sizeof ( *aoehdr ) ) {
305 DBGC ( aoedev, "AoE %s/%08x received underlength response "
306 "(%zd bytes)\n", aoedev_name ( aoedev ),
307 aoecmd->tag, iob_len ( iobuf ) );
308 rc = -EINVAL;
309 goto done;
310 }
311 aoehdr = iobuf->data;
312 if ( ( ntohs ( aoehdr->major ) != aoedev->major ) ||
313 ( aoehdr->minor != aoedev->minor ) ) {
314 DBGC ( aoedev, "AoE %s/%08x received response for incorrect "
315 "device e%d.%d\n", aoedev_name ( aoedev ), aoecmd->tag,
316 ntohs ( aoehdr->major ), aoehdr->minor );
317 rc = -EINVAL;
318 goto done;
319 }
320
321 /* Catch command failures */
322 if ( aoehdr->ver_flags & AOE_FL_ERROR ) {
323 DBGC ( aoedev, "AoE %s/%08x terminated in error\n",
324 aoedev_name ( aoedev ), aoecmd->tag );
325 aoecmd_close ( aoecmd, -EIO );
326 rc = -EIO;
327 goto done;
328 }
329
330 /* Hand off to command completion handler */
331 if ( ( rc = aoecmd->type->rsp ( aoecmd, iobuf->data, iob_len ( iobuf ),
332 ll_source ) ) != 0 )
333 goto done;
334
335 done:
336 /* Free I/O buffer */
337 free_iob ( iobuf );
338
339 /* Terminate command */
341
342 return rc;
343}
344
345/**
346 * Handle AoE retry timer expiry
347 *
348 * @v timer AoE retry timer
349 * @v fail Failure indicator
350 */
351static void aoecmd_expired ( struct retry_timer *timer, int fail ) {
352 struct aoe_command *aoecmd =
353 container_of ( timer, struct aoe_command, timer );
354
355 if ( fail ) {
357 } else {
358 aoecmd_tx ( aoecmd );
359 }
360}
361
362/**
363 * Calculate length of AoE ATA command IU
364 *
365 * @v aoecmd AoE command
366 * @ret len Length of command IU
367 */
368static size_t aoecmd_ata_cmd_len ( struct aoe_command *aoecmd ) {
369 struct ata_cmd *command = &aoecmd->command;
370
371 return ( sizeof ( struct aoehdr ) + sizeof ( struct aoeata ) +
372 command->data_out.len );
373}
374
375/**
376 * Build AoE ATA command IU
377 *
378 * @v aoecmd AoE command
379 * @v data Command IU
380 * @v len Length of command IU
381 * @ret rc Return status code
382 */
383static int aoecmd_ata_cmd ( struct aoe_command *aoecmd,
384 void *data, size_t len ) {
385 struct aoe_device *aoedev = aoecmd->aoedev;
386 struct ata_cmd *command = &aoecmd->command;
387 struct aoehdr *aoehdr = data;
388 struct aoeata *aoeata = &aoehdr->payload[0].ata;
389 int rc;
390
391 /* Sanity check */
392 static_assert ( AOE_FL_DEV_HEAD == ATA_DEV_SLAVE );
393 assert ( len == ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) +
394 command->data_out.len ) );
395
396 /* Build IU */
398 memset ( aoeata, 0, sizeof ( *aoeata ) );
399 aoeata->aflags = ( ( command->cb.lba48 ? AOE_FL_EXTENDED : 0 ) |
400 ( command->cb.device & ATA_DEV_SLAVE ) |
401 ( command->data_out.len ? AOE_FL_WRITE : 0 ) );
402 aoeata->err_feat = command->cb.err_feat.bytes.cur;
403 aoeata->count = command->cb.count.native;
404 aoeata->cmd_stat = command->cb.cmd_stat;
405 aoeata->lba.u64 = cpu_to_le64 ( command->cb.lba.native );
406 if ( ! command->cb.lba48 )
407 aoeata->lba.bytes[3] |=
408 ( command->cb.device & ATA_DEV_MASK );
409 DBGC2 ( aoedev, "AoE %s/%08x ATA cmd %02x:%02x:%02x:%02x:%08llx",
410 aoedev_name ( aoedev ), aoecmd->tag, aoeata->aflags,
412 aoeata->lba.u64 );
413 if ( command->data_out.len )
414 DBGC2 ( aoedev, " out %04zx", command->data_out.len );
415 if ( command->data_in.len )
416 DBGC2 ( aoedev, " in %04zx", command->data_in.len );
417 DBGC2 ( aoedev, "\n" );
418
419 /* Copy data-out (if any) to command IU */
420 if ( ( rc = xferbuf_read ( &command->data_out, 0, aoeata->data,
421 command->data_out.len ) ) != 0 ) {
422 DBGC ( aoedev, "AoE %s/%08x could not read data-out: %s\n",
423 aoedev_name ( aoedev ), aoecmd->tag, strerror ( rc ) );
424 return rc;
425 }
426
427 return 0;
428}
429
430/**
431 * Handle AoE ATA response IU
432 *
433 * @v aoecmd AoE command
434 * @v data Response IU
435 * @v len Length of response IU
436 * @v ll_source Link-layer source address
437 * @ret rc Return status code
438 */
439static int aoecmd_ata_rsp ( struct aoe_command *aoecmd, const void *data,
440 size_t len, const void *ll_source __unused ) {
441 struct aoe_device *aoedev = aoecmd->aoedev;
442 struct ata_cmd *command = &aoecmd->command;
443 const struct aoehdr *aoehdr = data;
444 const struct aoeata *aoeata = &aoehdr->payload[0].ata;
445 size_t data_len;
446 int rc;
447
448 /* Sanity check */
449 if ( len < ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) ) ) {
450 DBGC ( aoedev, "AoE %s/%08x received underlength ATA response "
451 "(%zd bytes)\n", aoedev_name ( aoedev ),
452 aoecmd->tag, len );
453 return -EINVAL;
454 }
455 data_len = ( len - ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) ) );
456 DBGC2 ( aoedev, "AoE %s/%08x ATA rsp %02x in %04zx\n",
457 aoedev_name ( aoedev ), aoecmd->tag, aoeata->cmd_stat,
458 data_len );
459
460 /* Check for command failure */
461 if ( aoeata->cmd_stat & ATA_STAT_ERR ) {
462 DBGC ( aoedev, "AoE %s/%08x status %02x\n",
463 aoedev_name ( aoedev ), aoecmd->tag, aoeata->cmd_stat );
464 return -EIO;
465 }
466
467 /* Check data-in length is sufficient. (There may be trailing
468 * garbage due to Ethernet minimum-frame-size padding.)
469 */
470 if ( data_len < command->data_in.len ) {
471 DBGC ( aoedev, "AoE %s/%08x data-in underrun (received %zd, "
472 "expected %zd)\n", aoedev_name ( aoedev ), aoecmd->tag,
473 data_len, command->data_in.len );
474 return -ERANGE;
475 }
476
477 /* Copy out data payload */
478 if ( ( rc = xferbuf_write ( &command->data_in, 0, aoeata->data,
479 command->data_in.len ) ) != 0 ) {
480 DBGC ( aoedev, "AoE %s/%08x could not write data-in: %s\n",
481 aoedev_name ( aoedev ), aoecmd->tag, strerror ( rc ) );
482 return rc;
483 }
484
485 return 0;
486}
487
488/** AoE ATA command */
490 .cmd_len = aoecmd_ata_cmd_len,
491 .cmd = aoecmd_ata_cmd,
492 .rsp = aoecmd_ata_rsp,
493};
494
495/**
496 * Calculate length of AoE configuration command IU
497 *
498 * @v aoecmd AoE command
499 * @ret len Length of command IU
500 */
502 return ( sizeof ( struct aoehdr ) + sizeof ( struct aoecfg ) );
503}
504
505/**
506 * Build AoE configuration command IU
507 *
508 * @v aoecmd AoE command
509 * @v data Command IU
510 * @v len Length of command IU
511 * @ret rc Return status code
512 */
513static int aoecmd_cfg_cmd ( struct aoe_command *aoecmd,
514 void *data, size_t len ) {
515 struct aoe_device *aoedev = aoecmd->aoedev;
516 struct aoehdr *aoehdr = data;
517 struct aoecfg *aoecfg = &aoehdr->payload[0].cfg;
518
519 /* Sanity check */
520 assert ( len == ( sizeof ( *aoehdr ) + sizeof ( *aoecfg ) ) );
521
522 /* Build IU */
524 memset ( aoecfg, 0, sizeof ( *aoecfg ) );
525 DBGC ( aoedev, "AoE %s/%08x CONFIG cmd\n",
526 aoedev_name ( aoedev ), aoecmd->tag );
527
528 return 0;
529}
530
531/**
532 * Handle AoE configuration response IU
533 *
534 * @v aoecmd AoE command
535 * @v data Response IU
536 * @v len Length of response IU
537 * @v ll_source Link-layer source address
538 * @ret rc Return status code
539 */
540static int aoecmd_cfg_rsp ( struct aoe_command *aoecmd, const void *data,
541 size_t len, const void *ll_source ) {
542 struct aoe_device *aoedev = aoecmd->aoedev;
543 struct ll_protocol *ll_protocol = aoedev->netdev->ll_protocol;
544 const struct aoehdr *aoehdr = data;
545 const struct aoecfg *aoecfg = &aoehdr->payload[0].cfg;
546
547 /* Sanity check */
548 if ( len < ( sizeof ( *aoehdr ) + sizeof ( *aoecfg ) ) ) {
549 DBGC ( aoedev, "AoE %s/%08x received underlength "
550 "configuration response (%zd bytes)\n",
551 aoedev_name ( aoedev ), aoecmd->tag, len );
552 return -EINVAL;
553 }
554 DBGC ( aoedev, "AoE %s/%08x CONFIG rsp buf %04x fw %04x scnt %02x\n",
555 aoedev_name ( aoedev ), aoecmd->tag, ntohs ( aoecfg->bufcnt ),
556 aoecfg->fwver, aoecfg->scnt );
557
558 /* Record target MAC address */
559 memcpy ( aoedev->target, ll_source, ll_protocol->ll_addr_len );
560 DBGC ( aoedev, "AoE %s has MAC address %s\n",
561 aoedev_name ( aoedev ), ll_protocol->ntoa ( aoedev->target ) );
562
563 return 0;
564}
565
566/** AoE configuration command */
568 .cmd_len = aoecmd_cfg_cmd_len,
569 .cmd = aoecmd_cfg_cmd,
570 .rsp = aoecmd_cfg_rsp,
571};
572
573/** AoE command ATA interface operations */
576};
577
578/** AoE command ATA interface descriptor */
580 INTF_DESC ( struct aoe_command, ata, aoecmd_ata_op );
581
582/**
583 * Identify AoE command by tag
584 *
585 * @v tag Command tag
586 * @ret aoecmd AoE command, or NULL
587 */
589 struct aoe_command *aoecmd;
590
591 list_for_each_entry ( aoecmd, &aoe_commands, list ) {
592 if ( aoecmd->tag == tag )
593 return aoecmd;
594 }
595 return NULL;
596}
597
598/**
599 * Choose an AoE command tag
600 *
601 * @ret tag New tag, or negative error
602 */
603static int aoecmd_new_tag ( void ) {
604 static uint16_t tag_idx;
605 unsigned int i;
606
607 for ( i = 0 ; i < 65536 ; i++ ) {
608 tag_idx++;
609 if ( aoecmd_find_tag ( tag_idx ) == NULL )
610 return ( AOE_TAG_MAGIC | tag_idx );
611 }
612 return -EADDRINUSE;
613}
614
615/**
616 * Create AoE command
617 *
618 * @v aoedev AoE device
619 * @v type AoE command type
620 * @ret aoecmd AoE command
621 */
622static struct aoe_command * aoecmd_create ( struct aoe_device *aoedev,
623 struct aoe_command_type *type ) {
624 struct aoe_command *aoecmd;
625 int tag;
626
627 /* Allocate command tag */
629 if ( tag < 0 )
630 return NULL;
631
632 /* Allocate and initialise structure */
633 aoecmd = zalloc ( sizeof ( *aoecmd ) );
634 if ( ! aoecmd )
635 return NULL;
636 ref_init ( &aoecmd->refcnt, aoecmd_free );
637 list_add ( &aoecmd->list, &aoe_commands );
638 intf_init ( &aoecmd->ata, &aoecmd_ata_desc, &aoecmd->refcnt );
639 timer_init ( &aoecmd->timer, aoecmd_expired, &aoecmd->refcnt );
640 aoecmd->aoedev = aoedev_get ( aoedev );
641 aoecmd->type = type;
642 aoecmd->tag = tag;
643
644 /* Preserve timeout from last completed command */
645 aoecmd->timer.timeout = aoedev->timeout;
646
647 /* Return already mortalised. (Reference is held by command list.) */
648 return aoecmd;
649}
650
651/**
652 * Issue AoE ATA command
653 *
654 * @v aoedev AoE device
655 * @v parent Parent interface
656 * @v command ATA command
657 * @ret tag Command tag, or negative error
658 */
660 struct interface *parent,
661 struct ata_cmd *command ) {
662 struct net_device *netdev = aoedev->netdev;
663 struct aoe_command *aoecmd;
664
665 /* Fail immediately if net device is closed */
666 if ( ! netdev_is_open ( netdev ) ) {
667 DBGC ( aoedev, "AoE %s cannot issue command while net device "
668 "is closed\n", aoedev_name ( aoedev ) );
669 return -EWOULDBLOCK;
670 }
671
672 /* Create command */
674 if ( ! aoecmd )
675 return -ENOMEM;
676 memcpy ( &aoecmd->command, command, sizeof ( aoecmd->command ) );
677
678 /* Attempt to send command. Allow failures to be handled by
679 * the retry timer.
680 */
681 aoecmd_tx ( aoecmd );
682
683 /* Attach to parent interface, leave reference with command
684 * list, and return.
685 */
686 intf_plug_plug ( &aoecmd->ata, parent );
687 return aoecmd->tag;
688}
689
690/**
691 * Issue AoE configuration command
692 *
693 * @v aoedev AoE device
694 * @v parent Parent interface
695 * @ret tag Command tag, or negative error
696 */
698 struct interface *parent ) {
699 struct aoe_command *aoecmd;
700
701 /* Create command */
703 if ( ! aoecmd )
704 return -ENOMEM;
705
706 /* Attempt to send command. Allow failures to be handled by
707 * the retry timer.
708 */
709 aoecmd_tx ( aoecmd );
710
711 /* Attach to parent interface, leave reference with command
712 * list, and return.
713 */
714 intf_plug_plug ( &aoecmd->ata, parent );
715 return aoecmd->tag;
716}
717
718/**
719 * Free AoE device
720 *
721 * @v refcnt Reference count
722 */
723static void aoedev_free ( struct refcnt *refcnt ) {
724 struct aoe_device *aoedev =
726
727 netdev_put ( aoedev->netdev );
728 free ( aoedev );
729}
730
731/**
732 * Close AoE device
733 *
734 * @v aoedev AoE device
735 * @v rc Reason for close
736 */
737static void aoedev_close ( struct aoe_device *aoedev, int rc ) {
738 struct aoe_command *aoecmd;
739 struct aoe_command *tmp;
740
741 /* Shut down interfaces */
742 intf_shutdown ( &aoedev->ata, rc );
744
745 /* Shut down any active commands */
746 list_for_each_entry_safe ( aoecmd, tmp, &aoe_commands, list ) {
747 if ( aoecmd->aoedev != aoedev )
748 continue;
749 aoecmd_get ( aoecmd );
751 aoecmd_put ( aoecmd );
752 }
753}
754
755/**
756 * Check AoE device flow-control window
757 *
758 * @v aoedev AoE device
759 * @ret len Length of window
760 */
761static size_t aoedev_window ( struct aoe_device *aoedev ) {
762 return ( aoedev->configured ? ~( ( size_t ) 0 ) : 0 );
763}
764
765/**
766 * Handle AoE device configuration completion
767 *
768 * @v aoedev AoE device
769 * @v rc Reason for completion
770 */
771static void aoedev_config_done ( struct aoe_device *aoedev, int rc ) {
772
773 /* Shut down interface */
775
776 /* Close device on failure */
777 if ( rc != 0 ) {
779 return;
780 }
781
782 /* Mark device as configured */
783 aoedev->configured = 1;
785}
786
787/**
788 * Identify device underlying AoE device
789 *
790 * @v aoedev AoE device
791 * @ret device Underlying device
792 */
793static struct device * aoedev_identify_device ( struct aoe_device *aoedev ) {
794 return aoedev->netdev->dev;
795}
796
797/**
798 * Get AoE ACPI descriptor
799 *
800 * @v aoedev AoE device
801 * @ret desc ACPI descriptor
802 */
803static struct acpi_descriptor * aoedev_describe ( struct aoe_device *aoedev ) {
804 return &aoedev->desc;
805}
806
807/** AoE device ATA interface operations */
817
818/** AoE device ATA interface descriptor */
820 INTF_DESC ( struct aoe_device, ata, aoedev_ata_op );
821
822/** AoE device configuration interface operations */
826
827/** AoE device configuration interface descriptor */
829 INTF_DESC ( struct aoe_device, config, aoedev_config_op );
830
831/**
832 * Open AoE device
833 *
834 * @v parent Parent interface
835 * @v netdev Network device
836 * @v major Device major number
837 * @v minor Device minor number
838 * @ret rc Return status code
839 */
840static int aoedev_open ( struct interface *parent, struct net_device *netdev,
841 unsigned int major, unsigned int minor ) {
842 struct aoe_device *aoedev;
843 int rc;
844
845 /* Allocate and initialise structure */
846 aoedev = zalloc ( sizeof ( *aoedev ) );
847 if ( ! aoedev ) {
848 rc = -ENOMEM;
849 goto err_zalloc;
850 }
851 ref_init ( &aoedev->refcnt, aoedev_free );
852 intf_init ( &aoedev->ata, &aoedev_ata_desc, &aoedev->refcnt );
853 intf_init ( &aoedev->config, &aoedev_config_desc, &aoedev->refcnt );
854 aoedev->netdev = netdev_get ( netdev );
855 aoedev->major = major;
856 aoedev->minor = minor;
857 memcpy ( aoedev->target, netdev->ll_broadcast,
858 netdev->ll_protocol->ll_addr_len );
859 acpi_init ( &aoedev->desc, &abft_model, &aoedev->refcnt );
860
861 /* Initiate configuration */
862 if ( ( rc = aoedev_cfg_command ( aoedev, &aoedev->config ) ) < 0 ) {
863 DBGC ( aoedev, "AoE %s could not initiate configuration: %s\n",
864 aoedev_name ( aoedev ), strerror ( rc ) );
865 goto err_config;
866 }
867
868 /* Attach ATA device to parent interface */
869 if ( ( rc = ata_open ( parent, &aoedev->ata, ATA_DEV_MASTER,
870 AOE_MAX_COUNT ) ) != 0 ) {
871 DBGC ( aoedev, "AoE %s could not create ATA device: %s\n",
872 aoedev_name ( aoedev ), strerror ( rc ) );
873 goto err_ata_open;
874 }
875
876 /* Mortalise self and return */
877 ref_put ( &aoedev->refcnt );
878 return 0;
879
880 err_ata_open:
881 err_config:
882 aoedev_close ( aoedev, rc );
883 ref_put ( &aoedev->refcnt );
884 err_zalloc:
885 return rc;
886}
887
888/******************************************************************************
889 *
890 * AoE network protocol
891 *
892 ******************************************************************************
893 */
894
895/**
896 * Process incoming AoE packets
897 *
898 * @v iobuf I/O buffer
899 * @v netdev Network device
900 * @v ll_dest Link-layer destination address
901 * @v ll_source Link-layer source address
902 * @v flags Packet flags
903 * @ret rc Return status code
904 */
905static int aoe_rx ( struct io_buffer *iobuf,
906 struct net_device *netdev __unused,
907 const void *ll_dest __unused,
908 const void *ll_source,
909 unsigned int flags __unused ) {
910 struct aoehdr *aoehdr;
911 struct aoe_command *aoecmd;
912 int rc;
913
914 /* Sanity check */
915 if ( iob_len ( iobuf ) < sizeof ( *aoehdr ) ) {
916 DBG ( "AoE received underlength packet (%zd bytes)\n",
917 iob_len ( iobuf ) );
918 rc = -EINVAL;
919 goto err_sanity;
920 }
921 aoehdr = iobuf->data;
923 DBG ( "AoE received packet for unsupported protocol version "
924 "%02x\n", ( aoehdr->ver_flags & AOE_VERSION_MASK ) );
926 goto err_sanity;
927 }
928 if ( ! ( aoehdr->ver_flags & AOE_FL_RESPONSE ) ) {
929 DBG ( "AoE received request packet\n" );
930 rc = -EOPNOTSUPP;
931 goto err_sanity;
932 }
933
934 /* Demultiplex amongst active AoE commands */
936 if ( ! aoecmd ) {
937 DBG ( "AoE received packet for unused tag %08x\n",
938 ntohl ( aoehdr->tag ) );
939 rc = -ENOENT;
940 goto err_demux;
941 }
942
943 /* Pass received frame to command */
944 aoecmd_get ( aoecmd );
945 if ( ( rc = aoecmd_rx ( aoecmd, iob_disown ( iobuf ),
946 ll_source ) ) != 0 )
947 goto err_rx;
948
949 err_rx:
950 aoecmd_put ( aoecmd );
951 err_demux:
952 err_sanity:
953 free_iob ( iobuf );
954 return rc;
955}
956
957/** AoE protocol */
958struct net_protocol aoe_protocol __net_protocol = {
959 .name = "AoE",
960 .net_proto = htons ( ETH_P_AOE ),
961 .rx = aoe_rx,
962};
963
964/******************************************************************************
965 *
966 * AoE URIs
967 *
968 ******************************************************************************
969 */
970
971/**
972 * Parse AoE URI
973 *
974 * @v uri URI
975 * @ret major Major device number
976 * @ret minor Minor device number
977 * @ret rc Return status code
978 *
979 * An AoE URI has the form "aoe:e<major>.<minor>".
980 */
981static int aoe_parse_uri ( struct uri *uri, unsigned int *major,
982 unsigned int *minor ) {
983 const char *ptr;
984 char *end;
985
986 /* Check for URI with opaque portion */
987 if ( ! uri->opaque )
988 return -EINVAL;
989 ptr = uri->opaque;
990
991 /* Check for initial 'e' */
992 if ( *ptr != 'e' )
993 return -EINVAL;
994 ptr++;
995
996 /* Parse major device number */
997 *major = strtoul ( ptr, &end, 10 );
998 if ( *end != '.' )
999 return -EINVAL;
1000 ptr = ( end + 1 );
1001
1002 /* Parse minor device number */
1003 *minor = strtoul ( ptr, &end, 10 );
1004 if ( *end )
1005 return -EINVAL;
1006
1007 return 0;
1008}
1009
1010/**
1011 * Open AoE URI
1012 *
1013 * @v parent Parent interface
1014 * @v uri URI
1015 * @ret rc Return status code
1016 */
1017static int aoe_open ( struct interface *parent, struct uri *uri ) {
1018 struct net_device *netdev;
1019 unsigned int major;
1020 unsigned int minor;
1021 int rc;
1022
1023 /* Identify network device. This is something of a hack, but
1024 * the AoE URI scheme that has been in use for some time now
1025 * provides no way to specify a particular device.
1026 */
1028 if ( ! netdev ) {
1029 DBG ( "AoE cannot identify network device\n" );
1030 return -ENODEV;
1031 }
1032
1033 /* Parse URI */
1034 if ( ( rc = aoe_parse_uri ( uri, &major, &minor ) ) != 0 ) {
1035 DBG ( "AoE cannot parse URI\n" );
1036 return rc;
1037 }
1038
1039 /* Open AoE device */
1040 if ( ( rc = aoedev_open ( parent, netdev, major, minor ) ) != 0 )
1041 return rc;
1042
1043 return 0;
1044}
1045
1046/** AoE URI opener */
1047struct uri_opener aoe_uri_opener __uri_opener = {
1048 .scheme = "aoe",
1049 .open = aoe_open,
1050};
1051
1052/******************************************************************************
1053 *
1054 * AoE boot firmware table (aBFT)
1055 *
1056 ******************************************************************************
1057 */
1058
1059/**
1060 * Check if AoE boot firmware table descriptor is complete
1061 *
1062 * @v desc ACPI descriptor
1063 * @ret rc Return status code
1064 */
1066 return 0;
1067}
1068
1069/**
1070 * Install AoE boot firmware table(s)
1071 *
1072 * @v install Installation method
1073 * @ret rc Return status code
1074 */
1075static int abft_install ( int ( * install ) ( struct acpi_header *acpi ) ) {
1076 struct aoe_device *aoedev;
1077 struct abft_table abft;
1078 int rc;
1079
1080 list_for_each_entry ( aoedev, &abft_model.descs, desc.list ) {
1081
1082 /* Populate table */
1083 memset ( &abft, 0, sizeof ( abft ) );
1085 abft.acpi.length = cpu_to_le32 ( sizeof ( abft ) );
1086 abft.acpi.revision = 1;
1087 abft.shelf = cpu_to_le16 ( aoedev->major );
1088 abft.slot = aoedev->minor;
1089 memcpy ( abft.mac, aoedev->netdev->ll_addr,
1090 sizeof ( abft.mac ) );
1091
1092 /* Install table */
1093 if ( ( rc = install ( &abft.acpi ) ) != 0 ) {
1094 DBGC ( aoedev, "AoE %s could not install aBFT: %s\n",
1095 aoedev_name ( aoedev ), strerror ( rc ) );
1096 return rc;
1097 }
1098 }
1099
1100 return 0;
1101}
1102
1103/** aBFT model */
1104struct acpi_model abft_model __acpi_model = {
1105 .descs = LIST_HEAD_INIT ( abft_model.descs ),
1106 .complete = abft_complete,
1107 .install = abft_install,
1108};
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
struct acpi_descriptor * acpi_describe(struct interface *intf)
Get object's ACPI descriptor.
Definition acpi.c:321
static int aoe_parse_uri(struct uri *uri, unsigned int *major, unsigned int *minor)
Parse AoE URI.
Definition aoe.c:981
static int aoedev_ata_command(struct aoe_device *aoedev, struct interface *parent, struct ata_cmd *command)
Issue AoE ATA command.
Definition aoe.c:659
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:439
static void aoecmd_free(struct refcnt *refcnt)
Free AoE command.
Definition aoe.c:189
static void aoecmd_close(struct aoe_command *aoecmd, int rc)
Close AoE command.
Definition aoe.c:206
static void aoedev_close(struct aoe_device *aoedev, int rc)
Close AoE device.
Definition aoe.c:737
static struct aoe_command_type aoecmd_ata
AoE ATA command.
Definition aoe.c:489
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:540
static void aoedev_free(struct refcnt *refcnt)
Free AoE device.
Definition aoe.c:723
static struct aoe_command * aoecmd_create(struct aoe_device *aoedev, struct aoe_command_type *type)
Create AoE command.
Definition aoe.c:622
static size_t aoecmd_cfg_cmd_len(struct aoe_command *aoecmd __unused)
Calculate length of AoE configuration command IU.
Definition aoe.c:501
static struct interface_descriptor aoecmd_ata_desc
AoE command ATA interface descriptor.
Definition aoe.c:579
static void aoecmd_expired(struct retry_timer *timer, int fail)
Handle AoE retry timer expiry.
Definition aoe.c:351
static struct aoe_device * aoedev_get(struct aoe_device *aoedev)
Get reference to AoE device.
Definition aoe.c:133
static struct device * aoedev_identify_device(struct aoe_device *aoedev)
Identify device underlying AoE device.
Definition aoe.c:793
static void aoedev_put(struct aoe_device *aoedev)
Drop reference to AoE device.
Definition aoe.c:144
static size_t aoedev_window(struct aoe_device *aoedev)
Check AoE device flow-control window.
Definition aoe.c:761
static struct interface_descriptor aoedev_ata_desc
AoE device ATA interface descriptor.
Definition aoe.c:819
static struct interface_operation aoedev_config_op[]
AoE device configuration interface operations.
Definition aoe.c:823
static int aoedev_cfg_command(struct aoe_device *aoedev, struct interface *parent)
Issue AoE configuration command.
Definition aoe.c:697
static void aoedev_config_done(struct aoe_device *aoedev, int rc)
Handle AoE device configuration completion.
Definition aoe.c:771
static int aoe_open(struct interface *parent, struct uri *uri)
Open AoE URI.
Definition aoe.c:1017
static int aoecmd_cfg_cmd(struct aoe_command *aoecmd, void *data, size_t len)
Build AoE configuration command IU.
Definition aoe.c:513
static struct interface_operation aoecmd_ata_op[]
AoE command ATA interface operations.
Definition aoe.c:574
static void aoecmd_put(struct aoe_command *aoecmd)
Drop reference to AoE command.
Definition aoe.c:166
static struct aoe_command * aoecmd_find_tag(uint32_t tag)
Identify AoE command by tag.
Definition aoe.c:588
static int aoecmd_rx(struct aoe_command *aoecmd, struct io_buffer *iobuf, const void *ll_source)
Receive AoE command response.
Definition aoe.c:297
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:905
static int aoedev_open(struct interface *parent, struct net_device *netdev, unsigned int major, unsigned int minor)
Open AoE device.
Definition aoe.c:840
static struct interface_descriptor aoedev_config_desc
AoE device configuration interface descriptor.
Definition aoe.c:828
static int aoecmd_ata_cmd(struct aoe_command *aoecmd, void *data, size_t len)
Build AoE ATA command IU.
Definition aoe.c:383
static int abft_install(int(*install)(struct acpi_header *acpi))
Install AoE boot firmware table(s).
Definition aoe.c:1075
static struct aoe_command * aoecmd_get(struct aoe_command *aoecmd)
Get reference to AoE command.
Definition aoe.c:155
static int aoecmd_new_tag(void)
Choose an AoE command tag.
Definition aoe.c:603
static struct interface_operation aoedev_ata_op[]
AoE device ATA interface operations.
Definition aoe.c:808
static int aoecmd_tx(struct aoe_command *aoecmd)
Transmit AoE command request.
Definition aoe.c:232
static size_t aoecmd_ata_cmd_len(struct aoe_command *aoecmd)
Calculate length of AoE ATA command IU.
Definition aoe.c:368
static struct acpi_descriptor * aoedev_describe(struct aoe_device *aoedev)
Get AoE ACPI descriptor.
Definition aoe.c:803
static int abft_complete(struct acpi_descriptor *desc __unused)
Check if AoE boot firmware table descriptor is complete.
Definition aoe.c:1065
static struct aoe_command_type aoecmd_cfg
AoE configuration command.
Definition aoe.c:567
static const char * aoedev_name(struct aoe_device *aoedev)
Name AoE device.
Definition aoe.c:176
AoE protocol.
#define AOE_FL_WRITE
Write command.
Definition aoe.h:60
#define AOE_FL_RESPONSE
Message is a response.
Definition aoe.h:91
#define AOE_FL_ERROR
Command generated an error.
Definition aoe.h:92
#define AOE_FL_DEV_HEAD
Device/head flag.
Definition aoe.h:58
#define AOE_TAG_MAGIC
AoE tag magic marker.
Definition aoe.h:110
#define AOE_CMD_CONFIG
Query Config Information.
Definition aoe.h:98
#define AOE_VERSION_MASK
Version part of ver_flags field.
Definition aoe.h:89
#define AOE_MAX_COUNT
Maximum number of sectors per packet.
Definition aoe.h:113
#define AOE_CMD_ATA
Issue ATA command.
Definition aoe.h:97
#define ABFT_SIG
AoE boot firmware table signature.
Definition aoe.h:145
#define AOE_VERSION
Version 1.
Definition aoe.h:88
#define AOE_FL_EXTENDED
LBA48 extended addressing.
Definition aoe.h:57
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned short uint16_t
Definition stdint.h:11
unsigned int uint32_t
Definition stdint.h:12
__SIZE_TYPE__ size_t
Definition stdint.h:6
Assertions.
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
int ata_open(struct interface *block, struct interface *ata, unsigned int device, unsigned int max_count)
Open ATA device.
Definition ata.c:654
ATA devices.
#define ATA_STAT_ERR
Command completed in error.
Definition ata.h:142
#define ATA_DEV_SLAVE
Slave ("device 1") flag in the ATA device register.
Definition ata.h:118
#define ATA_DEV_MASK
Mask of non-LBA portion of device register.
Definition ata.h:124
#define ATA_DEV_MASTER
Master ("device 0") flag in the ATA device register.
Definition ata.h:121
struct bofm_section_header done
Definition bofm_test.c:46
struct device * identify_device(struct interface *intf)
Identify a device behind an interface.
Definition device.c:126
Device model.
ring len
Length.
Definition dwmac.h:226
uint64_t tag
Identity tag.
Definition edd.h:1
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition efi_block.c:67
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition efi_path.c:949
EFI_DEVICE_PATH_PROTOCOL * efi_aoe_path(struct aoe_device *aoedev)
Construct EFI device path for AoE device.
Definition efi_path.c:601
EFI device paths.
uint32_t type
Operating system type.
Definition ena.h:1
uint8_t data[48]
Additional event data.
Definition ena.h:11
uint8_t flags
Flags.
Definition ena.h:7
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
Error codes.
static struct net_device * netdev
Definition gdbudp.c:53
#define __unused
Declare a variable or data structure as unused.
Definition compiler.h:598
#define DBGC2(...)
Definition compiler.h:547
#define DBGC(...)
Definition compiler.h:530
#define DBG(...)
Print a debugging message.
Definition compiler.h:523
#define DHCP_EB_FEATURE_AOE
AoE protocol.
Definition features.h:39
#define FEATURE_PROTOCOL
Network protocols.
Definition features.h:22
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
#define ENOENT
No such file or directory.
Definition errno.h:558
#define EINVAL
Invalid argument.
Definition errno.h:472
#define EWOULDBLOCK
Operation would block.
Definition errno.h:723
#define EOPNOTSUPP
Operation not supported on socket.
Definition errno.h:648
#define ETIMEDOUT
Connection timed out.
Definition errno.h:713
#define EADDRINUSE
Address already in use.
Definition errno.h:347
#define ENOMEM
Not enough space.
Definition errno.h:578
#define EIO
Input/output error.
Definition errno.h:477
#define ERANGE
Result too large.
Definition errno.h:683
#define ENODEV
No such device.
Definition errno.h:553
#define EPROTONOSUPPORT
Protocol not supported.
Definition errno.h:673
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:951
#define ETH_P_AOE
Definition if_ether.h:26
#define ntohl(value)
Definition byteswap.h:135
#define cpu_to_le64(value)
Definition byteswap.h:109
#define htonl(value)
Definition byteswap.h:134
#define cpu_to_le32(value)
Definition byteswap.h:108
#define htons(value)
Definition byteswap.h:136
#define ntohs(value)
Definition byteswap.h:137
#define cpu_to_le16(value)
Definition byteswap.h:107
#define __attribute__(x)
Definition compiler.h:10
#define __acpi_model
Declare an ACPI model.
Definition acpi.h:344
static void acpi_init(struct acpi_descriptor *desc, struct acpi_model *model, struct refcnt *refcnt)
Initialise ACPI descriptor.
Definition acpi.h:312
#define EFI_INTF_OP
Definition efi.h:381
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
Object interfaces.
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition iobuf.c:131
I/O buffers.
#define iob_put(iobuf, len)
Definition iobuf.h:185
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:277
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:220
#define iob_reserve(iobuf, len)
Definition iobuf.h:132
Feature list.
#define FEATURE(category, text, feature_opt, version)
Declare a feature.
Definition features.h:101
unsigned long tmp
Definition linux_pci.h:65
Linked lists.
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition list.h:31
#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
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
#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
#define list_empty(list)
Test whether a list is empty.
Definition list.h:137
#define LIST_HEAD(list)
Declare a static list head.
Definition list.h:38
#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:718
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:1078
struct net_device * last_opened_netdev(void)
Get most recently opened network device.
Definition netdevice.c:1052
Network device management.
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition netdevice.h:568
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition netdevice.h:665
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:579
#define MAX_LL_HEADER_LEN
Maximum length of a link-layer header.
Definition netdevice.h:46
#define __net_protocol
Declare a network-layer protocol.
Definition netdevice.h:477
uint32_t end
Ending offset.
Definition netvsc.h:7
uint32_t major
Major version.
Definition netvsc.h:3
uint32_t minor
Minor version.
Definition netvsc.h:5
Data transfer interface opening.
#define __uri_opener
Register a URI opener.
Definition open.h:68
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define ref_get(refcnt)
Get additional reference to object.
Definition refcnt.h:93
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
void start_timer(struct retry_timer *timer)
Start timer.
Definition retry.c:94
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition retry.c:118
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition string.c:516
AoE Boot Firmware Table (aBFT).
Definition aoe.h:150
uint8_t slot
AoE slot.
Definition aoe.h:156
uint8_t mac[ETH_ALEN]
MAC address.
Definition aoe.h:160
uint16_t shelf
AoE shelf.
Definition aoe.h:154
struct acpi_header acpi
ACPI header.
Definition aoe.h:152
An ACPI descriptor (used to construct ACPI tables).
Definition acpi.h:295
An ACPI description header.
Definition acpi.h:180
uint32_t signature
ACPI signature (4 ASCII characters).
Definition acpi.h:182
uint32_t length
Length of table, in bytes, including header.
Definition acpi.h:184
uint8_t revision
ACPI Specification minor version number.
Definition acpi.h:186
An ACPI table model.
Definition acpi.h:321
An AoE command type.
Definition aoe.c:96
int(* cmd)(struct aoe_command *aoecmd, void *data, size_t len)
Build AoE command IU.
Definition aoe.c:112
int(* rsp)(struct aoe_command *aoecmd, const void *data, size_t len, const void *ll_source)
Handle AoE response IU.
Definition aoe.c:122
size_t(* cmd_len)(struct aoe_command *aoecmd)
Calculate length of AoE command IU.
Definition aoe.c:103
An AoE command.
Definition aoe.c:73
struct interface ata
ATA command interface.
Definition aoe.c:82
struct list_head list
List of active commands.
Definition aoe.c:79
struct ata_cmd command
ATA command.
Definition aoe.c:85
struct aoe_device * aoedev
AOE device.
Definition aoe.c:77
struct aoe_command_type * type
Command type.
Definition aoe.c:87
struct refcnt refcnt
Reference count.
Definition aoe.c:75
uint32_t tag
Command tag.
Definition aoe.c:89
struct retry_timer timer
Retransmission timer.
Definition aoe.c:92
An AoE device.
Definition aoe.h:116
struct acpi_descriptor desc
ACPI descriptor.
Definition aoe.h:141
uint8_t minor
Minor number.
Definition aoe.h:128
struct interface ata
ATA command issuing interface.
Definition aoe.h:123
uint8_t target[MAX_LL_ADDR_LEN]
Target MAC address.
Definition aoe.h:130
int configured
Device is configued.
Definition aoe.h:138
struct refcnt refcnt
Reference counter.
Definition aoe.h:118
struct net_device * netdev
Network device.
Definition aoe.h:121
uint16_t major
Major number.
Definition aoe.h:126
struct interface config
Configuration command interface.
Definition aoe.h:136
unsigned long timeout
Saved timeout value.
Definition aoe.h:133
An AoE ATA command.
Definition aoe.h:39
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.
An AoE config command.
Definition aoe.h:23
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
An AoE header.
Definition aoe.h:71
uint16_t major
Major device number, in network byte order.
Definition aoe.h:77
uint8_t command
Command number.
Definition aoe.h:81
union aoecmd payload[0]
Payload.
Definition aoe.h:85
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
An ATA command information unit.
Definition ata.h:169
An ATA command.
Definition ata.c:110
A command-line command.
Definition command.h:10
A hardware device.
Definition device.h:77
An object interface descriptor.
Definition interface.h:56
An object interface operation.
Definition interface.h:18
An object interface.
Definition interface.h:125
A persistent I/O buffer.
Definition iobuf.h:98
void * data
Start of data.
Definition iobuf.h:113
A doubly-linked list entry (or list head).
Definition list.h:19
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
A network device.
Definition netdevice.h:353
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition netdevice.h:373
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition netdevice.h:363
struct device * dev
Underlying hardware device.
Definition netdevice.h:365
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition netdevice.h:388
A network-layer protocol.
Definition netdevice.h:65
A reference counter.
Definition refcnt.h:27
A retry timer.
Definition retry.h:22
A timer.
Definition timer.h:29
A URI opener.
Definition open.h:48
A Uniform Resource Identifier.
Definition uri.h:65
const char * opaque
Opaque part.
Definition uri.h:71
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes).
Definition ucode.h:15
An AoE command.
Definition aoe.h:63
struct aoeata ata
ATA command.
Definition aoe.h:67
struct aoecfg cfg
Config command.
Definition aoe.h:65
Uniform Resource Identifiers.
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition xfer.c:147
Data transfer interfaces.
int xferbuf_read(struct xfer_buffer *xferbuf, size_t offset, void *data, size_t len)
Read from data transfer buffer.
Definition xferbuf.c:166
int xferbuf_write(struct xfer_buffer *xferbuf, size_t offset, const void *data, size_t len)
Write to data transfer buffer.
Definition xferbuf.c:133