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

Reply via email to