[MTHCA]bug fixes:
[mirror/winof/.git] / hw / mthca / kernel / mthca_main.c
1 /*
2  * Copyright (c) 2004, 2005 Topspin Communications.  All rights reserved.
3  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
4  * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
5  *
6  * This software is available to you under a choice of one of two
7  * licenses.  You may choose to be licensed under the terms of the GNU
8  * General Public License (GPL) Version 2, available from the file
9  * COPYING in the main directory of this source tree, or the
10  * OpenIB.org BSD license below:
11  *
12  *     Redistribution and use in source and binary forms, with or
13  *     without modification, are permitted provided that the following
14  *     conditions are met:
15  *
16  *      - Redistributions of source code must retain the above
17  *        copyright notice, this list of conditions and the following
18  *        disclaimer.
19  *
20  *      - Redistributions in binary form must reproduce the above
21  *        copyright notice, this list of conditions and the following
22  *        disclaimer in the documentation and/or other materials
23  *        provided with the distribution.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32  * SOFTWARE.
33  *
34  * $Id$
35  */
36
37 #include "mthca_dev.h"
38 #if defined(EVENT_TRACING)
39 #ifdef offsetof
40 #undef offsetof
41 #endif
42 #include "mthca_main.tmh"
43 #endif
44 #include "mthca_config_reg.h"
45 #include "mthca_cmd.h"
46 #include "mthca_profile.h"
47 #include "mthca_memfree.h"
48
49 static const char mthca_version[] =
50         DRV_NAME ": HCA Driver v"
51         DRV_VERSION " (" DRV_RELDATE ")";
52
53 static struct mthca_profile default_profile = {
54         1 << 16,                // num_qp
55         4,                                      // rdb_per_qp
56         0,                              // num_srq
57         1 << 16,                // num_cq
58         1 << 13,                // num_mcg
59         1 << 17,                // num_mpt
60         1 << 20,                // num_mtt
61         1 << 15,                // num_udav (Tavor only)
62         0,                                      // num_uar
63         1 << 18,                // uarc_size (Arbel only)
64         1 << 18,                // fmr_reserved_mtts (Tavor only)
65 };
66
67 /* Types of supported HCA */
68 enum __hca_type {
69         TAVOR,                  /* MT23108                        */
70         ARBEL_COMPAT,           /* MT25208 in Tavor compat mode   */
71         ARBEL_NATIVE,           /* MT25218 with extended features */
72         SINAI,                  /* MT25204 */
73         LIVEFISH                /* a burning device */
74 };
75
76 #define MTHCA_FW_VER(major, minor, subminor) \
77         (((u64) (major) << 32) | ((u64) (minor) << 16) | (u64) (subminor))
78
79 static struct {
80         u64 max_unsupported_fw;
81         u64 min_supported_fw;
82         int is_memfree;
83         int is_pcie;
84 } mthca_hca_table[] = {
85         { MTHCA_FW_VER(3, 3, 2), MTHCA_FW_VER(3, 4, 0), 0, 0 }, /* TAVOR */
86         { MTHCA_FW_VER(4, 7, 0), MTHCA_FW_VER(4, 7, 400), 0, 1 },       /* ARBEL_COMPAT */
87         { MTHCA_FW_VER(5, 1, 0), MTHCA_FW_VER(5, 1, 400), 1, 1 },       /* ARBEL_NATIVE */
88         { MTHCA_FW_VER(1, 0, 800), MTHCA_FW_VER(1, 1, 0), 1, 1 },       /* SINAI */
89         { MTHCA_FW_VER(0, 0, 0), MTHCA_FW_VER(0, 0, 0), 0, 0 }          /* LIVEFISH */
90 };
91
92
93 #define HCA(v, d, t) \
94         { PCI_VENDOR_ID_##v,    PCI_DEVICE_ID_MELLANOX_##d, t }
95
96 static struct pci_device_id {
97         unsigned                vendor;
98         unsigned                device;
99         enum __hca_type driver_data;
100 } mthca_pci_table[] = {
101         HCA(MELLANOX, TAVOR,        TAVOR),
102         HCA(MELLANOX, ARBEL_COMPAT, ARBEL_COMPAT),
103         HCA(MELLANOX, ARBEL,        ARBEL_NATIVE),
104         HCA(MELLANOX, SINAI_OLD,    SINAI),
105         HCA(MELLANOX, SINAI,        SINAI),
106         HCA(TOPSPIN,  TAVOR,        TAVOR),
107         HCA(TOPSPIN,  ARBEL_COMPAT, TAVOR),
108         HCA(TOPSPIN,  ARBEL,        ARBEL_NATIVE),
109         HCA(TOPSPIN,  SINAI_OLD,    SINAI),
110         HCA(TOPSPIN,  SINAI,        SINAI),
111         // live fishes
112         HCA(MELLANOX, TAVOR_BD, LIVEFISH),
113         HCA(MELLANOX, ARBEL_BD,         LIVEFISH),
114         HCA(MELLANOX, SINAI_OLD_BD,     LIVEFISH),
115         HCA(MELLANOX, SINAI_BD,         LIVEFISH),
116         HCA(TOPSPIN, TAVOR_BD,          LIVEFISH),
117         HCA(TOPSPIN, ARBEL_BD,          LIVEFISH),
118         HCA(TOPSPIN, SINAI_OLD_BD,      LIVEFISH),
119         HCA(TOPSPIN, SINAI_BD,          LIVEFISH),
120 };
121 #define MTHCA_PCI_TABLE_SIZE (sizeof(mthca_pci_table)/sizeof(struct pci_device_id))
122
123 // wrapper to driver's hca_tune_pci
124 static NTSTATUS mthca_tune_pci(struct mthca_dev *mdev)
125 {
126         PDEVICE_OBJECT pdo = mdev->ext->cl_ext.p_self_do;
127         return hca_tune_pci(pdo, &mdev->uplink_info);
128 }
129
130 int mthca_get_dev_info(struct mthca_dev *mdev, __be64 *node_guid, u32 *hw_id)
131 {
132         struct ib_device_attr props;
133         struct ib_device *ib_dev = &mdev->ib_dev;
134         int err = (ib_dev->query_device )(ib_dev, &props );
135
136         if (err) {
137                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("can't get guid - mthca_query_port() failed (%08X)\n", err ));
138                 return err;
139         }
140
141         //TODO: do we need to convert GUID to LE by cl_ntoh64(x) ?
142         *node_guid = ib_dev->node_guid;
143         *hw_id = props.hw_ver;
144         return 0;
145 }
146
147 static struct pci_device_id * mthca_find_pci_dev(unsigned ven_id, unsigned dev_id)
148 {
149         struct pci_device_id *p_id = mthca_pci_table;
150         int i;
151
152         // find p_id (appropriate line in mthca_pci_table)
153         for (i = 0; i < MTHCA_PCI_TABLE_SIZE; ++i, ++p_id) {
154                 if (p_id->device == dev_id && p_id->vendor ==  ven_id)
155                         return p_id;
156         }
157         return NULL;
158 }
159
160
161 static int  mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim *dev_lim)
162 {
163         int err;
164         u8 status;
165
166         err = mthca_QUERY_DEV_LIM(mdev, dev_lim, &status);
167         if (err) {
168                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("QUERY_DEV_LIM command failed, aborting.\n"));
169                 return err;
170         }
171         if (status) {
172                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,("QUERY_DEV_LIM returned status 0x%02x, "
173                           "aborting.\n", status));
174                 return -EINVAL;
175         }
176         if (dev_lim->min_page_sz > PAGE_SIZE) {
177                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,("HCA minimum page size of %d bigger than "
178                           "kernel PAGE_SIZE of %ld, aborting.\n",
179                           dev_lim->min_page_sz, PAGE_SIZE));
180                 return -ENODEV;
181         }
182         if (dev_lim->num_ports > MTHCA_MAX_PORTS) {
183                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,("HCA has %d ports, but we only support %d, "
184                           "aborting.\n",
185                           dev_lim->num_ports, MTHCA_MAX_PORTS));
186                 return -ENODEV;
187         }
188
189         if (dev_lim->uar_size > (int)pci_resource_len(mdev, HCA_BAR_TYPE_UAR)) {
190                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW , ("HCA reported UAR size of 0x%x bigger than "
191                           "Bar%d size of 0x%lx, aborting.\n",
192                           dev_lim->uar_size, HCA_BAR_TYPE_UAR, 
193                           (unsigned long)pci_resource_len(mdev, HCA_BAR_TYPE_UAR)));
194                 return -ENODEV;
195         }
196         
197
198         mdev->limits.num_ports          = dev_lim->num_ports;
199         mdev->limits.vl_cap             = dev_lim->max_vl;
200         mdev->limits.mtu_cap            = dev_lim->max_mtu;
201         mdev->limits.gid_table_len      = dev_lim->max_gids;
202         mdev->limits.pkey_table_len     = dev_lim->max_pkeys;
203         mdev->limits.local_ca_ack_delay = dev_lim->local_ca_ack_delay;
204         mdev->limits.max_sg             = dev_lim->max_sg;
205         mdev->limits.max_wqes           = dev_lim->max_qp_sz;
206         mdev->limits.max_qp_init_rdma   = dev_lim->max_requester_per_qp;
207         mdev->limits.reserved_qps       = dev_lim->reserved_qps;
208         mdev->limits.max_srq_wqes       = dev_lim->max_srq_sz;
209         mdev->limits.reserved_srqs      = dev_lim->reserved_srqs;
210         mdev->limits.reserved_eecs      = dev_lim->reserved_eecs;
211         mdev->limits.max_desc_sz      = dev_lim->max_desc_sz;
212         mdev->limits.max_srq_sge        = mthca_max_srq_sge(mdev);
213         /*
214          * Subtract 1 from the limit because we need to allocate a
215          * spare CQE so the HCA HW can tell the difference between an
216          * empty CQ and a full CQ.
217          */
218         mdev->limits.max_cqes           = dev_lim->max_cq_sz - 1;
219         mdev->limits.reserved_cqs       = dev_lim->reserved_cqs;
220         mdev->limits.reserved_eqs       = dev_lim->reserved_eqs;
221         mdev->limits.reserved_mtts      = dev_lim->reserved_mtts;
222         mdev->limits.reserved_mrws      = dev_lim->reserved_mrws;
223         mdev->limits.reserved_uars      = dev_lim->reserved_uars;
224         mdev->limits.reserved_pds       = dev_lim->reserved_pds;
225         mdev->limits.port_width_cap     = (u8)dev_lim->max_port_width;
226         mdev->limits.page_size_cap      = !(u32)(dev_lim->min_page_sz - 1);
227         mdev->limits.flags                              = dev_lim->flags;
228
229         /* IB_DEVICE_RESIZE_MAX_WR not supported by driver.
230            May be doable since hardware supports it for SRQ.
231
232            IB_DEVICE_N_NOTIFY_CQ is supported by hardware but not by driver.
233
234            IB_DEVICE_SRQ_RESIZE is supported by hardware but SRQ is not
235            supported by driver. */
236         mdev->device_cap_flags = IB_DEVICE_CHANGE_PHY_PORT |
237                 IB_DEVICE_PORT_ACTIVE_EVENT |
238                 IB_DEVICE_SYS_IMAGE_GUID |
239                 IB_DEVICE_RC_RNR_NAK_GEN;
240
241         if (dev_lim->flags & DEV_LIM_FLAG_BAD_PKEY_CNTR)
242                 mdev->device_cap_flags |= IB_DEVICE_BAD_PKEY_CNTR;
243
244         if (dev_lim->flags & DEV_LIM_FLAG_BAD_QKEY_CNTR)
245                 mdev->device_cap_flags |= IB_DEVICE_BAD_QKEY_CNTR;
246
247         if (dev_lim->flags & DEV_LIM_FLAG_RAW_MULTI)
248                 mdev->device_cap_flags |= IB_DEVICE_RAW_MULTI;
249
250         if (dev_lim->flags & DEV_LIM_FLAG_AUTO_PATH_MIG)
251                 mdev->device_cap_flags |= IB_DEVICE_AUTO_PATH_MIG;
252
253         if (dev_lim->flags & DEV_LIM_FLAG_UD_AV_PORT_ENFORCE)
254                 mdev->device_cap_flags |= IB_DEVICE_UD_AV_PORT_ENFORCE;
255
256         if (dev_lim->flags & DEV_LIM_FLAG_SRQ)
257                 mdev->mthca_flags |= MTHCA_FLAG_SRQ;
258
259         return 0;
260 }
261
262 static int  mthca_init_tavor(struct mthca_dev *mdev)
263 {
264         u8 status;
265         int err;
266         struct mthca_dev_lim        dev_lim;
267         struct mthca_profile        profile;
268         struct mthca_init_hca_param init_hca;
269
270         err = mthca_SYS_EN(mdev, &status);
271         if (err) {
272                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,("SYS_EN command failed, aborting.\n"));
273                 return err;
274         }
275         if (status) {
276                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,("SYS_EN returned status 0x%02x, "
277                           "aborting.\n", status));
278                 return -EINVAL;
279         }
280
281         err = mthca_QUERY_FW(mdev, &status);
282         if (err) {
283                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("QUERY_FW command failed, aborting.\n"));
284                 goto err_disable;
285         }
286         if (status) {
287                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,("QUERY_FW returned status 0x%02x, "
288                           "aborting.\n", status));
289                 err = -EINVAL;
290                 goto err_disable;
291         }
292         err = mthca_QUERY_DDR(mdev, &status);
293         if (err) {
294                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("QUERY_DDR command failed, aborting.\n"));
295                 goto err_disable;
296         }
297         if (status) {
298                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,( "QUERY_DDR returned status 0x%02x, "
299                           "aborting.\n", status));
300                 err = -EINVAL;
301                 goto err_disable;
302         }
303
304         err = mthca_dev_lim(mdev, &dev_lim);
305         if (err) {
306                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,( "QUERY_DEV_LIM command failed, aborting.\n"));
307                 goto err_disable;
308         }
309
310         profile = default_profile;
311         profile.num_uar   = dev_lim.uar_size / PAGE_SIZE;
312         profile.uarc_size = 0;
313         if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
314                 profile.num_srq = dev_lim.max_srqs;
315
316         err = (int)mthca_make_profile(mdev, &profile, &dev_lim, &init_hca);
317         if (err < 0)
318                 goto err_disable;
319
320         err = (int)mthca_INIT_HCA(mdev, &init_hca, &status);
321         if (err) {
322                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("INIT_HCA command failed, aborting.\n"));
323                 goto err_disable;
324         }
325         if (status) {
326                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,("INIT_HCA returned status 0x%02x, "
327                           "aborting.\n", status));
328                 err = -EINVAL;
329                 goto err_disable;
330         }
331
332         return 0;
333
334 err_disable:
335         mthca_SYS_DIS(mdev, &status);
336
337         return err;
338 }
339
340 static int  mthca_load_fw(struct mthca_dev *mdev)
341 {
342         u8 status;
343         int err;
344
345         /* FIXME: use HCA-attached memory for FW if present */
346
347         mdev->fw.arbel.fw_icm =
348                 mthca_alloc_icm(mdev, mdev->fw.arbel.fw_pages,
349                                 GFP_HIGHUSER | __GFP_NOWARN);
350         if (!mdev->fw.arbel.fw_icm) {
351                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("Couldn't allocate FW area, aborting.\n"));
352                 return -ENOMEM;
353         }
354
355         err = mthca_MAP_FA(mdev, mdev->fw.arbel.fw_icm, &status);
356         if (err) {
357                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("MAP_FA command failed, aborting.\n"));
358                 goto err_free;
359         }
360         if (status) {
361                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("MAP_FA returned status 0x%02x, aborting.\n", status));
362                 err = -EINVAL;
363                 goto err_free;
364         }
365         err = mthca_RUN_FW(mdev, &status);
366         if (err) {
367                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("RUN_FW command failed, aborting.\n"));
368                 goto err_unmap_fa;
369         }
370         if (status) {
371                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("RUN_FW returned status 0x%02x, aborting.\n", status));
372                 err = -EINVAL;
373                 goto err_unmap_fa;
374         }
375
376         return 0;
377
378 err_unmap_fa:
379         mthca_UNMAP_FA(mdev, &status);
380
381 err_free:
382         mthca_free_icm(mdev, mdev->fw.arbel.fw_icm);
383         return err;
384 }
385
386 static int  mthca_init_icm(struct mthca_dev *mdev,
387                                     struct mthca_dev_lim *dev_lim,
388                                     struct mthca_init_hca_param *init_hca,
389                                     u64 icm_size)
390 {
391         u64 aux_pages;
392         u8 status;
393         int err;
394
395         err = mthca_SET_ICM_SIZE(mdev, icm_size, &aux_pages, &status);
396         if (err) {
397                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("SET_ICM_SIZE command failed, aborting.\n"));
398                 return err;
399         }
400         if (status) {
401                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,("SET_ICM_SIZE returned status 0x%02x, "
402                           "aborting.\n", status));
403                 return -EINVAL;
404         }
405
406         HCA_PRINT(TRACE_LEVEL_INFORMATION ,HCA_DBG_LOW , ("%I64d KB of HCA context requires %I64d KB aux memory.\n",
407                   (u64) icm_size >> 10,
408                   (u64) aux_pages << 2));
409
410         mdev->fw.arbel.aux_icm = mthca_alloc_icm(mdev, (int)aux_pages,
411                                                  GFP_HIGHUSER | __GFP_NOWARN);
412         if (!mdev->fw.arbel.aux_icm) {
413                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("Couldn't allocate aux memory, aborting.\n"));
414                 return -ENOMEM;
415         }
416
417         err = mthca_MAP_ICM_AUX(mdev, mdev->fw.arbel.aux_icm, &status);
418         if (err) {
419                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("MAP_ICM_AUX command failed, aborting.\n"));
420                 goto err_free_aux;
421         }
422         if (status) {
423                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("MAP_ICM_AUX returned status 0x%02x, aborting.\n", status));
424                 err = -EINVAL;
425                 goto err_free_aux;
426         }
427
428         err = mthca_map_eq_icm(mdev, init_hca->eqc_base);
429         if (err) {
430                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("Failed to map EQ context memory, aborting.\n"));
431                 goto err_unmap_aux;
432         }
433
434         mdev->mr_table.mtt_table = mthca_alloc_icm_table(mdev, init_hca->mtt_base,
435                                                          MTHCA_MTT_SEG_SIZE,
436                                                          mdev->limits.num_mtt_segs,
437                                                          mdev->limits.reserved_mtts, 1);
438         if (!mdev->mr_table.mtt_table) {
439                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("Failed to map MTT context memory, aborting.\n"));
440                 err = -ENOMEM;
441                 goto err_unmap_eq;
442         }
443
444         mdev->mr_table.mpt_table = mthca_alloc_icm_table(mdev, init_hca->mpt_base,
445                                                          dev_lim->mpt_entry_sz,
446                                                          mdev->limits.num_mpts,
447                                                          mdev->limits.reserved_mrws, 1);
448         if (!mdev->mr_table.mpt_table) {
449                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("Failed to map MPT context memory, aborting.\n"));
450                 err = -ENOMEM;
451                 goto err_unmap_mtt;
452         }
453
454         mdev->qp_table.qp_table = mthca_alloc_icm_table(mdev, init_hca->qpc_base,
455                                                         dev_lim->qpc_entry_sz,
456                                                         mdev->limits.num_qps,
457                                                         mdev->limits.reserved_qps, 0);
458         if (!mdev->qp_table.qp_table) {
459                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("Failed to map QP context memory, aborting.\n"));
460                 err = -ENOMEM;
461                 goto err_unmap_mpt;
462         }
463
464         mdev->qp_table.eqp_table = mthca_alloc_icm_table(mdev, init_hca->eqpc_base,
465                                                          dev_lim->eqpc_entry_sz,
466                                                          mdev->limits.num_qps,
467                                                          mdev->limits.reserved_qps, 0);
468         if (!mdev->qp_table.eqp_table) {
469                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("Failed to map EQP context memory, aborting.\n"));
470                 err = -ENOMEM;
471                 goto err_unmap_qp;
472         }
473
474         mdev->qp_table.rdb_table = mthca_alloc_icm_table(mdev, init_hca->rdb_base,
475                                                          MTHCA_RDB_ENTRY_SIZE,
476                                                          mdev->limits.num_qps <<
477                                                          mdev->qp_table.rdb_shift,
478                                                          0, 0);
479         if (!mdev->qp_table.rdb_table) {
480                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("Failed to map RDB context memory, aborting\n"));
481                 err = -ENOMEM;
482                 goto err_unmap_eqp;
483         }
484
485        mdev->cq_table.table = mthca_alloc_icm_table(mdev, init_hca->cqc_base,
486                                                     dev_lim->cqc_entry_sz,
487                                                     mdev->limits.num_cqs,
488                                                     mdev->limits.reserved_cqs, 0);
489         if (!mdev->cq_table.table) {
490                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("Failed to map CQ context memory, aborting.\n"));
491                 err = -ENOMEM;
492                 goto err_unmap_rdb;
493         }
494
495         if (mdev->mthca_flags & MTHCA_FLAG_SRQ) {
496                 mdev->srq_table.table =
497                         mthca_alloc_icm_table(mdev, init_hca->srqc_base,
498                                               dev_lim->srq_entry_sz,
499                                               mdev->limits.num_srqs,
500                                               mdev->limits.reserved_srqs, 0);
501                 if (!mdev->srq_table.table) {
502                         HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,("Failed to map SRQ context memory, "
503                                   "aborting.\n"));
504                         err = -ENOMEM;
505                         goto err_unmap_cq;
506                 }
507         }
508
509         /*
510          * It's not strictly required, but for simplicity just map the
511          * whole multicast group table now.  The table isn't very big
512          * and it's a lot easier than trying to track ref counts.
513          */
514         mdev->mcg_table.table = mthca_alloc_icm_table(mdev, init_hca->mc_base,
515                                                       MTHCA_MGM_ENTRY_SIZE,
516                                                       mdev->limits.num_mgms +
517                                                       mdev->limits.num_amgms,
518                                                       mdev->limits.num_mgms +
519                                                       mdev->limits.num_amgms,
520                                                       0);
521         if (!mdev->mcg_table.table) {
522                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("Failed to map MCG context memory, aborting.\n"));
523                 err = -ENOMEM;
524                 goto err_unmap_srq;
525         }
526
527         return 0;
528
529 err_unmap_srq:
530         if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
531                 mthca_free_icm_table(mdev, mdev->srq_table.table);
532
533 err_unmap_cq:
534         mthca_free_icm_table(mdev, mdev->cq_table.table);
535
536 err_unmap_rdb:
537         mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
538
539 err_unmap_eqp:
540         mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
541
542 err_unmap_qp:
543         mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
544
545 err_unmap_mpt:
546         mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
547
548 err_unmap_mtt:
549         mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
550
551 err_unmap_eq:
552         mthca_unmap_eq_icm(mdev);
553
554 err_unmap_aux:
555         mthca_UNMAP_ICM_AUX(mdev, &status);
556
557 err_free_aux:
558         mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);
559
560         return err;
561 }
562
563 static int  mthca_init_arbel(struct mthca_dev *mdev)
564 {
565         struct mthca_dev_lim        dev_lim;
566         struct mthca_profile        profile;
567         struct mthca_init_hca_param init_hca;
568         u64 icm_size;
569         u8 status;
570         int err;
571
572         err = mthca_QUERY_FW(mdev, &status);
573         if (err) {
574                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("QUERY_FW command failed, aborting.\n"));
575                 return err;
576         }
577         if (status) {
578                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,("QUERY_FW returned status 0x%02x, "
579                           "aborting.\n", status));
580                 return -EINVAL;
581         }
582
583         err = mthca_ENABLE_LAM(mdev, &status);
584         if (err) {
585                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("ENABLE_LAM command failed, aborting.\n"));
586                 return err;
587         }
588         if (status == MTHCA_CMD_STAT_LAM_NOT_PRE) {
589                 HCA_PRINT(TRACE_LEVEL_INFORMATION   ,HCA_DBG_LOW   ,("No HCA-attached memory (running in MemFree mode)\n"));
590                 mdev->mthca_flags |= MTHCA_FLAG_NO_LAM;
591         } else if (status) {
592                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,("ENABLE_LAM returned status 0x%02x, "
593                           "aborting.\n", status));
594                 return -EINVAL;
595         }
596
597         err = mthca_load_fw(mdev);
598         if (err) {
599                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("Failed to start FW, aborting.\n"));
600                 goto err_disable;
601         }
602
603         err = mthca_dev_lim(mdev, &dev_lim);
604         if (err) {
605                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("QUERY_DEV_LIM command failed, aborting.\n"));
606                 goto err_stop_fw;
607         }
608
609         profile = default_profile;
610         profile.num_uar  = dev_lim.uar_size / PAGE_SIZE;
611         profile.num_udav = 0;
612         if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
613                 profile.num_srq = dev_lim.max_srqs;
614
615         RtlZeroMemory( &init_hca, sizeof(init_hca));
616         icm_size = mthca_make_profile(mdev, &profile, &dev_lim, &init_hca);
617         if ((int) icm_size < 0) {
618                 err = (int)icm_size;
619                 goto err_stop_fw;
620         }
621
622         err = mthca_init_icm(mdev, &dev_lim, &init_hca, icm_size);
623         if (err)
624                 goto err_stop_fw;
625
626         err = mthca_INIT_HCA(mdev, &init_hca, &status);
627         if (err) {
628                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("INIT_HCA command failed, aborting.\n"));
629                 goto err_free_icm;
630         }
631         if (status) {
632                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,("INIT_HCA returned status 0x%02x, "
633                           "aborting.\n", status));
634                 err = -EINVAL;
635                 goto err_free_icm;
636         }
637
638         return 0;
639
640 err_free_icm:
641         if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
642                 mthca_free_icm_table(mdev, mdev->srq_table.table);
643         mthca_free_icm_table(mdev, mdev->cq_table.table);
644         mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
645         mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
646         mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
647         mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
648         mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
649         mthca_unmap_eq_icm(mdev);
650
651         mthca_UNMAP_ICM_AUX(mdev, &status);
652         mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);
653
654 err_stop_fw:
655         mthca_UNMAP_FA(mdev, &status);
656         mthca_free_icm(mdev, mdev->fw.arbel.fw_icm);
657
658 err_disable:
659         if (!(mdev->mthca_flags & MTHCA_FLAG_NO_LAM))
660                 mthca_DISABLE_LAM(mdev, &status);
661
662         return err;
663 }
664
665 static void mthca_close_hca(struct mthca_dev *mdev)
666 {
667         u8 status;
668
669         mthca_CLOSE_HCA(mdev, 0, &status);
670
671         if (mthca_is_memfree(mdev)) {
672                 if (mdev->mthca_flags & MTHCA_FLAG_SRQ)
673                         mthca_free_icm_table(mdev, mdev->srq_table.table);
674                 mthca_free_icm_table(mdev, mdev->cq_table.table);
675                 mthca_free_icm_table(mdev, mdev->qp_table.rdb_table);
676                 mthca_free_icm_table(mdev, mdev->qp_table.eqp_table);
677                 mthca_free_icm_table(mdev, mdev->qp_table.qp_table);
678                 mthca_free_icm_table(mdev, mdev->mr_table.mpt_table);
679                 mthca_free_icm_table(mdev, mdev->mr_table.mtt_table);
680                 mthca_free_icm_table(mdev, mdev->mcg_table.table);
681                 mthca_unmap_eq_icm(mdev);
682
683                 mthca_UNMAP_ICM_AUX(mdev, &status);
684                 mthca_free_icm(mdev, mdev->fw.arbel.aux_icm);
685
686                 mthca_UNMAP_FA(mdev, &status);
687                 mthca_free_icm(mdev, mdev->fw.arbel.fw_icm);
688
689                 if (!(mdev->mthca_flags & MTHCA_FLAG_NO_LAM))
690                         mthca_DISABLE_LAM(mdev, &status);
691         } else
692                 mthca_SYS_DIS(mdev, &status);
693 }
694
695 static int  mthca_init_hca(struct mthca_dev *mdev)
696 {
697         u8 status;
698         int err;
699         struct mthca_adapter adapter;
700
701         if (mthca_is_memfree(mdev))
702                 err = mthca_init_arbel(mdev);
703         else
704                 err = mthca_init_tavor(mdev);
705
706         if (err)
707                 return err;
708
709         err = mthca_QUERY_ADAPTER(mdev, &adapter, &status);
710         if (err) {
711                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("QUERY_ADAPTER command failed, aborting.\n"));
712                 goto err_close;
713         }
714         if (status) {
715                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,("QUERY_ADAPTER returned status 0x%02x, "
716                           "aborting.\n", status));
717                 err = -EINVAL;
718                 goto err_close;
719         }
720
721         mdev->eq_table.inta_pin = adapter.inta_pin;
722         mdev->rev_id            = adapter.revision_id;
723         memcpy(mdev->board_id, adapter.board_id, sizeof mdev->board_id);
724
725         return 0;
726
727 err_close:
728         mthca_close_hca(mdev);
729         return err;
730 }
731
732 static int  mthca_setup_hca(struct mthca_dev *mdev)
733 {
734         int err;
735         u8 status;
736
737         MTHCA_INIT_DOORBELL_LOCK(&mdev->doorbell_lock);
738
739         err = mthca_init_uar_table(mdev);
740         if (err) {
741                 HCA_PRINT_EV(TRACE_LEVEL_ERROR,HCA_DBG_LOW,("Failed to initialize "
742                           "user access region table, aborting.\n"));
743                 return err;
744         }
745
746         err = mthca_uar_alloc(mdev, &mdev->driver_uar);
747         if (err) {
748                 HCA_PRINT_EV(TRACE_LEVEL_ERROR,HCA_DBG_LOW,("Failed to allocate driver access region, "
749                           "aborting.\n"));
750                 goto err_uar_table_free;
751         }
752
753         mdev->kar = ioremap((io_addr_t)mdev->driver_uar.pfn << PAGE_SHIFT, PAGE_SIZE,&mdev->kar_size);
754         if (!mdev->kar) {
755                 HCA_PRINT_EV(TRACE_LEVEL_ERROR,HCA_DBG_LOW,("Couldn't map kernel access region, "
756                           "aborting.\n"));
757                 err = -ENOMEM;
758                 goto err_uar_free;
759         }
760
761         err = mthca_init_pd_table(mdev);
762         if (err) {
763                 HCA_PRINT_EV(TRACE_LEVEL_ERROR,HCA_DBG_LOW,("Failed to initialize "
764                           "protection domain table, aborting.\n"));
765                 goto err_kar_unmap;
766         }
767
768         err = mthca_init_mr_table(mdev);
769         if (err) {
770                 HCA_PRINT_EV(TRACE_LEVEL_ERROR,HCA_DBG_LOW,("Failed to initialize "
771                           "memory region table, aborting.\n"));
772                 goto err_pd_table_free;
773         }
774
775         err = mthca_pd_alloc(mdev, 1, &mdev->driver_pd);
776         if (err) {
777                 HCA_PRINT_EV(TRACE_LEVEL_ERROR,HCA_DBG_LOW,("Failed to create driver PD, "
778                           "aborting.\n"));
779                 goto err_mr_table_free;
780         }
781
782         err = mthca_init_eq_table(mdev);
783         if (err) {
784                 HCA_PRINT_EV(TRACE_LEVEL_ERROR,HCA_DBG_LOW, ("Failed to initialize "
785                           "event queue table, aborting.\n"));
786                 goto err_pd_free;
787         }
788
789         err = mthca_cmd_use_events(mdev);
790         if (err) {
791                 HCA_PRINT_EV(TRACE_LEVEL_ERROR,HCA_DBG_LOW,("Failed to switch to event-driven "
792                           "firmware commands, aborting.\n"));
793                 goto err_eq_table_free;
794         }
795
796         err = mthca_NOP(mdev, &status);
797         if (err || status) {
798                 HCA_PRINT_EV(TRACE_LEVEL_ERROR  ,HCA_DBG_LOW  ,("NOP command failed to generate interrupt, aborting.\n"));
799                 if (mdev->mthca_flags & (MTHCA_FLAG_MSI | MTHCA_FLAG_MSI_X)){
800                         HCA_PRINT_EV(TRACE_LEVEL_ERROR  ,HCA_DBG_LOW  ,("Try again with MSI/MSI-X disabled.\n"));
801                 }else{
802                         HCA_PRINT_EV(TRACE_LEVEL_ERROR  ,HCA_DBG_LOW  ,("BIOS or ACPI interrupt routing problem?\n"));
803                 }
804
805                 goto err_cmd_poll;
806         }
807
808         HCA_PRINT(TRACE_LEVEL_VERBOSE  ,HCA_DBG_LOW  ,("NOP command IRQ test passed\n"));
809
810         err = mthca_init_cq_table(mdev);
811         if (err) {
812                 HCA_PRINT_EV(TRACE_LEVEL_ERROR,HCA_DBG_LOW,("Failed to initialize "
813                           "completion queue table, aborting.\n"));
814                 goto err_cmd_poll;
815         }
816
817         err = mthca_init_srq_table(mdev);
818         if (err) {
819                 HCA_PRINT_EV(TRACE_LEVEL_ERROR,HCA_DBG_LOW,("Failed to initialize "
820                           "shared receive queue table, aborting.\n"));
821                 goto err_cq_table_free;
822         }
823
824         err = mthca_init_qp_table(mdev);
825         if (err) {
826                 HCA_PRINT_EV(TRACE_LEVEL_ERROR,HCA_DBG_LOW, ("Failed to initialize "
827                           "queue pair table, aborting.\n"));
828                 goto err_srq_table_free;
829         }
830
831         err = mthca_init_av_table(mdev);
832         if (err) {
833                 HCA_PRINT_EV(TRACE_LEVEL_ERROR,HCA_DBG_LOW,("Failed to initialize "
834                           "address vector table, aborting.\n"));
835                 goto err_qp_table_free;
836         }
837
838         err = mthca_init_mcg_table(mdev);
839         if (err) {
840                 HCA_PRINT_EV(TRACE_LEVEL_ERROR,HCA_DBG_LOW,("Failed to initialize "
841                           "multicast group table, aborting.\n"));
842                 goto err_av_table_free;
843         }
844
845         return 0;
846
847 err_av_table_free:
848         mthca_cleanup_av_table(mdev);
849
850 err_qp_table_free:
851         mthca_cleanup_qp_table(mdev);
852
853 err_srq_table_free:
854         mthca_cleanup_srq_table(mdev);
855
856 err_cq_table_free:
857         mthca_cleanup_cq_table(mdev);
858
859 err_cmd_poll:
860         mthca_cmd_use_polling(mdev);
861
862 err_eq_table_free:
863         mthca_cleanup_eq_table(mdev);
864
865 err_pd_free:
866         mthca_pd_free(mdev, &mdev->driver_pd);
867
868 err_mr_table_free:
869         mthca_cleanup_mr_table(mdev);
870
871 err_pd_table_free:
872         mthca_cleanup_pd_table(mdev);
873
874 err_kar_unmap:
875         iounmap(mdev->kar, mdev->kar_size);
876
877 err_uar_free:
878         mthca_uar_free(mdev, &mdev->driver_uar);
879
880 err_uar_table_free:
881         mthca_cleanup_uar_table(mdev);
882         return err;
883 }
884
885
886 static int      mthca_check_fw(struct mthca_dev *mdev, struct pci_device_id *p_id)
887 {
888         int err = 0;
889         
890         if (mdev->fw_ver < mthca_hca_table[p_id->driver_data].max_unsupported_fw) {
891                 HCA_PRINT_EV(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,("HCA FW version %d.%d.%d is not supported. Use %d.%d.%d or higher.\n",
892                            (int) (mdev->fw_ver >> 32), (int) (mdev->fw_ver >> 16) & 0xffff,
893                            (int) (mdev->fw_ver & 0xffff),
894                            (int) (mthca_hca_table[p_id->driver_data].min_supported_fw >> 32),
895                            (int) (mthca_hca_table[p_id->driver_data].min_supported_fw >> 16) & 0xffff,
896                            (int) (mthca_hca_table[p_id->driver_data].min_supported_fw & 0xffff)));
897                 err = -EINVAL;
898         }
899         else 
900         if (mdev->fw_ver < mthca_hca_table[p_id->driver_data].min_supported_fw) {
901                 HCA_PRINT_EV(TRACE_LEVEL_WARNING ,HCA_DBG_LOW ,
902                         ("The HCA FW version is %d.%d.%d, which is not the latest one. \n"
903                         "If you meet any issues with the HCA please first try to upgrade the FW to version %d.%d.%d or higher.\n",
904                                  (int) (mdev->fw_ver >> 32), (int) (mdev->fw_ver >> 16) & 0xffff,
905                                  (int) (mdev->fw_ver & 0xffff),
906                                  (int) (mthca_hca_table[p_id->driver_data].min_supported_fw >> 32),
907                                  (int) (mthca_hca_table[p_id->driver_data].min_supported_fw >> 16) & 0xffff,
908                                  (int) (mthca_hca_table[p_id->driver_data].min_supported_fw & 0xffff)));
909         }
910         else {
911                 HCA_PRINT(TRACE_LEVEL_INFORMATION ,HCA_DBG_LOW ,("Current HCA FW version is %d.%d.%d. \n",
912                                  (int) (mdev->fw_ver >> 32), (int) (mdev->fw_ver >> 16) & 0xffff,
913                                  (int) (mdev->fw_ver & 0xffff)));
914         }
915
916         return err;
917 }
918
919 NTSTATUS mthca_init_one(hca_dev_ext_t *ext)
920 {
921         static int mthca_version_printed = 0;
922         int err;
923         NTSTATUS status;
924         struct mthca_dev *mdev;
925         struct pci_device_id *p_id;
926
927         /* print version */
928         if (!mthca_version_printed) {
929                 HCA_PRINT(TRACE_LEVEL_INFORMATION ,HCA_DBG_LOW ,("%s\n", mthca_version));
930                 ++mthca_version_printed;
931         }
932
933         /* find the type of device */
934 find_pci_dev:   
935         p_id = mthca_find_pci_dev(
936                 (unsigned)ext->hcaConfig.VendorID,
937                 (unsigned)ext->hcaConfig.DeviceID);
938         if (p_id == NULL) {
939                 status = STATUS_NO_SUCH_DEVICE;
940                 goto end;
941         }
942
943         /* allocate mdev structure */
944         mdev = kzalloc(sizeof *mdev, GFP_KERNEL);
945         if (!mdev) {
946                 // can't use HCA_PRINT_EV here !
947                 HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_LOW ,("Device struct alloc failed, "
948                         "aborting.\n"));
949                 status = STATUS_INSUFFICIENT_RESOURCES;
950                 goto end;
951         }
952          
953         /* set some fields */
954         mdev->ext = ext;                /* pointer to DEVICE OBJECT extension */
955         mdev->hca_type = p_id->driver_data;
956         mdev->ib_dev.mdev = mdev;
957         if (p_id->driver_data == LIVEFISH)
958                 mdev->mthca_flags |= MTHCA_FLAG_LIVEFISH;
959         if (mthca_is_livefish(mdev))
960                 goto done;
961         if (ext->hca_hidden)
962                 mdev->mthca_flags |= MTHCA_FLAG_DDR_HIDDEN;
963         if (mthca_hca_table[p_id->driver_data].is_memfree)
964                 mdev->mthca_flags |= MTHCA_FLAG_MEMFREE;
965         if (mthca_hca_table[p_id->driver_data].is_pcie)
966                 mdev->mthca_flags |= MTHCA_FLAG_PCIE;
967         
968 //TODO: after we have a FW, capable of reset, 
969 // write a routine, that only presses the button
970
971         /*
972          * Now reset the HCA before we touch the PCI capabilities or
973          * attempt a firmware command, since a boot ROM may have left
974          * the HCA in an undefined state.
975          */
976         status = hca_reset( mdev->ext->cl_ext.p_self_do, p_id->driver_data == TAVOR );
977         if ( !NT_SUCCESS( status ) ) {
978                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("Failed to reset HCA, aborting.\n"));
979                 goto err_free_dev;
980         }
981
982         if (mthca_cmd_init(mdev)) {
983                 HCA_PRINT_EV(TRACE_LEVEL_ERROR   ,HCA_DBG_LOW   ,("Failed to init command interface, aborting.\n"));
984                 status = STATUS_DEVICE_DATA_ERROR;
985                 goto err_free_dev;
986         }
987
988         status = mthca_tune_pci(mdev);
989         if ( !NT_SUCCESS( status ) ) {
990                 goto err_cmd;
991         }
992
993         err = mthca_init_hca(mdev); 
994         if (err) {
995                 status = STATUS_UNSUCCESSFUL;
996                 goto err_cmd;
997         }
998
999         err = mthca_check_fw(mdev, p_id);
1000         if (err) {
1001                 status = STATUS_UNSUCCESSFUL;
1002                 goto err_close;
1003         }
1004
1005         err = mthca_setup_hca(mdev);
1006         if (err) {
1007                 status = STATUS_UNSUCCESSFUL;
1008                 goto err_close;
1009         }
1010
1011         err = mthca_register_device(mdev);
1012         if (err) {
1013                 status = STATUS_UNSUCCESSFUL;
1014                 goto err_cleanup;
1015         }
1016
1017         done:
1018         ext->hca.mdev = mdev;
1019         mdev->state = MTHCA_DEV_INITIALIZED;
1020         return 0;
1021
1022 err_cleanup:
1023         mthca_cleanup_mcg_table(mdev);
1024         mthca_cleanup_av_table(mdev);
1025         mthca_cleanup_qp_table(mdev);
1026         mthca_cleanup_srq_table(mdev);
1027         mthca_cleanup_cq_table(mdev);
1028         mthca_cmd_use_polling(mdev);
1029         mthca_cleanup_eq_table(mdev);
1030
1031         mthca_pd_free(mdev, &mdev->driver_pd);
1032
1033         mthca_cleanup_mr_table(mdev);
1034         mthca_cleanup_pd_table(mdev);
1035         mthca_cleanup_uar_table(mdev);
1036
1037 err_close:
1038         mthca_close_hca(mdev);
1039
1040 err_cmd:
1041         mthca_cmd_cleanup(mdev);
1042
1043 err_free_dev:
1044         kfree(mdev);
1045
1046         /* we failed device initialization - try to simulate "livefish" device to facilitate using FW burning tools */
1047         if (ext->hcaConfig.DeviceID == PCI_DEVICE_ID_MELLANOX_ARBEL)
1048                 ext->hcaConfig.DeviceID = PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT;
1049         ext->hcaConfig.DeviceID += 1;   /* generate appropriate "livefish" DevId */
1050         goto find_pci_dev;
1051         
1052 end:
1053         return status;
1054 }
1055
1056 void mthca_remove_one(hca_dev_ext_t *ext)
1057 {
1058         struct mthca_dev *mdev = ext->hca.mdev;
1059         u8 status;
1060         int p;
1061
1062         ext->hca.mdev = NULL;
1063         if (mdev) {
1064                 mdev->state = MTHCA_DEV_UNINITIALIZED;
1065                 if (mthca_is_livefish(mdev))
1066                         goto done;
1067                 mthca_unregister_device(mdev);
1068
1069                 for (p = 1; p <= mdev->limits.num_ports; ++p)
1070                         mthca_CLOSE_IB(mdev, p, &status);
1071
1072                 mthca_cleanup_mcg_table(mdev);
1073                 mthca_cleanup_av_table(mdev);
1074                 mthca_cleanup_qp_table(mdev);
1075                 mthca_cleanup_srq_table(mdev);
1076                 mthca_cleanup_cq_table(mdev);
1077                 mthca_cmd_use_polling(mdev);
1078                 mthca_cleanup_eq_table(mdev);
1079                 mthca_pd_free(mdev, &mdev->driver_pd);
1080                 mthca_cleanup_mr_table(mdev);
1081                 mthca_cleanup_pd_table(mdev);
1082                 iounmap(mdev->kar, mdev->kar_size);
1083                 mthca_uar_free(mdev, &mdev->driver_uar);
1084                 mthca_cleanup_uar_table(mdev);
1085                 mthca_close_hca(mdev);
1086                 mthca_cmd_cleanup(mdev);
1087 done:
1088                 kfree(mdev);
1089         }
1090 }
1091
1092
1093