On 10/28/10 11:48 AM, Kiran Patil wrote:
> From: Kiran Patil <[email protected]>
>
> Problem: In case of exchange responder case, EMA selection was defaulted to
> the last EMA
> from EMA list (lport.ema_list). If exchange ID is selected from
> offload pool
> and not setup DDP, resulting into incorrect selection of EMA, and
> eventually
> dropping the packet because unable to find exchange.
>
> Fix: Enhanced the exchange ID selection (depending upon request type and
> exchange responder)
> Made necessary enhancement in EMA selection algorithm.
>
> Technical Notes: N/A
>
> Signed-off-by: Kiran Patil <[email protected]>
> ---
>
> drivers/scsi/libfc/fc_exch.c | 68
> ++++++++++++++++++++++++++++++------------
> 1 files changed, 48 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
> index 0deb901..c02abc2 100644
> --- a/drivers/scsi/libfc/fc_exch.c
> +++ b/drivers/scsi/libfc/fc_exch.c
> @@ -2249,16 +2249,49 @@ void fc_exch_mgr_free(struct fc_lport *lport)
> EXPORT_SYMBOL(fc_exch_mgr_free);
>
> /**
> + * fc_find_ema() - Lookup and return appropriate Exchange Manager Anchor
> depending
> + * upon 'xid'.
> + * @f_ctl: f_ctl
> + * @lport: The local port the frame was received on
> + * @fh: The received frame header
> + */
> +static struct fc_exch_mgr_anchor *fc_find_ema(u32 f_ctl,
> + struct fc_lport *lport,
> + struct fc_frame_header *fh)
> +{
> + u32 found = 0;
> + struct fc_exch_mgr_anchor *ema;
> + u16 xid;
> +
> + if (f_ctl & FC_FC_EX_CTX)
> + xid = ntohs(fh->fh_ox_id);
> + else {
> + xid = ntohs(fh->fh_rx_id);
> + if (xid == FC_XID_UNKNOWN)
> + return ema = list_entry(lport->ema_list.prev,
> + typeof(*ema), ema_list);
No need to assign the local variable ema in the return expression.
> + }
> +
> + list_for_each_entry(ema, &lport->ema_list, ema_list) {
> + if ((xid >= ema->mp->min_xid) &&
> + (xid <= ema->mp->max_xid)) {
> + found = 1;
Just return ema. that saves the break and the curly brackets.
> + break;
> + }
> + }
> + return (1 == found) ? ema : 0;
Just return NULL if you get here. The found variable is unneeded.
> +}
> +/**
> * fc_exch_recv() - Handler for received frames
> * @lport: The local port the frame was received on
> - * @fp: The received frame
> + * @fp: The received frame
> */
> void fc_exch_recv(struct fc_lport *lport, struct fc_frame *fp)
> {
> struct fc_frame_header *fh = fc_frame_header_get(fp);
> struct fc_exch_mgr_anchor *ema;
> - u32 f_ctl, found = 0;
> - u16 oxid;
> + u32 f_ctl;
> + u16 xid;
>
> /* lport lock ? */
> if (!lport || lport->state == LPORT_ST_DISABLED) {
> @@ -2269,24 +2302,19 @@ void fc_exch_recv(struct fc_lport *lport, struct
> fc_frame *fp)
> }
>
> f_ctl = ntoh24(fh->fh_f_ctl);
> - oxid = ntohs(fh->fh_ox_id);
> - if (f_ctl & FC_FC_EX_CTX) {
> - list_for_each_entry(ema, &lport->ema_list, ema_list) {
> - if ((oxid >= ema->mp->min_xid) &&
> - (oxid <= ema->mp->max_xid)) {
> - found = 1;
> - break;
> - }
> - }
> + if (f_ctl & FC_FC_EX_CTX)
> + xid = ntohs(fh->fh_ox_id);
> + else
> + xid = ntohs(fh->fh_rx_id);
So, here we have the xid we need in fc_find_ema(). Too bad it needs
to figure it out again. What do we need xid for, just error messages?
Figure it out if printing the error message.
>
> - if (!found) {
> - FC_LPORT_DBG(lport, "Received response for out "
> - "of range oxid:%hx\n", oxid);
> - fc_frame_free(fp);
> - return;
> - }
> - } else
> - ema = list_entry(lport->ema_list.prev, typeof(*ema), ema_list);
> + ema = fc_find_ema(f_ctl, lport, fh);
> + if (!ema) {
> + FC_LPORT_DBG(lport, "Unable to find Exchange Manager Anchor,"
> + "fc_ctl <0x%x>, xid <0x%x>\n",
> + f_ctl, xid);
> + fc_frame_free(fp);
> + return;
> + }
>
> /*
> * If frame is marked invalid, just drop it.
>
> _______________________________________________
> devel mailing list
> [email protected]
> http://www.open-fcoe.org/mailman/listinfo/devel
_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel