Browse Source

Ready to start testing

tags/v0.9.3
Michael Brown 17 years ago
parent
commit
b94420a52b
6 changed files with 121 additions and 155 deletions
  1. 0
    73
      src/drivers/scsi/iscsidev.c
  2. 3
    0
      src/include/gpxe/iscsi.h
  3. 4
    1
      src/include/gpxe/scsi.h
  4. 24
    20
      src/net/tcp/iscsi.c
  5. 24
    35
      src/tests/iscsiboot.c
  6. 66
    26
      src/usr/autoboot.c

+ 0
- 73
src/drivers/scsi/iscsidev.c View File

@@ -1,73 +0,0 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA.
17
- */
18
-
19
-#include <stddef.h>
20
-#include <gpxe/async.h>
21
-#include <gpxe/iscsi.h>
22
-
23
-/** @file
24
- *
25
- * iSCSI SCSI device
26
- *
27
- */
28
-
29
-/**
30
- * Issue SCSI command via iSCSI device
31
- *
32
- * @v scsi		SCSI device
33
- * @v command		SCSI command
34
- * @ret rc		Return status code
35
- */
36
-static int iscsi_command ( struct scsi_device *scsi,
37
-			   struct scsi_command *command ) {
38
-	struct iscsi_device *iscsidev
39
-		= container_of ( scsi, struct iscsi_device, scsi );
40
-	struct async async;
41
-
42
-	return async_block ( &async, iscsi_issue ( &iscsidev->iscsi, command,
43
-						   &async ) );
44
-}
45
-
46
-/**
47
- * Initialise iSCSI device
48
- *
49
- * @v iscsidev		iSCSI device
50
- */
51
-int init_iscsidev ( struct iscsi_device *iscsidev ) {
52
-	int rc;
53
-
54
-	iscsidev->scsi.command = iscsi_command;
55
-	iscsidev->scsi.lun = iscsidev->iscsi.lun;
56
-	if ( ( rc = init_scsidev ( &iscsidev->scsi ) ) != 0 )
57
-		goto err;
58
-
59
-	return 0;
60
-
61
- err:
62
-	fini_iscsidev ( iscsidev );
63
-	return rc;
64
-}
65
-
66
-/**
67
- * Shut down iSCSI device
68
- *
69
- * @v iscsidev		iSCSI device
70
- */
71
-void fini_iscsidev ( struct iscsi_device *iscsidev ) {
72
-	iscsi_shutdown ( &iscsidev->iscsi );
73
-}

+ 3
- 0
src/include/gpxe/iscsi.h View File

