[driver] Add sBFT detection and debug parsing
authorMichael Brown <mcb30@etherboot.org>
Thu, 22 Oct 2009 23:42:51 +0000 (00:42 +0100)
committerMichael Brown <mcb30@etherboot.org>
Fri, 23 Oct 2009 00:07:49 +0000 (01:07 +0100)
bin/amd64/sanbootconf.sys
bin/amd64/setup.exe
bin/i386/sanbootconf.sys
bin/i386/setup.exe
driver/sanbootconf.c
driver/sbft.c [new file with mode: 0644]
driver/sbft.h [new file with mode: 0644]
driver/sources

index ce5a1d0..8974785 100755 (executable)
Binary files a/bin/amd64/sanbootconf.sys and b/bin/amd64/sanbootconf.sys differ
index aa9e85c..f74788d 100755 (executable)
Binary files a/bin/amd64/setup.exe and b/bin/amd64/setup.exe differ
index 1855c2e..3cd0f43 100755 (executable)
Binary files a/bin/i386/sanbootconf.sys and b/bin/i386/sanbootconf.sys differ
index ae7fb87..c09452b 100755 (executable)
Binary files a/bin/i386/setup.exe and b/bin/i386/setup.exe differ
index 97cbd7a..d815bfb 100644 (file)
 #include "sanbootconf.h"
 #include "acpi.h"
 #include "ibft.h"
+#include "sbft.h"
 
 /** Device private data */
 typedef struct _SANBOOTCONF_PRIV {
-       /* Copy of iBFT */
+       /* Copy of iBFT, if any */
        PIBFT_TABLE ibft;
+       /* Copy of sBFT, if any */
+       PSBFT_TABLE sbft;
 } SANBOOTCONF_PRIV, *PSANBOOTCONF_PRIV;
 
 /** Unique GUID for IoCreateDeviceSecure() */
