Browse Source

[fcp] Add support for describing an FCP device using EDD

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
a5a4dcd0c7
1 changed files with 68 additions and 4 deletions
  1. 68
    4
      src/net/fcp.c

+ 68
- 4
src/net/fcp.c View File

36
 #include <ipxe/uri.h>
36
 #include <ipxe/uri.h>
37
 #include <ipxe/acpi.h>
37
 #include <ipxe/acpi.h>
38
 #include <ipxe/scsi.h>
38
 #include <ipxe/scsi.h>
39
+#include <ipxe/device.h>
40
+#include <ipxe/edd.h>
39
 #include <ipxe/fc.h>
41
 #include <ipxe/fc.h>
40
 #include <ipxe/fcels.h>
42
 #include <ipxe/fcels.h>
41
 #include <ipxe/fcp.h>
43
 #include <ipxe/fcp.h>
152
 	struct interface scsi;
154
 	struct interface scsi;
153
 	/** List of active commands */
155
 	/** List of active commands */
154
 	struct list_head fcpcmds;
156
 	struct list_head fcpcmds;
157
+
158
+	/** Fibre Channel WWN (for boot firmware table) */
159
+	struct fc_name wwn;
160
+	/** SCSI LUN (for boot firmware table) */
161
+	struct scsi_lun lun;
155
 };
162
 };
156
 
163
 
157
 /** An FCP command */
164
 /** An FCP command */
840
  * @v len		Length of ACPI table
847
  * @v len		Length of ACPI table
841
  * @ret rc		Return status code
848
  * @ret rc		Return status code
842
  */
849
  */
843
-static int fcpdev_describe ( struct fcp_device *fcpdev,
844
-			     struct acpi_description_header *acpi,
845
-			     size_t len ) {
850
+static int fcpdev_acpi_describe ( struct fcp_device *fcpdev,
851
+				  struct acpi_description_header *acpi,
852
+				  size_t len ) {
846
 
853
 
847
 	DBGC ( fcpdev, "FCP %p cannot yet describe device in an ACPI table\n",
854
 	DBGC ( fcpdev, "FCP %p cannot yet describe device in an ACPI table\n",
848
 	       fcpdev );
855
 	       fcpdev );
851
 	return 0;
858
 	return 0;
852
 }
859
 }
853
 
860
 
861
+/**
862
+ * Describe FCP device using EDD
863
+ *
864
+ * @v fcpdev		FCP device
865
+ * @v type		EDD interface type
866
+ * @v path		EDD device path
867
+ * @ret rc		Return status code
868
+ */
869
+static int fcpdev_edd_describe ( struct fcp_device *fcpdev,
870
+				 struct edd_interface_type *type,
871
+				 union edd_device_path *path ) {
872
+	union {
873
+		struct fc_name fc;
874
+		uint64_t u64;
875
+	} wwn;
876
+	union {
877
+		struct scsi_lun scsi;
878
+		uint64_t u64;
879
+	} lun;
880
+
881
+	type->type = cpu_to_le64 ( EDD_INTF_TYPE_FIBRE );
882
+	memcpy ( &wwn.fc, &fcpdev->wwn, sizeof ( wwn.fc ) );
883
+	path->fibre.wwn = be64_to_cpu ( wwn.u64 );
884
+	memcpy ( &lun.scsi, &fcpdev->lun, sizeof ( lun.scsi ) );
885
+	path->fibre.lun = be64_to_cpu ( lun.u64 );
886
+	return 0;
887
+}
888
+
889
+/**
890
+ * Identify device underlying FCP device
891
+ *
892
+ * @v fcpdev		FCP device
893
+ * @ret device		Underlying device
894
+ */
895
+static struct device * fcpdev_identify_device ( struct fcp_device *fcpdev ) {
896
+
897
+	/* We know the underlying device only if the link is up;
898
+	 * otherwise we don't have a port to examine.
899
+	 */
900
+	if ( ! fc_link_ok ( &fcpdev->ulp->link ) ) {
901
+		DBGC ( fcpdev, "FCP %p doesn't know underlying device "
902
+		       "until link is up\n", fcpdev );
903
+		return NULL;
904
+	}
905
+
906
+	/* Hand off to port's transport interface */
907
+	assert ( fcpdev->ulp->peer->port != NULL );
908
+	return identify_device ( &fcpdev->ulp->peer->port->transport );
909
+}
910
+
854
 /** FCP device SCSI interface operations */
911
 /** FCP device SCSI interface operations */
855
 static struct interface_operation fcpdev_scsi_op[] = {
912
 static struct interface_operation fcpdev_scsi_op[] = {
856
 	INTF_OP ( scsi_command, struct fcp_device *, fcpdev_scsi_command ),
913
 	INTF_OP ( scsi_command, struct fcp_device *, fcpdev_scsi_command ),
857
 	INTF_OP ( xfer_window, struct fcp_device *, fcpdev_window ),
914
 	INTF_OP ( xfer_window, struct fcp_device *, fcpdev_window ),
858
 	INTF_OP ( intf_close, struct fcp_device *, fcpdev_close ),
915
 	INTF_OP ( intf_close, struct fcp_device *, fcpdev_close ),
859
-	INTF_OP ( acpi_describe, struct fcp_device *, fcpdev_describe ),
916
+	INTF_OP ( acpi_describe, struct fcp_device *, fcpdev_acpi_describe ),
917
+	INTF_OP ( edd_describe, struct fcp_device *, fcpdev_edd_describe ),
918
+	INTF_OP ( identify_device, struct fcp_device *,
919
+		  fcpdev_identify_device ),
860
 };
920
 };
861
 
921
 
862
 /** FCP device SCSI interface descriptor */
922
 /** FCP device SCSI interface descriptor */
898
 
958
 
899
 	DBGC ( fcpdev, "FCP %p opened for %s\n", fcpdev, fc_ntoa ( wwn ) );
959
 	DBGC ( fcpdev, "FCP %p opened for %s\n", fcpdev, fc_ntoa ( wwn ) );
900
 
960
 
961
+	/* Preserve parameters required for boot firmware table */
962
+	memcpy ( &fcpdev->wwn, wwn, sizeof ( fcpdev->wwn ) );
963
+	memcpy ( &fcpdev->lun, lun, sizeof ( fcpdev->lun ) );
964
+
901
 	/* Attach SCSI device to parent interface */
965
 	/* Attach SCSI device to parent interface */
902
 	if ( ( rc = scsi_open ( parent, &fcpdev->scsi, lun ) ) != 0 ) {
966
 	if ( ( rc = scsi_open ( parent, &fcpdev->scsi, lun ) ) != 0 ) {
903
 		DBGC ( fcpdev, "FCP %p could not create SCSI device: %s\n",
967
 		DBGC ( fcpdev, "FCP %p could not create SCSI device: %s\n",

Loading…
Cancel
Save