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