aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe/fcoe.c
diff options
context:
space:
mode:
authorVasu Dev <vasu.dev@intel.com>2009-07-29 20:05:21 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-08-22 18:52:09 -0400
commitd7179680d04f1e196b7a5f70e7f93bb1850407c6 (patch)
treee31aaf450afcd7cba0d719178424ece5013964f8 /drivers/scsi/fcoe/fcoe.c
parente8af4d4380babc89d193c16163f070a6418f033b (diff)
[SCSI] fcoe, libfc: adds offload EM per eth device with only single xid range per EM
Updates fcoe_em_config to allocate a single instance of sharable offload EM for supported lp->lro_xid per eth device, and then share this EM for subsequently more lports creation on same eth device (e.g when using VLAN). Adds tiny fcoe_oem_match function for offload EM to return true for read types IO to have read IO exchanges allocated from offload shared EM. Removes fc_em_alloc_xid function completely which was needed to manage two xid ranges within a EM, this is not needed any more with allocation of separate sharable offload EM per eth device. Instead this patch adds simple xid allocation logic to manage single xid range. Adds fc_exch_em_alloc with mp->next_xid as cursor to allocate new xid from single xid range of EM, uses mp->next_xid instead removed mp->last_xid which slightly increase probability of finding empty xid on exch allocation. Removes restriction of not allowing use of xid zero along with changing two xid range change to single xid range. Makes fc_fcp_ddp_setup calling conditional to only xid allocated from shared offload EM. Signed-off-by: Vasu Dev <vasu.dev@intel.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/fcoe/fcoe.c')
-rw-r--r--drivers/scsi/fcoe/fcoe.c67
1 files changed, 65 insertions, 2 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 86410b9a30c3..0306aa95eb34 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -415,6 +415,17 @@ static int fcoe_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
415 return 0; 415 return 0;
416} 416}
417 417
418/*
419 * fcoe_oem_match() - match for read types IO
420 * @fp: the fc_frame for new IO.
421 *
422 * Returns : true for read types IO, otherwise returns false.
423 */
424bool fcoe_oem_match(struct fc_frame *fp)
425{
426 return fc_fcp_is_read(fr_fsp(fp));
427}
428
418/** 429/**
419 * fcoe_em_config() - allocates em for this lport 430 * fcoe_em_config() - allocates em for this lport
420 * @lp: the port that em is to allocated for 431 * @lp: the port that em is to allocated for
@@ -425,9 +436,61 @@ static int fcoe_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
425 */ 436 */
426static inline int fcoe_em_config(struct fc_lport *lp) 437static inline int fcoe_em_config(struct fc_lport *lp)
427{ 438{
428 if (!fc_exch_mgr_alloc(lp, FC_CLASS_3, FCOE_MIN_XID, 439 struct fcoe_softc *fc = lport_priv(lp);
429 FCOE_MAX_XID, NULL)) 440 struct fcoe_softc *oldfc = NULL;
441 u16 min_xid = FCOE_MIN_XID;
442 u16 max_xid = FCOE_MAX_XID;
443
444 /*
445 * Check if need to allocate an em instance for
446 * offload exchange ids to be shared across all VN_PORTs/lport.
447 */
448 if (!lp->lro_enabled || !lp->lro_xid || (lp->lro_xid >= max_xid)) {
449 lp->lro_xid = 0;
450 goto skip_oem;
451 }
452
453 /*
454 * Reuse existing offload em instance in case
455 * it is already allocated on phys_dev.
456 */
457 list_for_each_entry(oldfc, &fcoe_hostlist, list) {
458 if (oldfc->phys_dev == fc->phys_dev) {
459 fc->oem = oldfc->oem;
460 break;
461 }
462 }
463
464 if (fc->oem) {
465 if (!fc_exch_mgr_add(lp, fc->oem, fcoe_oem_match)) {
466 printk(KERN_ERR "fcoe_em_config: failed to add "
467 "offload em:%p on interface:%s\n",
468 fc->oem, fc->real_dev->name);
469 return -ENOMEM;
470 }
471 } else {
472 fc->oem = fc_exch_mgr_alloc(lp, FC_CLASS_3,
473 FCOE_MIN_XID, lp->lro_xid,
474 fcoe_oem_match);
475 if (!fc->oem) {
476 printk(KERN_ERR "fcoe_em_config: failed to allocate "
477 "em for offload exches on interface:%s\n",
478 fc->real_dev->name);
479 return -ENOMEM;
480 }
481 }
482
483 /*
484 * Exclude offload EM xid range from next EM xid range.
485 */
486 min_xid += lp->lro_xid + 1;
487
488skip_oem:
489 if (!fc_exch_mgr_alloc(lp, FC_CLASS_3, min_xid, max_xid, NULL)) {
490 printk(KERN_ERR "fcoe_em_config: failed to "
491 "allocate em on interface %s\n", fc->real_dev->name);
430 return -ENOMEM; 492 return -ENOMEM;
493 }
431 494
432 return 0; 495 return 0;
433} 496}