]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
[MLX4] added HCA Soft Reset mechanism (used by Ethernet interface so far)
authorleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 4 Aug 2008 16:18:23 +0000 (16:18 +0000)
committerleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 4 Aug 2008 16:18:23 +0000 (16:18 +0000)
Soft Reset here is HCA re-initialization without bus driver reloading.
A reset can be initiated by clients (mlx4_eth, mlx4_hca) and/or driver (mlx4_bus).
Driver issues reset upon card fatal error, which prevents the following work with the card.
Clients may request the reset at any moment upon their will.

Clients have to register event callback after getting bus interface.

When a reset event comes, the bus driver will:
   - bar the following work with card, returning –EFAULT to all, but destroy_xx, commands;
   - reset the card to stop incoming traffic (only in case of client-initiated reset);
   - notify all registered clients about pending reset.

Getting this notification clients have to:
   - wait for all issued commands to end;
   - reset its own clients, if any, and bar their work;
   - release all the device resources, they were using till now;
   - send “I’m reset-ready” notification to the bus driver;

The driver starts to perform device reset only after receiving the “I’m reset-ready” notifications from all the registered clients. It re-initializes the device and notifies all the clients.

Having received this notification, clients have to:
   - dereference the old bus interface;
   - get the new interface from bus driver;
   - register new event handler;
   - resume/restart itself;
   - wake up its own clients, if any;

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

32 files changed:
trunk/hw/mlx4/kernel/bus/core/SOURCES
trunk/hw/mlx4/kernel/bus/core/cache.c
trunk/hw/mlx4/kernel/bus/drv/drv.c
trunk/hw/mlx4/kernel/bus/drv/drv.h
trunk/hw/mlx4/kernel/bus/drv/mlx4_bus.inx
trunk/hw/mlx4/kernel/bus/drv/pdo.c
trunk/hw/mlx4/kernel/bus/ib/ah.c
trunk/hw/mlx4/kernel/bus/ib/cq.c
trunk/hw/mlx4/kernel/bus/ib/mad.c
trunk/hw/mlx4/kernel/bus/ib/main.c
trunk/hw/mlx4/kernel/bus/ib/mr.c
trunk/hw/mlx4/kernel/bus/ib/qp.c
trunk/hw/mlx4/kernel/bus/ib/srq.c
trunk/hw/mlx4/kernel/bus/inc/bus_intf.h
trunk/hw/mlx4/kernel/bus/inc/device.h
trunk/hw/mlx4/kernel/bus/inc/ib_verbs.h
trunk/hw/mlx4/kernel/bus/net/alloc.c
trunk/hw/mlx4/kernel/bus/net/catas.c
trunk/hw/mlx4/kernel/bus/net/cmd.c
trunk/hw/mlx4/kernel/bus/net/cq.c
trunk/hw/mlx4/kernel/bus/net/eq.c
trunk/hw/mlx4/kernel/bus/net/fw.c
trunk/hw/mlx4/kernel/bus/net/main.c
trunk/hw/mlx4/kernel/bus/net/mlx4.h
trunk/hw/mlx4/kernel/bus/net/mr.c
trunk/hw/mlx4/kernel/bus/net/pd.c
trunk/hw/mlx4/kernel/bus/net/port.c
trunk/hw/mlx4/kernel/bus/net/qp.c
trunk/hw/mlx4/kernel/bus/net/srq.c
trunk/hw/mlx4/kernel/hca/data.c
trunk/hw/mlx4/kernel/inc/l2w.h
trunk/hw/mlx4/kernel/inc/vip_dev.h

index d138a00a2820b0908512febfb8fb0c95c8a7b83c..2f921072e3e59026dd168960cb502ab72c4e960f 100644 (file)
@@ -35,8 +35,7 @@ C_DEFINES=$(C_DEFINES) -DDRIVER -DDEPRECATE_DDK_FUNCTIONS -D__LITTLE_ENDIAN -DUS
 \r
 TARGETLIBS= \\r
     $(DDK_LIB_PATH)\ntstrsafe.lib \\r
-       $(TARGETPATH)\*\complib.lib\r
-       \r
+       $(TARGETPATH)\*\complib.lib \r
 \r
 !IFDEF ENABLE_EVENT_TRACING\r
 \r
