]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/lpfc/lpfc_nportdisc.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
[linux-2.6-omap-h63xx.git] / drivers / scsi / lpfc / lpfc_nportdisc.c
index 9a58de876d40e0853178a4753714db6a12af2a74..fbead786031f9ec948df36249d557d6e646a2d17 100644 (file)
@@ -55,55 +55,76 @@ lpfc_check_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
        return (1);
 }
 
-
 int
 lpfc_check_sparm(struct lpfc_hba * phba,
                 struct lpfc_nodelist * ndlp, struct serv_parm * sp,
                 uint32_t class)
 {
        volatile struct serv_parm *hsp = &phba->fc_sparam;
-       /* First check for supported version */
-
-       /* Next check for class validity */
+       uint16_t hsp_value, ssp_value = 0;
+
+       /*
+        * The receive data field size and buffer-to-buffer receive data field
+        * size entries are 16 bits but are represented as two 8-bit fields in
+        * the driver data structure to account for rsvd bits and other control
+        * bits.  Reconstruct and compare the fields as a 16-bit values before
+        * correcting the byte values.
+        */
        if (sp->cls1.classValid) {
-
-               if (sp->cls1.rcvDataSizeMsb > hsp->cls1.rcvDataSizeMsb)
-                       sp->cls1.rcvDataSizeMsb = hsp->cls1.rcvDataSizeMsb;
-               if (sp->cls1.rcvDataSizeLsb > hsp->cls1.rcvDataSizeLsb)
+               hsp_value = (hsp->cls1.rcvDataSizeMsb << 8) |
+                               hsp->cls1.rcvDataSizeLsb;
+               ssp_value = (sp->cls1.rcvDataSizeMsb << 8) |
+                               sp->cls1.rcvDataSizeLsb;
+               if (ssp_value > hsp_value) {
                        sp->cls1.rcvDataSizeLsb = hsp->cls1.rcvDataSizeLsb;
+                       sp->cls1.rcvDataSizeMsb = hsp->cls1.rcvDataSizeMsb;
+               }
        } else if (class == CLASS1) {
-               return (0);
+               return 0;
        }
 
        if (sp->cls2.classValid) {
-
-               if (sp->cls2.rcvDataSizeMsb > hsp->cls2.rcvDataSizeMsb)
-                       sp->cls2.rcvDataSizeMsb = hsp->cls2.rcvDataSizeMsb;
-               if (sp->cls2.rcvDataSizeLsb > hsp->cls2.rcvDataSizeLsb)
+               hsp_value = (hsp->cls2.rcvDataSizeMsb << 8) |
+                               hsp->cls2.rcvDataSizeLsb;
+               ssp_value = (sp->cls2.rcvDataSizeMsb << 8) |
+                               sp->cls2.rcvDataSizeLsb;
+               if (ssp_value > hsp_value) {
                        sp->cls2.rcvDataSizeLsb = hsp->cls2.rcvDataSizeLsb;
+                       sp->cls2.rcvDataSizeMsb = hsp->cls2.rcvDataSizeMsb;
+               }
        } else if (class == CLASS2) {
-               return (0);
+               return 0;
        }
 
        if (sp->cls3.classValid) {
-
-               if (sp->cls3.rcvDataSizeMsb > hsp->cls3.rcvDataSizeMsb)
-                       sp->cls3.rcvDataSizeMsb = hsp->cls3.rcvDataSizeMsb;
-               if (sp->cls3.rcvDataSizeLsb > hsp->cls3.rcvDataSizeLsb)
+               hsp_value = (hsp->cls3.rcvDataSizeMsb << 8) |
+                               hsp->cls3.rcvDataSizeLsb;
+               ssp_value = (sp->cls3.rcvDataSizeMsb << 8) |
+                               sp->cls3.rcvDataSizeLsb;
+               if (ssp_value > hsp_value) {
                        sp->cls3.rcvDataSizeLsb = hsp->cls3.rcvDataSizeLsb;
+                       sp->cls3.rcvDataSizeMsb = hsp->cls3.rcvDataSizeMsb;
+               }
        } else if (class == CLASS3) {
-               return (0);
+               return 0;
        }
 
-       if (sp->cmn.bbRcvSizeMsb > hsp->cmn.bbRcvSizeMsb)
-               sp->cmn.bbRcvSizeMsb = hsp->cmn.bbRcvSizeMsb;
-       if (sp->cmn.bbRcvSizeLsb > hsp->cmn.bbRcvSizeLsb)
+       /*
+        * Preserve the upper four bits of the MSB from the PLOGI response.
+        * These bits contain the Buffer-to-Buffer State Change Number
+        * from the target and need to be passed to the FW.
+        */
+       hsp_value = (hsp->cmn.bbRcvSizeMsb << 8) | hsp->cmn.bbRcvSizeLsb;
+       ssp_value = (sp->cmn.bbRcvSizeMsb << 8) | sp->cmn.bbRcvSizeLsb;
+       if (ssp_value > hsp_value) {
                sp->cmn.bbRcvSizeLsb = hsp->cmn.bbRcvSizeLsb;
+               sp->cmn.bbRcvSizeMsb = (sp->cmn.bbRcvSizeMsb & 0xF0) |
+                                      (hsp->cmn.bbRcvSizeMsb & 0x0F);
+       }
 
-       /* If check is good, copy wwpn wwnn into ndlp */
        memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof (struct lpfc_name));
        memcpy(&ndlp->nlp_portname, &sp->portName, sizeof (struct lpfc_name));
-       return (1);
+       return 1;
 }
 
 static void *
@@ -187,10 +208,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
                                        spin_unlock_irq(phba->host->host_lock);
                                        (iocb->iocb_cmpl) (phba, iocb, iocb);
                                        spin_lock_irq(phba->host->host_lock);
-                               } else {
-                                       list_add_tail(&iocb->list,
-                                                       &phba->lpfc_iocb_list);
-                               }
+                               } else
+                                       lpfc_sli_release_iocbq(phba, iocb);
                                break;
                        }
                }
@@ -232,10 +251,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp,
                                        spin_unlock_irq(phba->host->host_lock);
                                        (iocb->iocb_cmpl) (phba, iocb, iocb);
                                        spin_lock_irq(phba->host->host_lock);
-                               } else {
-                                       list_add_tail(&iocb->list,
-                                                       &phba->lpfc_iocb_list);
-                               }
+                               } else
+                                       lpfc_sli_release_iocbq(phba, iocb);
                                break;
                        }
                }