[MLX4] limit the process of reading VPD with timeout, but continue to work on error...
authorleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 26 Oct 2009 10:14:38 +0000 (10:14 +0000)
committerleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 26 Oct 2009 10:14:38 +0000 (10:14 +0000)
This patch solves the freeze of the driver in case when FW doesn't provide VPD.
(in fact - it's a workaround of a FW bug).
VPD is not used today in IB drivers.

git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@2513 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

hw/mlx4/kernel/bus/drv/drv.c
hw/mlx4/kernel/bus/drv/pci.c

index 72c2db2..4e9e6c9 100644 (file)
@@ -789,14 +789,13 @@ EvtPrepareHardware(
                goto err;\r
        mdev = pdev->dev;\r
 \r
-       // get VPD \r
+       // get VPD - as far as it just info, we proceed the work in case of error\r
        status = pci_get_vpd( &pdev->bus_pci_ifc, \r
                &pdev->pci_cfg_space, &pdev->vpd, &pdev->vpd_size );\r
        if( !NT_SUCCESS( status ) )\r
        {\r
-               MLX4_PRINT_EV(TRACE_LEVEL_ERROR, MLX4_DBG_DRV, \r
-                       ("pci_get_vpd failed,  status=0x%x\n", status));\r
-               goto err;\r
+               MLX4_PRINT_EV(TRACE_LEVEL_WARNING, MLX4_DBG_DRV, \r
+                       ("Failed to read VPD from the card (status=0x%x). Continue the work.\n", status));\r
        }\r
 \r
        // get card location\r
index 4fd5c8f..a036e38 100644 (file)
@@ -435,7 +435,8 @@ static NTSTATUS __read_vpd_dword(
                OUT                     UCHAR                                           *p_data\r
        )\r
 {\r
-       ULONG len;\r
+       #define MAX_TRIES       500     \r
+       ULONG len, tries=0;\r
        USHORT addr = (USHORT)offset;\r
 \r
        /* write offset inside VPD data */\r
@@ -443,13 +444,17 @@ static NTSTATUS __read_vpd_dword(
        if ( len != 2 ) \r
                goto err_write;\r
 \r
-       /* wait for data to be put in the data register */\r
-       while ( !(addr & 0x8000) ) {\r
+       /* wait for data to be put in the data register for (MAX_TRIES*2) usecs */\r
+       while ( !(addr & 0x8000) && tries++ < MAX_TRIES ) {\r
                len = pBusIfc->GetBusData( pBusIfc->Context, PCI_WHICHSPACE_CONFIG, &addr, cap_offset+2, 2 );\r
                if ( len != 2 )\r
                        goto err_read;\r
+               cond_resched();\r
        } \r
 \r
+       if ( tries >= MAX_TRIES )\r
+               goto err_to;\r
+               \r
        /* get the tag value */\r
        len = pBusIfc->GetBusData( pBusIfc->Context, PCI_WHICHSPACE_CONFIG, p_data, cap_offset+4, 4 );\r
        if ( len != 4 )\r
@@ -466,6 +471,12 @@ err_read:
        MLX4_PRINT( TRACE_LEVEL_ERROR  , MLX4_DBG_PNP  , \r
                ("Failed to read HCA config. \n" )); \r
        return STATUS_DEVICE_NOT_READY;\r
+\r
+err_to:        \r
+       MLX4_PRINT( TRACE_LEVEL_ERROR  , MLX4_DBG_PNP  , \r
+               ("FW hasn't provided VPD data in %d usecs \n", \r
+               (g_cmd_interval.u.LowPart / (-10)) * MAX_TRIES )); \r
+       return STATUS_DEVICE_NOT_READY;\r
 }\r
 \r
 \r