Ready to start testing
authorMichael Brown <mcb30@etherboot.org>
Sun, 8 Jul 2007 21:01:49 +0000 (22:01 +0100)
committerMichael Brown <mcb30@etherboot.org>
Sun, 8 Jul 2007 21:01:49 +0000 (22:01 +0100)
src/drivers/scsi/iscsidev.c [deleted file]
src/include/gpxe/iscsi.h
src/include/gpxe/scsi.h
src/net/tcp/iscsi.c
src/tests/iscsiboot.c
src/usr/autoboot.c

diff --git a/src/drivers/scsi/iscsidev.c b/src/drivers/scsi/iscsidev.c
deleted file mode 100644 (file)
index aab9903..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <stddef.h>
-#include <gpxe/async.h>
-#include <gpxe/iscsi.h>
-
-/** @file
- *
- * iSCSI SCSI device
- *
- */
-
-/**
- * Issue SCSI command via iSCSI device
- *
- * @v scsi             SCSI device
- * @v command          SCSI command
- * @ret rc             Return status code
- */
-static int iscsi_command ( struct scsi_device *scsi,
-                          struct scsi_command *command ) {
-       struct iscsi_device *iscsidev
-               = container_of ( scsi, struct iscsi_device, scsi );
-       struct async async;
-
-       return async_block ( &async, iscsi_issue ( &iscsidev->iscsi, command,
-                                                  &async ) );
-}
-
-/**
- * Initialise iSCSI device
- *
- * @v iscsidev         iSCSI device
- */
-int init_iscsidev ( struct iscsi_device *iscsidev ) {
-       int rc;
-
-       iscsidev->scsi.command = iscsi_command;
-       iscsidev->scsi.lun = iscsidev->iscsi.lun;
-       if ( ( rc = init_scsidev ( &iscsidev->scsi ) ) != 0 )
-               goto err;
-
-       return 0;
-
- err:
-       fini_iscsidev ( iscsidev );
-       return rc;
-}
-
-/**
- * Shut down iSCSI device
- *
- * @v iscsidev         iSCSI device
- */
-void fini_iscsidev ( struct iscsi_device *iscsidev ) {
-       iscsi_shutdown ( &iscsidev->iscsi );
-}
index 03fc064..d9dd430 100644 (file)
@@ -639,4 +639,7 @@ struct iscsi_session {
 /** Maximum number of retries at connecting */
 #define ISCSI_MAX_RETRIES 2
 
+extern int iscsi_attach ( struct scsi_device *scsi, const char *root_path );
+extern void iscsi_detach ( struct scsi_device *scsi );
+
 #endif /* _GPXE_ISCSI_H */
index 9d5952d..e820117 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdint.h>
 #include <gpxe/blockdev.h>
 #include <gpxe/uaccess.h>
+#include <gpxe/refcnt.h>
 
 /** @file
  *
@@ -229,7 +230,7 @@ struct scsi_command {
         * Must be zero if @c data_in is NULL
         */
        size_t data_in_len;
-       /** SCSI statua code */
+       /** SCSI status code */
        uint8_t status;
        /** SCSI sense response code */
        uint8_t sense_response;
@@ -260,6 +261,8 @@ struct scsi_device {
         */
        int ( * command ) ( struct scsi_device *scsi,
                            struct scsi_command *command );
+       /** Backing device */
+       struct refcnt *backend;
 };
 
 extern int init_scsidev ( struct scsi_device *scsi );
index f0f6db0..0bfb19e 100644 (file)
@@ -1261,21 +1261,21 @@ static struct xfer_interface_operations iscsi_socket_operations = {
 
 /****************************************************************************
  *
- * iSCSI to SCSI interface
+ * iSCSI command issuing
  *
  */
 
 /**
  * Issue SCSI command
  *
- * @v scsi             SCSI interface
+ * @v scsi             SCSI device
  * @v command          SCSI command
  * @ret rc             Return status code
  */
-static int iscsi_scsi_issue ( struct scsi_interface *scsi,
-                             struct scsi_command *command ) {
+static int iscsi_command ( struct scsi_device *scsi,
+                          struct scsi_command *command ) {
        struct iscsi_session *iscsi =
-               container_of ( scsi, struct iscsi_session, scsi );
+               container_of ( scsi->backend, struct iscsi_session, refcnt );
        int rc;
 
        /* Record SCSI command */
@@ -1306,26 +1306,27 @@ static int iscsi_scsi_issue ( struct scsi_interface *scsi,
        return rc;
 }
 
+static int iscsi_detached_command ( struct scsi_device *scsi __unused,
+                                   struct scsi_command *command __unused ) {
+       return -ENODEV;
+}
+
 /**
- * Detach SCSI interface
+ * Shut down iSCSI interface
  *
- * @v scsi             SCSI interface
- * @v rc               Reason for close
+ * @v scsi             SCSI device
  */
-static void iscsi_scsi_detach ( struct scsi_interface *scsi, int rc ) {
+void iscsi_detach ( struct scsi_device *scsi ) {
        struct iscsi_session *iscsi =
-               container_of ( scsi, struct iscsi_session, scsi );
+               container_of ( scsi->backend, struct iscsi_session, refcnt );
 
-       iscsi_close_connection ( iscsi, rc );
+       iscsi_close_connection ( iscsi, 0 );
        process_del ( &iscsi->process );
+       scsi->command = iscsi_detached_command;
+       ref_put ( scsi->backend );
+       scsi->backend = NULL;
 }
 
-/** iSCSI SCSI operations */
-struct scsi_operations iscsi_scsi_operations = {
-       .detach         = iscsi_scsi_detach,
-       .issue          = iscsi_scsi_issue,
-};
-
 /****************************************************************************
  *
  * Instantiator
@@ -1430,11 +1431,11 @@ static int iscsi_parse_root_path ( struct iscsi_session *iscsi,
 /**
  * Attach iSCSI interface
  *
- * @v scsi             SCSI interface
+ * @v scsi             SCSI device
  * @v root_path                iSCSI root path (as per RFC4173)
  * @ret rc             Return status code
  */
-int iscsi_attach ( struct scsi_interface *scsi, const char *root_path ) {
+int iscsi_attach ( struct scsi_device *scsi, const char *root_path ) {
        struct iscsi_session *iscsi;
        int rc;
 
@@ -1442,6 +1443,7 @@ int iscsi_attach ( struct scsi_interface *scsi, const char *root_path ) {
        iscsi = zalloc ( sizeof ( *iscsi ) );
        if ( ! iscsi )
                return -ENOMEM;
+       iscsi->refcnt.free = iscsi_free;
        xfer_init ( &iscsi->socket, &iscsi_socket_operations, &iscsi->refcnt );
        process_init ( &iscsi->process, iscsi_tx_step, &iscsi->refcnt );
 
@@ -1464,7 +1466,9 @@ int iscsi_attach ( struct scsi_interface *scsi, const char *root_path ) {
        }
 
        /* Attach parent interface, mortalise self, and return */
-       scsi_plug_plug ( &iscsi->scsi, scsi );
+       scsi->backend = ref_get ( &iscsi->refcnt );
+       scsi->command = iscsi_command;
+       scsi->lun = iscsi->lun;
        ref_put ( &iscsi->refcnt );
        return 0;
        
index 22dccb1..9331357 100644 (file)
@@ -1,48 +1,36 @@
 #include <stdint.h>
 #include <string.h>
 #include <stdio.h>
-#include <byteswap.h>
-#include <gpxe/netdevice.h>
 #include <gpxe/iscsi.h>
-#include <gpxe/ibft.h>
-#include <gpxe/tcpip.h>
+#include <gpxe/dhcp.h>
 #include <int13.h>
 
-static struct iscsi_device test_iscsidev;
-
-int test_iscsiboot ( const char *initiator_iqn,
-                    struct sockaddr_tcpip *target,
-                    const char *target_iqn,
-                    unsigned int lun,
-                    const char *username,
-                    const char *password,
-                    struct net_device *netdev,
-                    unsigned int drivenum ) {
+int iscsiboot ( const char *root_path ) {
+       struct scsi_device scsi;
        struct int13_drive drive;
        int rc;
 
-       memset ( &test_iscsidev, 0, sizeof ( test_iscsidev ) );
-       memcpy ( &test_iscsidev.iscsi.target, target,
-                sizeof ( test_iscsidev.iscsi.target ) );
-       test_iscsidev.iscsi.initiator_iqn = initiator_iqn;
-       test_iscsidev.iscsi.target_iqn = target_iqn;
-       test_iscsidev.iscsi.lun = lun;
-       test_iscsidev.iscsi.username = username;
-       test_iscsidev.iscsi.password = password;
-
-       printf ( "Initialising %s\n", target_iqn );
-       if ( ( rc = init_iscsidev ( &test_iscsidev ) ) != 0 ) {
-               printf ( "Could not reach %s: %s\n", target_iqn,
+       memset ( &scsi, 0, sizeof ( scsi ) );
+       memset ( &drive, 0, sizeof ( drive ) );
+
+       printf ( "iSCSI booting from %s\n", root_path );
+
+       if ( ( rc = iscsi_attach ( &scsi, root_path ) ) != 0 ) {
+               printf ( "Could not attach iSCSI device: %s\n",
                         strerror ( rc ) );
-               return rc;
+               goto error_attach;
        }
-       ibft_fill_data ( netdev, &test_iscsidev.iscsi );
-       memset ( &drive, 0, sizeof ( drive ) );
-       drive.drive = drivenum;
-       drive.blockdev = &test_iscsidev.scsi.blockdev;
+       if ( ( rc = init_scsidev ( &scsi ) ) != 0 ) {
+               printf ( "Could not initialise iSCSI device: %s\n",
+                        strerror ( rc ) );
+               goto error_init;
+       }
+
+       drive.drive = find_global_dhcp_num_option ( DHCP_EB_BIOS_DRIVE );
+       drive.blockdev = &scsi.blockdev;
+
        register_int13_drive ( &drive );
-       printf ( "Registered %s as BIOS drive %#02x\n",
-                target_iqn, drive.drive );
+       printf ( "Registered as BIOS drive %#02x\n", drive.drive );
        printf ( "Booting from BIOS drive %#02x\n", drive.drive );
        rc = int13_boot ( drive.drive );
        printf ( "Boot failed\n" );
@@ -50,7 +38,8 @@ int test_iscsiboot ( const char *initiator_iqn,
        printf ( "Unregistering BIOS drive %#02x\n", drive.drive );
        unregister_int13_drive ( &drive );
 
-       fini_iscsidev ( &test_iscsidev );
-
+ error_init:
+       iscsi_detach ( &scsi );
+ error_attach:
        return rc;
 }
index 302e189..277e8b0 100644 (file)
@@ -44,56 +44,96 @@ static struct net_device * find_boot_netdev ( void ) {
 }
 
 /**
- * Boot from a network device
+ * Boot using filename
  *
- * @v netdev           Network device
+ * @v filename         Boot filename
+ * @ret rc             Return status code
  */
-void netboot ( struct net_device *netdev ) {
-       char filename[256];
+static int boot_filename ( const char *filename ) {
        struct image *image;
        int rc;
 
-       /* Open device and display device status */
-       if ( ( rc = ifopen ( netdev ) ) != 0 )
-               return;
-       ifstat ( netdev );
-
-       /* Configure device via DHCP */
-       if ( ( rc = dhcp ( netdev ) ) != 0 )
-               return;
-       route();
-
-       /* Try to download and boot whatever we are given as a filename */
-       dhcp_snprintf ( filename, sizeof ( filename ),
-                       find_global_dhcp_option ( DHCP_BOOTFILE_NAME ) );
-       if ( ! filename[0] ) {
-               printf ( "No boot filename\n" );
-               return;
-       }
-       printf ( "Booting \"%s\"\n", filename );
        image = alloc_image();
        if ( ! image ) {
                printf ( "Out of memory\n" );
-               return;
+               return -ENOMEM;
        }
        if ( ( rc = imgfetch ( image, filename, 0 ) ) != 0 ) {
                printf ( "Could not retrieve %s: %s\n",
                         filename, strerror ( rc ) );
                image_put ( image );
-               return;
+               return rc;
        }
        if ( ( rc = imgload ( image ) ) != 0 ) {
                printf ( "Could not load %s: %s\n", image->name,
                         strerror ( rc ) );
                image_put ( image );
-               return;
+               return rc;
        }
        if ( ( rc = imgexec ( image ) ) != 0 ) {
                printf ( "Could not execute %s: %s\n", image->name,
                         strerror ( rc ) );
                image_put ( image );
-               return;
+               return rc;
+       }
+
+       return 0;
+}
+
+/**
+ * Boot using root path
+ *
+ * @v root_path                Root path
+ * @ret rc             Return status code
+ */
+static int boot_root_path ( const char *root_path ) {
+       int rc;
+
+       /* Quick hack */
+       if ( ( rc = iscsiboot ( root_path ) ) != 0 )
+               return rc;
+
+       return 0;
+}
+
+/**
+ * Boot from a network device
+ *
+ * @v netdev           Network device
+ * @ret rc             Return status code
+ */
+int netboot ( struct net_device *netdev ) {
+       char buf[256];
+       int rc;
+
+       /* Open device and display device status */
+       if ( ( rc = ifopen ( netdev ) ) != 0 )
+               return rc;
+       ifstat ( netdev );
+
+       /* Configure device via DHCP */
+       if ( ( rc = dhcp ( netdev ) ) != 0 )
+               return rc;
+       route();
+
+       /* Try to download and boot whatever we are given as a filename */
+       dhcp_snprintf ( buf, sizeof ( buf ),
+                       find_global_dhcp_option ( DHCP_BOOTFILE_NAME ) );
+       if ( buf[0] ) {
+               printf ( "Booting from filename \"%s\"\n", buf );
+               return boot_filename ( buf );
        }
+       
+       /* No filename; try the root path */
+       dhcp_snprintf ( buf, sizeof ( buf ),
+                       find_global_dhcp_option ( DHCP_ROOT_PATH ) );
+       if ( buf[0] ) {
+               printf ( "Booting from root path \"%s\"\n", buf );
+               return boot_root_path ( buf );
+       }
+
+       printf ( "No filename or root path specified\n" );
+       return -ENOENT;
 }
 
 /**