1 #include <stdint.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <errno.h>
6 #include <gpxe/aoe.h>
7 #include <gpxe/ata.h>
8 #include <gpxe/netdevice.h>
9 #include <gpxe/sanboot.h>
10 #include <gpxe/abft.h>
11 #include <int13.h>
12
13 FILE_LICENCE ( GPL2_OR_LATER );
14
aoeboot(const char * root_path)15 static int aoeboot ( const char *root_path ) {
16 struct ata_device *ata;
17 struct int13_drive *drive;
18 int rc;
19
20 ata = zalloc ( sizeof ( *ata ) );
21 if ( ! ata ) {
22 rc = -ENOMEM;
23 goto err_alloc_ata;
24 }
25 drive = zalloc ( sizeof ( *drive ) );
26 if ( ! drive ) {
27 rc = -ENOMEM;
28 goto err_alloc_drive;
29 }
30
31 /* FIXME: ugly, ugly hack */
32 struct net_device *netdev = last_opened_netdev();
33
34 if ( ( rc = aoe_attach ( ata, netdev, root_path ) ) != 0 ) {
35 printf ( "Could not attach AoE device: %s\n",
36 strerror ( rc ) );
37 goto err_attach;
38 }
39 if ( ( rc = init_atadev ( ata ) ) != 0 ) {
40 printf ( "Could not initialise AoE device: %s\n",
41 strerror ( rc ) );
42 goto err_init;
43 }
44
45 /* FIXME: ugly, ugly hack */
46 struct aoe_session *aoe =
47 container_of ( ata->backend, struct aoe_session, refcnt );
48 abft_fill_data ( aoe );
49
50 drive->blockdev = &ata->blockdev;
51
52 register_int13_drive ( drive );
53 printf ( "Registered as BIOS drive %#02x\n", drive->drive );
54 printf ( "Booting from BIOS drive %#02x\n", drive->drive );
55 rc = int13_boot ( drive->drive );
56 printf ( "Boot failed\n" );
57
58 /* Leave drive registered, if instructed to do so */
59 if ( keep_san() )
60 return rc;
61
62 printf ( "Unregistering BIOS drive %#02x\n", drive->drive );
63 unregister_int13_drive ( drive );
64
65 err_init:
66 aoe_detach ( ata );
67 err_attach:
68 free ( drive );
69 err_alloc_drive:
70 free ( ata );
71 err_alloc_ata:
72 return rc;
73 }
74
75 struct sanboot_protocol aoe_sanboot_protocol __sanboot_protocol = {
76 .prefix = "aoe:",
77 .boot = aoeboot,
78 };
79