fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / infiniband / hw / ipath / ipath_eeprom.c
index a2f1cea..a4019a6 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2006 QLogic, Inc. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -99,9 +100,9 @@ static int i2c_gpio_set(struct ipath_devdata *dd,
        gpioval = &dd->ipath_gpio_out;
        read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extctrl);
        if (line == i2c_line_scl)
-               mask = ipath_gpio_scl;
+               mask = dd->ipath_gpio_scl;
        else
-               mask = ipath_gpio_sda;
+               mask = dd->ipath_gpio_sda;
 
        if (new_line_state == i2c_line_high)
                /* tri-state the output rather than force high */
@@ -118,12 +119,12 @@ static int i2c_gpio_set(struct ipath_devdata *dd,
                write_val = 0x0UL;
 
        if (line == i2c_line_scl) {
-               write_val <<= ipath_gpio_scl_num;
-               *gpioval = *gpioval & ~(1UL << ipath_gpio_scl_num);
+               write_val <<= dd->ipath_gpio_scl_num;
+               *gpioval = *gpioval & ~(1UL << dd->ipath_gpio_scl_num);
                *gpioval |= write_val;
        } else {
-               write_val <<= ipath_gpio_sda_num;
-               *gpioval = *gpioval & ~(1UL << ipath_gpio_sda_num);
+               write_val <<= dd->ipath_gpio_sda_num;
+               *gpioval = *gpioval & ~(1UL << dd->ipath_gpio_sda_num);
                *gpioval |= write_val;
        }
        ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_out, *gpioval);
@@ -156,9 +157,9 @@ static int i2c_gpio_get(struct ipath_devdata *dd,
        read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extctrl);
        /* config line to be an input */
        if (line == i2c_line_scl)
-               mask = ipath_gpio_scl;
+               mask = dd->ipath_gpio_scl;
        else
-               mask = ipath_gpio_sda;
+               mask = dd->ipath_gpio_sda;
        write_val = read_val & ~mask;
        ipath_write_kreg(dd, dd->ipath_kregs->kr_extctrl, write_val);
        read_val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_extstatus);
@@ -186,6 +187,7 @@ bail:
 static void i2c_wait_for_writes(struct ipath_devdata *dd)
 {
        (void)ipath_read_kreg32(dd, dd->ipath_kregs->kr_scratch);
+       rmb();
 }
 
 static void scl_out(struct ipath_devdata *dd, u8 bit)
@@ -600,8 +602,31 @@ void ipath_get_eeprom_info(struct ipath_devdata *dd)
                guid = *(__be64 *) ifp->if_guid;
        dd->ipath_guid = guid;
        dd->ipath_nguid = ifp->if_numguid;
-       memcpy(dd->ipath_serial, ifp->if_serial,
-              sizeof(ifp->if_serial));
+       /*
+        * Things are slightly complicated by the desire to transparently
+        * support both the Pathscale 10-digit serial number and the QLogic
+        * 13-character version.
+        */
+       if ((ifp->if_fversion > 1) && ifp->if_sprefix[0]
+               && ((u8 *)ifp->if_sprefix)[0] != 0xFF) {
+               /* This board has a Serial-prefix, which is stored
+                * elsewhere for backward-compatibility.
+                */
+               char *snp = dd->ipath_serial;
+               int len;
+               memcpy(snp, ifp->if_sprefix, sizeof ifp->if_sprefix);
+               snp[sizeof ifp->if_sprefix] = '\0';
+               len = strlen(snp);
+               snp += len;
+               len = (sizeof dd->ipath_serial) - len;
+               if (len > sizeof ifp->if_serial) {
+                       len = sizeof ifp->if_serial;
+               }
+               memcpy(snp, ifp->if_serial, len);
+       } else
+               memcpy(dd->ipath_serial, ifp->if_serial,
+                      sizeof ifp->if_serial);
+
        ipath_cdbg(VERBOSE, "Initted GUID to %llx from eeprom\n",
                   (unsigned long long) be64_to_cpu(dd->ipath_guid));