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