Browse Source

[fc] Support Fibre Channel ECHO

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 years ago
parent
commit
90930be8fe
3 changed files with 237 additions and 103 deletions
  1. 15
    22
      src/include/ipxe/fcels.h
  2. 219
    76
      src/net/fcels.c
  3. 3
    5
      src/net/fcp.c

+ 15
- 22
src/include/ipxe/fcels.h View File

@@ -34,6 +34,7 @@ enum fc_els_command_code {
34 34
 	FC_ELS_FLOGI = 0x04,		/**< Fabric Login */
35 35
 	FC_ELS_LOGO = 0x05,		/**< Logout */
36 36
 	FC_ELS_RTV = 0x0e,		/**< Read Timeout Value */
37
+	FC_ELS_ECHO = 0x10,		/**< Echo */
37 38
 	FC_ELS_PRLI = 0x20,		/**< Process Login */
38 39
 	FC_ELS_PRLO = 0x21,		/**< Process Logout */
39 40
 };
@@ -310,6 +311,14 @@ struct fc_rtv_response_frame {
310 311
 /** Short R_T timeout */
311 312
 #define FC_RTV_SHORT_R_T_TOV 0x0008
312 313
 
314
+/** A Fibre Channel ECHO frame */
315
+struct fc_echo_frame_header {
316
+	/** ELS command code */
317
+	uint8_t command;
318
+	/** Reserved */
319
+	uint8_t reserved[3];
320
+} __attribute__ (( packed ));
321
+
313 322
 /** A Fibre Channel extended link services transaction */
314 323
 struct fc_els {
315 324
 	/** Reference count */
@@ -343,37 +352,21 @@ enum fc_els_flags {
343 352
 struct fc_els_handler {
344 353
 	/** Name */
345 354
 	const char *name;
346
-	/** Transmit ELS request frame
347
-	 *
348
-	 * @v els		Fibre Channel ELS transaction
349
-	 * @ret rc		Return status code
350
-	 */
351
-	int ( * tx_request ) ( struct fc_els *els );
352
-	/** Transmit ELS response frame
353
-	 *
354
-	 * @v els		Fibre Channel ELS transaction
355
-	 * @ret rc		Return status code
356
-	 */
357
-	int ( * tx_response ) ( struct fc_els *els );
358
-	/** Receive ELS request frame
355
+	/** Transmit ELS frame
359 356
 	 *
360 357
 	 * @v els		Fibre Channel ELS transaction
361
-	 * @v data		ELS frame
362
-	 * @v len		Length of ELS frame
363 358
 	 * @ret rc		Return status code
364 359
 	 */
365
-	int ( * rx_request ) ( struct fc_els *els, const void *data,
366
-			       size_t len );
367
-	/** Receive ELS response frame
360
+	int ( * tx ) ( struct fc_els *els );
361
+	/** Receive ELS frame
368 362
 	 *
369 363
 	 * @v els		Fibre Channel ELS transaction
370 364
 	 * @v data		ELS frame
371 365
 	 * @v len		Length of ELS frame
372 366
 	 * @ret rc		Return status code
373 367
 	 */
374
-	int ( * rx_response ) ( struct fc_els *els, const void *data,
375
-				size_t len );
376
-	/** Detect ELS request frame
368
+	int ( * rx ) ( struct fc_els *els, void *data, size_t len );
369
+	/** Detect ELS frame
377 370
 	 *
378 371
 	 * @v els		Fibre Channel ELS transaction
379 372
 	 * @v data		ELS frame
@@ -444,7 +437,7 @@ extern int fc_els_prli_tx ( struct fc_els *els,
444 437
 			    void *param );
445 438
 extern int fc_els_prli_rx ( struct fc_els *els,
446 439
 			    struct fc_els_prli_descriptor *descriptor,
447
-			    const void *data, size_t len );
440
+			    void *data, size_t len );
448 441
 extern int fc_els_prli_detect ( struct fc_els *els __unused,
449 442
 				struct fc_els_prli_descriptor *descriptor,
450 443
 				const void *data, size_t len );

+ 219
- 76
src/net/fcels.c View File

@@ -158,7 +158,6 @@ static int fc_els_rx ( struct fc_els *els,
158 158
 	struct sockaddr_fc *src = ( ( struct sockaddr_fc * ) meta->src );
159 159
 	struct sockaddr_fc *dest = ( ( struct sockaddr_fc * ) meta->dest );
160 160
 	size_t len = iob_len ( iobuf );
161
-	int ( * rx ) ( struct fc_els *els, const void *data, size_t len );
162 161
 	int rc;
163 162
 
164 163
 	/* Sanity check */
@@ -206,28 +205,13 @@ static int fc_els_rx ( struct fc_els *els,
206 205
 	DBGC2_HDA ( els, 0, frame, len );
207 206
 
208 207
 	/* Handle received frame */
209
-	rx = ( fc_els_is_request ( els ) ?
210
-	       els->handler->rx_response : els->handler->rx_request );
211
-	if ( ( rc = rx ( els, frame, len ) ) != 0 ) {
208
+	if ( ( rc = els->handler->rx ( els, frame, len ) ) != 0 ) {
212 209
 		DBGC ( els, FCELS_FMT " could not handle received frame: "
213 210
 		       "%s\n", FCELS_ARGS ( els ), strerror ( rc ) );
214 211
 		DBGC_HDA ( els, 0, frame, len );
215 212
 		goto done;
216 213
 	}
217 214
 
218
-	/* Free I/O buffer.  Do this before transmitting response to
219
-	 * minimise memory consumption.
220
-	 */
221
-	free_iob ( iob_disown ( iobuf ) );
222
-
223
-	/* Transmit response if applicable */
224
-	if ( ( ! fc_els_is_request ( els ) ) &&
225
-	     ( ( rc = els->handler->tx_response ( els ) ) != 0 ) ) {
226
-		DBGC ( els, FCELS_FMT " could not transmit response: %s\n",
227
-		       FCELS_ARGS ( els ), strerror ( rc ) );
228
-		goto done;
229
-	}
230
-
231 215
  done:
232 216
 	/* Free I/O buffer */
233 217
 	free_iob ( iobuf );
@@ -286,7 +270,7 @@ static void fc_els_step ( struct process *process ) {
286 270
 	}
287 271
 
288 272
 	/* Transmit request */
289
-	if ( ( rc = els->handler->tx_request ( els ) ) != 0 ) {
273
+	if ( ( rc = els->handler->tx ( els ) ) != 0 ) {
290 274
 		DBGC ( els, FCELS_FMT " could not transmit request: %s\n",
291 275
 		       FCELS_ARGS ( els ), strerror ( rc ) );
292 276
 		fc_els_close ( els, rc );
@@ -394,7 +378,7 @@ struct fc_responder fc_els_responder __fc_responder = {
394 378
  * @v els		Fibre Channel ELS transaction
395 379
  * @ret rc		Return status code
396 380
  */
397
-static int fc_els_unknown_tx_request ( struct fc_els *els __unused ) {
381
+static int fc_els_unknown_tx ( struct fc_els *els __unused ) {
398 382
 	return -ENOTSUP;
399 383
 }
400 384
 
@@ -417,34 +401,26 @@ static int fc_els_unknown_tx_response ( struct fc_els *els ) {
417 401
 }
418 402
 
419 403
 /**
420
- * Receive unknown ELS request
404
+ * Receive unknown ELS
421 405
  *
422 406
  * @v els		Fibre Channel ELS transaction
423 407
  * @v data		ELS frame
424 408
  * @v len		Length of ELS frame
425 409
  * @ret rc		Return status code
426 410
  */
427
-static int fc_els_unknown_rx_request ( struct fc_els *els, const void *data,
428
-				       size_t len ) {
411
+static int fc_els_unknown_rx ( struct fc_els *els, void *data, size_t len ) {
412
+	int rc;
429 413
 
430 414
 	DBGC ( els, FCELS_FMT ":\n", FCELS_ARGS ( els ) );
431 415
 	DBGC_HDA ( els, 0, data, len );
432
-	return 0;
433
-}
434 416
 
435
-/**
436
- * Receive unknown ELS response
437
- *
438
- * @v els		Fibre Channel ELS transaction
439
- * @v data		ELS frame
440
- * @v len		Length of ELS frame
441
- * @ret rc		Return status code
442
- */
443
-static int fc_els_unknown_rx_response ( struct fc_els *els __unused,
444
-					const void *data __unused,
445
-					size_t len __unused ) {
446
-	assert ( 0 );
447
-	return -EINVAL;
417
+	/* Transmit response, if applicable */
418
+	if ( ! fc_els_is_request ( els ) ) {
419
+		if ( ( rc = fc_els_unknown_tx_response ( els ) ) != 0 )
420
+			return rc;
421
+	}
422
+
423
+	return 0;
448 424
 }
449 425
 
450 426
 /**
@@ -464,10 +440,8 @@ static int fc_els_unknown_detect ( struct fc_els *els __unused,
464 440
 /** Unknown ELS handler */
465 441
 struct fc_els_handler fc_els_unknown_handler __fc_els_handler = {
466 442
 	.name		= "UNKNOWN",
467
-	.tx_request	= fc_els_unknown_tx_request,
468
-	.tx_response	= fc_els_unknown_tx_response,
469
-	.rx_request	= fc_els_unknown_rx_request,
470
-	.rx_response	= fc_els_unknown_rx_response,
443
+	.tx		= fc_els_unknown_tx,
444
+	.rx		= fc_els_unknown_rx,
471 445
 	.detect		= fc_els_unknown_detect,
472 446
 };
473 447
 
@@ -513,9 +487,8 @@ static int fc_els_flogi_tx ( struct fc_els *els ) {
513 487
  * @v len		Length of ELS frame
514 488
  * @ret rc		Return status code
515 489
  */
516
-static int fc_els_flogi_rx ( struct fc_els *els, const void *data,
517
-			     size_t len ) {
518
-	const struct fc_login_frame *flogi = data;
490
+static int fc_els_flogi_rx ( struct fc_els *els, void *data, size_t len ) {
491
+	struct fc_login_frame *flogi = data;
519 492
 	int has_fabric;
520 493
 	int rc;
521 494
 
@@ -557,6 +530,12 @@ static int fc_els_flogi_rx ( struct fc_els *els, const void *data,
557 530
 			 sizeof ( els->peer_port_id ) );
558 531
 	}
559 532
 
533
+	/* Transmit response, if applicable */
534
+	if ( ! fc_els_is_request ( els ) ) {
535
+		if ( ( rc = fc_els_flogi_tx ( els ) ) != 0 )
536
+			return rc;
537
+	}
538
+
560 539
 	return 0;
561 540
 }
562 541
 
@@ -582,10 +561,8 @@ static int fc_els_flogi_detect ( struct fc_els *els __unused, const void *data,
582 561
 /** FLOGI ELS handler */
583 562
 struct fc_els_handler fc_els_flogi_handler __fc_els_handler = {
584 563
 	.name		= "FLOGI",
585
-	.tx_request	= fc_els_flogi_tx,
586
-	.tx_response	= fc_els_flogi_tx,
587
-	.rx_request	= fc_els_flogi_rx,
588
-	.rx_response	= fc_els_flogi_rx,
564
+	.tx		= fc_els_flogi_tx,
565
+	.rx		= fc_els_flogi_rx,
589 566
 	.detect		= fc_els_flogi_detect,
590 567
 };
591 568
 
@@ -650,9 +627,8 @@ static int fc_els_plogi_tx ( struct fc_els *els ) {
650 627
  * @v len		Length of ELS frame
651 628
  * @ret rc		Return status code
652 629
  */
653
-static int fc_els_plogi_rx ( struct fc_els *els, const void *data,
654
-			     size_t len ) {
655
-	const struct fc_login_frame *plogi = data;
630
+static int fc_els_plogi_rx ( struct fc_els *els, void *data, size_t len ) {
631
+	struct fc_login_frame *plogi = data;
656 632
 	struct fc_peer *peer;
657 633
 	int rc;
658 634
 
@@ -695,11 +671,18 @@ static int fc_els_plogi_rx ( struct fc_els *els, const void *data,
695 671
 		goto err_login;
696 672
 	}
697 673
 
674
+	/* Transmit response, if applicable */
675
+	if ( ! fc_els_is_request ( els ) ) {
676
+		if ( ( rc = fc_els_plogi_tx ( els ) ) != 0 )
677
+			goto err_plogi_tx;
678
+	}
679
+
698 680
 	/* Drop temporary reference to peer */
699 681
 	fc_peer_put ( peer );
700 682
 
701 683
 	return 0;
702 684
 
685
+ err_plogi_tx:
703 686
  err_login:
704 687
 	fc_peer_put ( peer );
705 688
  err_peer_get_wwn:
@@ -729,10 +712,8 @@ static int fc_els_plogi_detect ( struct fc_els *els __unused, const void *data,
729 712
 /** PLOGI ELS handler */
730 713
 struct fc_els_handler fc_els_plogi_handler __fc_els_handler = {
731 714
 	.name		= "PLOGI",
732
-	.tx_request	= fc_els_plogi_tx,
733
-	.tx_response	= fc_els_plogi_tx,
734
-	.rx_request	= fc_els_plogi_rx,
735
-	.rx_response	= fc_els_plogi_rx,
715
+	.tx		= fc_els_plogi_tx,
716
+	.rx		= fc_els_plogi_rx,
736 717
 	.detect		= fc_els_plogi_detect,
737 718
 };
738 719
 
@@ -764,7 +745,7 @@ int fc_els_plogi ( struct interface *parent, struct fc_port *port,
764 745
  * @v els		Fibre Channel ELS transaction
765 746
  * @ret rc		Return status code
766 747
  */
767
-static int fc_els_logo_tx_request ( struct fc_els *els ) {
748
+static int fc_els_logo_tx ( struct fc_els *els ) {
768 749
 	struct fc_logout_request_frame logo;
769 750
 
770 751
 	/* Construct LOGO */
@@ -802,7 +783,7 @@ static int fc_els_logo_tx_response ( struct fc_els *els ) {
802 783
  * @v port_id		Peer port ID
803 784
  */
804 785
 static void fc_els_logo_logout ( struct fc_els *els,
805
-				 const struct fc_port_id *peer_port_id ) {
786
+				 struct fc_port_id *peer_port_id ) {
806 787
 	struct fc_peer *peer;
807 788
 
808 789
 	if ( ( memcmp ( peer_port_id, &fc_f_port_id,
@@ -827,9 +808,10 @@ static void fc_els_logo_logout ( struct fc_els *els,
827 808
  * @v len		Length of ELS frame
828 809
  * @ret rc		Return status code
829 810
  */
830
-static int fc_els_logo_rx_request ( struct fc_els *els, const void *data,
811
+static int fc_els_logo_rx_request ( struct fc_els *els, void *data,
831 812
 				    size_t len ) {
832
-	const struct fc_logout_request_frame *logo = data;
813
+	struct fc_logout_request_frame *logo = data;
814
+	int rc;
833 815
 
834 816
 	/* Sanity check */
835 817
 	if ( len < sizeof ( *logo ) ) {
@@ -845,6 +827,10 @@ static int fc_els_logo_rx_request ( struct fc_els *els, const void *data,
845 827
 	/* Log out individual peer or whole port as applicable */
846 828
 	fc_els_logo_logout ( els, &logo->port_id );
847 829
 
830
+	/* Transmit repsonse */
831
+	if ( ( rc = fc_els_logo_tx_response ( els ) ) != 0 )
832
+		return rc;
833
+
848 834
 	return 0;
849 835
 }
850 836
 
@@ -856,8 +842,7 @@ static int fc_els_logo_rx_request ( struct fc_els *els, const void *data,
856 842
  * @v len		Length of ELS frame
857 843
  * @ret rc		Return status code
858 844
  */
859
-static int fc_els_logo_rx_response ( struct fc_els *els,
860
-				     const void *data __unused,
845
+static int fc_els_logo_rx_response ( struct fc_els *els, void *data __unused,
861 846
 				     size_t len __unused ) {
862 847
 
863 848
 	/* Log out individual peer or whole port as applicable */
@@ -866,6 +851,23 @@ static int fc_els_logo_rx_response ( struct fc_els *els,
866 851
 	return 0;
867 852
 }
868 853
 
854
+/**
855
+ * Receive LOGO
856
+ *
857
+ * @v els		Fibre Channel ELS transaction
858
+ * @v data		ELS frame
859
+ * @v len		Length of ELS frame
860
+ * @ret rc		Return status code
861
+ */
862
+static int fc_els_logo_rx ( struct fc_els *els, void *data, size_t len ) {
863
+
864
+	if ( fc_els_is_request ( els ) ) {
865
+		return fc_els_logo_rx_response ( els, data, len );
866
+	} else {
867
+		return fc_els_logo_rx_request ( els, data, len );
868
+	}
869
+}
870
+
869 871
 /**
870 872
  * Detect LOGO
871 873
  *
@@ -888,10 +890,8 @@ static int fc_els_logo_detect ( struct fc_els *els __unused, const void *data,
888 890
 /** LOGO ELS handler */
889 891
 struct fc_els_handler fc_els_logo_handler __fc_els_handler = {
890 892
 	.name		= "LOGO",
891
-	.tx_request	= fc_els_logo_tx_request,
892
-	.tx_response	= fc_els_logo_tx_response,
893
-	.rx_request	= fc_els_logo_rx_request,
894
-	.rx_response	= fc_els_logo_rx_response,
893
+	.tx		= fc_els_logo_tx,
894
+	.rx		= fc_els_logo_rx,
895 895
 	.detect		= fc_els_logo_detect,
896 896
 };
897 897
 
@@ -1000,8 +1000,8 @@ int fc_els_prli_tx ( struct fc_els *els,
1000 1000
  */
1001 1001
 int fc_els_prli_rx ( struct fc_els *els,
1002 1002
 		     struct fc_els_prli_descriptor *descriptor,
1003
-		     const void *data, size_t len ) {
1004
-	const struct {
1003
+		     void *data, size_t len ) {
1004
+	struct {
1005 1005
 		struct fc_prli_frame frame;
1006 1006
 		uint8_t param[descriptor->param_len];
1007 1007
 	} __attribute__ (( packed )) *prli = data;
@@ -1055,11 +1055,18 @@ int fc_els_prli_rx ( struct fc_els *els,
1055 1055
 		}
1056 1056
 	}
1057 1057
 
1058
+	/* Transmit response, if applicable */
1059
+	if ( ! fc_els_is_request ( els ) ) {
1060
+		if ( ( rc = els->handler->tx ( els ) ) != 0 )
1061
+			goto err_tx;
1062
+	}
1063
+
1058 1064
 	/* Drop temporary reference to ULP */
1059 1065
 	fc_ulp_put ( ulp );
1060 1066
 
1061 1067
 	return 0;
1062 1068
 
1069
+ err_tx:
1063 1070
  err_login:
1064 1071
  err_link:
1065 1072
 	fc_ulp_put ( ulp );
@@ -1148,20 +1155,25 @@ static int fc_els_rtv_tx_response ( struct fc_els *els ) {
1148 1155
 }
1149 1156
 
1150 1157
 /**
1151
- * Receive RTV request
1158
+ * Receive RTV
1152 1159
  *
1153 1160
  * @v els		Fibre Channel ELS transaction
1154 1161
  * @v data		ELS frame
1155 1162
  * @v len		Length of ELS frame
1156 1163
  * @ret rc		Return status code
1157 1164
  */
1158
-static int fc_els_rtv_rx_request ( struct fc_els *els,
1159
-				   const void *data __unused,
1160
-				   size_t len __unused ) {
1165
+static int fc_els_rtv_rx ( struct fc_els *els, void *data __unused,
1166
+			   size_t len __unused ) {
1167
+	int rc;
1161 1168
 
1162 1169
 	DBGC ( els, FCELS_FMT "\n", FCELS_ARGS ( els ) );
1163 1170
 
1164
-	/* Nothing to do */
1171
+	/* Transmit response */
1172
+	if ( ! fc_els_is_request ( els ) ) {
1173
+		if ( ( rc = fc_els_rtv_tx_response ( els ) ) != 0 )
1174
+			return rc;
1175
+	}
1176
+
1165 1177
 	return 0;
1166 1178
 }
1167 1179
 
@@ -1187,9 +1199,140 @@ static int fc_els_rtv_detect ( struct fc_els *els __unused, const void *data,
1187 1199
 /** RTV ELS handler */
1188 1200
 struct fc_els_handler fc_els_rtv_handler __fc_els_handler = {
1189 1201
 	.name		= "RTV",
1190
-	.tx_request	= fc_els_unknown_tx_request,
1191
-	.tx_response	= fc_els_rtv_tx_response,
1192
-	.rx_request	= fc_els_rtv_rx_request,
1193
-	.rx_response	= fc_els_unknown_rx_response,
1202
+	.tx		= fc_els_unknown_tx,
1203
+	.rx		= fc_els_rtv_rx,
1194 1204
 	.detect		= fc_els_rtv_detect,
1195 1205
 };
1206
+
1207
+/******************************************************************************
1208
+ *
1209
+ * ECHO
1210
+ *
1211
+ ******************************************************************************
1212
+ */
1213
+
1214
+/** ECHO request data */
1215
+struct fc_echo_request_frame {
1216
+	/** ECHO frame header */
1217
+	struct fc_echo_frame_header echo;
1218
+	/** Magic marker */
1219
+	uint32_t magic;
1220
+} __attribute__ (( packed ));
1221
+
1222
+/** ECHO magic marker */
1223
+#define FC_ECHO_MAGIC 0x69505845
1224
+
1225
+/**
1226
+ * Transmit ECHO
1227
+ *
1228
+ * @v els		Fibre Channel ELS transaction
1229
+ * @ret rc		Return status code
1230
+ */
1231
+static int fc_els_echo_tx ( struct fc_els *els ) {
1232
+	struct fc_echo_request_frame echo;
1233
+
1234
+	/* Construct ECHO */
1235
+	memset ( &echo, 0, sizeof ( echo ) );
1236
+	echo.echo.command = FC_ELS_ECHO;
1237
+	echo.magic = htonl ( FC_ECHO_MAGIC );
1238
+
1239
+	/* Transmit ECHO */
1240
+	return fc_els_tx ( els, &echo, sizeof ( echo ) );
1241
+}
1242
+
1243
+/**
1244
+ * Receive ECHO request
1245
+ *
1246
+ * @v els		Fibre Channel ELS transaction
1247
+ * @v data		ELS frame
1248
+ * @v len		Length of ELS frame
1249
+ * @ret rc		Return status code
1250
+ */
1251
+static int fc_els_echo_rx_request ( struct fc_els *els, void *data,
1252
+				    size_t len ) {
1253
+	struct {
1254
+		struct fc_echo_frame_header echo;
1255
+		char payload[ len - sizeof ( struct fc_echo_frame_header ) ];
1256
+	} *echo = data;
1257
+	int rc;
1258
+
1259
+	DBGC ( els, FCELS_FMT "\n", FCELS_ARGS ( els ) );
1260
+
1261
+	/* Transmit response */
1262
+	echo->echo.command = FC_ELS_LS_ACC;
1263
+	if ( ( rc = fc_els_tx ( els, echo, sizeof ( *echo ) ) ) != 0 )
1264
+		return rc;
1265
+
1266
+	/* Nothing to do */
1267
+	return 0;
1268
+}
1269
+
1270
+/**
1271
+ * Receive ECHO response
1272
+ *
1273
+ * @v els		Fibre Channel ELS transaction
1274
+ * @v data		ELS frame
1275
+ * @v len		Length of ELS frame
1276
+ * @ret rc		Return status code
1277
+ */
1278
+static int fc_els_echo_rx_response ( struct fc_els *els, void *data,
1279
+				     size_t len ) {
1280
+	struct fc_echo_request_frame *echo = data;
1281
+
1282
+	DBGC ( els, FCELS_FMT "\n", FCELS_ARGS ( els ) );
1283
+
1284
+	/* Check response is correct */
1285
+	if ( ( len != sizeof ( *echo ) ) ||
1286
+	     ( echo->magic != htonl ( FC_ECHO_MAGIC ) ) ) {
1287
+		DBGC ( els, FCELS_FMT " received bad echo response\n",
1288
+		       FCELS_ARGS ( els ) );
1289
+		DBGC_HDA ( els, 0, data, len );
1290
+		return -EIO;
1291
+	}
1292
+
1293
+	return 0;
1294
+}
1295
+
1296
+/**
1297
+ * Receive ECHO
1298
+ *
1299
+ * @v els		Fibre Channel ELS transaction
1300
+ * @v data		ELS frame
1301
+ * @v len		Length of ELS frame
1302
+ * @ret rc		Return status code
1303
+ */
1304
+static int fc_els_echo_rx ( struct fc_els *els, void *data, size_t len ) {
1305
+
1306
+	if ( fc_els_is_request ( els ) ) {
1307
+		return fc_els_echo_rx_response ( els, data, len );
1308
+	} else {
1309
+		return fc_els_echo_rx_request ( els, data, len );
1310
+	}
1311
+}
1312
+
1313
+/**
1314
+ * Detect ECHO
1315
+ *
1316
+ * @v els		Fibre Channel ELS transaction
1317
+ * @v data		ELS frame
1318
+ * @v len		Length of ELS frame
1319
+ * @ret rc		Return status code
1320
+ */
1321
+static int fc_els_echo_detect ( struct fc_els *els __unused, const void *data,
1322
+				size_t len __unused ) {
1323
+	const struct fc_echo_frame_header *echo = data;
1324
+
1325
+	/* Check for ECHO */
1326
+	if ( echo->command != FC_ELS_ECHO )
1327
+		return -EINVAL;
1328
+
1329
+	return 0;
1330
+}
1331
+
1332
+/** ECHO ELS handler */
1333
+struct fc_els_handler fc_els_echo_handler __fc_els_handler = {
1334
+	.name		= "ECHO",
1335
+	.tx		= fc_els_echo_tx,
1336
+	.rx		= fc_els_echo_rx,
1337
+	.detect		= fc_els_echo_detect,
1338
+};

+ 3
- 5
src/net/fcp.c View File

@@ -103,7 +103,7 @@ static int fcp_prli_tx ( struct fc_els *els ) {
103 103
  * @v len		Length of ELS frame
104 104
  * @ret rc		Return status code
105 105
  */
106
-static int fcp_prli_rx ( struct fc_els *els, const void *data, size_t len ) {
106
+static int fcp_prli_rx ( struct fc_els *els, void *data, size_t len ) {
107 107
 	return fc_els_prli_rx ( els, &fcp_prli_descriptor, data, len );
108 108
 }
109 109
 
@@ -123,10 +123,8 @@ static int fcp_prli_detect ( struct fc_els *els, const void *data,
123 123
 /** FCP PRLI ELS handler */
124 124
 struct fc_els_handler fcp_prli_handler __fc_els_handler = {
125 125
 	.name		= "PRLI-FCP",
126
-	.tx_request	= fcp_prli_tx,
127
-	.tx_response	= fcp_prli_tx,
128
-	.rx_request	= fcp_prli_rx,
129
-	.rx_response	= fcp_prli_rx,
126
+	.tx		= fcp_prli_tx,
127
+	.rx		= fcp_prli_rx,
130 128
 	.detect		= fcp_prli_detect,
131 129
 };
132 130
 

Loading…
Cancel
Save