index a313236fe6be7aa01a93631325d15c05bae1da49..5b81935896f6d8900d9586c64dcafd72450be79a 100644 (file)
@@ -83,6 +83,9 @@ int ib_get_cached_gid(struct ib_device *device,
        unsigned long flags;
        int ret = 0;
 
+       if (mlx4_is_barred(device->dma_device))
+               return -EFAULT;
+
        if (port_num < start_port(device) || port_num > end_port(device))
                return -EINVAL;
 
@@ -111,6 +114,9 @@ int ib_find_cached_gid(struct ib_device *device,
        int p, i;
        int ret = -ENOENT;
 
+       if (mlx4_is_barred(device->dma_device))
+               return -EFAULT;
+
        *port_num = (u8)-1;
        if (index)
                *index = (u16)-1;
@@ -145,6 +151,9 @@ int ib_get_cached_pkey(struct ib_device *device,
        unsigned long flags;
        int ret = 0;
 
+       if (mlx4_is_barred(device->dma_device))
+               return -EFAULT;
+
        if (port_num < start_port(device) || port_num > end_port(device))
                return -EINVAL;
 
@@ -173,6 +182,9 @@ int ib_find_cached_pkey(struct ib_device *device,
        int i;
        int ret = -ENOENT;
 
+       if (mlx4_is_barred(device->dma_device))
+               return -EFAULT;
+
        if (port_num < start_port(device) || port_num > end_port(device))
                return -EINVAL;
 
@@ -382,7 +394,7 @@ static void ib_cache_setup_one(struct ib_device *device)
        }
 
        INIT_IB_EVENT_HANDLER(&device->cache.event_handler,
-                             device, ib_cache_event, NULL);
+                             device, ib_cache_event, NULL, NULL, 0);
        if (ib_register_event_handler(&device->cache.event_handler))
                goto err_cache;
 
index f531a8b2f6f6439e332238a2cfa3a0e9071123c0..35bc591ba4afa3e3d2328ac88b70755f6da4da31 100644 (file)
@@ -646,6 +646,16 @@ err:
        return status;\r
 }\r
 \r
+void fix_bus_ifc(struct pci_dev *pdev)\r
+{\r
+       PFDO_DEVICE_DATA p_fdo;\r
+\r
+       p_fdo =  CONTAINING_RECORD(pdev, FDO_DEVICE_DATA, pci_dev);\r
+       p_fdo->bus_ib_ifc.p_ibdev = p_fdo->pci_dev.ib_dev;\r
+       p_fdo->bus_ib_ifc.pmlx4_dev = to_mdev(p_fdo->pci_dev.ib_dev)->dev;\r
+       p_fdo->bus_ib_ifc.is_livefish = mlx4_is_livefish(p_fdo->pci_dev.dev);\r
+}\r
+\r
 NTSTATUS\r
 EvtReleaseHardware(\r
        IN WDFDEVICE  Device,\r
@@ -941,7 +951,7 @@ __read_registry(WDFDRIVER *hDriver)
        // "Ports L2 type (ib/eth/auto, entry per port, comma seperated, default ib for all)"\r
        DECLARE_CONST_UNICODE_STRING(PortType, L"PortType");\r
 \r
-       \r
+\r
        ULONG value;\r
        WDFKEY hKey = NULL;\r
        NTSTATUS status = STATUS_SUCCESS;\r
@@ -1031,6 +1041,7 @@ __read_registry(WDFDRIVER *hDriver)
                else\r
                        g.mod_interrupt_from_first = 1;\r
 \r
+\r
                uvalue.Buffer = uvalue_data;\r
                uvalue.MaximumLength = MAX_UVALUE;\r
                uvalue.Length = 0;\r
index 636f7e157f537c7b1330cec428d9147cbdab29f5..2873a243f559014eea3db1104a7f3ffefe3ddfa3 100644 (file)
@@ -70,18 +70,10 @@ typedef struct _FDO_DEVICE_DATA
        MLX4_BUS_IB_INTERFACE           bus_ib_ifc;\r
        int                                                     children_created;\r
        // Data for the Ethernet device\r
-#ifdef _WIN64   \r
-    UCHAR   pad[0x8];\r
-#endif\r
-\r
        struct VipBusIfc                        mtnic_Ifc;\r
 \r
 } FDO_DEVICE_DATA, *PFDO_DEVICE_DATA;\r
 \r
-#ifdef _WIN64   \r
-C_ASSERT((FIELD_OFFSET(FDO_DEVICE_DATA, mtnic_Ifc) % 16) == 0);\r
-#endif\r
-\r
 WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(FDO_DEVICE_DATA, FdoGetData)\r
 \r
 //\r
index fa4fbcac3fcc30a2b47ffbbbecf6a5fca7aeef7b..be5495d5f00ea8438ad18333bd5788120079a1f2 100644 (file)
@@ -95,40 +95,6 @@ wdfcoinstaller01007.dll = 1,,
 %MT26428.DeviceDesc%=MLX4BUS.DDInstall, PCI\VEN_15B3&DEV_673c\r
 %MT00401.DeviceDesc%=MLX4BUS.DDInstall, PCI\VEN_15B3&DEV_0191\r
 \r
-[MLX4BUS.DDInstall.ntx86.hw]\r
-AddReg = MLX4BUS.HwReg\r
-\r
-[MLX4BUS.DDInstall.ntamd64.hw]\r
-AddReg = MLX4BUS.HwReg\r
-\r
-[MLX4BUS.DDInstall.ntia64.hw]\r
-AddReg = MLX4BUS.HwReg\r
-\r
-[MLX4BUS.HwReg]\r
-HKR,"Interrupt Management", 0x00000010\r
-HKR,"Interrupt Management\MessageSignaledInterruptProperties",0x00000010\r
-\r
-; MSI/MSI-X support\r
-HKR,"Interrupt Management\MessageSignaledInterruptProperties",MSISupported,0x00010001,0\r
-HKR,"Interrupt Management\MessageSignaledInterruptProperties",MessageNumberLimit,0x00010001,8\r
-HKR,"Interrupt Management\Affinity Policy",0x00000010\r
-\r
-; AssignmentSetOverride - processors KAFFINITY mask  \r
-HKR,"Interrupt Management\Affinity Policy",AssignmentSetOverride,0x00000001,0x0\r
-\r
-; IrqPolicyMachineDefault (0) - use default policy for the computer\r
-; IrqPolicyAllCloseProcessors (1) - connect interrupts to all processors of the near NUMA node\r
-; IrqPolicyOneCloseProcessor (2) - connect interrupts to one processor\r
-; IrqPolicyAllProcessorsInMachine (3) - connect interrupts to all processors in the machine\r
-; IrqPolicySpecifiedProcessors (4) - connects interrupts according to AssignmentSetOverride\r
-HKR,"Interrupt Management\Affinity Policy",DevicePolicy,0x00010001,0x0\r
-\r
-; IrqArbPriorityUndefined (0) - no interrupt priority policy. \r
-; IrqArbPriorityLow (1) - device can tolerate low IRQL\r
-; IrqArbPriorityNormal (2) - device expects normal interrupt latencies\r
-; IrqArbPriorityHigh (3) - device requires the lowest possible interrupt latency\r
-HKR,"Interrupt Management\Affinity Policy",DevicePriority,0x00010001,0x0\r
-\r
 [MLX4BUS.DDInstall.ntx86]\r
 CopyFiles = MLX4BUS.CopyFiles\r
 \r
index 430a6956bfead545e13bed38cafa1a2680e947dc..920cd476bb5286f395db136faa996d994addaf9b 100644 (file)
 \r
 #define MAX_ID_LEN 80\r
 \r
+NTSTATUS\r
+EvtDeviceProcessQueryInterfaceRequest(\r
+       IN WDFDEVICE  Device,\r
+       IN LPGUID  InterfaceType,\r
+       IN OUT PINTERFACE  ExposedInterface,\r
+       IN OUT PVOID  ExposedInterfaceSpecificData\r
+       )\r
+{\r
+       PPDO_DEVICE_DATA p_pdo = PdoGetData(Device);\r
+       PFDO_DEVICE_DATA p_fdo  = p_pdo->p_fdo;\r
+       PMLX4_BUS_IB_INTERFACE p_ib_ifc = (PMLX4_BUS_IB_INTERFACE)ExposedInterface;\r
+\r
+       UNUSED_PARAM(InterfaceType);\r
+       UNUSED_PARAM(ExposedInterfaceSpecificData);\r
+\r
+       p_ib_ifc->p_ibdev = p_fdo->bus_ib_ifc.p_ibdev;\r
+       p_ib_ifc->pmlx4_dev = p_fdo->bus_ib_ifc.pmlx4_dev;\r
+       p_ib_ifc->is_livefish = p_fdo->bus_ib_ifc.is_livefish;\r
+\r
+       return STATUS_SUCCESS;\r
+}\r
+\r
 NTSTATUS\r
 create_pdo(\r
        __in WDFDEVICE  Device,\r
@@ -186,9 +208,6 @@ Return Value:
 \r
        p_fdo->bus_ib_ifc.port_id = (u8) SerialNo;\r
        p_fdo->bus_ib_ifc.pVipBusIfc = &p_fdo->mtnic_Ifc;\r
-       p_fdo->bus_ib_ifc.pVipBusIfc->ulAllocatePortObjSize = MAX_PORT_SIZE;\r
-       p_fdo->bus_ib_ifc.register_interface = mlx4_register_interface;\r
-       p_fdo->bus_ib_ifc.unregister_interface = mlx4_unregister_interface;\r
        p_fdo->bus_ib_ifc.mlx4_interface.mlx4_pd_alloc = mlx4_pd_alloc;\r
        p_fdo->bus_ib_ifc.mlx4_interface.mlx4_pd_free = mlx4_pd_free;\r
        p_fdo->bus_ib_ifc.mlx4_interface.mlx4_uar_alloc = mlx4_uar_alloc;\r
@@ -228,8 +247,10 @@ Return Value:
        p_fdo->bus_ib_ifc.mlx4_interface.mlx4_CLOSE_PORT = mlx4_CLOSE_PORT;\r
        p_fdo->bus_ib_ifc.mlx4_interface.mlx4_add_eq = mlx4_add_eq;\r
        p_fdo->bus_ib_ifc.mlx4_interface.mlx4_remove_eq = mlx4_remove_eq;\r
-       p_fdo->bus_ib_ifc.mlx4_interface.mlx4_register_ev_cb = ib_register_event_handler;\r
-       p_fdo->bus_ib_ifc.mlx4_interface.mlx4_unregister_ev_cb = ib_unregister_event_handler;\r
+       p_fdo->bus_ib_ifc.mlx4_interface.mlx4_register_ev_cb = mlx4_reset_cb_register;\r
+       p_fdo->bus_ib_ifc.mlx4_interface.mlx4_unregister_ev_cb = mlx4_reset_cb_unregister;\r
+       p_fdo->bus_ib_ifc.mlx4_interface.mlx4_reset_request = mlx4_reset_request;\r
+       p_fdo->bus_ib_ifc.mlx4_interface.mlx4_reset_execute = mlx4_reset_execute;\r
        \r
        //\r
        // Create a custom interface so that other drivers can\r
@@ -239,7 +260,7 @@ Return Value:
 \r
        WDF_QUERY_INTERFACE_CONFIG_INIT( &p_pdo->qiMlx4Bus,\r
                (PINTERFACE) &p_fdo->bus_ib_ifc,\r
-               &MLX4_BUS_IB_INTERFACE_GUID, NULL);\r
+               &MLX4_BUS_IB_INTERFACE_GUID, EvtDeviceProcessQueryInterfaceRequest);\r
 \r
        status = WdfDeviceAddQueryInterface( hChild, &p_pdo->qiMlx4Bus );\r
        if (!NT_SUCCESS(status))\r
@@ -252,6 +273,8 @@ Return Value:
                (PINTERFACE) &p_fdo->pci_dev.bus_pci_ifc,\r
                &GUID_BUS_INTERFACE_STANDARD, NULL);\r
 \r
+       // TODO: Soft Reset - how tobar getting interface during RESET_IN_PROGRESS\r
+       // maybe - using EvtDeviceProcessQueryInterfaceRequest\r
        status = WdfDeviceAddQueryInterface( hChild, &p_pdo->qiPciBus );\r
        if (!NT_SUCCESS(status))\r
                goto Cleanup;\r
index d281e629b5b3f29fe7e67a562ae2c2a1b3c4cf44..85a0da1366a2b979032df74a33c177d54f5ae503 100644 (file)
@@ -37,6 +37,9 @@ struct ib_ah *mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
        struct mlx4_dev *dev = to_mdev(pd->device)->dev;
        struct mlx4_ib_ah *ah;
 
+       if (mlx4_is_barred(pd->device->dma_device))
+               return ERR_PTR(-EFAULT);
+
        ah = kmalloc(sizeof *ah, GFP_ATOMIC);
        if (!ah)
                return ERR_PTR(-ENOMEM);
@@ -70,6 +73,9 @@ int mlx4_ib_query_ah(struct ib_ah *ibah, struct ib_ah_attr *ah_attr)
 {
        struct mlx4_ib_ah *ah = to_mah(ibah);
 
+       if (mlx4_is_barred(ibah->device->dma_device))
+               return -EFAULT;
+
        memset(ah_attr, 0, sizeof *ah_attr);
        ah_attr->dlid          = be16_to_cpu(ah->av.dlid);
        ah_attr->sl            = (u8)(be32_to_cpu(ah->av.sl_tclass_flowlabel) >> 28);
@@ -105,6 +111,9 @@ int mlx4_ib_modify_ah( struct ib_ah *ibah, struct ib_ah_attr *ah_attr )
        struct mlx4_av *av       = &to_mah(ibah)->av;
        struct mlx4_dev *dev = to_mdev(ibah->pd->device)->dev;
 
+       if (mlx4_is_barred(dev))
+               return -EFAULT;
+
        // taken from mthca_create_av
        av->port_pd = cpu_to_be32(to_mpd(ibah->pd)->pdn | (ah_attr->port_num << 24));
        av->g_slid      = ah_attr->src_path_bits;
index 939702f7a9260c51ec548062438b2918d8f3d024..5be4388f7d28832494cd3c2ce942ba0915d08cfa 100644 (file)
@@ -95,6 +95,9 @@ int mlx4_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period)
        struct mlx4_cq_context *context;\r
        int err;\r
 \r
+       if (mlx4_is_barred(dev->dev))\r
+               return -EFAULT;\r
+\r
        context = kzalloc(sizeof *context, GFP_KERNEL);\r
        if (!context)\r
                return -ENOMEM;\r
@@ -119,6 +122,9 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, int entries, int vector
 \r
        UNUSED_PARAM(vector);\r
 \r
+       if (mlx4_is_barred(ibdev->dma_device))\r
+               return ERR_PTR(-EFAULT);\r
+\r
        if (entries < 1 || entries > dev->dev->caps.max_cqes)\r
                return ERR_PTR(-EINVAL);\r
 \r
