176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdint.h> 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <string.h> 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdlib.h> 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdio.h> 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <errno.h> 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/aoe.h> 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/ata.h> 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/netdevice.h> 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/sanboot.h> 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/abft.h> 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <int13.h> 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1376d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( GPL2_OR_LATER ); 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic int aoeboot ( const char *root_path ) { 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct ata_device *ata; 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct int13_drive *drive; 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int rc; 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ata = zalloc ( sizeof ( *ata ) ); 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ! ata ) { 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rc = -ENOMEM; 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto err_alloc_ata; 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman drive = zalloc ( sizeof ( *drive ) ); 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ! drive ) { 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rc = -ENOMEM; 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto err_alloc_drive; 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* FIXME: ugly, ugly hack */ 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct net_device *netdev = last_opened_netdev(); 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ( rc = aoe_attach ( ata, netdev, root_path ) ) != 0 ) { 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman printf ( "Could not attach AoE device: %s\n", 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman strerror ( rc ) ); 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto err_attach; 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( ( rc = init_atadev ( ata ) ) != 0 ) { 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman printf ( "Could not initialise AoE device: %s\n", 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman strerror ( rc ) ); 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman goto err_init; 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* FIXME: ugly, ugly hack */ 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct aoe_session *aoe = 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman container_of ( ata->backend, struct aoe_session, refcnt ); 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman abft_fill_data ( aoe ); 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman drive->blockdev = &ata->blockdev; 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman register_int13_drive ( drive ); 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman printf ( "Registered as BIOS drive %#02x\n", drive->drive ); 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman printf ( "Booting from BIOS drive %#02x\n", drive->drive ); 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman rc = int13_boot ( drive->drive ); 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman printf ( "Boot failed\n" ); 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /* Leave drive registered, if instructed to do so */ 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman if ( keep_san() ) 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return rc; 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman printf ( "Unregistering BIOS drive %#02x\n", drive->drive ); 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unregister_int13_drive ( drive ); 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman err_init: 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman aoe_detach ( ata ); 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman err_attach: 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman free ( drive ); 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman err_alloc_drive: 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman free ( ata ); 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman err_alloc_ata: 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return rc; 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct sanboot_protocol aoe_sanboot_protocol __sanboot_protocol = { 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .prefix = "aoe:", 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman .boot = aoeboot, 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 79