@@ -639,4 +639,7 @@ struct iscsi_session {
639 639
 /** Maximum number of retries at connecting */
640 640
 #define ISCSI_MAX_RETRIES 2
641 641
 
642
+extern int iscsi_attach ( struct scsi_device *scsi, const char *root_path );
643
+extern void iscsi_detach ( struct scsi_device *scsi );
644
+
642 645
 #endif /* _GPXE_ISCSI_H */

+ 4
- 1
src/include/gpxe/scsi.h View File

@@ -4,6 +4,7 @@
4 4
 #include <stdint.h>
5 5
 #include <gpxe/blockdev.h>
6 6
 #include <gpxe/uaccess.h>
7
+#include <gpxe/refcnt.h>
7 8
 
8 9
 /** @file
9 10
  *
@@ -229,7 +230,7 @@ struct scsi_command {
229 230
 	 * Must be zero if @c data_in is NULL
230 231
 	 */
231 232
 	size_t data_in_len;
232
-	/** SCSI statua code */
233
+	/** SCSI status code */
233 234
 	uint8_t status;
234 235
 	/** SCSI sense response code */
235 236
 	uint8_t sense_response;
@@ -260,6 +261,8 @@ struct scsi_device {
260 261
 	 */
261 262
 	int ( * command ) ( struct scsi_device *scsi,
262 263
 			    struct scsi_command *command );
264
+	/** Backing device */
265
+	struct refcnt *backend;
263 266
 };
264 267
 
265 268
 extern int init_scsidev ( struct scsi_device *scsi );

+ 24
- 20
src/net/tcp/iscsi.c View File

@@ -1261,21 +1261,21 @@ static struct xfer_interface_operations iscsi_socket_operations = {
1261 1261
 
1262 1262
 /****************************************************************************
1263 1263
  *
1264
- * iSCSI to SCSI interface
1264
+ * iSCSI command issuing
1265 1265
  *
1266 1266
  */
1267 1267
 
1268 1268
 /**
1269 1269
  * Issue SCSI command
1270 1270
  *
1271
- * @v scsi		SCSI interface
1271
+ * @v scsi		SCSI device
1272 1272
  * @v command		SCSI command
1273 1273
  * @ret rc		Return status code
1274 1274
  */
1275
-static int iscsi_scsi_issue ( struct scsi_interface *scsi,
1276
-			      struct scsi_command *command ) {
1275
+static int iscsi_command ( struct scsi_device *scsi,
1276
+			   struct scsi_command *command ) {
1277 1277
 	struct iscsi_session *iscsi =
1278
-		container_of ( scsi, struct iscsi_session, scsi );
1278
+		container_of ( scsi->backend, struct iscsi_session, refcnt );
1279 1279
 	int rc;
1280 1280
 
1281 1281
 	/* Record SCSI command */
@@ -1306,26 +1306,27 @@ static int iscsi_scsi_issue ( struct scsi_interface *scsi,
1306 1306
 	return rc;
1307 1307
 }
1308 1308
 
1309
+static int iscsi_detached_command ( struct scsi_device *scsi __unused,
1310
+				    struct scsi_command *command __unused ) {
1311
+	return -ENODEV;
1312
+}
1313
+
1309 1314
 /**
1310
- * Detach SCSI interface
1315
+ * Shut down iSCSI interface
1311 1316
  *
1312
- * @v scsi		SCSI interface
1313
- * @v rc		Reason for close
1317
+ * @v scsi		SCSI device
1314 1318
  */
1315
-static void iscsi_scsi_detach ( struct scsi_interface *scsi, int rc ) {
1319
+void iscsi_detach ( struct scsi_device *scsi ) {
1316 1320
 	struct iscsi_session *iscsi =
1317
-		container_of ( scsi, struct iscsi_session, scsi );
1321
+		container_of ( scsi->backend, struct iscsi_session, refcnt );
1318 1322
 
1319
-	iscsi_close_connection ( iscsi, rc );
1323
+	iscsi_close_connection ( iscsi, 0 );
1320 1324
 	process_del ( &iscsi->process );
1325
+	scsi->command = iscsi_detached_command;
1326
+	ref_put ( scsi->backend );
1327
+	scsi->backend = NULL;
1321 1328
 }
1322 1329
 
1323
-/** iSCSI SCSI operations */
1324
-struct scsi_operations iscsi_scsi_operations = {
1325
-	.detach		= iscsi_scsi_detach,
1326
-	.issue		= iscsi_scsi_issue,
1327
-};
1328
-
1329 1330
 /****************************************************************************
1330 1331
  *
1331 1332
  * Instantiator
@@ -1430,11 +1431,11 @@ static int iscsi_parse_root_path ( struct iscsi_session *iscsi,
1430 1431
 /**
1431 1432
  * Attach iSCSI interface
1432 1433
  *
1433
- * @v scsi		SCSI interface
1434
+ * @v scsi		SCSI device
1434 1435
  * @v root_path		iSCSI root path (as per RFC4173)
1435 1436
  * @ret rc		Return status code
1436 1437
  */
1437
-int iscsi_attach ( struct scsi_interface *scsi, const char *root_path ) {
1438
+int iscsi_attach ( struct scsi_device *scsi, const char *root_path ) {
1438 1439
 	struct iscsi_session *iscsi;
1439 1440
 	int rc;
1440 1441
 
@@ -1442,6 +1443,7 @@ int iscsi_attach ( struct scsi_interface *scsi, const char *root_path ) {
1442 1443
 	iscsi = zalloc ( sizeof ( *iscsi ) );
1443 1444
 	if ( ! iscsi )
1444 1445
 		return -ENOMEM;
1446
+	iscsi->refcnt.free = iscsi_free;
1445 1447
 	xfer_init ( &iscsi->socket, &iscsi_socket_operations, &iscsi->refcnt );
1446 1448
 	process_init ( &iscsi->process, iscsi_tx_step, &iscsi->refcnt );
1447 1449
 
@@ -1464,7 +1466,9 @@ int iscsi_attach ( struct scsi_interface *scsi, const char *root_path ) {
1464 1466
 	}
1465 1467
 
1466 1468
 	/* Attach parent interface, mortalise self, and return */
1467
-	scsi_plug_plug ( &iscsi->scsi, scsi );
1469
+	scsi->backend = ref_get ( &iscsi->refcnt );
1470
+	scsi->command = iscsi_command;
1471
+	scsi->lun = iscsi->lun;
1468 1472
 	ref_put ( &iscsi->refcnt );
1469 1473
 	return 0;
1470 1474
 	

+ 24
- 35
src/tests/iscsiboot.c View File

@@ -1,48 +1,36 @@
1 1
 #include <stdint.h>
2 2
 #include <string.h>
3 3
 #include <stdio.h>
4
-#include <byteswap.h>
5
-#include <gpxe/netdevice.h>
6 4
 #include <gpxe/iscsi.h>
7
-#include <gpxe/ibft.h>
8
-#include <gpxe/tcpip.h>
5
+#include <gpxe/dhcp.h>
9 6
 #include <int13.h>
10 7
 
11
-static struct iscsi_device test_iscsidev;
12
-
13
-int test_iscsiboot ( const char *initiator_iqn,
14
-		     struct sockaddr_tcpip *target,
15
-		     const char *target_iqn,
16
-		     unsigned int lun,
17
-		     const char *username,
18
-		     const char *password,
19
-		     struct net_device *netdev,
20
-		     unsigned int drivenum ) {
8
+int iscsiboot ( const char *root_path ) {
9
+	struct scsi_device scsi;
21 10
 	struct int13_drive drive;
22 11
 	int rc;
23 12
 
24
-	memset ( &test_iscsidev, 0, sizeof ( test_iscsidev ) );
25
-	memcpy ( &test_iscsidev.iscsi.target, target,
26
-		 sizeof ( test_iscsidev.iscsi.target ) );
27
-	test_iscsidev.iscsi.initiator_iqn = initiator_iqn;
28
-	test_iscsidev.iscsi.target_iqn = target_iqn;
29
-	test_iscsidev.iscsi.lun = lun;
30
-	test_iscsidev.iscsi.username = username;
31
-	test_iscsidev.iscsi.password = password;
32
-
33
-	printf ( "Initialising %s\n", target_iqn );
34
-	if ( ( rc = init_iscsidev ( &test_iscsidev ) ) != 0 ) {
35
-		printf ( "Could not reach %s: %s\n", target_iqn,
13
+	memset ( &scsi, 0, sizeof ( scsi ) );
14
+	memset ( &drive, 0, sizeof ( drive ) );
15
+
16
+	printf ( "iSCSI booting from %s\n", root_path );
17
+
18
+	if ( ( rc = iscsi_attach ( &scsi, root_path ) ) != 0 ) {
19
+		printf ( "Could not attach iSCSI device: %s\n",
36 20
 			 strerror ( rc ) );
37
-		return rc;
21
+		goto error_attach;
38 22
 	}
39
-	ibft_fill_data ( netdev, &test_iscsidev.iscsi );
40
-	memset ( &drive, 0, sizeof ( drive ) );
41
-	drive.drive = drivenum;
42
-	drive.blockdev = &test_iscsidev.scsi.blockdev;
23
+	if ( ( rc = init_scsidev ( &scsi ) ) != 0 ) {
24
+		printf ( "Could not initialise iSCSI device: %s\n",
25
+			 strerror ( rc ) );
26
+		goto error_init;
27
+	}
28
+
29
+	drive.drive = find_global_dhcp_num_option ( DHCP_EB_BIOS_DRIVE );
30
+	drive.blockdev = &scsi.blockdev;
31
+
43 32
 	register_int13_drive ( &drive );
44
-	printf ( "Registered %s as BIOS drive %#02x\n",
45
-		 target_iqn, drive.drive );
33
+	printf ( "Registered as BIOS drive %#02x\n", drive.drive );
46 34
 	printf ( "Booting from BIOS drive %#02x\n", drive.drive );
47 35
 	rc = int13_boot ( drive.drive );
48 36
 	printf ( "Boot failed\n" );
@@ -50,7 +38,8 @@ int test_iscsiboot ( const char *initiator_iqn,
50 38
 	printf ( "Unregistering BIOS drive %#02x\n", drive.drive );
51 39
 	unregister_int13_drive ( &drive );
52 40
 
53
-	fini_iscsidev ( &test_iscsidev );
54
-
41
+ error_init:
42
+	iscsi_detach ( &scsi );
43
+ error_attach:
55 44
 	return rc;
56 45
 }

+ 66
- 26
src/usr/autoboot.c View File

@@ -44,56 +44,96 @@ static struct net_device * find_boot_netdev ( void ) {
44 44
 }
45 45
 
46 46
 /**
47
- * Boot from a network device
47
+ * Boot using filename
48 48
  *
49
- * @v netdev		Network device
49
+ * @v filename		Boot filename
50
+ * @ret rc		Return status code
50 51
  */
51
-void netboot ( struct net_device *netdev ) {
52
-	char filename[256];
52
+static int boot_filename ( const char *filename ) {
53 53
 	struct image *image;
54 54
 	int rc;
55 55
 
56
-	/* Open device and display device status */
57
-	if ( ( rc = ifopen ( netdev ) ) != 0 )
58
-		return;
59
-	ifstat ( netdev );
60
-
61
-	/* Configure device via DHCP */
62
-	if ( ( rc = dhcp ( netdev ) ) != 0 )
63
-		return;
64
-	route();
65
-
66
-	/* Try to download and boot whatever we are given as a filename */
67
-	dhcp_snprintf ( filename, sizeof ( filename ),
68
-			find_global_dhcp_option ( DHCP_BOOTFILE_NAME ) );
69
-	if ( ! filename[0] ) {
70
-		printf ( "No boot filename\n" );
71
-		return;
72
-	}
73
-	printf ( "Booting \"%s\"\n", filename );
74 56
 	image = alloc_image();
75 57
 	if ( ! image ) {
76 58
 		printf ( "Out of memory\n" );
77
-		return;
59
+		return -ENOMEM;
78 60
 	}
79 61
 	if ( ( rc = imgfetch ( image, filename, 0 ) ) != 0 ) {
80 62
 		printf ( "Could not retrieve %s: %s\n",
81 63
 			 filename, strerror ( rc ) );
82 64
 		image_put ( image );
83
-		return;
65
+		return rc;
84 66
 	}
85 67
 	if ( ( rc = imgload ( image ) ) != 0 ) {
86 68
 		printf ( "Could not load %s: %s\n", image->name,
87 69
 			 strerror ( rc ) );
88 70
 		image_put ( image );
89
-		return;
71
+		return rc;
90 72
 	}
91 73
 	if ( ( rc = imgexec ( image ) ) != 0 ) {
92 74
 		printf ( "Could not execute %s: %s\n", image->name,
93 75
 			 strerror ( rc ) );
94 76
 		image_put ( image );
95
-		return;
77
+		return rc;
78
+	}
79
+
80
+	return 0;
81
+}
82
+
83
+/**
84
+ * Boot using root path
85
+ *
86
+ * @v root_path		Root path
87
+ * @ret rc		Return status code
88
+ */
89
+static int boot_root_path ( const char *root_path ) {
90
+	int rc;
91
+
92
+	/* Quick hack */
93
+	if ( ( rc = iscsiboot ( root_path ) ) != 0 )
94
+		return rc;
95
+
96
+	return 0;
97
+}
98
+
99
+/**
100
+ * Boot from a network device
101
+ *
102
+ * @v netdev		Network device
103
+ * @ret rc		Return status code
104
+ */
105
+int netboot ( struct net_device *netdev ) {
106
+	char buf[256];
107
+	int rc;
108
+
109
+	/* Open device and display device status */
110
+	if ( ( rc = ifopen ( netdev ) ) != 0 )
111
+		return rc;
112
+	ifstat ( netdev );
113
+
114
+	/* Configure device via DHCP */
115
+	if ( ( rc = dhcp ( netdev ) ) != 0 )
116
+		return rc;
117
+	route();
118
+
119
+	/* Try to download and boot whatever we are given as a filename */
120
+	dhcp_snprintf ( buf, sizeof ( buf ),
121
+			find_global_dhcp_option ( DHCP_BOOTFILE_NAME ) );
122
+	if ( buf[0] ) {
123
+		printf ( "Booting from filename \"%s\"\n", buf );
124
+		return boot_filename ( buf );
96 125
 	}
126
+	
127
+	/* No filename; try the root path */
128
+	dhcp_snprintf ( buf, sizeof ( buf ),
129
+			find_global_dhcp_option ( DHCP_ROOT_PATH ) );
130
+	if ( buf[0] ) {
131
+		printf ( "Booting from root path \"%s\"\n", buf );
132
+		return boot_root_path ( buf );
133
+	}
134
+
135
+	printf ( "No filename or root path specified\n" );
136
+	return -ENOENT;
97 137
 }
98 138
 
99 139
 /**

Loading…
Cancel
Save