|
@@ -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 );
|