@@ -548,7 +554,8 @@ int mlx4_ib_poll_cq(
 \r
 int mlx4_ib_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags)\r
 {\r
-       mlx4_cq_arm(&to_mcq(ibcq)->mcq,\r
+       if (!mlx4_is_barred(ibcq->device->dma_device))\r
+               mlx4_cq_arm(&to_mcq(ibcq)->mcq,\r
                    (flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ?\r
                    MLX4_CQ_DB_REQ_NOT_SOL : MLX4_CQ_DB_REQ_NOT,\r
                    to_mdev(ibcq->device)->uar_map,\r
index 513b8da38100576221843cbca0d42f3f78014a48..01ba48cb13013649fed5d451327c502a70d4edcc 100644 (file)
@@ -202,6 +202,9 @@ int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags,     u8 port_num,
        u16 slid;
        int err;
 
+       if (mlx4_is_barred(ibdev->dma_device))
+               return -EFAULT;
+
        slid = in_wc ? be16_to_cpu(in_wc->recv.ud.remote_lid) : be16_to_cpu(XIB_LID_PERMISSIVE);
 
        if (in_mad->mad_hdr.method == IB_MGMT_METHOD_TRAP && slid == 0) {
index 3f7c9fd77c92ccb31da39a8ef4b848c6773a414a..5faa22b6636b542004a2fcf8b1216c4b94225f8b 100644 (file)
@@ -55,6 +55,9 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
        struct ib_smp *out_mad = NULL;
        int err = -ENOMEM;
 
+       if (mlx4_is_barred(ibdev->dma_device))
+               return -EFAULT;
+       
        in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
        out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
        if (!in_mad || !out_mad)
@@ -132,6 +135,9 @@ static int mlx4_ib_query_port(struct ib_device *ibdev, u8 port,
        struct ib_smp *out_mad = NULL;
        int err = -ENOMEM;
 
+       if (mlx4_is_barred(ibdev->dma_device))
+               return -EFAULT;
+       
        in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
        out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
        if (!in_mad || !out_mad)
@@ -182,6 +188,9 @@ static int mlx4_ib_query_gid_chunk(struct ib_device *ibdev, u8 port, int index,
        __be64  subnet_prefix;
        int err = -ENOMEM;
 
+       if (mlx4_is_barred(ibdev->dma_device))
+               return -EFAULT;
+       
        in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
        out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
        if (!in_mad || !out_mad)
@@ -227,6 +236,9 @@ static int mlx4_ib_query_pkey_chunk(struct ib_device *ibdev, u8 port, u16 index,
        struct ib_smp *out_mad = NULL;
        int err = -ENOMEM;
 
+       if (mlx4_is_barred(ibdev->dma_device))
+               return -EFAULT;
+
        in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
        out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
        if (!in_mad || !out_mad)
@@ -256,6 +268,9 @@ out:
 static int mlx4_ib_modify_device(struct ib_device *ibdev, int mask,
                                 struct ib_device_modify *props)
 {
+       if (mlx4_is_barred(ibdev->dma_device))
+               return -EFAULT;
+
        if (mask & ~IB_DEVICE_MODIFY_NODE_DESC)
                return -EOPNOTSUPP;
 
@@ -274,6 +289,9 @@ static int mlx4_ib_modify_port(struct ib_device *ibdev, u8 port, int mask,
        u32 cap_mask;
        int err;
 
+       if (mlx4_is_barred(ibdev->dma_device))
+               return -EFAULT;
+
        mutex_lock(&to_mdev(ibdev)->cap_mask_mutex);
 
        err = mlx4_ib_query_port(ibdev, port, &attr);
@@ -300,6 +318,9 @@ static struct ib_ucontext *mlx4_ib_alloc_ucontext(struct ib_device *ibdev,
        struct mlx4_ib_alloc_ucontext_resp resp;
        int err;
 
+       if (mlx4_is_barred(ibdev->dma_device))
+               return ERR_PTR(-EFAULT);
+
        resp.qp_tab_size      = dev->dev->caps.num_qps;
        resp.bf_reg_size      = (__u16)dev->dev->caps.bf_reg_size;
        resp.bf_regs_per_page = (__u16)dev->dev->caps.bf_regs_per_page;
@@ -381,6 +402,9 @@ static struct ib_pd *mlx4_ib_alloc_pd(struct ib_device *ibdev,
        struct mlx4_ib_pd *pd;
        int err;
 
+       if (mlx4_is_barred(ibdev->dma_device))
+               return ERR_PTR(-EFAULT);
+
        pd = kmalloc(sizeof *pd, GFP_KERNEL);
        if (!pd)
                return ERR_PTR(-ENOMEM);
@@ -417,6 +441,8 @@ static int mlx4_ib_dealloc_pd(struct ib_pd *pd)
 static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
 {
        UNUSED_PARAM(lid);
+       if (mlx4_is_barred(ibqp->device->dma_device))
+               return -EFAULT;
        return mlx4_multicast_attach(to_mdev(ibqp->device)->dev,
                                     &to_mqp(ibqp)->mqp, gid->raw);
 }
@@ -424,6 +450,8 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
 static int mlx4_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
 {
        UNUSED_PARAM(lid);
+       if (mlx4_is_barred(ibqp->device->dma_device))
+               return -EFAULT;
        return mlx4_multicast_detach(to_mdev(ibqp->device)->dev,
                                     &to_mqp(ibqp)->mqp, gid->raw);
 }
index 1475d9e8fa2544185251db1f6d788ef930b85572..5b63f2106bdaafadfa2167178df470bb87b19935 100644 (file)
@@ -46,6 +46,9 @@ struct ib_mr *mlx4_ib_get_dma_mr(struct ib_pd *pd, int acc)
        struct mlx4_ib_mr *mr;
        int err;
 
+       if (mlx4_is_barred(pd->device->dma_device))
+               return ERR_PTR(-EFAULT);
+
        mr = kmalloc(sizeof *mr, GFP_KERNEL);
        if (!mr)
                return ERR_PTR(-ENOMEM);
@@ -124,6 +127,9 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
        int n;
 
        UNUSED_PARAM(udata);
+
+       if (mlx4_is_barred(pd->device->dma_device))
+               return ERR_PTR(-EFAULT);
        
        mr = kmalloc(sizeof *mr, GFP_KERNEL);
        if (!mr)
@@ -188,6 +194,9 @@ struct ib_fmr *mlx4_ib_fmr_alloc(struct ib_pd *pd, int acc,
        struct mlx4_ib_fmr *fmr;
        int err = -ENOMEM;
 
+       if (mlx4_is_barred(pd->device->dma_device))
+               return ERR_PTR(-EFAULT);
+
        fmr = kmalloc(sizeof *fmr, GFP_KERNEL);
        if (!fmr)
                return ERR_PTR(-ENOMEM);
@@ -221,6 +230,9 @@ int mlx4_ib_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
        struct mlx4_ib_fmr *ifmr = to_mfmr(ibfmr);
        struct mlx4_ib_dev *dev = to_mdev(ifmr->ibfmr.device);
 
+       if (mlx4_is_barred(ifmr->ibfmr.device->dma_device))
+               return -EFAULT;
+
        return mlx4_map_phys_fmr(dev->dev, &ifmr->mfmr, page_list, npages, iova,
                                 &ifmr->ibfmr.lkey, &ifmr->ibfmr.rkey);
 }
@@ -228,7 +240,7 @@ int mlx4_ib_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list,
 int mlx4_ib_unmap_fmr(struct list_head *fmr_list)
 {
        struct ib_fmr *ibfmr;
-       int err;
+       int err = 0;
        struct mlx4_dev *mdev = NULL;
 
        list_for_each_entry(ibfmr, fmr_list, list, struct ib_fmr) {
@@ -252,7 +264,8 @@ int mlx4_ib_unmap_fmr(struct list_head *fmr_list)
         */
        wmb();
 
-       err = mlx4_SYNC_TPT(mdev);
+       if (!mlx4_is_barred(mdev))
+               err = mlx4_SYNC_TPT(mdev);
        if (err)
                printk(KERN_WARNING "mlx4_ib: SYNC_TPT error %d when "
                       "unmapping FMRs\n", err);
index 18e1af1e9900d868686f5c5eb2412a1640a53fc7..40a51eced125b3196e69ae95ed3cdb0641afd10d 100644 (file)
@@ -561,6 +561,9 @@ struct ib_qp *mlx4_ib_create_qp(struct ib_pd *pd,
        struct mlx4_ib_qp *qp;\r
        int err;\r
 \r
+       if (mlx4_is_barred(pd->device->dma_device))\r
+               return ERR_PTR(-EFAULT);\r
+\r
        switch (init_attr->qp_type) {\r
        case IB_QPT_RC:\r
        case IB_QPT_UC:\r
@@ -621,7 +624,7 @@ int mlx4_ib_destroy_qp(struct ib_qp *qp)
        struct mlx4_ib_dev *dev = to_mdev(qp->device);\r
        struct mlx4_ib_qp *mqp = to_mqp(qp);\r
 \r
-       if (is_qp0(dev, mqp))\r
+       if (!mlx4_is_barred(dev->dev) && is_qp0(dev, mqp))\r
                mlx4_CLOSE_PORT(dev->dev, mqp->port);\r
 \r
        destroy_qp_common(dev, mqp, !!qp->pd->p_uctx);\r
@@ -1028,6 +1031,9 @@ int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
 \r
        UNUSED_PARAM(udata);\r
        \r
+       if (mlx4_is_barred(dev->dev))\r
+               return -EFAULT; \r
+\r
        mutex_lock(&qp->mutex);\r
 \r
        cur_state = attr_mask & IB_QP_CUR_STATE ? attr->cur_qp_state : qp->state;\r
@@ -1330,6 +1336,9 @@ int mlx4_ib_post_send(struct ib_qp *ibqp, ib_send_wr_t *wr,
        int size;\r
        int i;\r
 \r
+       if (mlx4_is_barred(ibqp->device->dma_device))\r
+               return -EFAULT;\r
+\r
        spin_lock_irqsave(&qp->sq.lock, &flags);\r
 \r
        ind = qp->sq.head;\r
@@ -1527,6 +1536,9 @@ int mlx4_ib_post_recv(struct ib_qp *ibqp, ib_recv_wr_t *wr,
        int ind;\r
        int i;\r
 \r
+       if (mlx4_is_barred(ibqp->device->dma_device))\r
+               return -EFAULT;\r
+\r
        spin_lock_irqsave(&qp->rq.lock, &flags);\r
 \r
        ind = qp->rq.head & (qp->rq.wqe_cnt - 1);\r
@@ -1662,6 +1674,9 @@ int mlx4_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr
 \r
        UNUSED_PARAM(qp_attr_mask);\r
 \r
+       if (mlx4_is_barred(dev->dev))\r
+               return -EFAULT;\r
+       \r
        if (qp->state == XIB_QPS_RESET) {\r
                qp_attr->qp_state = XIB_QPS_RESET;\r
                goto done;\r
index 4758305133610408e150f41ae37643bcf1d69a6e..9067e1fc247ce6ab5819934780cb8d30f92514c9 100644 (file)
@@ -82,6 +82,9 @@ struct ib_srq *mlx4_ib_create_srq(struct ib_pd *pd,
        u32 cqn = 0;\r
        u16 xrcd = 0;\r
 \r
+       if (mlx4_is_barred(pd->device->dma_device))\r
+               return ERR_PTR(-EFAULT);\r
+\r
        /* Sanity check SRQ size before proceeding */\r
        if ((int)init_attr->attr.max_wr  >= dev->dev->caps.max_srq_wqes ||\r
            (int)init_attr->attr.max_sge >  dev->dev->caps.max_srq_sge)\r
@@ -219,6 +222,9 @@ int mlx4_ib_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr,
        int ret;\r
 \r
        UNUSED_PARAM(udata);\r
+\r
+       if (mlx4_is_barred(ibsrq->device->dma_device))\r
+               return -EFAULT;\r
        \r
        /* We don't support resizing SRQs (yet?) */\r
        if (attr_mask & XIB_SRQ_MAX_WR)\r
@@ -246,6 +252,9 @@ int mlx4_ib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
        int ret;\r
        int limit_watermark;\r
 \r
+       if (mlx4_is_barred(ibsrq->device->dma_device))\r
+               return -EFAULT;\r
+\r
        ret = mlx4_srq_query(dev->dev, &srq->msrq, &limit_watermark);\r
        if (ret)\r
                return ret;\r
@@ -262,7 +271,8 @@ int mlx4_ib_destroy_srq(struct ib_srq *srq)
        struct mlx4_ib_dev *dev = to_mdev(srq->device);\r
        struct mlx4_ib_srq *msrq = to_msrq(srq);\r
 \r
-       mlx4_srq_invalidate(dev->dev, &msrq->msrq);\r
+       if (!mlx4_is_barred(dev->dev))\r
+               mlx4_srq_invalidate(dev->dev, &msrq->msrq);\r
        mlx4_srq_remove(dev->dev, &msrq->msrq);\r
 \r
        mlx4_srq_free(dev->dev, &msrq->msrq);\r
@@ -308,6 +318,9 @@ int mlx4_ib_post_srq_recv(struct ib_srq *ibsrq, ib_recv_wr_t *wr,
        int nreq;\r
        int i;\r
 \r
+       if (mlx4_is_barred(ibsrq->device->dma_device))\r
+               return -EFAULT;\r
+\r
        spin_lock_irqsave(&srq->lock, &flags);\r
 \r
        for (nreq = 0; wr; ++nreq, wr = wr->p_next) {\r
index f507d929532793a52a036650858d9ca736e899e9..5d5c5e5cfee8c989f9ee9d4d5abbc95eb57b3cc8 100644 (file)
@@ -115,6 +115,8 @@ typedef void (*MLX4_REMOVE_EQ) (struct mlx4_dev *dev, u8 eq_num);
 typedef int (*MLX4_REGISTER_EVENT_HANDLER) (struct ib_event_handler *event_handler);
 typedef int (*MLX4_UNREGISTER_EVENT_HANDLER)(struct ib_event_handler *event_handler);
 
+typedef int (*MLX4_RESET_REQUEST) (struct ib_event_handler *event_handler);
+typedef int (*MLX4_RESET_EXECUTE) (struct ib_event_handler *event_handler);
 
 struct mlx4_interface_ex {
        MLX4_PD_ALLOC       mlx4_pd_alloc;
@@ -165,6 +167,8 @@ struct mlx4_interface_ex {
 
        MLX4_REGISTER_EVENT_HANDLER mlx4_register_ev_cb;
        MLX4_UNREGISTER_EVENT_HANDLER mlx4_unregister_ev_cb;
+       MLX4_RESET_REQUEST mlx4_reset_request;
+       MLX4_RESET_EXECUTE mlx4_reset_execute;
        
 };
 
@@ -176,8 +180,6 @@ typedef struct _MLX4_BUS_IB_INTERFACE{
        struct mlx4_dev                 *       pmlx4_dev;
        struct mlx4_interface_ex        mlx4_interface;
        int                                                     is_livefish;
-       MLX4_REGISTER_INTERFACE     register_interface;
-       MLX4_UNREGISTER_INTERFACE   unregister_interface;
        u8                                                      port_id;
        struct VipBusIfc                        *pVipBusIfc;
        
index 29d7d725622ede261bb468ca291096fe258109fc..09b0c77bdfbb9002d00d9aa0fc4e2c4e9ec20173 100644 (file)
 enum {
        MLX4_FLAG_MSI_X                 = 1 << 0,
        MLX4_FLAG_OLD_PORT_CMDS = 1 << 1,
-       MLX4_FLAG_LIVEFISH              = 1 << 10
+       MLX4_FLAG_LIVEFISH              = 1 << 10,
+       MLX4_FLAG_RESET_CLIENT  = 1 << 11,
+       MLX4_FLAG_RESET_DRIVER  = 1 << 12,
+       MLX4_FLAG_RESET_STARTED = 1 << 13
 };
 
 enum {
index 7e40518fee0193d6ac978c93750b33aa5c6944d2..d05558da3dbd62b8e566ef1251c39bf8cb14fa07 100644 (file)
@@ -272,7 +272,10 @@ enum ib_event_type {
        IB_EVENT_LID_CHANGE                                                     = IB_AE_UNKNOWN + 1,\r
        IB_EVENT_PKEY_CHANGE,\r
        IB_EVENT_SM_CHANGE,\r
-       IB_EVENT_CLIENT_REREGISTER\r
+       IB_EVENT_CLIENT_REREGISTER,\r
+       IB_EVENT_RESET_DRIVER,          // device will be reset upon fatal error\r
+       IB_EVENT_RESET_CLIENT,          // device will be upon client request\r
+       IB_EVENT_RESET_END                      // device has been reset \r
 };\r
 \r
 struct ib_event {\r
@@ -285,21 +288,32 @@ struct ib_event {
        } element;\r
        enum ib_event_type      event;\r
        struct ib_event_ex      x;\r
-       };\r
+};\r
+\r
+enum ib_event_handler_flags {\r
+       IB_IVH_RESET_CB         = (1 << 0),\r
+       IB_IVH_NOTIFIED         = (1 << 1),\r
+       IB_IVH_RESET_READY      = (1 << 2)\r
+};\r
+\r
 \r
 struct ib_event_handler {\r
        struct ib_device *device;\r
        void            (*handler)(struct ib_event_handler *, struct ib_event *);\r
-       void *            ctx;\r
        struct list_head  list;\r
+       void *            ctx;\r
+       void *            rsrv_ptr;\r
+       u32               flags;\r
 };\r
 \r
-#define INIT_IB_EVENT_HANDLER(_ptr, _device, _handler, _ctx)           \\r
+#define INIT_IB_EVENT_HANDLER(_ptr, _device, _handler, _ctx, _rptr, _flags)            \\r
        {                                                       \\r
                (_ptr)->device  = _device;                      \\r
                (_ptr)->handler = _handler;             \\r
+               INIT_LIST_HEAD(&(_ptr)->list);          \\r
                (_ptr)->ctx = _ctx;             \\r
-               INIT_LIST_HEAD(&(_ptr)->list);                  \\r
+               (_ptr)->rsrv_ptr = _rptr;               \\r
+               (_ptr)->flags = _flags;                 \\r
        }\r
 \r
 struct ib_global_route {\r
index 16b1d79e1c3392c665ca524c6d036d3d36724848..62a074e6b0a0eed7318f907db7e3a223844e01dc 100644 (file)
@@ -395,6 +395,9 @@ int mlx4_alloc_hwq_res(struct mlx4_dev *dev, struct mlx4_hwq_resources *wqres,
 {
        int err;
 
+       if ( mlx4_is_barred(dev) )
+               return -EFAULT;
+
        err = mlx4_db_alloc(dev, &wqres->db, 1);
        if (err)
                return err;
index 9658bdd9cdefbfde7af8c790dd4d250d5a1eadfd..564d55492ef9c9c6c84b0eed08bb236c51571e9f 100644 (file)
@@ -43,6 +43,58 @@ static LIST_HEAD(catas_list);
 // "Reset device on internal errors if non-zero (default 1)")
 int g_internal_err_reset = 1;
 
+static void dispatch_event(struct ib_device *ibdev, enum ib_event_type type)
+{
+       unsigned long flags;
+       struct ib_event event;
+       struct ib_event_handler *handler;
+
+       event.device = ibdev;
+       event.event = type;
+
+       spin_lock_irqsave(&ibdev->event_handler_lock, &flags);
+
+       list_for_each_entry(handler, &ibdev->event_handler_list, list, struct ib_event_handler)
+       {
+               // notify only those, that are not notified
+               if ( handler->flags & IB_IVH_RESET_CB )
+                       if ( !(handler->flags & IB_IVH_NOTIFIED) ) {
+                               handler->flags |= IB_IVH_NOTIFIED;
+                               handler->handler(handler, &event);
+                       }
+       }
+
+       spin_unlock_irqrestore(&ibdev->event_handler_lock, flags);
+}
+
+/**
+ * get_event_handlers - return list of handlers of the device
+ * @device:device
+ * @tlist:list
+ *
+ * get_event_handlers() remove all the device event handlers and put them in 'tlist'
+ */
+static void get_event_handlers(struct ib_device *device, struct list_head *tlist)
+{
+       unsigned long flags;
+       struct ib_event_handler *handler, *thandler;
+
+       spin_lock_irqsave(&device->event_handler_lock, &flags);
+
+       list_for_each_entry_safe(handler, thandler, &device->event_handler_list, 
+               list, struct ib_event_handler, struct ib_event_handler)
+       {
+               // take out only reset callbacks
+               if ( handler->flags & IB_IVH_RESET_CB ) {
+                       list_del( &handler->list );
+                       list_add_tail( &handler->list, tlist );
+               }
+       }
+
+       spin_unlock_irqrestore(&device->event_handler_lock, flags);
+}
+
+
 static void dump_err_buf(struct mlx4_dev *dev)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
@@ -97,6 +149,12 @@ static void poll_catas(struct mlx4_dev *dev)
 
                mlx4_dispatch_event(dev, MLX4_EVENT_TYPE_LOCAL_CATAS_ERROR, 0, 0);
 
+               // bar the device
+               dev->flags |= MLX4_FLAG_RESET_DRIVER;
+
+               // notify the clients
+               dispatch_event(dev->pdev->ib_dev, IB_EVENT_RESET_DRIVER);
+
                if (g_internal_err_reset) {
                        PIO_WORKITEM catas_work = IoAllocateWorkItem( dev->pdev->p_self_do );
 
@@ -163,6 +221,10 @@ void mlx4_stop_catas_poll(struct mlx4_dev *dev)
        struct mlx4_priv *priv = mlx4_priv(dev);
 
        spin_lock_irq(&catas_lock);
+       if (priv->catas_err.stop) {
+               spin_unlock_irq(&catas_lock);
+               return;
+       }
        priv->catas_err.stop = 1;
        spin_unlock_irq(&catas_lock);
 
@@ -177,4 +239,126 @@ void mlx4_stop_catas_poll(struct mlx4_dev *dev)
        spin_unlock_irq(&catas_lock);
 }
 
+static int wait4reset(struct ib_event_handler *event_handler)
+{
+       int n_not_ready = 0;
+       unsigned long flags;
+       struct ib_event_handler *handler;
+       struct ib_device *ibdev = event_handler->device;
+
+       spin_lock_irqsave(&ibdev->event_handler_lock, &flags);
+
+       // mark this handler (=client) reset-ready
+       event_handler->flags |= IB_IVH_RESET_READY;
+
+       // check the number of still not ready client
+       
+       list_for_each_entry(handler, &ibdev->event_handler_list, list, struct ib_event_handler)
+               if ( handler->flags & IB_IVH_RESET_CB )
+                       if ( !(handler->flags & IB_IVH_RESET_READY) ) 
+                               ++n_not_ready;
+       
+       spin_unlock_irqrestore(&ibdev->event_handler_lock, flags);
+
+       return n_not_ready;
+}
+
+int mlx4_reset_execute( struct ib_event_handler *event_handler )
+{
+       int err;
+       struct ib_event event;
+       struct list_head tlist;
+       struct ib_event_handler *handler, *thandler;
+       struct ib_device *ibdev = event_handler->device;
+       struct pci_dev *pdev = ibdev->dma_device->pdev;
+
+       // mark client as "ready for reset" and check whether we can do reset
+       if (wait4reset(event_handler))
+               return 0;
+
+       // fully bar the device
+       ibdev->dma_device->flags |= MLX4_FLAG_RESET_STARTED;
+       
+       // get old handler list 
+       INIT_LIST_HEAD(&tlist);
+       get_event_handlers(ibdev, &tlist);
+
+       // restart the device
+       err = mlx4_restart_one(pdev);
+
+       // recreate interfaces
+       fix_bus_ifc(pdev);
+
+       // notify the clients
+       event.event = IB_EVENT_RESET_END;
+       list_for_each_entry_safe(handler, thandler, &tlist, 
+               list, struct ib_event_handler, struct ib_event_handler)
+       {
+               // because 'handler' will be re-registered during the next call
+               list_del( &handler->list );
+               handler->handler(handler, &event);
+       }
+       
+       return err;
+}
+
+static void
+card_reset_wi(
+       IN                              DEVICE_OBJECT*                          p_dev_obj,
+       IN                              struct ib_event_handler *       event_handler )
+{
+       NTSTATUS status;
+       struct ib_device *ibdev = event_handler->device;
+       struct mlx4_dev *dev = ibdev->dma_device;
+
+       UNUSED_PARAM(p_dev_obj);
+       IoFreeWorkItem( event_handler->rsrv_ptr );
+
+       // reset the card
+       mlx4_stop_catas_poll( dev );
+       status = mlx4_reset( dev );
+       if ( !NT_SUCCESS( status ) )
+               mlx4_err( dev, "Failed to reset HCA, aborting. (status %#x)\n", status );
+
+       // notify the clients
+       dispatch_event(ibdev, IB_EVENT_RESET_CLIENT);
+}
+
+int mlx4_reset_request( struct ib_event_handler *event_handler )
+{
+       struct ib_device *ibdev = event_handler->device;
+       struct mlx4_dev *dev = ibdev->dma_device;
+       
+       // set device to RESET_PENDING mode
+       if (!mlx4_is_barred(dev)) {
+               PIO_WORKITEM reset_work;
+
+               // bar the device
+               dev->flags |= MLX4_FLAG_RESET_CLIENT;
+
+               // delay reset to a system thread
+               // to allow for end of operations that are in progress
+               reset_work = IoAllocateWorkItem( dev->pdev->p_self_do );
+               if (!reset_work)
+                       return -EFAULT;
+               event_handler->rsrv_ptr = reset_work;
+               IoQueueWorkItem( reset_work, card_reset_wi, DelayedWorkQueue, event_handler );
+       }
+
+       return 0;
+}
+
+int mlx4_reset_cb_register( struct ib_event_handler *event_handler )
+{
+       if (mlx4_is_in_reset(event_handler->device->dma_device))
+               return -EBUSY;
+
+       return ib_register_event_handler(event_handler);
+}
+
+int mlx4_reset_cb_unregister( struct ib_event_handler *event_handler )
+{
+       return ib_unregister_event_handler(event_handler);
+}
+
 
index 5dac0dd88a3860dcf1347f0c27972401672563fb..a49a5f10402c8940c322db1d72e3c424a2bb9dba 100644 (file)
@@ -491,6 +491,9 @@ struct mlx4_cmd_mailbox *mlx4_alloc_cmd_mailbox(struct mlx4_dev *dev)
 {
        struct mlx4_cmd_mailbox *mailbox;
 
+       if ( mlx4_is_barred(dev) )
+               return ERR_PTR(-EFAULT);
+
        mailbox = kmalloc(sizeof *mailbox, GFP_KERNEL);
        if (!mailbox)
                return ERR_PTR(-ENOMEM);
@@ -520,6 +523,9 @@ EXPORT_SYMBOL_GPL(mlx4_free_cmd_mailbox);
 int imlx4_cmd(struct mlx4_dev *dev, u64 in_param, u64 *out_param, int out_is_imm,
                u32 in_modifier, u8 op_modifier, u16 op, unsigned long timeout)
 {
+       if ( mlx4_is_barred(dev) )
+               return -EFAULT;
+       
        return __mlx4_cmd(dev, in_param, out_param, out_is_imm, in_modifier,
                          op_modifier, op, timeout);
 }
index d810b35116394b3112850fa4aa5eca2eb9fcd032..9fed0ade483c1f5e8868ef7f8d88afe52f046660 100644 (file)
@@ -130,6 +130,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt,
 #define COLLAPSED_SHIFT        18
 #define ENTRIES_SHIFT  24
 
+       if ( mlx4_is_barred(dev) )
+               return -EFAULT;
+
        cq->cqn = mlx4_bitmap_alloc(&cq_table->bitmap);
        if (cq->cqn == -1)
                return -ENOMEM;
@@ -212,6 +215,9 @@ int mlx4_cq_modify(struct mlx4_dev *dev, struct mlx4_cq *cq,
        struct mlx4_cmd_mailbox *mailbox;
        int err;
 
+       if ( mlx4_is_barred(dev) )
+               return -EFAULT;
+
        mailbox = mlx4_alloc_cmd_mailbox(dev);
        if (IS_ERR(mailbox))
                return PTR_ERR(mailbox);
@@ -228,9 +234,10 @@ void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
        struct mlx4_cq_table *cq_table = &priv->cq_table;
-       int err;
+       int err = 0;
 
-       err = mlx4_HW2SW_CQ(dev, NULL, cq->cqn);
+       if (!mlx4_is_barred(dev))
+               err = mlx4_HW2SW_CQ(dev, NULL, cq->cqn);
        if (err)
                mlx4_warn(dev, "HW2SW_CQ failed (%d) for CQN %06x\n", err, cq->cqn);
 
@@ -242,7 +249,8 @@ void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq)
 
        if (atomic_dec_and_test(&cq->refcount))
                complete(&cq->free);
-       wait_for_completion(&cq->free);
+       if (!mlx4_is_barred(dev))
+               wait_for_completion(&cq->free);
 
        mlx4_table_put(dev, &cq_table->table, cq->cqn);
        mlx4_bitmap_free(&cq_table->bitmap, cq->cqn);
index 5296160ac9a979acf2d22f6c66b979bf176c55af..bd8741c4c5dc995e1234f945de488eb34bd5aaf6 100644 (file)
@@ -663,6 +663,9 @@ int mlx4_add_eq(struct mlx4_dev *dev, int nent,
 
     UNREFERENCED_PARAMETER(intr);
        
+       if ( mlx4_is_barred(dev) )
+               return -EFAULT;
+       
        for (i = MLX4_NUM_EQ; i < MLX4_NUM_EQ + MLX4_MAX_EXTRA_EQS ; i++) {
                if(priv->eq_table.eq[MLX4_NUM_EQ].isr == NULL) {
                        new_eq = i;
index ac61f25cfed6513143e767d951fde6885ee3b5f1..b945ab38cd005c9c9f8a52c6a8ec308ffa1423d1 100644 (file)
@@ -780,6 +780,9 @@ int mlx4_INIT_PORT(struct mlx4_dev *dev, int port)
        u32 flags;
        u16 field;
 
+       if ( mlx4_is_barred(dev) )
+               return -EFAULT;
+       
        if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
 #define INIT_PORT_IN_SIZE          256
 #define INIT_PORT_FLAGS_OFFSET     0x00
@@ -828,6 +831,9 @@ EXPORT_SYMBOL_GPL(mlx4_INIT_PORT);
 
 int mlx4_CLOSE_PORT(struct mlx4_dev *dev, int port)
 {
+       if ( mlx4_is_barred(dev) )
+               return -EFAULT;
+       
        return mlx4_cmd(dev, 0, port, 0, MLX4_CMD_CLOSE_PORT, 1000);
 }
 EXPORT_SYMBOL_GPL(mlx4_CLOSE_PORT);
index 907574e92ecc2f07e6d43eb1eead3fc11523ccdd..af2c0b8e39a7fc304b35e593396c7879d33471a6 100644 (file)
@@ -898,6 +898,7 @@ int mlx4_init_one(struct pci_dev *pdev)
        struct mlx4_priv *priv;
        struct mlx4_dev *dev;
        int err;
+       NTSTATUS status;
 
 #ifdef FORCE_LIVEFISH
                if (pdev)
@@ -963,9 +964,10 @@ run_as_livefish:
         * attempt a firmware command, since a boot ROM may have left
         * the HCA in an undefined state.
         */
-       err = mlx4_reset(dev);
-       if (err) {
-               mlx4_err(dev, "Failed to reset HCA, aborting.\n");
+       status = mlx4_reset(dev);
+       if ( !NT_SUCCESS( status ) ) {
+               mlx4_err(dev, "Failed to reset HCA, aborting.(status %#x)\n", status);
+               err = -EFAULT;
                goto err_free_dev;
        }
 
index 9ece1bf965f0b35bcf3f9f1a91b351b7fd0787f1..0027c707c3f1183d91a87bcb492ab9a3b7f2b836 100644 (file)
@@ -427,4 +427,17 @@ int mlx4_add_eq(struct mlx4_dev *dev, int nent,
                          u8* p_eq_num, struct mlx4_eq ** p_eq);
 
 void mlx4_remove_eq(struct mlx4_dev *dev, u8 eq_num);
+
+int mlx4_reset_execute( struct ib_event_handler *event_handler );
+
+int mlx4_reset_request( struct ib_event_handler *event_handler );
+
+int mlx4_reset_cb_register( struct ib_event_handler *event_handler );
+
+int mlx4_reset_cb_unregister( struct ib_event_handler *event_handler );
+
+void fix_bus_ifc(struct pci_dev *pdev);
+
+
+
 #endif /* MLX4_H */
index 6a6f68a8bab1bda7367fd58eaf943d8217258cc4..1036e70d7c64e0d9b2c95b21d70890067f31162c 100644 (file)
@@ -256,6 +256,9 @@ int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access,
        u32 index;
        int err;
 
+       if ( mlx4_is_barred(dev) )
+               return -EFAULT;
+
        index = mlx4_bitmap_alloc(&priv->mr_table.mpt_bitmap);
        if (index == -1)
                return -ENOMEM;
@@ -280,7 +283,7 @@ void mlx4_mr_free(struct mlx4_dev *dev, struct mlx4_mr *mr)
        struct mlx4_priv *priv = mlx4_priv(dev);
        int err;
 
-       if (mr->enabled) {
+       if (!mlx4_is_barred(dev) && mr->enabled) {
                err = mlx4_HW2SW_MPT(dev, NULL,
                                     key_to_hw_index(mr->key) &
                                     (dev->caps.num_mpts - 1));
@@ -300,6 +303,9 @@ int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr)
        struct mlx4_mpt_entry *mpt_entry;
        int err;
 
+       if ( mlx4_is_barred(dev) )
+               return -EFAULT;
+
        err = mlx4_table_get(dev, &mr_table->dmpt_table, key_to_hw_index(mr->key));
        if (err)
                return err;
index 3009a9e8a196b5dba9b3d1fd182ed7035a88934f..ed036c9df3ebd3e1c4ee1402e8617848bf1e03d4 100644 (file)
@@ -39,6 +39,9 @@ int mlx4_pd_alloc(struct mlx4_dev *dev, u32 *pdn)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
 
+       if ( mlx4_is_barred(dev) )
+               return -EFAULT;
+
        *pdn = mlx4_bitmap_alloc(&priv->pd_bitmap);
        if (*pdn == -1)
                return -ENOMEM;
@@ -69,6 +72,9 @@ void mlx4_cleanup_pd_table(struct mlx4_dev *dev)
 
 int mlx4_uar_alloc(struct mlx4_dev *dev, struct mlx4_uar *uar)
 {
+       if ( mlx4_is_barred(dev) )
+               return -EFAULT;
+
        uar->index = mlx4_bitmap_alloc(&mlx4_priv(dev)->uar_table.bitmap);
        if (uar->index == -1)
                return -ENOMEM;
index fda61f47fa14dc434ec8705ce3e83704e1160ab6..125470841c11b1cc1b48e030122e24c732b412d6 100644 (file)
-/*
- * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses.  You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- */
-
-#include "mlx4.h"
-#include "cmd.h"
-
-
-void mlx4_init_mac_table(struct mlx4_dev *dev, u8 port)
-{
-       struct mlx4_mac_table *table = &mlx4_priv(dev)->port[port].mac_table;
-       int i;
-
-       sema_init(&table->mac_sem, 1);
-       for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
-               table->entries[i] = 0;
-               table->refs[i] = 0;
-       }
-       table->max = 1 << dev->caps.log_num_macs;
-       table->total = 0;
-}
-
-void mlx4_init_vlan_table(struct mlx4_dev *dev, u8 port)
-{
-       struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;
-       int i;
-
-       sema_init(&table->vlan_sem, 1);
-       for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {
-               table->entries[i] = 0;
-               table->refs[i] = 0;
-       }
-       table->max = 1 << dev->caps.log_num_vlans;
-       table->total = 0;
-}
-
-static int mlx4_SET_PORT_mac_table(struct mlx4_dev *dev, u8 port,
-                                  __be64 *entries)
-{
-       struct mlx4_cmd_mailbox *mailbox;
-       u32 in_mod;
-       int err;
-
-       mailbox = mlx4_alloc_cmd_mailbox(dev);
-       if (IS_ERR(mailbox))
-               return PTR_ERR(mailbox);
-
-       memcpy(mailbox->buf, entries, MLX4_MAC_TABLE_SIZE);
-
-       in_mod = MLX4_SET_PORT_MAC_TABLE << 8 | port;
-       err = mlx4_cmd(dev, mailbox->dma.da, in_mod, 1, MLX4_CMD_SET_PORT,
-                      MLX4_CMD_TIME_CLASS_B);
-
-       mlx4_free_cmd_mailbox(dev, mailbox);
-       return err;
-}
-
-int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *index)
-{
-       struct mlx4_mac_table *table =
-       &mlx4_priv(dev)->port[port - 1].mac_table;
-       int i, err = 0;
-       int free = -1;
-       u64 valid = 1;
-
-       mlx4_dbg(dev, "Registering mac : 0x%llx\n", mac);
-       down(&table->mac_sem);
-       for (i = 0; i < MLX4_MAX_MAC_NUM - 1; i++) {
-               if (free < 0 && !table->refs[i]) {
-                       free = i;
-                       continue;
-               }
-
-               if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) {
-                       /* Mac already registered, increase refernce count */
-                       *index = i;
-                       ++table->refs[i];
-                       goto out;
-               }
-       }
-       mlx4_dbg(dev, "Free mac index is %d\n", free);
-
-       if (table->total == table->max) {
-               /* No free mac entries */
-               err = -ENOSPC;
-               goto out;
-       }
-
-       /* Register new MAC */
-       table->refs[free] = 1;
-       table->entries[free] = cpu_to_be64(mac | valid << MLX4_MAC_VALID_SHIFT);
-
-       err = mlx4_SET_PORT_mac_table(dev, port, table->entries);
-       if (unlikely(err)) {
-               mlx4_err(dev, "Failed adding mac: 0x%llx\n", mac);
-               table->refs[free] = 0;
-               table->entries[free] = 0;
-               goto out;
-       }
-
-       *index = free;
-       ++table->total;
-out:
-       up(&table->mac_sem);
-       return err;
-}
-EXPORT_SYMBOL_GPL(mlx4_register_mac);
-
-void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int index)
-{
-       struct mlx4_mac_table *table =
-       &mlx4_priv(dev)->port[port - 1].mac_table;
-
-       down(&table->mac_sem);
-       if (!table->refs[index]) {
-               mlx4_warn(dev, "No mac entry for index %d\n", index);
-               goto out;
-       }
-       if (--table->refs[index]) {
-               mlx4_warn(dev, "Have more references for index %d,"
-                         "no need to modify mac table\n", index);
-               goto out;
-       }
-       table->entries[index] = 0;
-       mlx4_SET_PORT_mac_table(dev, port, table->entries);
-       --table->total;
-out:
-       up(&table->mac_sem);
-}
-EXPORT_SYMBOL_GPL(mlx4_unregister_mac);
-
-static int mlx4_SET_PORT_vlan_table(struct mlx4_dev *dev, u8 port,
-                                   __be32 *entries)
-{
-       struct mlx4_cmd_mailbox *mailbox;
-       u32 in_mod;
-       int err;
-
-       mailbox = mlx4_alloc_cmd_mailbox(dev);
-       if (IS_ERR(mailbox))
-               return PTR_ERR(mailbox);
-
-       memcpy(mailbox->buf, entries, MLX4_VLAN_TABLE_SIZE);
-       in_mod = MLX4_SET_PORT_VLAN_TABLE << 8 | port;
-       err = mlx4_cmd(dev, mailbox->dma.da, in_mod, 1, MLX4_CMD_SET_PORT,
-                      MLX4_CMD_TIME_CLASS_B);
-
-       mlx4_free_cmd_mailbox(dev, mailbox);
-
-       return err;
-}
-
-int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)
-{
-       struct mlx4_vlan_table *table =
-       &mlx4_priv(dev)->port[port - 1].vlan_table;
-       int i, err = 0;
-       int free = -1;
-
-       down(&table->vlan_sem);
-       for (i = 0; i < MLX4_MAX_VLAN_NUM; i++) {
-               if (free < 0 && (table->refs[i] == 0)) {
-                       free = i;
-                       continue;
-               }
-
-               if (table->refs[i] &&
-                   (vlan == (MLX4_VLAN_MASK &
-                             be32_to_cpu(table->entries[i])))) {
-                       /* Vlan already registered, increase refernce count */
-                       *index = i;
-                       ++table->refs[i];
-                       goto out;
-               }
-       }
-
-       if (table->total == table->max) {
-               /* No free vlan entries */
-               err = -ENOSPC;
-               goto out;
-       }
-
-       /* Register new MAC */
-       table->refs[free] = 1;
-       table->entries[free] = cpu_to_be32(vlan | MLX4_VLAN_VALID);
-
-       err = mlx4_SET_PORT_vlan_table(dev, port, table->entries);
-       if (unlikely(err)) {
-               mlx4_warn(dev, "Failed adding vlan: %u\n", vlan);
-               table->refs[free] = 0;
-               table->entries[free] = 0;
-               goto out;
-       }
-
-       *index = free;
-       ++table->total;
-out:
-       up(&table->vlan_sem);
-       return err;
-}
-EXPORT_SYMBOL_GPL(mlx4_register_vlan);
-
-void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)
-{
-       struct mlx4_vlan_table *table =
-       &mlx4_priv(dev)->port[port - 1].vlan_table;
-
-       down(&table->vlan_sem);
-       if (!table->refs[index]) {
-               mlx4_warn(dev, "No vlan entry for index %d\n", index);
-               goto out;
-       }
-       if (--table->refs[index]) {
-               mlx4_dbg(dev, "Have more references for index %d,"
-                        "no need to modify vlan table\n", index);
-               goto out;
-       }
-       table->entries[index] = 0;
-       mlx4_SET_PORT_vlan_table(dev, port, table->entries);
-       --table->total;
-out:
-       up(&table->vlan_sem);
-}
-EXPORT_SYMBOL_GPL(mlx4_unregister_vlan);
-
-int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, 
-       int reset_qkey_viols, u32 cap_mask)
-{
-       struct mlx4_cmd_mailbox *mailbox;
-       int err;
-       u8 is_eth = (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) ? 1 : 0;
-
-       mailbox = mlx4_alloc_cmd_mailbox(dev);
-       if (IS_ERR(mailbox))
-               return PTR_ERR(mailbox);
-
-       memset(mailbox->buf, 0, 256);
-       if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
+/*\r
+ * Copyright (c) 2007 Mellanox Technologies. All rights reserved.\r
+ *\r
+ * This software is available to you under a choice of one of two\r
+ * licenses.  You may choose to be licensed under the terms of the GNU\r
+ * General Public License (GPL) Version 2, available from the file\r
+ * COPYING in the main directory of this source tree, or the\r
+ * OpenIB.org BSD license below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ */\r
+\r
+#include "mlx4.h"\r
+#include "cmd.h"\r
+\r
+\r
+void mlx4_init_mac_table(struct mlx4_dev *dev, u8 port)\r
+{\r
+       struct mlx4_mac_table *table = &mlx4_priv(dev)->port[port].mac_table;\r
+       int i;\r
+\r
+       sema_init(&table->mac_sem, 1);\r
+       for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {\r
+               table->entries[i] = 0;\r
+               table->refs[i] = 0;\r
+       }\r
+       table->max = 1 << dev->caps.log_num_macs;\r
+       table->total = 0;\r
+}\r
+\r
+void mlx4_init_vlan_table(struct mlx4_dev *dev, u8 port)\r
+{\r
+       struct mlx4_vlan_table *table = &mlx4_priv(dev)->port[port].vlan_table;\r
+       int i;\r
+\r
+       sema_init(&table->vlan_sem, 1);\r
+       for (i = 0; i < MLX4_MAX_MAC_NUM; i++) {\r
+               table->entries[i] = 0;\r
+               table->refs[i] = 0;\r
+       }\r
+       table->max = 1 << dev->caps.log_num_vlans;\r
+       table->total = 0;\r
+}\r
+\r
+static int mlx4_SET_PORT_mac_table(struct mlx4_dev *dev, u8 port,\r
+                                  __be64 *entries)\r
+{\r
+       struct mlx4_cmd_mailbox *mailbox;\r
+       u32 in_mod;\r
+       int err;\r
+\r
+       mailbox = mlx4_alloc_cmd_mailbox(dev);\r
+       if (IS_ERR(mailbox))\r
+               return PTR_ERR(mailbox);\r
+\r
+       memcpy(mailbox->buf, entries, MLX4_MAC_TABLE_SIZE);\r
+\r
+       in_mod = MLX4_SET_PORT_MAC_TABLE << 8 | port;\r
+       err = mlx4_cmd(dev, mailbox->dma.da, in_mod, 1, MLX4_CMD_SET_PORT,\r
+                      MLX4_CMD_TIME_CLASS_B);\r
+\r
+       mlx4_free_cmd_mailbox(dev, mailbox);\r
+       return err;\r
+}\r
+\r
+int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *index)\r
+{\r
+       struct mlx4_mac_table *table =\r
+       &mlx4_priv(dev)->port[port - 1].mac_table;\r
+       int i, err = 0;\r
+       int free = -1;\r
+       u64 valid = 1;\r
+\r
+       if ( mlx4_is_barred(dev) )\r
+               return -EFAULT;\r
+\r
+       mlx4_dbg(dev, "Registering mac : 0x%llx\n", mac);\r
+       down(&table->mac_sem);\r
+       for (i = 0; i < MLX4_MAX_MAC_NUM - 1; i++) {\r
+               if (free < 0 && !table->refs[i]) {\r
+                       free = i;\r
+                       continue;\r
+               }\r
+\r
+               if (mac == (MLX4_MAC_MASK & be64_to_cpu(table->entries[i]))) {\r
+                       /* Mac already registered, increase refernce count */\r
+                       *index = i;\r
+                       ++table->refs[i];\r
+                       goto out;\r
+               }\r
+       }\r
+       mlx4_dbg(dev, "Free mac index is %d\n", free);\r
+\r
+       if (table->total == table->max) {\r
+               /* No free mac entries */\r
+               err = -ENOSPC;\r
+               goto out;\r
+       }\r
+\r
+       /* Register new MAC */\r
+       table->refs[free] = 1;\r
+       table->entries[free] = cpu_to_be64(mac | valid << MLX4_MAC_VALID_SHIFT);\r
+\r
+       err = mlx4_SET_PORT_mac_table(dev, port, table->entries);\r
+       if (unlikely(err)) {\r
+               mlx4_err(dev, "Failed adding mac: 0x%llx\n", mac);\r
+               table->refs[free] = 0;\r
+               table->entries[free] = 0;\r
+               goto out;\r
+       }\r
+\r
+       *index = free;\r
+       ++table->total;\r
+out:\r
+       up(&table->mac_sem);\r
+       return err;\r
+}\r
+EXPORT_SYMBOL_GPL(mlx4_register_mac);\r
+\r
+void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int index)\r
+{\r
+       struct mlx4_mac_table *table =\r
+       &mlx4_priv(dev)->port[port - 1].mac_table;\r
+\r
+       down(&table->mac_sem);\r
+       if (!table->refs[index]) {\r
+               mlx4_warn(dev, "No mac entry for index %d\n", index);\r
+               goto out;\r
+       }\r
+       if (--table->refs[index]) {\r
+               mlx4_warn(dev, "Have more references for index %d,"\r
+                         "no need to modify mac table\n", index);\r
+               goto out;\r
+       }\r
+       table->entries[index] = 0;\r
+       if ( !mlx4_is_barred(dev) )\r
+               mlx4_SET_PORT_mac_table(dev, port, table->entries);\r
+       --table->total;\r
+out:\r
+       up(&table->mac_sem);\r
+}\r
+EXPORT_SYMBOL_GPL(mlx4_unregister_mac);\r
+\r
+static int mlx4_SET_PORT_vlan_table(struct mlx4_dev *dev, u8 port,\r
+                                   __be32 *entries)\r
+{\r
+       struct mlx4_cmd_mailbox *mailbox;\r
+       u32 in_mod;\r
+       int err;\r
+\r
+       mailbox = mlx4_alloc_cmd_mailbox(dev);\r
+       if (IS_ERR(mailbox))\r
+               return PTR_ERR(mailbox);\r
+\r
+       memcpy(mailbox->buf, entries, MLX4_VLAN_TABLE_SIZE);\r
+       in_mod = MLX4_SET_PORT_VLAN_TABLE << 8 | port;\r
+       err = mlx4_cmd(dev, mailbox->dma.da, in_mod, 1, MLX4_CMD_SET_PORT,\r
+                      MLX4_CMD_TIME_CLASS_B);\r
+\r
+       mlx4_free_cmd_mailbox(dev, mailbox);\r
+\r
+       return err;\r
+}\r
+\r
+int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index)\r
+{\r
+       struct mlx4_vlan_table *table =\r
+       &mlx4_priv(dev)->port[port - 1].vlan_table;\r
+       int i, err = 0;\r
+       int free = -1;\r
+\r
+       down(&table->vlan_sem);\r
+       for (i = 0; i < MLX4_MAX_VLAN_NUM; i++) {\r
+               if (free < 0 && (table->refs[i] == 0)) {\r
+                       free = i;\r
+                       continue;\r
+               }\r
+\r
+               if (table->refs[i] &&\r
+                   (vlan == (MLX4_VLAN_MASK &\r
+                             be32_to_cpu(table->entries[i])))) {\r
+                       /* Vlan already registered, increase refernce count */\r
+                       *index = i;\r
+                       ++table->refs[i];\r
+                       goto out;\r
+               }\r
+       }\r
+\r
+       if (table->total == table->max) {\r
+               /* No free vlan entries */\r
+               err = -ENOSPC;\r
+               goto out;\r
+       }\r
+\r
+       /* Register new MAC */\r
+       table->refs[free] = 1;\r
+       table->entries[free] = cpu_to_be32(vlan | MLX4_VLAN_VALID);\r
+\r
+       err = mlx4_SET_PORT_vlan_table(dev, port, table->entries);\r
+       if (unlikely(err)) {\r
+               mlx4_warn(dev, "Failed adding vlan: %u\n", vlan);\r
+               table->refs[free] = 0;\r
+               table->entries[free] = 0;\r
+               goto out;\r
+       }\r
+\r
+       *index = free;\r
+       ++table->total;\r
+out:\r
+       up(&table->vlan_sem);\r
+       return err;\r
+}\r
+EXPORT_SYMBOL_GPL(mlx4_register_vlan);\r
+\r
+void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index)\r
+{\r
+       struct mlx4_vlan_table *table =\r
+       &mlx4_priv(dev)->port[port - 1].vlan_table;\r
+\r
+       down(&table->vlan_sem);\r
+       if (!table->refs[index]) {\r
+               mlx4_warn(dev, "No vlan entry for index %d\n", index);\r
+               goto out;\r
+       }\r
+       if (--table->refs[index]) {\r
+               mlx4_dbg(dev, "Have more references for index %d,"\r
+                        "no need to modify vlan table\n", index);\r
+               goto out;\r
+       }\r
+       table->entries[index] = 0;\r
+       mlx4_SET_PORT_vlan_table(dev, port, table->entries);\r
+       --table->total;\r
+out:\r
+       up(&table->vlan_sem);\r
+}\r
+EXPORT_SYMBOL_GPL(mlx4_unregister_vlan);\r
+\r
+int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port, \r
+       int reset_qkey_viols, u32 cap_mask)\r
+{\r
+       struct mlx4_cmd_mailbox *mailbox;\r
+       int err;\r
+       u8 is_eth = (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) ? 1 : 0;\r
+\r
+       mailbox = mlx4_alloc_cmd_mailbox(dev);\r
+       if (IS_ERR(mailbox))\r
+               return PTR_ERR(mailbox);\r
+\r
+       memset(mailbox->buf, 0, 256);\r
+       if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {\r
                *(u8 *) mailbox->buf         = (u8)(!!reset_qkey_viols << 6);
                ((__be32 *) mailbox->buf)[2] = cpu_to_be32(cap_mask);
        } else {
                ((u8 *) mailbox->buf)[3]     = (u8)!!reset_qkey_viols;
                ((__be32 *) mailbox->buf)[1] = cpu_to_be32(cap_mask);
        }
-       
-       if (is_eth) {
-               ((u8 *) mailbox->buf)[3] = 7;
-               ((__be16 *) mailbox->buf)[3] =
-                       cpu_to_be16(dev->caps.eth_mtu_cap[port] +
-                                   ETH_HLEN + ETH_FCS_LEN);
-               ((__be16 *) mailbox->buf)[4] = cpu_to_be16(1 << 15);
-               ((__be16 *) mailbox->buf)[6] = cpu_to_be16(1 << 15);
-       }
-       err = mlx4_cmd(dev, mailbox->dma.da, port, is_eth, MLX4_CMD_SET_PORT,
-                      MLX4_CMD_TIME_CLASS_B);
-
-       mlx4_free_cmd_mailbox(dev, mailbox);
-       return err;
-}
-
+       \r
+       if (is_eth) {\r
+               ((u8 *) mailbox->buf)[3] = 7;\r
+               ((__be16 *) mailbox->buf)[3] =\r
+                       cpu_to_be16(dev->caps.eth_mtu_cap[port] +\r
+                                   ETH_HLEN + ETH_FCS_LEN);\r
+               ((__be16 *) mailbox->buf)[4] = cpu_to_be16(1 << 15);\r
+               ((__be16 *) mailbox->buf)[6] = cpu_to_be16(1 << 15);\r
+       }\r
+       err = mlx4_cmd(dev, mailbox->dma.da, port, is_eth, MLX4_CMD_SET_PORT,\r
+                      MLX4_CMD_TIME_CLASS_B);\r
+\r
+       mlx4_free_cmd_mailbox(dev, mailbox);\r
+       return err;\r
+}\r
+\r
index 18807eecb9224a5a6394968e41c938bae9760921..71ce754a54709a521ac177368b35065835933861 100644 (file)
@@ -74,6 +74,9 @@ int mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
        static u16 op[MLX4_QP_NUM_STATE][MLX4_QP_NUM_STATE];
        static int op_inited = 0;
 
+       if ( mlx4_is_barred(dev) )
+               return -EFAULT;
+
        if (!op_inited) {
                op[MLX4_QP_STATE_RST][MLX4_QP_STATE_RST]        = MLX4_CMD_2RST_QP;
                op[MLX4_QP_STATE_RST][MLX4_QP_STATE_ERR]        = MLX4_CMD_2ERR_QP;
@@ -174,6 +177,9 @@ int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp)
        struct mlx4_qp_table *qp_table = &priv->qp_table;
        int err;
 
+       if ( mlx4_is_barred(dev) )
+               return -EFAULT;
+
        if (!qpn)
                return -EINVAL;
 
@@ -259,7 +265,8 @@ void mlx4_qp_free(struct mlx4_dev *dev, struct mlx4_qp *qp)
 
        if (atomic_dec_and_test(&qp->refcount))
                complete(&qp->free);
-       wait_for_completion(&qp->free);
+       if (!mlx4_is_barred(dev))
+               wait_for_completion(&qp->free);
 
        mlx4_table_put(dev, &qp_table->cmpt_table, qp->qpn);
        mlx4_table_put(dev, &qp_table->rdmarc_table, qp->qpn);
index 5ff433d0116a31be36d58517a46cb635d0ccfbea..9c45f1037c741763b3f18374900dd7e958cf15c1 100644 (file)
@@ -117,6 +117,9 @@ int mlx4_srq_alloc(struct mlx4_dev *dev, u32 pdn, u32 cqn, u16 xrcd,
        int err;
        UNREFERENCED_PARAMETER(xrcd);
 
+       if ( mlx4_is_barred(dev) )
+               return -EFAULT;
+
        srq->srqn = mlx4_bitmap_alloc(&srq_table->bitmap);
        if (srq->srqn == -1)
                return -ENOMEM;
@@ -190,6 +193,9 @@ void mlx4_srq_invalidate(struct mlx4_dev *dev, struct mlx4_srq *srq)
 {
        int err;
 
+       if ( mlx4_is_barred(dev) )
+               return;
+
        err = mlx4_HW2SW_SRQ(dev, NULL, srq->srqn);
        if (err)
                mlx4_warn(dev, "HW2SW_SRQ failed (%d) for SRQN %06x\n", err, srq->srqn);
@@ -212,7 +218,8 @@ void mlx4_srq_free(struct mlx4_dev *dev, struct mlx4_srq *srq)
 
        if (atomic_dec_and_test(&srq->refcount))
                complete(&srq->free);
-       wait_for_completion(&srq->free);
+       if (!mlx4_is_barred(dev))
+               wait_for_completion(&srq->free);
 
        mlx4_table_put(dev, &srq_table->table, srq->srqn);
        mlx4_bitmap_free(&srq_table->bitmap, srq->srqn);
index 9a51a6f21078eb194a25b83441b98017dec5cc71..a3cea329310b3836bfd86d002f14b8e0679d3373 100644 (file)
@@ -383,8 +383,7 @@ to_av(
                        &p_ib_ah_attr->grh.traffic_class, &p_ib_ah_attr->grh.flow_label );\r
                err = p_ib_dev->x.find_cached_gid((struct ib_device *)p_ib_dev, \r
                        (union ib_gid   *)p_ib_av_attr->grh.src_gid.raw, &port_num, &gid_index);\r
-               if (err) {\r
-\r
+               if (err) {\r\r
                        HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,\r
                        ("ib_find_cached_gid failed %d (%#x). Using default:  sgid_index = 0\n", err, err));\r
                        gid_index = 0;\r
@@ -435,8 +434,7 @@ int from_av(
                err = p_ib_dev->x.get_cached_gid((struct ib_device *)p_ib_dev, \r
                        p_ib_ah_attr->port_num, p_ib_ah_attr->grh.sgid_index,\r
                        (union ib_gid*)p_ib_av_attr->grh.src_gid.raw );\r
-               if (err) {\r
-\r
+               if (err) {\r\r
                        HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_SHIM ,\r
                        ("ib_get_cached_gid failed %d (%#x). Using default:  sgid_index = 0\n", err, err));\r
                }\r
index 5bfc2dae1208e4ed2a89ffcf222503878e850c65..a67c670a6f66177d0069ebfc780c500c961ca340 100644 (file)
@@ -304,4 +304,14 @@ static inline int mlx4_is_livefish(struct mlx4_dev *dev)
        return dev->flags & MLX4_FLAG_LIVEFISH;
 }
 
+static inline int mlx4_is_barred(struct mlx4_dev *dev)
+{
+       return dev->flags & (MLX4_FLAG_RESET_CLIENT | MLX4_FLAG_RESET_DRIVER);
+}
+
+static inline int mlx4_is_in_reset(struct mlx4_dev *dev)
+{
+       return dev->flags & MLX4_FLAG_RESET_STARTED;
+}
+
 #endif
index cae7adfa4fa69cc024cb7e73fcad4bfffb9e2c51..83729a33ba027b7bba0cf3167e369396ea2e0ea8 100644 (file)
@@ -25,7 +25,6 @@ Notes:
 \r
 #define MTNIC_MAX_PORTS     2\r
 \r
-#define MAX_PORT_SIZE 250000\r
 #define MXE_INTERFACE_VERSION  2\r
 \r
 enum mtnic_state {\r
@@ -35,13 +34,11 @@ enum mtnic_state {
        CARD_DISABLED\r
 };\r
 \r
+struct _MP_PORT;\r
+\r
 typedef struct {\r
     enum mtnic_state     state;\r
-    NDIS_WORK_ITEM  PortStateWorkItem;\r
-    NDIS_WORK_ITEM  ResetWorkItem;\r
     KEVENT          ConfigChangeEvent; \r
-    KTIMER          HeardBeatTimer;   \r
-    LONG            ResetCount;\r
 \r
     // Objects that are needed in order to work with the hw\r
 \r
@@ -59,22 +56,12 @@ struct VipBusIfc
 {\r
     PVOID           Context;\r
     LONG            NoOfConnectedPorts;\r
-    ULONG           ulAllocatePortObjSize;\r
+\r
     NicData_t       NicData;\r
-#ifdef _WIN64   \r
-    UCHAR   pad[0x8];\r
-#else\r
-    UCHAR   pad[0x8];    \r
-#endif    \r
-#ifdef MTNIC\r
-    C_ASSERT(MAX_PORT_SIZE >= sizeof(struct _MP_PORT));\r
-    MP_PORT         ports[MTNIC_MAX_PORTS];\r
-#else\r
-    UCHAR           ports[MAX_PORT_SIZE * MTNIC_MAX_PORTS];\r
-#endif    \r
-};\r
 \r
-C_ASSERT((FIELD_OFFSET(struct VipBusIfc, ports) % 16) == 0);\r
+    struct _MP_PORT *ports[MTNIC_MAX_PORTS];\r
+    \r
+};\r
 \r
 \r
 \r