Просмотр исходного кода

[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 лет назад
Родитель
Сommit
a5a4dcd0c7
1 измененных файлов: 68 добавлений и 4 удалений
  1. 68
    4
      src/net/fcp.c

+ 68
- 4
src/net/fcp.c Просмотреть файл

@@ -36,6 +36,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
36 36
 #include <ipxe/uri.h>
37 37
 #include <ipxe/acpi.h>
38 38
 #include <ipxe/scsi.h>
39
+#include <ipxe/device.h>
40
+#include <ipxe/edd.h>
39 41
 #include <ipxe/fc.h>
40 42
 #include <ipxe/fcels.h>
41 43
 #include <ipxe/fcp.h>
@@ -152,6 +154,11 @@ struct fcp_device {
152 154
 	struct interface scsi;
153 155
 	/** List of active commands */
154 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 164
 /** An FCP command */
@@ -840,9 +847,9 @@ static size_t fcpdev_window ( struct fcp_device *fcpdev ) {
840 847
  * @v len		Length of ACPI table
841 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 854
 	DBGC ( fcpdev, "FCP %p cannot yet describe device in an ACPI table\n",
848 855
 	       fcpdev );
@@ -851,12 +858,65 @@ static int fcpdev_describe ( struct fcp_device *fcpdev,
851 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 911
 /** FCP device SCSI interface operations */
855 912
 static struct interface_operation fcpdev_scsi_op[] = {
856 913
 	INTF_OP ( scsi_command, struct fcp_device *, fcpdev_scsi_command ),
857 914
 	INTF_OP ( xfer_window, struct fcp_device *, fcpdev_window ),
858 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 922
 /** FCP device SCSI interface descriptor */
@@ -898,6 +958,10 @@ static int fcpdev_open ( struct interface *parent, struct fc_name *wwn,
898 958
 
899 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 965
 	/* Attach SCSI device to parent interface */
902 966
 	if ( ( rc = scsi_open ( parent, &fcpdev->scsi, lun ) ) != 0 ) {
903 967
 		DBGC ( fcpdev, "FCP %p could not create SCSI device: %s\n",

Загрузка…
Отмена
Сохранить