2 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
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.
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.
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
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.
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
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>
42 #include <ipxe/open.h>
44 #include <ipxe/device.h>
53 FEATURE ( FEATURE_PROTOCOL, "AoE", DHCP_EB_FEATURE_AOE, 1 );
55 struct net_protocol aoe_protocol __net_protocol;
57 /******************************************************************************
59 * AoE devices and commands
61 ******************************************************************************
64 /** List of all AoE devices */
65 static LIST_HEAD ( aoe_devices );
67 /** List of active AoE commands */
68 static LIST_HEAD ( aoe_commands );
72 /** Reference counter */
76 struct net_device *netdev;
77 /** ATA command issuing interface */
84 /** Target MAC address */
85 uint8_t target[MAX_LL_ADDR_LEN];
87 /** Saved timeout value */
88 unsigned long timeout;
90 /** Configuration command interface */
91 struct interface config;
92 /** Device is configued */
98 /** Reference count */
101 struct aoe_device *aoedev;
102 /** List of active commands */
103 struct list_head list;
105 /** ATA command interface */
106 struct interface ata;
109 struct ata_cmd command;
111 struct aoe_command_type *type;
115 /** Retransmission timer */
116 struct retry_timer timer;
119 /** An AoE command type */
120 struct aoe_command_type {
122 * Calculate length of AoE command IU
124 * @v aoecmd AoE command
125 * @ret len Length of command IU
127 size_t ( * cmd_len ) ( struct aoe_command *aoecmd );
129 * Build AoE command IU
131 * @v aoecmd AoE command
133 * @v len Length of command IU
135 void ( * cmd ) ( struct aoe_command *aoecmd, void *data, size_t len );
137 * Handle AoE response IU
139 * @v aoecmd AoE command
140 * @v data Response IU
141 * @v len Length of response IU
142 * @v ll_source Link-layer source address
143 * @ret rc Return status code
145 int ( * rsp ) ( struct aoe_command *aoecmd, const void *data,
146 size_t len, const void *ll_source );
150 * Get reference to AoE device
152 * @v aoedev AoE device
153 * @ret aoedev AoE device
155 static inline __attribute__ (( always_inline )) struct aoe_device *
156 aoedev_get ( struct aoe_device *aoedev ) {
157 ref_get ( &aoedev->refcnt );
162 * Drop reference to AoE device
164 * @v aoedev AoE device
166 static inline __attribute__ (( always_inline )) void
167 aoedev_put ( struct aoe_device *aoedev ) {
168 ref_put ( &aoedev->refcnt );
172 * Get reference to AoE command
174 * @v aoecmd AoE command
175 * @ret aoecmd AoE command
177 static inline __attribute__ (( always_inline )) struct aoe_command *
178 aoecmd_get ( struct aoe_command *aoecmd ) {
179 ref_get ( &aoecmd->refcnt );
184 * Drop reference to AoE command
186 * @v aoecmd AoE command
188 static inline __attribute__ (( always_inline )) void
189 aoecmd_put ( struct aoe_command *aoecmd ) {
190 ref_put ( &aoecmd->refcnt );
196 * @v aoedev AoE device
197 * @ret name AoE device name
199 static const char * aoedev_name ( struct aoe_device *aoedev ) {
202 snprintf ( buf, sizeof ( buf ), "%s/e%d.%d", aoedev->netdev->name,
203 aoedev->major, aoedev->minor );
210 * @v refcnt Reference counter
212 static void aoecmd_free ( struct refcnt *refcnt ) {
213 struct aoe_command *aoecmd =
214 container_of ( refcnt, struct aoe_command, refcnt );
216 assert ( ! timer_running ( &aoecmd->timer ) );
217 assert ( list_empty ( &aoecmd->list ) );
219 aoedev_put ( aoecmd->aoedev );
226 * @v aoecmd AoE command
227 * @v rc Reason for close
229 static void aoecmd_close ( struct aoe_command *aoecmd, int rc ) {
230 struct aoe_device *aoedev = aoecmd->aoedev;
233 stop_timer ( &aoecmd->timer );
235 /* Preserve the timeout value for subsequent commands */
236 aoedev->timeout = aoecmd->timer.timeout;
238 /* Remove from list of commands */
239 if ( ! list_empty ( &aoecmd->list ) ) {
240 list_del ( &aoecmd->list );
241 INIT_LIST_HEAD ( &aoecmd->list );
242 aoecmd_put ( aoecmd );
245 /* Shut down interfaces */
246 intf_shutdown ( &aoecmd->ata, rc );
250 * Transmit AoE command request
252 * @v aoecmd AoE command
253 * @ret rc Return status code
255 static int aoecmd_tx ( struct aoe_command *aoecmd ) {
256 struct aoe_device *aoedev = aoecmd->aoedev;
257 struct net_device *netdev = aoedev->netdev;
258 struct io_buffer *iobuf;
259 struct aoehdr *aoehdr;
264 assert ( netdev != NULL );
266 /* If we are transmitting anything that requires a response,
267 * start the retransmission timer. Do this before attempting
268 * to allocate the I/O buffer, in case allocation itself
271 start_timer ( &aoecmd->timer );
273 /* Create outgoing I/O buffer */
274 cmd_len = aoecmd->type->cmd_len ( aoecmd );
275 iobuf = alloc_iob ( MAX_LL_HEADER_LEN + cmd_len );
278 iob_reserve ( iobuf, MAX_LL_HEADER_LEN );
279 aoehdr = iob_put ( iobuf, cmd_len );
281 /* Fill AoE header */
282 memset ( aoehdr, 0, sizeof ( *aoehdr ) );
283 aoehdr->ver_flags = AOE_VERSION;
284 aoehdr->major = htons ( aoedev->major );
285 aoehdr->minor = aoedev->minor;
286 aoehdr->tag = htonl ( aoecmd->tag );
287 aoecmd->type->cmd ( aoecmd, iobuf->data, iob_len ( iobuf ) );
290 if ( ( rc = net_tx ( iobuf, netdev, &aoe_protocol, aoedev->target,
291 netdev->ll_addr ) ) != 0 ) {
292 DBGC ( aoedev, "AoE %s/%08x could not transmit: %s\n",
293 aoedev_name ( aoedev ), aoecmd->tag,
302 * Receive AoE command response
304 * @v aoecmd AoE command
305 * @v iobuf I/O buffer
306 * @v ll_source Link-layer source address
307 * @ret rc Return status code
309 static int aoecmd_rx ( struct aoe_command *aoecmd, struct io_buffer *iobuf,
310 const void *ll_source ) {
311 struct aoe_device *aoedev = aoecmd->aoedev;
312 struct aoehdr *aoehdr = iobuf->data;
316 if ( iob_len ( iobuf ) < sizeof ( *aoehdr ) ) {
317 DBGC ( aoedev, "AoE %s/%08x received underlength response "
318 "(%zd bytes)\n", aoedev_name ( aoedev ),
319 aoecmd->tag, iob_len ( iobuf ) );
323 if ( ( ntohs ( aoehdr->major ) != aoedev->major ) ||
324 ( aoehdr->minor != aoedev->minor ) ) {
325 DBGC ( aoedev, "AoE %s/%08x received response for incorrect "
326 "device e%d.%d\n", aoedev_name ( aoedev ), aoecmd->tag,
327 ntohs ( aoehdr->major ), aoehdr->minor );
332 /* Catch command failures */
333 if ( aoehdr->ver_flags & AOE_FL_ERROR ) {
334 DBGC ( aoedev, "AoE %s/%08x terminated in error\n",
335 aoedev_name ( aoedev ), aoecmd->tag );
336 aoecmd_close ( aoecmd, -EIO );
341 /* Hand off to command completion handler */
342 if ( ( rc = aoecmd->type->rsp ( aoecmd, iobuf->data, iob_len ( iobuf ),
347 /* Free I/O buffer */
350 /* Terminate command */
351 aoecmd_close ( aoecmd, rc );
357 * Handle AoE retry timer expiry
359 * @v timer AoE retry timer
360 * @v fail Failure indicator
362 static void aoecmd_expired ( struct retry_timer *timer, int fail ) {
363 struct aoe_command *aoecmd =
364 container_of ( timer, struct aoe_command, timer );
367 aoecmd_close ( aoecmd, -ETIMEDOUT );
369 aoecmd_tx ( aoecmd );
374 * Calculate length of AoE ATA command IU
376 * @v aoecmd AoE command
377 * @ret len Length of command IU
379 static size_t aoecmd_ata_cmd_len ( struct aoe_command *aoecmd ) {
380 struct ata_cmd *command = &aoecmd->command;
382 return ( sizeof ( struct aoehdr ) + sizeof ( struct aoeata ) +
383 command->data_out_len );
387 * Build AoE ATA command IU
389 * @v aoecmd AoE command
391 * @v len Length of command IU
393 static void aoecmd_ata_cmd ( struct aoe_command *aoecmd,
394 void *data, size_t len ) {
395 struct aoe_device *aoedev = aoecmd->aoedev;
396 struct ata_cmd *command = &aoecmd->command;
397 struct aoehdr *aoehdr = data;
398 struct aoeata *aoeata = &aoehdr->payload[0].ata;
401 linker_assert ( AOE_FL_DEV_HEAD == ATA_DEV_SLAVE, __fix_ata_h__ );
402 assert ( len == ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) +
403 command->data_out_len ) );
406 aoehdr->command = AOE_CMD_ATA;
407 memset ( aoeata, 0, sizeof ( *aoeata ) );
408 aoeata->aflags = ( ( command->cb.lba48 ? AOE_FL_EXTENDED : 0 ) |
409 ( command->cb.device & ATA_DEV_SLAVE ) |
410 ( command->data_out_len ? AOE_FL_WRITE : 0 ) );
411 aoeata->err_feat = command->cb.err_feat.bytes.cur;
412 aoeata->count = command->cb.count.native;
413 aoeata->cmd_stat = command->cb.cmd_stat;
414 aoeata->lba.u64 = cpu_to_le64 ( command->cb.lba.native );
415 if ( ! command->cb.lba48 )
416 aoeata->lba.bytes[3] |=
417 ( command->cb.device & ATA_DEV_MASK );
418 copy_from_user ( aoeata->data, command->data_out, 0,
419 command->data_out_len );
421 DBGC2 ( aoedev, "AoE %s/%08x ATA cmd %02x:%02x:%02x:%02x:%08llx",
422 aoedev_name ( aoedev ), aoecmd->tag, aoeata->aflags,
423 aoeata->err_feat, aoeata->count, aoeata->cmd_stat,
425 if ( command->data_out_len )
426 DBGC2 ( aoedev, " out %04zx", command->data_out_len );
427 if ( command->data_in_len )
428 DBGC2 ( aoedev, " in %04zx", command->data_in_len );
429 DBGC2 ( aoedev, "\n" );
433 * Handle AoE ATA response IU
435 * @v aoecmd AoE command
436 * @v data Response IU
437 * @v len Length of response IU
438 * @v ll_source Link-layer source address
439 * @ret rc Return status code
441 static int aoecmd_ata_rsp ( struct aoe_command *aoecmd, const void *data,
442 size_t len, const void *ll_source __unused ) {
443 struct aoe_device *aoedev = aoecmd->aoedev;
444 struct ata_cmd *command = &aoecmd->command;
445 const struct aoehdr *aoehdr = data;
446 const struct aoeata *aoeata = &aoehdr->payload[0].ata;
450 if ( len < ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) ) ) {
451 DBGC ( aoedev, "AoE %s/%08x received underlength ATA response "
452 "(%zd bytes)\n", aoedev_name ( aoedev ),
456 data_len = ( len - ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) ) );
457 DBGC2 ( aoedev, "AoE %s/%08x ATA rsp %02x in %04zx\n",
458 aoedev_name ( aoedev ), aoecmd->tag, aoeata->cmd_stat,
461 /* Check for command failure */
462 if ( aoeata->cmd_stat & ATA_STAT_ERR ) {
463 DBGC ( aoedev, "AoE %s/%08x status %02x\n",
464 aoedev_name ( aoedev ), aoecmd->tag, aoeata->cmd_stat );
468 /* Check data-in length is sufficient. (There may be trailing
469 * garbage due to Ethernet minimum-frame-size padding.)
471 if ( data_len < command->data_in_len ) {
472 DBGC ( aoedev, "AoE %s/%08x data-in underrun (received %zd, "
473 "expected %zd)\n", aoedev_name ( aoedev ), aoecmd->tag,
474 data_len, command->data_in_len );
478 /* Copy out data payload */
479 copy_to_user ( command->data_in, 0, aoeata->data,
480 command->data_in_len );
485 /** AoE ATA command */
486 static struct aoe_command_type aoecmd_ata = {
487 .cmd_len = aoecmd_ata_cmd_len,
488 .cmd = aoecmd_ata_cmd,
489 .rsp = aoecmd_ata_rsp,
493 * Calculate length of AoE configuration command IU
495 * @v aoecmd AoE command
496 * @ret len Length of command IU
498 static size_t aoecmd_cfg_cmd_len ( struct aoe_command *aoecmd __unused ) {
499 return ( sizeof ( struct aoehdr ) + sizeof ( struct aoecfg ) );
503 * Build AoE configuration command IU
505 * @v aoecmd AoE command
507 * @v len Length of command IU
509 static void aoecmd_cfg_cmd ( struct aoe_command *aoecmd,
510 void *data, size_t len ) {
511 struct aoe_device *aoedev = aoecmd->aoedev;
512 struct aoehdr *aoehdr = data;
513 struct aoecfg *aoecfg = &aoehdr->payload[0].cfg;
516 assert ( len == ( sizeof ( *aoehdr ) + sizeof ( *aoecfg ) ) );
519 aoehdr->command = AOE_CMD_CONFIG;
520 memset ( aoecfg, 0, sizeof ( *aoecfg ) );
522 DBGC ( aoedev, "AoE %s/%08x CONFIG cmd\n",
523 aoedev_name ( aoedev ), aoecmd->tag );
527 * Handle AoE configuration response IU
529 * @v aoecmd AoE command
530 * @v data Response IU
531 * @v len Length of response IU
532 * @v ll_source Link-layer source address
533 * @ret rc Return status code
535 static int aoecmd_cfg_rsp ( struct aoe_command *aoecmd, const void *data,
536 size_t len, const void *ll_source ) {
537 struct aoe_device *aoedev = aoecmd->aoedev;
538 struct ll_protocol *ll_protocol = aoedev->netdev->ll_protocol;
539 const struct aoehdr *aoehdr = data;
540 const struct aoecfg *aoecfg = &aoehdr->payload[0].cfg;
543 if ( len < ( sizeof ( *aoehdr ) + sizeof ( *aoecfg ) ) ) {
544 DBGC ( aoedev, "AoE %s/%08x received underlength "
545 "configuration response (%zd bytes)\n",
546 aoedev_name ( aoedev ), aoecmd->tag, len );
549 DBGC ( aoedev, "AoE %s/%08x CONFIG rsp buf %04x fw %04x scnt %02x\n",
550 aoedev_name ( aoedev ), aoecmd->tag, ntohs ( aoecfg->bufcnt ),
551 aoecfg->fwver, aoecfg->scnt );
553 /* Record target MAC address */
554 memcpy ( aoedev->target, ll_source, ll_protocol->ll_addr_len );
555 DBGC ( aoedev, "AoE %s has MAC address %s\n",
556 aoedev_name ( aoedev ), ll_protocol->ntoa ( aoedev->target ) );
561 /** AoE configuration command */
562 static struct aoe_command_type aoecmd_cfg = {
563 .cmd_len = aoecmd_cfg_cmd_len,
564 .cmd = aoecmd_cfg_cmd,
565 .rsp = aoecmd_cfg_rsp,
568 /** AoE command ATA interface operations */
569 static struct interface_operation aoecmd_ata_op[] = {
570 INTF_OP ( intf_close, struct aoe_command *, aoecmd_close ),
573 /** AoE command ATA interface descriptor */
574 static struct interface_descriptor aoecmd_ata_desc =
575 INTF_DESC ( struct aoe_command, ata, aoecmd_ata_op );
578 * Identify AoE command by tag
581 * @ret aoecmd AoE command, or NULL
583 static struct aoe_command * aoecmd_find_tag ( uint32_t tag ) {
584 struct aoe_command *aoecmd;
586 list_for_each_entry ( aoecmd, &aoe_commands, list ) {
587 if ( aoecmd->tag == tag )
594 * Choose an AoE command tag
596 * @ret tag New tag, or negative error
598 static int aoecmd_new_tag ( void ) {
599 static uint16_t tag_idx;
602 for ( i = 0 ; i < 65536 ; i++ ) {
604 if ( aoecmd_find_tag ( tag_idx ) == NULL )
605 return ( AOE_TAG_MAGIC | tag_idx );
613 * @v aoedev AoE device
614 * @v type AoE command type
615 * @ret aoecmd AoE command
617 static struct aoe_command * aoecmd_create ( struct aoe_device *aoedev,
618 struct aoe_command_type *type ) {
619 struct aoe_command *aoecmd;
622 /* Allocate command tag */
623 tag = aoecmd_new_tag();
627 /* Allocate and initialise structure */
628 aoecmd = zalloc ( sizeof ( *aoecmd ) );
631 ref_init ( &aoecmd->refcnt, aoecmd_free );
632 list_add ( &aoecmd->list, &aoe_commands );
633 intf_init ( &aoecmd->ata, &aoecmd_ata_desc, &aoecmd->refcnt );
634 timer_init ( &aoecmd->timer, aoecmd_expired, &aoecmd->refcnt );
635 aoecmd->aoedev = aoedev_get ( aoedev );
639 /* Preserve timeout from last completed command */
640 aoecmd->timer.timeout = aoedev->timeout;
642 /* Return already mortalised. (Reference is held by command list.) */
647 * Issue AoE ATA command
649 * @v aoedev AoE device
650 * @v parent Parent interface
651 * @v command ATA command
652 * @ret tag Command tag, or negative error
654 static int aoedev_ata_command ( struct aoe_device *aoedev,
655 struct interface *parent,
656 struct ata_cmd *command ) {
657 struct net_device *netdev = aoedev->netdev;
658 struct aoe_command *aoecmd;
660 /* Fail immediately if net device is closed */
661 if ( ! netdev_is_open ( netdev ) ) {
662 DBGC ( aoedev, "AoE %s cannot issue command while net device "
663 "is closed\n", aoedev_name ( aoedev ) );
668 aoecmd = aoecmd_create ( aoedev, &aoecmd_ata );
671 memcpy ( &aoecmd->command, command, sizeof ( aoecmd->command ) );
673 /* Attempt to send command. Allow failures to be handled by
676 aoecmd_tx ( aoecmd );
678 /* Attach to parent interface, leave reference with command
681 intf_plug_plug ( &aoecmd->ata, parent );
686 * Issue AoE configuration command
688 * @v aoedev AoE device
689 * @v parent Parent interface
690 * @ret tag Command tag, or negative error
692 static int aoedev_cfg_command ( struct aoe_device *aoedev,
693 struct interface *parent ) {
694 struct aoe_command *aoecmd;
697 aoecmd = aoecmd_create ( aoedev, &aoecmd_cfg );
701 /* Attempt to send command. Allow failures to be handled by
704 aoecmd_tx ( aoecmd );
706 /* Attach to parent interface, leave reference with command
709 intf_plug_plug ( &aoecmd->ata, parent );
716 * @v refcnt Reference count
718 static void aoedev_free ( struct refcnt *refcnt ) {
719 struct aoe_device *aoedev =
720 container_of ( refcnt, struct aoe_device, refcnt );
722 netdev_put ( aoedev->netdev );
729 * @v aoedev AoE device
730 * @v rc Reason for close
732 static void aoedev_close ( struct aoe_device *aoedev, int rc ) {
733 struct aoe_command *aoecmd;
734 struct aoe_command *tmp;
736 /* Shut down interfaces */
737 intf_shutdown ( &aoedev->ata, rc );
738 intf_shutdown ( &aoedev->config, rc );
740 /* Shut down any active commands */
741 list_for_each_entry_safe ( aoecmd, tmp, &aoe_commands, list ) {
742 if ( aoecmd->aoedev != aoedev )
744 aoecmd_get ( aoecmd );
745 aoecmd_close ( aoecmd, rc );
746 aoecmd_put ( aoecmd );
751 * Check AoE device flow-control window
753 * @v aoedev AoE device
754 * @ret len Length of window
756 static size_t aoedev_window ( struct aoe_device *aoedev ) {
757 return ( aoedev->configured ? ~( ( size_t ) 0 ) : 0 );
761 * Handle AoE device configuration completion
763 * @v aoedev AoE device
764 * @v rc Reason for completion
766 static void aoedev_config_done ( struct aoe_device *aoedev, int rc ) {
768 /* Shut down interface */
769 intf_shutdown ( &aoedev->config, rc );
771 /* Close device on failure */
773 aoedev_close ( aoedev, rc );
777 /* Mark device as configured */
778 aoedev->configured = 1;
779 xfer_window_changed ( &aoedev->ata );
783 * Identify device underlying AoE device
785 * @v aoedev AoE device
786 * @ret device Underlying device
788 static struct device * aoedev_identify_device ( struct aoe_device *aoedev ) {
789 return aoedev->netdev->dev;
793 * Describe AoE device in an ACPI table
795 * @v aoedev AoE device
797 * @v len Length of ACPI table
798 * @ret rc Return status code
800 static int aoedev_describe ( struct aoe_device *aoedev,
801 struct acpi_description_header *acpi,
803 struct abft_table *abft =
804 container_of ( acpi, struct abft_table, acpi );
807 if ( len < sizeof ( *abft ) )
811 abft->acpi.signature = cpu_to_le32 ( ABFT_SIG );
812 abft->acpi.length = cpu_to_le32 ( sizeof ( *abft ) );
813 abft->acpi.revision = 1;
814 abft->shelf = cpu_to_le16 ( aoedev->major );
815 abft->slot = aoedev->minor;
816 memcpy ( abft->mac, aoedev->netdev->ll_addr, sizeof ( abft->mac ) );
821 /** AoE device ATA interface operations */
822 static struct interface_operation aoedev_ata_op[] = {
823 INTF_OP ( ata_command, struct aoe_device *, aoedev_ata_command ),
824 INTF_OP ( xfer_window, struct aoe_device *, aoedev_window ),
825 INTF_OP ( intf_close, struct aoe_device *, aoedev_close ),
826 INTF_OP ( acpi_describe, struct aoe_device *, aoedev_describe ),
827 INTF_OP ( identify_device, struct aoe_device *,
828 aoedev_identify_device ),
831 /** AoE device ATA interface descriptor */
832 static struct interface_descriptor aoedev_ata_desc =
833 INTF_DESC ( struct aoe_device, ata, aoedev_ata_op );
835 /** AoE device configuration interface operations */
836 static struct interface_operation aoedev_config_op[] = {
837 INTF_OP ( intf_close, struct aoe_device *, aoedev_config_done ),
840 /** AoE device configuration interface descriptor */
841 static struct interface_descriptor aoedev_config_desc =
842 INTF_DESC ( struct aoe_device, config, aoedev_config_op );
847 * @v parent Parent interface
848 * @v netdev Network device
849 * @v major Device major number
850 * @v minor Device minor number
851 * @ret rc Return status code
853 static int aoedev_open ( struct interface *parent, struct net_device *netdev,
854 unsigned int major, unsigned int minor ) {
855 struct aoe_device *aoedev;
858 /* Allocate and initialise structure */
859 aoedev = zalloc ( sizeof ( *aoedev ) );
864 ref_init ( &aoedev->refcnt, aoedev_free );
865 intf_init ( &aoedev->ata, &aoedev_ata_desc, &aoedev->refcnt );
866 intf_init ( &aoedev->config, &aoedev_config_desc, &aoedev->refcnt );
867 aoedev->netdev = netdev_get ( netdev );
868 aoedev->major = major;
869 aoedev->minor = minor;
870 memcpy ( aoedev->target, netdev->ll_broadcast,
871 netdev->ll_protocol->ll_addr_len );
873 /* Initiate configuration */
874 if ( ( rc = aoedev_cfg_command ( aoedev, &aoedev->config ) ) < 0 ) {
875 DBGC ( aoedev, "AoE %s could not initiate configuration: %s\n",
876 aoedev_name ( aoedev ), strerror ( rc ) );
880 /* Attach ATA device to parent interface */
881 if ( ( rc = ata_open ( parent, &aoedev->ata, ATA_DEV_MASTER,
882 AOE_MAX_COUNT ) ) != 0 ) {
883 DBGC ( aoedev, "AoE %s could not create ATA device: %s\n",
884 aoedev_name ( aoedev ), strerror ( rc ) );
888 /* Mortalise self and return */
889 ref_put ( &aoedev->refcnt );
894 aoedev_close ( aoedev, rc );
895 ref_put ( &aoedev->refcnt );
900 /******************************************************************************
902 * AoE network protocol
904 ******************************************************************************
908 * Process incoming AoE packets
910 * @v iobuf I/O buffer
911 * @v netdev Network device
912 * @v ll_dest Link-layer destination address
913 * @v ll_source Link-layer source address
914 * @v flags Packet flags
915 * @ret rc Return status code
917 static int aoe_rx ( struct io_buffer *iobuf,
918 struct net_device *netdev __unused,
919 const void *ll_dest __unused,
920 const void *ll_source,
921 unsigned int flags __unused ) {
922 struct aoehdr *aoehdr = iobuf->data;
923 struct aoe_command *aoecmd;
927 if ( iob_len ( iobuf ) < sizeof ( *aoehdr ) ) {
928 DBG ( "AoE received underlength packet (%zd bytes)\n",
933 if ( ( aoehdr->ver_flags & AOE_VERSION_MASK ) != AOE_VERSION ) {
934 DBG ( "AoE received packet for unsupported protocol version "
935 "%02x\n", ( aoehdr->ver_flags & AOE_VERSION_MASK ) );
936 rc = -EPROTONOSUPPORT;
939 if ( ! ( aoehdr->ver_flags & AOE_FL_RESPONSE ) ) {
940 DBG ( "AoE received request packet\n" );
945 /* Demultiplex amongst active AoE commands */
946 aoecmd = aoecmd_find_tag ( ntohl ( aoehdr->tag ) );
948 DBG ( "AoE received packet for unused tag %08x\n",
949 ntohl ( aoehdr->tag ) );
954 /* Pass received frame to command */
955 aoecmd_get ( aoecmd );
956 if ( ( rc = aoecmd_rx ( aoecmd, iob_disown ( iobuf ),
961 aoecmd_put ( aoecmd );
969 struct net_protocol aoe_protocol __net_protocol = {
971 .net_proto = htons ( ETH_P_AOE ),
975 /******************************************************************************
979 ******************************************************************************
986 * @ret major Major device number
987 * @ret minor Minor device number
988 * @ret rc Return status code
990 * An AoE URI has the form "aoe:e<major>.<minor>".
992 static int aoe_parse_uri ( struct uri *uri, unsigned int *major,
993 unsigned int *minor ) {
997 /* Check for URI with opaque portion */
1002 /* Check for initial 'e' */
1007 /* Parse major device number */
1008 *major = strtoul ( ptr, &end, 10 );
1013 /* Parse minor device number */
1014 *minor = strtoul ( ptr, &end, 10 );
1024 * @v parent Parent interface
1026 * @ret rc Return status code
1028 static int aoe_open ( struct interface *parent, struct uri *uri ) {
1029 struct net_device *netdev;
1034 /* Identify network device. This is something of a hack, but
1035 * the AoE URI scheme that has been in use for some time now
1036 * provides no way to specify a particular device.
1038 netdev = last_opened_netdev();
1040 DBG ( "AoE cannot identify network device\n" );
1045 if ( ( rc = aoe_parse_uri ( uri, &major, &minor ) ) != 0 ) {
1046 DBG ( "AoE cannot parse URI\n" );
1050 /* Open AoE device */
1051 if ( ( rc = aoedev_open ( parent, netdev, major, minor ) ) != 0 )
1057 /** AoE URI opener */
1058 struct uri_opener aoe_uri_opener __uri_opener = {