@@ -35,7 +38,13 @@ DEFINE_GUID ( GUID_SANBOOTCONF_CLASS, 0x8a2f8602, 0x8f0b, 0x4138,
 
 /** IoControl code to retrieve iBFT */
 #define IOCTL_SANBOOTCONF_IBFT \
-       CTL_CODE ( FILE_DEVICE_UNKNOWN, 1, METHOD_BUFFERED, FILE_READ_ACCESS )
+       CTL_CODE ( FILE_DEVICE_UNKNOWN, 0x0001, METHOD_BUFFERED, \
+                  FILE_READ_ACCESS )
+
+/** IoControl code to retrieve sBFT */
+#define IOCTL_SANBOOTCONF_SBFT \
+       CTL_CODE ( FILE_DEVICE_UNKNOWN, 0x0873, METHOD_BUFFERED, \
+                  FILE_READ_ACCESS )
 
 /** Device name */
 static const WCHAR sanbootconf_device_name[] = L"\\Device\\sanbootconf";
@@ -79,11 +88,29 @@ static NTSTATUS sanbootconf_iocontrol_irp ( PDEVICE_OBJECT device, PIRP irp ) {
        switch ( irpsp->Parameters.DeviceIoControl.IoControlCode ) {
        case IOCTL_SANBOOTCONF_IBFT:
                DbgPrint ( "iBFT requested\n" );
-               if ( len > priv->ibft->acpi.length )
-                       len = priv->ibft->acpi.length;
-               RtlCopyMemory ( irp->AssociatedIrp.SystemBuffer,
-                               priv->ibft, len );
-               status = STATUS_SUCCESS;
+               if ( priv->ibft ) {
+                       if ( len > priv->ibft->acpi.length )
+                               len = priv->ibft->acpi.length;
+                       RtlCopyMemory ( irp->AssociatedIrp.SystemBuffer,
+                                       priv->ibft, len );
+                       status = STATUS_SUCCESS;
+               } else {
+                       DbgPrint ( "No iBFT available!\n" );
+                       status = STATUS_NO_SUCH_FILE;
+               }
+               break;
+       case IOCTL_SANBOOTCONF_SBFT:
+               DbgPrint ( "sBFT requested\n" );
+               if ( priv->sbft ) {
+                       if ( len > priv->sbft->acpi.length )
+                               len = priv->sbft->acpi.length;
+                       RtlCopyMemory ( irp->AssociatedIrp.SystemBuffer,
+                                       priv->sbft, len );
+                       status = STATUS_SUCCESS;
+               } else {
+                       DbgPrint ( "No sbft available!\n" );
+                       status = STATUS_NO_SUCH_FILE;
+               }
                break;
        default:
                DbgPrint ( "Unrecognised IoControl %x\n",
@@ -108,12 +135,13 @@ static NTSTATUS create_sanbootconf_device ( PDRIVER_OBJECT driver,
                                            PDEVICE_OBJECT *device ) {
        UNICODE_STRING u_device_name;
        UNICODE_STRING u_device_symlink;
-       unsigned int i;
+       PSANBOOTCONF_PRIV priv;
+       ULONG i;
        NTSTATUS status;
 
        /* Create device */
        RtlInitUnicodeString ( &u_device_name, sanbootconf_device_name );
-       status = IoCreateDeviceSecure ( driver, sizeof ( SANBOOTCONF_PRIV ),
+       status = IoCreateDeviceSecure ( driver, sizeof ( *priv ),
                                        &u_device_name, FILE_DEVICE_UNKNOWN,
                                        FILE_DEVICE_SECURE_OPEN, FALSE,
                                        &SDDL_DEVOBJ_SYS_ALL_ADM_ALL,
@@ -123,6 +151,8 @@ static NTSTATUS create_sanbootconf_device ( PDRIVER_OBJECT driver,
                           sanbootconf_device_name, status );
                return status;
        }
+       priv = (*device)->DeviceExtension;
+       RtlZeroMemory ( priv, sizeof ( *priv ) );
        (*device)->Flags &= ~DO_DEVICE_INITIALIZING;
 
        /* Create device symlinks */
@@ -183,6 +213,17 @@ NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject,
                status = STATUS_SUCCESS;
        }
 
+       /* Look for an sBFT */
+       status = find_acpi_table ( SBFT_SIG, &table );
+       if ( NT_SUCCESS ( status ) ) {
+               priv->sbft = ( ( PSBFT_TABLE ) table );
+               parse_sbft ( priv->sbft );
+       } else {
+               /* Lack of an sBFT is not necessarily an error */
+               DbgPrint ( "No sBFT found\n" );
+               status = STATUS_SUCCESS;
+       }
+
        DbgPrint ( "SAN Boot Configuration Driver initialisation complete\n" );
 
  err_create_sanbootconf_device:
diff --git a/driver/sbft.c b/driver/sbft.c
new file mode 100644 (file)
index 0000000..2ca79bc
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2009 Fen Systems Ltd <mbrown@fensystems.co.uk>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ntddk.h>
+#include <ntstrsafe.h>
+#include "sanbootconf.h"
+#include "sbft.h"
+
+/**
+ * Parse sBFT SCSI subtable
+ *
+ * @v sbft             sBFT
+ * @v scsi             SCSI subtable
+ */
+static VOID parse_sbft_scsi ( PSBFT_TABLE sbft, PSBFT_SCSI_SUBTABLE scsi ) {
+
+       DbgPrint ( "Found sBFT SCSI subtable:\n" );
+       DbgPrint ( "  LUN = %04x-%04x-%04x-%04x\n",
+                  ( ( scsi->lun >> 48 ) & 0xffff ),
+                  ( ( scsi->lun >> 32 ) & 0xffff ),
+                  ( ( scsi->lun >> 16 ) & 0xffff ),
+                  ( ( scsi->lun >> 0  ) & 0xffff ) );
+       ( VOID ) sbft;
+}
+
+/**
+ * Parse sBFT SRP subtable
+ *
+ * @v sbft             sBFT
+ * @v srp              SRP subtable
+ */
+static VOID parse_sbft_srp ( PSBFT_TABLE sbft, PSBFT_SRP_SUBTABLE srp ) {
+
+       DbgPrint ( "Found sBFT SRP subtable:\n" );
+       DbgPrint ( "  Initiator port ID = 0x%08x%08x%08x%08x\n",
+                  RtlUlongByteSwap ( srp->initiator_port_id.u.dwords[0] ),
+                  RtlUlongByteSwap ( srp->initiator_port_id.u.dwords[1] ),
+                  RtlUlongByteSwap ( srp->initiator_port_id.u.dwords[2] ),
+                  RtlUlongByteSwap ( srp->initiator_port_id.u.dwords[3] ) );
+       DbgPrint ( "  Target port ID = 0x%08x%08x%08x%08x\n",
+                  RtlUlongByteSwap ( srp->target_port_id.u.dwords[0] ),
+                  RtlUlongByteSwap ( srp->target_port_id.u.dwords[1] ),
+                  RtlUlongByteSwap ( srp->target_port_id.u.dwords[2] ),
+                  RtlUlongByteSwap ( srp->target_port_id.u.dwords[3] ) );
+       ( VOID ) sbft;
+}
+
+/**
+ * Parse sBFT IB subtable
+ *
+ * @v sbft             sBFT
+ * @v ib               IB subtable
+ */
+static VOID parse_sbft_ib ( PSBFT_TABLE sbft, PSBFT_IB_SUBTABLE ib ) {
+
+       DbgPrint ( "Found sBFT IB subtable:\n" );
+       DbgPrint ( "  Source GID = 0x%08x%08x%08x%08x\n",
+                  RtlUlongByteSwap ( ib->sgid.u.dwords[0] ),
+                  RtlUlongByteSwap ( ib->sgid.u.dwords[1] ),
+                  RtlUlongByteSwap ( ib->sgid.u.dwords[2] ),
+                  RtlUlongByteSwap ( ib->sgid.u.dwords[3] ) );
+       DbgPrint ( "  Destination GID = 0x%08x%08x%08x%08x\n",
+                  RtlUlongByteSwap ( ib->dgid.u.dwords[0] ),
+                  RtlUlongByteSwap ( ib->dgid.u.dwords[1] ),
+                  RtlUlongByteSwap ( ib->dgid.u.dwords[2] ),
+                  RtlUlongByteSwap ( ib->dgid.u.dwords[3] ) );
+       DbgPrint ( "  Service ID = 0x%08x%08x\n",
+                  RtlUlongByteSwap ( ib->service_id.u.dwords[0] ),
+                  RtlUlongByteSwap ( ib->service_id.u.dwords[1] ) );
+       DbgPrint ( "  Partition key = 0x%04x\n", ib->pkey );
+       ( VOID ) sbft;
+}
+
+/**
+ * Parse sBFT
+ *
+ * @v sbft             sBFT
+ */
+VOID parse_sbft ( PSBFT_TABLE sbft ) {
+       PSBFT_SCSI_SUBTABLE scsi;
+       PSBFT_SRP_SUBTABLE srp;
+       PSBFT_IB_SUBTABLE ib;
+
+       if ( sbft->scsi_offset ) {
+               scsi = ( ( PSBFT_SCSI_SUBTABLE )
+                        ( ( PUCHAR ) sbft + sbft->scsi_offset ) );
+               parse_sbft_scsi ( sbft, scsi );
+       }
+       if ( sbft->srp_offset ) {
+               srp = ( ( PSBFT_SRP_SUBTABLE )
+                       ( ( PUCHAR ) sbft + sbft->srp_offset ) );
+               parse_sbft_srp ( sbft, srp );
+       }
+       if ( sbft->ib_offset ) {
+               ib = ( ( PSBFT_IB_SUBTABLE )
+                      ( ( PUCHAR ) sbft + sbft->ib_offset ) );
+               parse_sbft_ib ( sbft, ib );
+       }
+}
diff --git a/driver/sbft.h b/driver/sbft.h
new file mode 100644 (file)
index 0000000..e95060a
--- /dev/null
@@ -0,0 +1,144 @@
+#ifndef _SBFT_H
+#define _SBFT_H
+
+/*
+ * Copyright (C) 2009 Fen Systems Ltd <mbrown@fensystems.co.uk>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ *
+ * SRP boot firmware table
+ *
+ * The working draft specification for the SRP boot firmware table can
+ * be found at
+ *
+ *   http://etherboot.org/wiki/srp/sbft
+ *
+ */
+
+#include "acpi.h"
+
+/** SRP Boot Firmware Table signature */
+#define SBFT_SIG "sBFT"
+
+/**
+ * SRP Boot Firmware Table
+ */
+#pragma pack(1)
+typedef struct _SBFT_TABLE {
+       /** ACPI header */
+       ACPI_DESCRIPTION_HEADER acpi;
+       /** Offset to SCSI subtable */
+       USHORT scsi_offset;
+       /** Offset to SRP subtable */
+       USHORT srp_offset;
+       /** Offset to IB subtable, if present */
+       USHORT ib_offset;
+       /** Reserved */
+       UCHAR reserved[6];
+} SBFT_TABLE, *PSBFT_TABLE;
+#pragma pack()
+
+/**
+ * sBFT SCSI subtable
+ */
+#pragma pack(1)
+typedef struct _SBFT_SCSI_SUBTABLE {
+       /** LUN */
+       ULONGLONG lun;
+} SBFT_SCSI_SUBTABLE, *PSBFT_SCSI_SUBTABLE;
+#pragma pack()
+
+/** An SRP port ID */
+#pragma pack(1)
+typedef struct _SRP_PORT_ID {
+       union {
+               UCHAR bytes[16];
+               USHORT words[8];
+               ULONG dwords[4];
+       } u;
+} SRP_PORT_ID, *PSRP_PORT_ID;
+#pragma pack()
+
+/**
+ * sBFT SRP subtable
+ */
+#pragma pack(1)
+typedef struct _SBFT_SRP_SUBTABLE {
+       /** Initiator port identifier */
+       SRP_PORT_ID initiator_port_id;
+       /** Target port identifier */
+       SRP_PORT_ID target_port_id;
+} SBFT_SRP_SUBTABLE, *PSBFT_SRP_SUBTABLE;
+#pragma pack()
+
+/** An Infiniband GUID */
+#pragma pack(1)
+typedef struct _IB_GUID {
+       union {
+               UCHAR bytes[8];
+               USHORT words[4];
+               ULONG dwords[2];
+       } u;
+} IB_GUID, *PIB_GUID;
+#pragma pack()
+
+/** An Infiniband GID */
+#pragma pack(1)
+typedef struct _IB_GID {
+       union {
+               UCHAR bytes[16];
+               USHORT words[8];
+               ULONG dwords[4];
+               IB_GUID guid[2];
+       } u;
+} IB_GID, *PIB_GID;
+#pragma pack()
+
+/**
+ * sBFT IB subtable
+ */
+#pragma pack(1)
+typedef struct _SBFT_IB_SUBTABLE {
+       /** Source GID */
+       IB_GID sgid;
+       /** Destination GID */
+       IB_GID dgid;
+       /** Service ID */
+       IB_GUID service_id;
+       /** Partition key */
+       USHORT pkey;
+       /** Reserved */
+       UCHAR reserved[6];
+} SBFT_IB_SUBTABLE, *PSBFT_IB_SUBTABLE;
+#pragma pack()
+
+extern VOID parse_sbft ( PSBFT_TABLE sbft );
+
+#endif /* _SBFT_H */
index 6367621..0a85d3c 100644 (file)
@@ -8,4 +8,4 @@ TARGETLIBS = $(DDK_LIB_PATH)\ndis.lib $(DDK_LIB_PATH)\ntstrsafe.lib $(DDK_LIB_PA
 
 MSC_WARNING_LEVEL = /W4 /Wp64 /WX
 
-SOURCES = sanbootconf.c registry.c acpi.c ibft.c
+SOURCES = sanbootconf.c registry.c acpi.c ibft.c sbft.c