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