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 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_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 
56 struct net_protocol aoe_protocol __net_protocol;
57 struct acpi_model abft_model __acpi_model;
58 
59 /******************************************************************************
60  *
61  * AoE devices and commands
62  *
63  ******************************************************************************
64  */
65 
66 /** List of all AoE devices */
67 static LIST_HEAD ( aoe_devices );
68 
69 /** List of active AoE commands */
70 static LIST_HEAD ( aoe_commands );
71 
72 /** An AoE command */
73 struct aoe_command {
74  /** Reference count */
75  struct refcnt refcnt;
76  /** AOE device */
77  struct aoe_device *aoedev;
78  /** List of active commands */
79  struct list_head list;
80 
81  /** ATA command interface */
82  struct interface ata;
83 
84  /** ATA command */
85  struct ata_cmd 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  */
111  void ( * cmd ) ( struct aoe_command *aoecmd, void *data, size_t len );
112  /**
113  * Handle AoE response IU
114  *
115  * @v aoecmd AoE command
116  * @v data Response IU
117  * @v len Length of response IU
118  * @v ll_source Link-layer source address
119  * @ret rc Return status code
120  */
121  int ( * rsp ) ( struct aoe_command *aoecmd, const void *data,
122  size_t len, const void *ll_source );
123 };
124 
125 /**
126  * Get reference to AoE device
127  *
128  * @v aoedev AoE device
129  * @ret aoedev AoE device
130  */
131 static inline __attribute__ (( always_inline )) struct aoe_device *
132 aoedev_get ( struct aoe_device *aoedev ) {
133  ref_get ( &aoedev->refcnt );
134  return aoedev;
135 }
136 
137 /**
138  * Drop reference to AoE device
139  *
140  * @v aoedev AoE device
141  */
142 static inline __attribute__ (( always_inline )) void
143 aoedev_put ( struct aoe_device *aoedev ) {
144  ref_put ( &aoedev->refcnt );
145 }
146 
147 /**
148  * Get reference to AoE command
149  *
150  * @v aoecmd AoE command
151  * @ret aoecmd AoE command
152  */
153 static inline __attribute__ (( always_inline )) struct aoe_command *
155  ref_get ( &aoecmd->refcnt );
156  return aoecmd;
157 }
158 
159 /**
160  * Drop reference to AoE command
161  *
162  * @v aoecmd AoE command
163  */
164 static inline __attribute__ (( always_inline )) void
166  ref_put ( &aoecmd->refcnt );
167 }
168 
169 /**
170  * Name AoE device
171  *
172  * @v aoedev AoE device
173  * @ret name AoE device name
174  */
175 static const char * aoedev_name ( struct aoe_device *aoedev ) {
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 }
182 
183 /**
184  * Free AoE command
185  *
186  * @v refcnt Reference counter
187  */
188 static void aoecmd_free ( struct refcnt *refcnt ) {
189  struct aoe_command *aoecmd =
190  container_of ( refcnt, struct aoe_command, refcnt );
191 
192  assert ( ! timer_running ( &aoecmd->timer ) );
193  assert ( list_empty ( &aoecmd->list ) );
194 
195  aoedev_put ( aoecmd->aoedev );
196  free ( aoecmd );
197 }
198 
199 /**
200  * Close AoE command
201  *
202  * @v aoecmd AoE command
203  * @v rc Reason for close
204  */
205 static void aoecmd_close ( struct aoe_command *aoecmd, int rc ) {
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 }
224 
225 /**
226  * Transmit AoE command request
227  *
228  * @v aoecmd AoE command
229  * @ret rc Return status code
230  */
231 static int aoecmd_tx ( struct aoe_command *aoecmd ) {
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;
254  iob_reserve ( iobuf, MAX_LL_HEADER_LEN );
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 }
276 
277 /**
278  * Receive AoE command response
279  *
280  * @v aoecmd AoE command
281  * @v iobuf I/O buffer
282  * @v ll_source Link-layer source address
283  * @ret rc Return status code
284  */
285 static int aoecmd_rx ( struct aoe_command *aoecmd, struct io_buffer *iobuf,
286  const void *ll_source ) {
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 */
327  aoecmd_close ( aoecmd, rc );
328 
329  return rc;
330 }
331 
332 /**
333  * Handle AoE retry timer expiry
334  *
335  * @v timer AoE retry timer
336  * @v fail Failure indicator
337  */
338 static void aoecmd_expired ( struct retry_timer *timer, int fail ) {
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 }
348 
349 /**
350  * Calculate length of AoE ATA command IU
351  *
352  * @v aoecmd AoE command
353  * @ret len Length of command IU
354  */
355 static size_t aoecmd_ata_cmd_len ( struct aoe_command *aoecmd ) {
356  struct ata_cmd *command = &aoecmd->command;
357 
358  return ( sizeof ( struct aoehdr ) + sizeof ( struct aoeata ) +
359  command->data_out_len );
360 }
361 
362 /**
363  * Build AoE ATA command IU
364  *
365  * @v aoecmd AoE command
366  * @v data Command IU
367  * @v len Length of command IU
368  */
369 static void aoecmd_ata_cmd ( struct aoe_command *aoecmd,
370  void *data, size_t len ) {
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 */
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 }
406 
407 /**
408  * Handle AoE ATA response IU
409  *
410  * @v aoecmd AoE command
411  * @v data Response IU
412  * @v len Length of response IU
413  * @v ll_source Link-layer source address
414  * @ret rc Return status code
415  */
416 static int aoecmd_ata_rsp ( struct aoe_command *aoecmd, const void *data,
417  size_t len, const void *ll_source __unused ) {
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 }
458 
459 /** AoE ATA command */
460 static struct aoe_command_type aoecmd_ata = {
462  .cmd = aoecmd_ata_cmd,
463  .rsp = aoecmd_ata_rsp,
464 };
465 
466 /**
467  * Calculate length of AoE configuration command IU
468  *
469  * @v aoecmd AoE command
470  * @ret len Length of command IU
471  */
472 static size_t aoecmd_cfg_cmd_len ( struct aoe_command *aoecmd __unused ) {
473  return ( sizeof ( struct aoehdr ) + sizeof ( struct aoecfg ) );
474 }
475 
476 /**
477  * Build AoE configuration command IU
478  *
479  * @v aoecmd AoE command
480  * @v data Command IU
481  * @v len Length of command IU
482  */
483 static void aoecmd_cfg_cmd ( struct aoe_command *aoecmd,
484  void *data, size_t len ) {
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 }
499 
500 /**
501  * Handle AoE configuration response IU
502  *
503  * @v aoecmd AoE command
504  * @v data Response IU
505  * @v len Length of response IU
506  * @v ll_source Link-layer source address
507  * @ret rc Return status code
508  */
509 static int aoecmd_cfg_rsp ( struct aoe_command *aoecmd, const void *data,
510  size_t len, const void *ll_source ) {
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 }
534 
535 /** AoE configuration command */
536 static struct aoe_command_type aoecmd_cfg = {
538  .cmd = aoecmd_cfg_cmd,
539  .rsp = aoecmd_cfg_rsp,
540 };
541 
542 /** AoE command ATA interface operations */
545 };
546 
547 /** AoE command ATA interface descriptor */
549  INTF_DESC ( struct aoe_command, ata, aoecmd_ata_op );
550 
551 /**
552  * Identify AoE command by tag
553  *
554  * @v tag Command tag
555  * @ret aoecmd AoE command, or NULL
556  */
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 }
566 
567 /**
568  * Choose an AoE command tag
569  *
570  * @ret tag New tag, or negative error
571  */
572 static int aoecmd_new_tag ( void ) {
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 }
583 
584 /**
585  * Create AoE command
586  *
587  * @v aoedev AoE device
588  * @v type AoE command type
589  * @ret aoecmd AoE command
590  */
591 static struct aoe_command * aoecmd_create ( struct aoe_device *aoedev,
592  struct aoe_command_type *type ) {
593  struct aoe_command *aoecmd;
594  int tag;
595 
596  /* Allocate command tag */
597  tag = aoecmd_new_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 }
619 
620 /**
621  * Issue AoE ATA command
622  *
623  * @v aoedev AoE device
624  * @v parent Parent interface
625  * @v command ATA command
626  * @ret tag Command tag, or negative error
627  */
628 static int aoedev_ata_command ( struct aoe_device *aoedev,
629  struct interface *parent,
630  struct ata_cmd *command ) {
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 }
658 
659 /**
660  * Issue AoE configuration command
661  *
662  * @v aoedev AoE device
663  * @v parent Parent interface
664  * @ret tag Command tag, or negative error
665  */
666 static int aoedev_cfg_command ( struct aoe_device *aoedev,
667  struct interface *parent ) {
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 }
686 
687 /**
688  * Free AoE device
689  *
690  * @v refcnt Reference count
691  */
692 static void aoedev_free ( struct refcnt *refcnt ) {
693  struct aoe_device *aoedev =
694  container_of ( refcnt, struct aoe_device, refcnt );
695 
696  netdev_put ( aoedev->netdev );
697  free ( aoedev );
698 }
699 
700 /**
701  * Close AoE device
702  *
703  * @v aoedev AoE device
704  * @v rc Reason for close
705  */
706 static void aoedev_close ( struct aoe_device *aoedev, int rc ) {
707  struct aoe_command *aoecmd;
708  struct aoe_command *tmp;
709 
710  /* Shut down interfaces */
711  intf_shutdown ( &aoedev->ata, rc );
712  intf_shutdown ( &aoedev->config, 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 );
719  aoecmd_close ( aoecmd, rc );
720  aoecmd_put ( aoecmd );
721  }
722 }
723 
724 /**
725  * Check AoE device flow-control window
726  *
727  * @v aoedev AoE device
728  * @ret len Length of window
729  */
730 static size_t aoedev_window ( struct aoe_device *aoedev ) {
731  return ( aoedev->configured ? ~( ( size_t ) 0 ) : 0 );
732 }
733 
734 /**
735  * Handle AoE device configuration completion
736  *
737  * @v aoedev AoE device
738  * @v rc Reason for completion
739  */
740 static void aoedev_config_done ( struct aoe_device *aoedev, int rc ) {
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;
754 }
755 
756 /**
757  * Identify device underlying AoE device
758  *
759  * @v aoedev AoE device
760  * @ret device Underlying device
761  */
762 static struct device * aoedev_identify_device ( struct aoe_device *aoedev ) {
763  return aoedev->netdev->dev;
764 }
765 
766 /**
767  * Get AoE ACPI descriptor
768  *
769  * @v aoedev AoE device
770  * @ret desc ACPI descriptor
771  */
772 static struct acpi_descriptor * aoedev_describe ( struct aoe_device *aoedev ) {
773  return &aoedev->desc;
774 }
775 
776 /** AoE device ATA interface operations */
780  INTF_OP ( intf_close, struct aoe_device *, aoedev_close ),
782  INTF_OP ( identify_device, struct aoe_device *,
785 };
786 
787 /** AoE device ATA interface descriptor */
789  INTF_DESC ( struct aoe_device, ata, aoedev_ata_op );
790 
791 /** AoE device configuration interface operations */
794 };
795 
796 /** AoE device configuration interface descriptor */
798  INTF_DESC ( struct aoe_device, config, aoedev_config_op );
799 
800 /**
801  * Open AoE device
802  *
803  * @v parent Parent interface
804  * @v netdev Network device
805  * @v major Device major number
806  * @v minor Device minor number
807  * @ret rc Return status code
808  */
809 static int aoedev_open ( struct interface *parent, struct net_device *netdev,
810  unsigned int major, unsigned int minor ) {
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,
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 }
856 
857 /******************************************************************************
858  *
859  * AoE network protocol
860  *
861  ******************************************************************************
862  */
863 
864 /**
865  * Process incoming AoE packets
866  *
867  * @v iobuf I/O buffer
868  * @v netdev Network device
869  * @v ll_dest Link-layer destination address
870  * @v ll_source Link-layer source address
871  * @v flags Packet flags
872  * @ret rc Return status code
873  */
874 static int aoe_rx ( struct io_buffer *iobuf,
875  struct net_device *netdev __unused,
876  const void *ll_dest __unused,
877  const void *ll_source,
878  unsigned int flags __unused ) {
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  }
890  if ( ( aoehdr->ver_flags & AOE_VERSION_MASK ) != AOE_VERSION ) {
891  DBG ( "AoE received packet for unsupported protocol version "
892  "%02x\n", ( aoehdr->ver_flags & AOE_VERSION_MASK ) );
893  rc = -EPROTONOSUPPORT;
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 }
924 
925 /** AoE protocol */
926 struct net_protocol aoe_protocol __net_protocol = {
927  .name = "AoE",
928  .net_proto = htons ( ETH_P_AOE ),
929  .rx = aoe_rx,
930 };
931 
932 /******************************************************************************
933  *
934  * AoE URIs
935  *
936  ******************************************************************************
937  */
938 
939 /**
940  * Parse AoE URI
941  *
942  * @v uri URI
943  * @ret major Major device number
944  * @ret minor Minor device number
945  * @ret rc Return status code
946  *
947  * An AoE URI has the form "aoe:e<major>.<minor>".
948  */
949 static int aoe_parse_uri ( struct uri *uri, unsigned int *major,
950  unsigned int *minor ) {
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 }
977 
978 /**
979  * Open AoE URI
980  *
981  * @v parent Parent interface
982  * @v uri URI
983  * @ret rc Return status code
984  */
985 static int aoe_open ( struct interface *parent, struct uri *uri ) {
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 }
1013 
1014 /** AoE URI opener */
1015 struct uri_opener aoe_uri_opener __uri_opener = {
1016  .scheme = "aoe",
1017  .open = aoe_open,
1018 };
1019 
1020 /******************************************************************************
1021  *
1022  * AoE boot firmware table (aBFT)
1023  *
1024  ******************************************************************************
1025  */
1026 
1027 /**
1028  * Check if AoE boot firmware table descriptor is complete
1029  *
1030  * @v desc ACPI descriptor
1031  * @ret rc Return status code
1032  */
1033 static int abft_complete ( struct acpi_descriptor *desc __unused ) {
1034  return 0;
1035 }
1036 
1037 /**
1038  * Install AoE boot firmware table(s)
1039  *
1040  * @v install Installation method
1041  * @ret rc Return status code
1042  */
1043 static int abft_install ( int ( * install ) ( struct acpi_header *acpi ) ) {
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 }
1070 
1071 /** aBFT model */
1072 struct acpi_model abft_model __acpi_model = {
1073  .descs = LIST_HEAD_INIT ( abft_model.descs ),
1074  .complete = abft_complete,
1075  .install = abft_install,
1076 };
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define __attribute__(x)
Definition: compiler.h:10
#define EINVAL
Invalid argument.
Definition: errno.h:429
An object interface operation.
Definition: interface.h:18
struct aoecfg cfg
Config command.
Definition: aoe.h:65
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:147
unsigned short uint16_t
Definition: stdint.h:11
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:250
static struct aoe_command * aoecmd_find_tag(uint32_t tag)
Identify AoE command by tag.
Definition: aoe.c:557
const char * name
Protocol name.
Definition: netdevice.h:67
struct acpi_header acpi
ACPI header.
Definition: aoe.h:152
#define iob_put(iobuf, len)
Definition: iobuf.h:125
#define AOE_TAG_MAGIC
AoE tag magic marker.
Definition: aoe.h:110
static struct aoe_device * aoedev_get(struct aoe_device *aoedev)
Get reference to AoE device.
Definition: aoe.c:132
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:279
static size_t aoecmd_ata_cmd_len(struct aoe_command *aoecmd)
Calculate length of AoE ATA command IU.
Definition: aoe.c:355
static struct interface_operation aoedev_ata_op[]
AoE device ATA interface operations.
Definition: aoe.c:777
uint8_t ll_addr_len
Link-layer address length.
Definition: netdevice.h:199
static int aoe_parse_uri(struct uri *uri, unsigned int *major, unsigned int *minor)
Parse AoE URI.
Definition: aoe.c:949
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:485
static int abft_complete(struct acpi_descriptor *desc __unused)
Check if AoE boot firmware table descriptor is complete.
Definition: aoe.c:1033
uint8_t err_feat
ATA error/feature register.
Definition: aoe.h:43
struct acpi_model abft_model __acpi_model
aBFT model
Definition: aoe.c:57
uint32_t signature
ACPI signature (4 ASCII characters)
Definition: acpi.h:182
An AoE ATA command.
Definition: aoe.h:39
int(* rsp)(struct aoe_command *aoecmd, const void *data, size_t len, const void *ll_source)
Handle AoE response IU.
Definition: aoe.c:121
#define FEATURE_PROTOCOL
Network protocols.
Definition: features.h:22
static struct interface_descriptor aoedev_config_desc
AoE device configuration interface descriptor.
Definition: aoe.c:797
static int aoe_open(struct interface *parent, struct uri *uri)
Open AoE URI.
Definition: aoe.c:985
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:70
#define AOE_MAX_COUNT
Maximum number of sectors per packet.
Definition: aoe.h:113
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:65
Error codes.
__SIZE_TYPE__ size_t
Definition: stdint.h:6
struct list_head descs
List of descriptors.
Definition: acpi.h:323
A command-line command.
Definition: command.h:10
I/O buffers.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
uint8_t bytes[6]
Definition: aoe.h:51
static struct interface_descriptor aoecmd_ata_desc
AoE command ATA interface descriptor.
Definition: aoe.c:548
uint32_t type
Operating system type.
Definition: ena.h:12
#define EADDRINUSE
Address already in use.
Definition: errno.h:304
uint16_t major
Major number.
Definition: aoe.h:126
uint8_t data[0]
Data payload.
Definition: aoe.h:54
#define DBGC(...)
Definition: compiler.h:505
union aoecmd payload[0]
Payload.
Definition: aoe.h:85
static size_t aoedev_window(struct aoe_device *aoedev)
Check AoE device flow-control window.
Definition: aoe.c:730
#define AOE_VERSION_MASK
Version part of ver_flags field.
Definition: aoe.h:89
static struct aoe_command_type aoecmd_cfg
AoE configuration command.
Definition: aoe.c:536
static int aoecmd_new_tag(void)
Choose an AoE command tag.
Definition: aoe.c:572
A retry timer.
Definition: retry.h:22
#define ENOENT
No such file or directory.
Definition: errno.h:515
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:108
const uint8_t * ll_broadcast
Link-layer broadcast address.
Definition: netdevice.h:390
uint16_t major
Major device number, in network byte order.
Definition: aoe.h:77
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 int aoecmd_tx(struct aoe_command *aoecmd)
Transmit AoE command request.
Definition: aoe.c:231
#define ntohl(value)
Definition: byteswap.h:135
uint16_t fwver
ATA target firmware version.
Definition: aoe.h:27
static int abft_install(int(*install)(struct acpi_header *acpi))
Install AoE boot firmware table(s)
Definition: aoe.c:1043
#define cpu_to_le64(value)
Definition: byteswap.h:109
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition: ucode.h:26
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 ntohs(value)
Definition: byteswap.h:137
#define static_assert(x)
Assert a condition at build time.
Definition: assert.h:66
Uniform Resource Identifiers.
struct list_head list
List of active commands.
Definition: aoe.c:79
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:131
unsigned long timeout
Saved timeout value.
Definition: aoe.h:133
#define htonl(value)
Definition: byteswap.h:134
uint8_t cmd_stat
ATA command/status register.
Definition: aoe.h:47
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:117
A link-layer protocol.
Definition: netdevice.h:115
FEATURE(FEATURE_PROTOCOL, "AoE", DHCP_EB_FEATURE_AOE, 1)
An AoE device.
Definition: aoe.h:116
A doubly-linked list entry (or list head)
Definition: list.h:19
uint8_t command
Command number.
Definition: aoe.h:81
Data transfer interfaces.
A reference counter.
Definition: refcnt.h:27
A timer.
Definition: timer.h:29
struct net_protocol aoe_protocol __net_protocol
AoE protocol.
Definition: aoe.c:56
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:137
uint8_t mac[ETH_ALEN]
MAC address.
Definition: aoe.h:160
unsigned long tmp
Definition: linux_pci.h:65
static void aoecmd_ata_cmd(struct aoe_command *aoecmd, void *data, size_t len)
Build AoE ATA command IU.
Definition: aoe.c:369
#define list_del(list)
Delete an entry from a list.
Definition: list.h:120
struct ena_llq_option desc
Descriptor counts.
Definition: ena.h:20
#define ENOMEM
Not enough space.
Definition: errno.h:535
A hardware device.
Definition: device.h:77
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:217
AoE protocol.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
union aoeata::@508 lba
Logical block address, in little-endian order.
static void aoecmd_cfg_cmd(struct aoe_command *aoecmd, void *data, size_t len)
Build AoE configuration command IU.
Definition: aoe.c:483
uint32_t major
Major version.
Definition: netvsc.h:14
uint32_t minor
Minor version.
Definition: netvsc.h:16
static int netdev_is_open(struct net_device *netdev)
Check whether or not network device is open.
Definition: netdevice.h:662
#define AOE_FL_WRITE
Write command.
Definition: aoe.h:60
Assertions.
#define ATA_DEV_MASTER
Master ("device 0") flag in the ATA device register.
Definition: ata.h:120
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:576
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:36
An object interface.
Definition: interface.h:125
#define EWOULDBLOCK
Operation would block.
Definition: errno.h:680
An ACPI table model.
Definition: acpi.h:321
uint32_t length
Length of table, in bytes, including header.
Definition: acpi.h:184
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:432
size_t(* cmd_len)(struct aoe_command *aoecmd)
Calculate length of AoE command IU.
Definition: aoe.c:103
void(* cmd)(struct aoe_command *aoecmd, void *data, size_t len)
Build AoE command IU.
Definition: aoe.c:111
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
Object interfaces.
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition: efi_block.c:67
struct aoe_device * aoedev
AOE device.
Definition: aoe.c:77
ring len
Length.
Definition: dwmac.h:231
#define AOE_VERSION
Version 1.
Definition: aoe.h:88
static struct net_device * netdev
Definition: gdbudp.c:52
const char * scheme
URI protocol name.
Definition: open.h:54
struct net_device * last_opened_netdev(void)
Get most recently opened network device.
Definition: netdevice.c:1048
An ATA command information unit.
Definition: ata.h:168
#define MAX_LL_HEADER_LEN
Maximum length of a link-layer header.
Definition: netdevice.h:46
struct acpi_descriptor desc
ACPI descriptor.
Definition: aoe.h:141
uint8_t minor
Minor device number.
Definition: aoe.h:79
Feature list.
static int aoedev_cfg_command(struct aoe_device *aoedev, struct interface *parent)
Issue AoE configuration command.
Definition: aoe.c:666
struct interface ata
ATA command issuing interface.
Definition: aoe.h:123
uint8_t slot
AoE slot.
Definition: aoe.h:156
#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 cpu_to_le32(value)
Definition: byteswap.h:108
struct aoe_command_type * type
Command type.
Definition: aoe.c:87
static struct aoe_command * aoecmd_create(struct aoe_device *aoedev, struct aoe_command_type *type)
Create AoE command.
Definition: aoe.c:591
An AoE command.
Definition: aoe.h:63
Linked lists.
#define EFI_INTF_OP
Definition: efi.h:374
#define DHCP_EB_FEATURE_AOE
AoE protocol.
Definition: features.h:39
An object interface descriptor.
Definition: interface.h:56
uint8_t target[MAX_LL_ADDR_LEN]
Target MAC address.
Definition: aoe.h:130
uint8_t flags
Flags.
Definition: ena.h:18
#define ERANGE
Result too large.
Definition: errno.h:640
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
An AoE config command.
Definition: aoe.h:23
static void aoedev_close(struct aoe_device *aoedev, int rc)
Close AoE device.
Definition: aoe.c:706
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662
#define ETH_P_AOE
Definition: if_ether.h:26
static struct interface_operation aoecmd_ata_op[]
AoE command ATA interface operations.
Definition: aoe.c:543
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:93
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33
uint32_t tag
Tag, in network byte order.
Definition: aoe.h:83
uint16_t bufcnt
AoE queue depth.
Definition: aoe.h:25
#define EOPNOTSUPP
Operation not supported on socket.
Definition: errno.h:605
struct refcnt refcnt
Reference counter.
Definition: aoe.h:118
A network device.
Definition: netdevice.h:353
struct interface config
Configuration command interface.
Definition: aoe.h:136
#define ENODEV
No such device.
Definition: errno.h:510
Data transfer interface opening.
EFI device paths.
uint8_t aflags
AoE command flags.
Definition: aoe.h:41
static struct net_device * netdev_get(struct net_device *netdev)
Get reference to network device.
Definition: netdevice.h:565
AoE Boot Firmware Table (aBFT)
Definition: aoe.h:150
ATA devices.
uint32_t tag
Command tag.
Definition: aoe.c:89
An ACPI description header.
Definition: acpi.h:180
static int aoecmd_rx(struct aoe_command *aoecmd, struct io_buffer *iobuf, const void *ll_source)
Receive AoE command response.
Definition: aoe.c:285
unsigned int uint32_t
Definition: stdint.h:12
struct acpi_descriptor * acpi_describe(struct interface *intf)
Get object's ACPI descriptor.
Definition: acpi.c:321
#define ATA_STAT_ERR
Command completed in error.
Definition: ata.h:141
uint64_t u64
Definition: aoe.h:50
struct uri_opener aoe_uri_opener __uri_opener
AoE URI opener.
Definition: aoe.c:1015
#define AOE_CMD_CONFIG
Query Config Information.
Definition: aoe.h:98
struct device * dev
Underlying hardware device.
Definition: netdevice.h:365
void start_timer(struct retry_timer *timer)
Start timer.
Definition: retry.c:94
A network-layer protocol.
Definition: netdevice.h:65
Network device management.
#define iob_reserve(iobuf, len)
Definition: iobuf.h:72
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:46
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:81
An ACPI descriptor (used to construct ACPI tables)
Definition: acpi.h:295
static void aoedev_config_done(struct aoe_device *aoedev, int rc)
Handle AoE device configuration completion.
Definition: aoe.c:740
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:118
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
#define ABFT_SIG
AoE boot firmware table signature.
Definition: aoe.h:145
static struct device * aoedev_identify_device(struct aoe_device *aoedev)
Identify device underlying AoE device.
Definition: aoe.c:762
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition: efi_path.c:920
char name[NETDEV_NAME_LEN]
Name of this network device.
Definition: netdevice.h:363
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
const char * opaque
Opaque part.
Definition: uri.h:71
#define DBGC2(...)
Definition: compiler.h:522
#define EPROTONOSUPPORT
Protocol not supported.
Definition: errno.h:630
static void aoecmd_expired(struct retry_timer *timer, int fail)
Handle AoE retry timer expiry.
Definition: aoe.c:338
EFI_DEVICE_PATH_PROTOCOL * efi_aoe_path(struct aoe_device *aoedev)
Construct EFI device path for AoE device.
Definition: efi_path.c:572
int configured
Device is configued.
Definition: aoe.h:138
void * data
Start of data.
Definition: iobuf.h:53
uint8_t count
ATA sector count register.
Definition: aoe.h:45
static void aoecmd_put(struct aoe_command *aoecmd)
Drop reference to AoE command.
Definition: aoe.c:165
#define EIO
Input/output error.
Definition: errno.h:434
static void aoecmd_free(struct refcnt *refcnt)
Free AoE command.
Definition: aoe.c:188
static struct aoe_command_type aoecmd_ata
AoE ATA command.
Definition: aoe.c:460
static size_t aoecmd_cfg_cmd_len(struct aoe_command *aoecmd __unused)
Calculate length of AoE configuration command IU.
Definition: aoe.c:472
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
#define cpu_to_le16(value)
Definition: byteswap.h:107
uint8_t minor
Minor number.
Definition: aoe.h:128
uint32_t end
Ending offset.
Definition: netvsc.h:18
struct net_device * netdev
Network device.
Definition: aoe.h:121
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t ver_flags
Protocol version number and flags.
Definition: aoe.h:73
static void aoedev_free(struct refcnt *refcnt)
Free AoE device.
Definition: aoe.c:692
#define AOE_FL_ERROR
Command generated an error.
Definition: aoe.h:92
const char *(* ntoa)(const void *ll_addr)
Transcribe link-layer address.
Definition: netdevice.h:164
static int aoedev_open(struct interface *parent, struct net_device *netdev, unsigned int major, unsigned int minor)
Open AoE device.
Definition: aoe.c:809
Device model.
int ata_open(struct interface *block, struct interface *ata, unsigned int device, unsigned int max_count)
Open ATA device.
Definition: ata.c:663
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:383
A Uniform Resource Identifier.
Definition: uri.h:65
uint8_t scnt
ATA target sector count.
Definition: aoe.h:29
struct aoeata ata
ATA command.
Definition: aoe.h:67
uint8_t revision
ACPI Specification minor version number.
Definition: acpi.h:186
#define AOE_CMD_ATA
Issue ATA command.
Definition: aoe.h:97
struct device * identify_device(struct interface *intf)
Identify a device behind an interface.
Definition: device.c:126
static void aoecmd_close(struct aoe_command *aoecmd, int rc)
Close AoE command.
Definition: aoe.c:205
An AoE header.
Definition: aoe.h:71
static void aoedev_put(struct aoe_device *aoedev)
Drop reference to AoE device.
Definition: aoe.c:143
static LIST_HEAD(aoe_devices)
List of all AoE devices.
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:388
#define AOE_FL_RESPONSE
Message is a response.
Definition: aoe.h:91
#define AOE_FL_EXTENDED
LBA48 extended addressing.
Definition: aoe.h:57
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
static struct interface_descriptor aoedev_ata_desc
AoE device ATA interface descriptor.
Definition: aoe.c:788
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition: list.h:31
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:204
A URI opener.
Definition: open.h:48
uint64_t tag
Identity tag.
Definition: edd.h:31
static struct aoe_command * aoecmd_get(struct aoe_command *aoecmd)
Get reference to AoE command.
Definition: aoe.c:154
FILE_SECBOOT(PERMITTED)
#define ATA_DEV_SLAVE
Slave ("device 1") flag in the ATA device register.
Definition: ata.h:117
An AoE command.
Definition: aoe.c:73
#define ATA_DEV_MASK
Mask of non-LBA portion of device register.
Definition: ata.h:123
An ATA command.
Definition: ata.c:110
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#define AOE_FL_DEV_HEAD
Device/head flag.
Definition: aoe.h:58
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:670
String functions.
static struct acpi_descriptor * aoedev_describe(struct aoe_device *aoedev)
Get AoE ACPI descriptor.
Definition: aoe.c:772
uint16_t shelf
AoE shelf.
Definition: aoe.h:154
#define htons(value)
Definition: byteswap.h:136
struct bofm_section_header done
Definition: bofm_test.c:46
struct ll_protocol * ll_protocol
Link-layer protocol.
Definition: netdevice.h:373
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:107
static void acpi_init(struct acpi_descriptor *desc, struct acpi_model *model, struct refcnt *refcnt)
Initialise ACPI descriptor.
Definition: acpi.h:312
struct interface ata
ATA command interface.
Definition: aoe.c:82
void * memset(void *dest, int character, size_t len) __nonnull
static const char * aoedev_name(struct aoe_device *aoedev)
Name AoE device.
Definition: aoe.c:175
A persistent I/O buffer.
Definition: iobuf.h:38
An AoE command type.
Definition: aoe.c:96
static struct interface_operation aoedev_config_op[]
AoE device configuration interface operations.
Definition: aoe.c:792