Browse Source

[fc] Do not use the command reference number in FCP_CMND IUs

The FCP command reference number is intended to be used for
controlling precise delivery of FCP commands, rather than being an
essentially arbitrary tag field (as with iSCSI and SRP).

Use the Fibre Channel local exchange ID as the tag for FCP commands,
instead of the FCP command reference.  The local exchange ID does not
appear within the FCP IU itself, but does appear within the FC frame
header; debug traces can therefore still be correlated with packet
captures.

Reported-by: Hadar Hen Zion <hadarh@mellanox.co.il>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
b0e434280e
3 changed files with 65 additions and 62 deletions
  1. 2
    2
      src/net/fc.c
  2. 5
    3
      src/net/fcels.c
  3. 58
    57
      src/net/fcp.c

+ 2
- 2
src/net/fc.c View File

@@ -703,7 +703,7 @@ static struct fc_exchange * fc_xchg_create ( struct fc_port *port,
703 703
  * @v parent		Interface to which to attach
704 704
  * @v port		Fibre Channel port
705 705
  * @v peer_port_id	Peer port ID
706
- * @ret rc		Return status code
706
+ * @ret xchg_id		Exchange ID, or negative error
707 707
  */
708 708
 int fc_xchg_originate ( struct interface *parent, struct fc_port *port,
709 709
 			struct fc_port_id *peer_port_id, unsigned int type ) {
@@ -722,7 +722,7 @@ int fc_xchg_originate ( struct interface *parent, struct fc_port *port,
722 722
 
723 723
 	/* Attach to parent interface and return */
724 724
 	intf_plug_plug ( &xchg->ulp, parent );
725
-	return 0;
725
+	return xchg->xchg_id;
726 726
 }
727 727
 
728 728
 /**

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

@@ -265,6 +265,7 @@ static struct interface_descriptor fc_els_job_desc =
265 265
 static void fc_els_step ( struct process *process ) {
266 266
 	struct fc_els *els =
267 267
 		container_of ( process, struct fc_els, process );
268
+	int xchg_id;
268 269
 	int rc;
269 270
 
270 271
 	/* Sanity check */
@@ -274,9 +275,10 @@ static void fc_els_step ( struct process *process ) {
274 275
 	process_del ( &els->process );
275 276
 
276 277
 	/* Create exchange */
277
-	if ( ( rc = fc_xchg_originate ( &els->xchg, els->port,
278
-					&els->peer_port_id,
279
-					FC_TYPE_ELS ) ) != 0 ) {
278
+	if ( ( xchg_id = fc_xchg_originate ( &els->xchg, els->port,
279
+					     &els->peer_port_id,
280
+					     FC_TYPE_ELS ) ) < 0 ) {
281
+		rc = xchg_id;
280 282
 		DBGC ( els, FCELS_FMT " could not create exchange: %s\n",
281 283
 		       FCELS_ARGS ( els ), strerror ( rc ) );
282 284
 		fc_els_close ( els, rc );

+ 58
- 57
src/net/fcp.c View File

@@ -187,8 +187,8 @@ struct fcp_command {
187 187
 	size_t offset;
188 188
 	/** Length of data remaining to be sent within this IU */
189 189
 	size_t remaining;
190
-	/** Command reference */
191
-	uint8_t ref;
190
+	/** Exchange ID */
191
+	uint16_t xchg_id;
192 192
 };
193 193
 
194 194
 /**
@@ -285,8 +285,8 @@ static void fcpcmd_close ( struct fcp_command *fcpcmd, int rc ) {
285 285
 	struct fcp_device *fcpdev = fcpcmd->fcpdev;
286 286
 
287 287
 	if ( rc != 0 ) {
288
-		DBGC ( fcpdev, "FCP %p ref %02x closed: %s\n",
289
-		       fcpdev, fcpcmd->ref, strerror ( rc ) );
288
+		DBGC ( fcpdev, "FCP %p xchg %04x closed: %s\n",
289
+		       fcpdev, fcpcmd->xchg_id, strerror ( rc ) );
290 290
 	}
291 291
 
292 292
 	/* Stop sending */
@@ -325,16 +325,16 @@ static int fcpcmd_send_cmnd ( struct fcp_command *fcpcmd ) {
325 325
 
326 326
 	/* Sanity check */
327 327
 	if ( command->data_in_len && command->data_out_len ) {
328
-		DBGC ( fcpdev, "FCP %p ref %02x cannot handle bidirectional "
329
-		       "command\n", fcpdev, fcpcmd->ref );
328
+		DBGC ( fcpdev, "FCP %p xchg %04x cannot handle bidirectional "
329
+		       "command\n", fcpdev, fcpcmd->xchg_id );
330 330
 		return -ENOTSUP;
331 331
 	}
332 332
 
333 333
 	/* Allocate I/O buffer */
334 334
 	iobuf = xfer_alloc_iob ( &fcpcmd->xchg, sizeof ( *cmnd ) );
335 335
 	if ( ! iobuf ) {
336
-		DBGC ( fcpdev, "FCP %p ref %02x cannot allocate command IU\n",
337
-		       fcpdev, fcpcmd->ref );
336
+		DBGC ( fcpdev, "FCP %p xchg %04x cannot allocate command IU\n",
337
+		       fcpdev, fcpcmd->xchg_id );
338 338
 		return -ENOMEM;
339 339
 	}
340 340
 
@@ -342,7 +342,6 @@ static int fcpcmd_send_cmnd ( struct fcp_command *fcpcmd ) {
342 342
 	cmnd = iob_put ( iobuf, sizeof ( *cmnd ) );
343 343
 	memset ( cmnd, 0, sizeof ( *cmnd ) );
344 344
 	memcpy ( &cmnd->lun, &command->lun, sizeof ( cmnd->lun ) );
345
-	cmnd->ref = fcpcmd->ref;
346 345
 	assert ( ! ( command->data_in_len && command->data_out_len ) );
347 346
 	if ( command->data_in_len )
348 347
 		cmnd->dirn |= FCP_CMND_RDDATA;
@@ -352,8 +351,8 @@ static int fcpcmd_send_cmnd ( struct fcp_command *fcpcmd ) {
352 351
 	cmnd->len = htonl ( command->data_in_len + command->data_out_len );
353 352
 	memset ( &meta, 0, sizeof ( meta ) );
354 353
 	meta.flags = ( XFER_FL_CMD_STAT | XFER_FL_OVER );
355
-	DBGC2 ( fcpdev, "FCP %p ref %02x CMND " SCSI_CDB_FORMAT " %04x\n",
356
-		fcpdev, fcpcmd->ref, SCSI_CDB_DATA ( cmnd->cdb ),
354
+	DBGC2 ( fcpdev, "FCP %p xchg %04x CMND " SCSI_CDB_FORMAT " %04x\n",
355
+		fcpdev, fcpcmd->xchg_id, SCSI_CDB_DATA ( cmnd->cdb ),
357 356
 		ntohl ( cmnd->len ) );
358 357
 
359 358
 	/* No further data to send within this IU */
@@ -362,8 +361,8 @@ static int fcpcmd_send_cmnd ( struct fcp_command *fcpcmd ) {
362 361
 	/* Send command IU frame */
363 362
 	if ( ( rc = xfer_deliver ( &fcpcmd->xchg, iob_disown ( iobuf ),
364 363
 				   &meta ) ) != 0 ) {
365
-		DBGC ( fcpdev, "FCP %p ref %02x cannot deliver command IU: "
366
-		       "%s\n", fcpdev, fcpcmd->ref, strerror ( rc ) );
364
+		DBGC ( fcpdev, "FCP %p xchg %04x cannot deliver command IU: "
365
+		       "%s\n", fcpdev, fcpcmd->xchg_id, strerror ( rc ) );
367 366
 		return rc;
368 367
 	}
369 368
 
@@ -389,27 +388,27 @@ static int fcpcmd_recv_rddata ( struct fcp_command *fcpcmd,
389 388
 
390 389
 	/* Sanity checks */
391 390
 	if ( ! ( meta->flags & XFER_FL_ABS_OFFSET ) ) {
392
-		DBGC ( fcpdev, "FCP %p ref %02x read data missing offset\n",
393
-		       fcpdev, fcpcmd->ref );
391
+		DBGC ( fcpdev, "FCP %p xchg %04x read data missing offset\n",
392
+		       fcpdev, fcpcmd->xchg_id );
394 393
 		rc = -ERANGE_READ_DATA_ORDERING;
395 394
 		goto done;
396 395
 	}
397 396
 	if ( offset != fcpcmd->offset ) {
398
-		DBGC ( fcpdev, "FCP %p ref %02x read data out of order "
397
+		DBGC ( fcpdev, "FCP %p xchg %04x read data out of order "
399 398
 		       "(expected %zd, received %zd)\n",
400
-		       fcpdev, fcpcmd->ref, fcpcmd->offset, offset );
399
+		       fcpdev, fcpcmd->xchg_id, fcpcmd->offset, offset );
401 400
 		rc = -ERANGE_READ_DATA_ORDERING;
402 401
 		goto done;
403 402
 	}
404 403
 	if ( ( offset + len ) > command->data_in_len ) {
405
-		DBGC ( fcpdev, "FCP %p ref %02x read data overrun (max %zd, "
406
-		       "received %zd)\n", fcpdev, fcpcmd->ref,
404
+		DBGC ( fcpdev, "FCP %p xchg %04x read data overrun (max %zd, "
405
+		       "received %zd)\n", fcpdev, fcpcmd->xchg_id,
407 406
 		       command->data_in_len, ( offset + len ) );
408 407
 		rc = -ERANGE_READ_DATA_OVERRUN;
409 408
 		goto done;
410 409
 	}
411
-	DBGC2 ( fcpdev, "FCP %p ref %02x RDDATA [%08zx,%08zx)\n",
412
-		fcpdev, fcpcmd->ref, offset, ( offset + len ) );
410
+	DBGC2 ( fcpdev, "FCP %p xchg %04x RDDATA [%08zx,%08zx)\n",
411
+		fcpdev, fcpcmd->xchg_id, offset, ( offset + len ) );
413 412
 
414 413
 	/* Copy to user buffer */
415 414
 	copy_to_user ( command->data_in, offset, iobuf->data, len );
@@ -443,13 +442,13 @@ static int fcpcmd_send_wrdata ( struct fcp_command *fcpcmd ) {
443 442
 
444 443
 	/* Sanity checks */
445 444
 	if ( len == 0 ) {
446
-		DBGC ( fcpdev, "FCP %p ref %02x write data stuck\n",
447
-		       fcpdev, fcpcmd->ref );
445
+		DBGC ( fcpdev, "FCP %p xchg %04x write data stuck\n",
446
+		       fcpdev, fcpcmd->xchg_id );
448 447
 		return -ERANGE_WRITE_DATA_STUCK;
449 448
 	}
450 449
 	if ( ( fcpcmd->offset + len ) > command->data_out_len ) {
451
-		DBGC ( fcpdev, "FCP %p ref %02x write data overrun (max %zd, "
452
-		       "requested %zd)\n", fcpdev, fcpcmd->ref,
450
+		DBGC ( fcpdev, "FCP %p xchg %04x write data overrun (max %zd, "
451
+		       "requested %zd)\n", fcpdev, fcpcmd->xchg_id,
453 452
 		       command->data_out_len, ( fcpcmd->offset + len ) );
454 453
 		return -ERANGE_WRITE_DATA_OVERRUN;
455 454
 	}
@@ -457,8 +456,8 @@ static int fcpcmd_send_wrdata ( struct fcp_command *fcpcmd ) {
457 456
 	/* Allocate I/O buffer */
458 457
 	iobuf = xfer_alloc_iob ( &fcpcmd->xchg, len );
459 458
 	if ( ! iobuf ) {
460
-		DBGC ( fcpdev, "FCP %p ref %02x cannot allocate write data IU "
461
-		       "for %zd bytes\n", fcpdev, fcpcmd->ref, len );
459
+		DBGC ( fcpdev, "FCP %p xchg %04x cannot allocate write data "
460
+		       "IU for %zd bytes\n", fcpdev, fcpcmd->xchg_id, len );
462 461
 		return -ENOMEM;
463 462
 	}
464 463
 
@@ -468,8 +467,8 @@ static int fcpcmd_send_wrdata ( struct fcp_command *fcpcmd ) {
468 467
 	memset ( &meta, 0, sizeof ( meta ) );
469 468
 	meta.flags = ( XFER_FL_RESPONSE | XFER_FL_ABS_OFFSET );
470 469
 	meta.offset = fcpcmd->offset;
471
-	DBGC2 ( fcpdev, "FCP %p ref %02x WRDATA [%08zx,%04zx)\n",
472
-		fcpdev, fcpcmd->ref, fcpcmd->offset,
470
+	DBGC2 ( fcpdev, "FCP %p xchg %04x WRDATA [%08zx,%04zx)\n",
471
+		fcpdev, fcpcmd->xchg_id, fcpcmd->offset,
473 472
 		( fcpcmd->offset + iob_len ( iobuf ) ) );
474 473
 
475 474
 	/* Calculate amount of data remaining to be sent within this IU */
@@ -485,8 +484,8 @@ static int fcpcmd_send_wrdata ( struct fcp_command *fcpcmd ) {
485 484
 	/* Send data IU frame */
486 485
 	if ( ( rc = xfer_deliver ( &fcpcmd->xchg, iob_disown ( iobuf ),
487 486
 				   &meta ) ) != 0 ) {
488
-		DBGC ( fcpdev, "FCP %p ref %02x cannot deliver write data IU: "
489
-		       "%s\n", fcpdev, fcpcmd->ref, strerror ( rc ) );
487
+		DBGC ( fcpdev, "FCP %p xchg %04x cannot deliver write data "
488
+		       "IU: %s\n", fcpdev, fcpcmd->xchg_id, strerror ( rc ) );
490 489
 		return rc;
491 490
 	}
492 491
 
@@ -510,23 +509,23 @@ static int fcpcmd_recv_xfer_rdy ( struct fcp_command *fcpcmd,
510 509
 
511 510
 	/* Sanity checks */
512 511
 	if ( iob_len ( iobuf ) != sizeof ( *xfer_rdy ) ) {
513
-		DBGC ( fcpdev, "FCP %p ref %02x received invalid transfer "
514
-		       "ready IU:\n", fcpdev, fcpcmd->ref );
512
+		DBGC ( fcpdev, "FCP %p xchg %04x received invalid transfer "
513
+		       "ready IU:\n", fcpdev, fcpcmd->xchg_id );
515 514
 		DBGC_HDA ( fcpdev, 0, iobuf->data, iob_len ( iobuf ) );
516 515
 		rc = -EINVAL;
517 516
 		goto done;
518 517
 	}
519 518
 	if ( ntohl ( xfer_rdy->offset ) != fcpcmd->offset ) {
520 519
 		/* We do not advertise out-of-order delivery */
521
-		DBGC ( fcpdev, "FCP %p ref %02x cannot support out-of-order "
520
+		DBGC ( fcpdev, "FCP %p xchg %04x cannot support out-of-order "
522 521
 		       "delivery (expected %zd, requested %d)\n",
523
-		       fcpdev, fcpcmd->ref, fcpcmd->offset,
522
+		       fcpdev, fcpcmd->xchg_id, fcpcmd->offset,
524 523
 		       ntohl ( xfer_rdy->offset ) );
525 524
 		rc = -EINVAL;
526 525
 		goto done;
527 526
 	}
528
-	DBGC2 ( fcpdev, "FCP %p ref %02x XFER_RDY [%08x,%08x)\n",
529
-		fcpdev, fcpcmd->ref, ntohl ( xfer_rdy->offset ),
527
+	DBGC2 ( fcpdev, "FCP %p xchg %04x XFER_RDY [%08x,%08x)\n",
528
+		fcpdev, fcpcmd->xchg_id, ntohl ( xfer_rdy->offset ),
530 529
 		( ntohl ( xfer_rdy->offset ) + ntohl ( xfer_rdy->len ) ) );
531 530
 
532 531
 	/* Start sending requested data */
@@ -562,28 +561,28 @@ static int fcpcmd_recv_rsp ( struct fcp_command *fcpcmd,
562 561
 	     ( iob_len ( iobuf ) < ( sizeof ( *rsp ) +
563 562
 				     fcp_rsp_response_data_len ( rsp ) +
564 563
 				     fcp_rsp_sense_data_len ( rsp ) ) ) ) {
565
-		DBGC ( fcpdev, "FCP %p ref %02x received invalid response "
566
-		       "IU:\n", fcpdev, fcpcmd->ref );
564
+		DBGC ( fcpdev, "FCP %p xchg %04x received invalid response "
565
+		       "IU:\n", fcpdev, fcpcmd->xchg_id );
567 566
 		DBGC_HDA ( fcpdev, 0, iobuf->data, iob_len ( iobuf ) );
568 567
 		rc = -EINVAL;
569 568
 		goto done;
570 569
 	}
571
-	DBGC2 ( fcpdev, "FCP %p ref %02x RSP stat %02x resid %08x flags %02x"
572
-		"%s%s%s%s\n", fcpdev, fcpcmd->ref, rsp->status,
570
+	DBGC2 ( fcpdev, "FCP %p xchg %04x RSP stat %02x resid %08x flags %02x"
571
+		"%s%s%s%s\n", fcpdev, fcpcmd->xchg_id, rsp->status,
573 572
 		ntohl ( rsp->residual ), rsp->flags,
574 573
 		( ( rsp->flags & FCP_RSP_RESPONSE_LEN_VALID ) ? " resp" : "" ),
575 574
 		( ( rsp->flags & FCP_RSP_SENSE_LEN_VALID ) ? " sense" : "" ),
576 575
 		( ( rsp->flags & FCP_RSP_RESIDUAL_OVERRUN ) ? " over" : "" ),
577 576
 		( ( rsp->flags & FCP_RSP_RESIDUAL_UNDERRUN ) ? " under" : "" ));
578 577
 	if ( fcp_rsp_response_data ( rsp ) ) {
579
-		DBGC2 ( fcpdev, "FCP %p ref %02x response data:\n",
580
-			fcpdev, fcpcmd->ref );
578
+		DBGC2 ( fcpdev, "FCP %p xchg %04x response data:\n",
579
+			fcpdev, fcpcmd->xchg_id );
581 580
 		DBGC2_HDA ( fcpdev, 0, fcp_rsp_response_data ( rsp ),
582 581
 			    fcp_rsp_response_data_len ( rsp ) );
583 582
 	}
584 583
 	if ( fcp_rsp_sense_data ( rsp ) ) {
585
-		DBGC2 ( fcpdev, "FCP %p ref %02x sense data:\n",
586
-			fcpdev, fcpcmd->ref );
584
+		DBGC2 ( fcpdev, "FCP %p xchg %04x sense data:\n",
585
+			fcpdev, fcpcmd->xchg_id );
587 586
 		DBGC2_HDA ( fcpdev, 0, fcp_rsp_sense_data ( rsp ),
588 587
 			    fcp_rsp_sense_data_len ( rsp ) );
589 588
 	}
@@ -592,8 +591,8 @@ static int fcpcmd_recv_rsp ( struct fcp_command *fcpcmd,
592 591
 	if ( ( rsp->status == 0 ) &&
593 592
 	     ( fcpcmd->offset != ( command->data_in_len +
594 593
 				   command->data_out_len ) ) ) {
595
-		DBGC ( fcpdev, "FCP %p ref %02x data underrun (expected %zd, "
596
-		       "got %zd)\n", fcpdev, fcpcmd->ref,
594
+		DBGC ( fcpdev, "FCP %p xchg %04x data underrun (expected %zd, "
595
+		       "got %zd)\n", fcpdev, fcpcmd->xchg_id,
597 596
 		       ( command->data_in_len + command->data_out_len ),
598 597
 		       fcpcmd->offset );
599 598
 		rc = -ERANGE_DATA_UNDERRUN;
@@ -642,8 +641,8 @@ static int fcpcmd_recv_unknown ( struct fcp_command *fcpcmd,
642 641
 				 struct xfer_metadata *meta __unused ) {
643 642
 	struct fcp_device *fcpdev = fcpcmd->fcpdev;
644 643
 
645
-	DBGC ( fcpdev, "FCP %p ref %02x received unknown IU:\n",
646
-	       fcpdev, fcpcmd->ref );
644
+	DBGC ( fcpdev, "FCP %p xchg %04x received unknown IU:\n",
645
+	       fcpdev, fcpcmd->xchg_id );
647 646
 	DBGC_HDA ( fcpdev, 0, iobuf->data, iob_len ( iobuf ) );
648 647
 	free_iob ( iobuf );
649 648
 	return -EINVAL;
@@ -738,8 +737,8 @@ static int fcpdev_scsi_command ( struct fcp_device *fcpdev,
738 737
 				 struct interface *parent,
739 738
 				 struct scsi_cmd *command ) {
740 739
 	struct fcp_prli_service_parameters *param = fcpdev->ulp->param;
741
-	static uint8_t ref = 0;
742 740
 	struct fcp_command *fcpcmd;
741
+	int xchg_id;
743 742
 	int rc;
744 743
 
745 744
 	/* Check link */
@@ -772,16 +771,18 @@ static int fcpdev_scsi_command ( struct fcp_device *fcpdev,
772 771
 	fcpcmd->fcpdev = fcpdev_get ( fcpdev );
773 772
 	list_add ( &fcpcmd->list, &fcpdev->fcpcmds );
774 773
 	memcpy ( &fcpcmd->command, command, sizeof ( fcpcmd->command ) );
775
-	fcpcmd->ref = ref++; /* Not used for demultiplexing, only for debug */
776 774
 
777 775
 	/* Create new exchange */
778
-	if ( ( rc = fc_xchg_originate ( &fcpcmd->xchg, fcpdev->ulp->peer->port,
779
-					&fcpdev->ulp->peer->port_id,
780
-					FC_TYPE_FCP ) ) != 0 ) {
781
-		DBGC ( fcpdev, "FCP %p ref %02x could not create exchange: "
782
-		       "%s\n", fcpdev, fcpcmd->ref, strerror ( rc ) );
776
+	if ( ( xchg_id = fc_xchg_originate ( &fcpcmd->xchg,
777
+					     fcpdev->ulp->peer->port,
778
+					     &fcpdev->ulp->peer->port_id,
779
+					     FC_TYPE_FCP ) ) < 0 ) {
780
+		rc = xchg_id;
781
+		DBGC ( fcpdev, "FCP %p xchg %04x could not create exchange: "
782
+		       "%s\n", fcpdev, fcpcmd->xchg_id, strerror ( rc ) );
783 783
 		goto err_xchg_originate;
784 784
 	}
785
+	fcpcmd->xchg_id = xchg_id;
785 786
 
786 787
 	/* Start sending command IU */
787 788
 	fcpcmd_start_send ( fcpcmd, fcpcmd_send_cmnd );
@@ -789,7 +790,7 @@ static int fcpdev_scsi_command ( struct fcp_device *fcpdev,
789 790
 	/* Attach to parent interface, mortalise self, and return */
790 791
 	intf_plug_plug ( &fcpcmd->scsi, parent );
791 792
 	ref_put ( &fcpcmd->refcnt );
792
-	return ( FCP_TAG_MAGIC | fcpcmd->ref );
793
+	return ( FCP_TAG_MAGIC | fcpcmd->xchg_id );
793 794
 
794 795
  err_xchg_originate:
795 796
 	fcpcmd_close ( fcpcmd, rc );

Loading…
Cancel
Save