2 * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36 MLX4_CATAS_POLL_INTERVAL = 5 * HZ,
39 static DEFINE_SPINLOCK(catas_lock);
40 static LIST_HEAD(catas_list);
42 // TODO: put into Globals
43 // "Reset device on internal errors if non-zero (default 1)")
44 int g_internal_err_reset = 0;
46 static void dispatch_event(struct ib_device *ibdev, enum ib_event_type type)
49 struct ib_event event;
50 struct ib_event_handler *handler;
55 spin_lock_irqsave(&ibdev->event_handler_lock, &flags);
57 list_for_each_entry(handler, &ibdev->event_handler_list, list, struct ib_event_handler)
59 // notify only those, that are not notified
60 if ( handler->flags & IB_IVH_RESET_CB )
61 if ( !(handler->flags & IB_IVH_NOTIFIED) ) {
62 handler->flags |= IB_IVH_NOTIFIED;
63 handler->handler(handler, &event);
67 spin_unlock_irqrestore(&ibdev->event_handler_lock, flags);
71 * get_event_handlers - return list of handlers of the device
75 * get_event_handlers() remove all the device event handlers and put them in 'tlist'
77 static void get_event_handlers(struct ib_device *device, struct list_head *tlist)
80 struct ib_event_handler *handler, *thandler;
82 spin_lock_irqsave(&device->event_handler_lock, &flags);
84 list_for_each_entry_safe(handler, thandler, &device->event_handler_list,
85 list, struct ib_event_handler, struct ib_event_handler)
87 // take out only reset callbacks
88 if ( handler->flags & IB_IVH_RESET_CB ) {
89 list_del( &handler->list );
90 list_add_tail( &handler->list, tlist );
94 spin_unlock_irqrestore(&device->event_handler_lock, flags);
98 static void dump_err_buf(struct mlx4_dev *dev)
100 struct mlx4_priv *priv = mlx4_priv(dev);
104 mlx4_err(dev, "Internal error detected:\n");
105 for (i = 0; i < priv->fw.catas_size; ++i)
106 mlx4_err(dev, " buf[%02x]: %08x\n",
107 i, swab32(readl(priv->catas_err.map + i)));
110 static void catas_reset()
112 struct mlx4_priv *priv, *tmppriv;
113 struct mlx4_dev *dev;
114 struct list_head tlist;
117 INIT_LIST_HEAD(&tlist);
118 spin_lock_irq(&catas_lock);
119 list_splice_init(&catas_list, &tlist);
120 spin_unlock_irq(&catas_lock);
122 list_for_each_entry_safe(priv, tmppriv, &tlist, catas_err.list, struct mlx4_priv, struct mlx4_priv) {
123 ret = mlx4_restart_one(priv->dev.pdev);
126 mlx4_err(dev, "Reset failed (%d)\n", ret);
128 mlx4_dbg(dev, "Reset succeeded\n");
134 IN DEVICE_OBJECT* p_dev_obj,
137 UNUSED_PARAM(p_dev_obj);
138 IoFreeWorkItem( context );
142 /* polling on DISPATCH_LEVEL */
143 static void poll_catas(struct mlx4_dev *dev)
145 struct mlx4_priv *priv = mlx4_priv(dev);
147 if (readl(priv->catas_err.map)) {
150 mlx4_dispatch_event(dev, MLX4_EVENT_TYPE_LOCAL_CATAS_ERROR, 0, 0);
153 dev->flags |= MLX4_FLAG_RESET_DRIVER;
155 // notify the clients
156 dispatch_event(dev->pdev->ib_dev, IB_EVENT_RESET_DRIVER);
158 if (g_internal_err_reset) {
159 PIO_WORKITEM catas_work = IoAllocateWorkItem( dev->pdev->p_self_do );
161 spin_lock_dpc(&catas_lock);
162 list_add(&priv->catas_err.list, &catas_list);
163 spin_unlock_dpc(&catas_lock);
166 IoQueueWorkItem( catas_work, catas_reset_wi, DelayedWorkQueue, catas_work );
169 spin_lock_dpc(&catas_lock);
170 if (!priv->catas_err.stop) {
171 KeSetTimerEx( &priv->catas_err.timer, priv->catas_err.interval,
172 0, &priv->catas_err.timer_dpc );
174 spin_unlock_dpc(&catas_lock);
178 static void timer_dpc(
179 IN struct _KDPC *Dpc,
180 IN PVOID DeferredContext,
181 IN PVOID SystemArgument1,
182 IN PVOID SystemArgument2
185 struct mlx4_dev *dev = (struct mlx4_dev *)DeferredContext;
186 UNREFERENCED_PARAMETER(Dpc);
187 UNREFERENCED_PARAMETER(SystemArgument1);
188 UNREFERENCED_PARAMETER(SystemArgument2);
192 void mlx4_start_catas_poll(struct mlx4_dev *dev)
194 struct mlx4_priv *priv = mlx4_priv(dev);
197 INIT_LIST_HEAD(&priv->catas_err.list);
198 priv->catas_err.map = NULL;
200 addr = pci_resource_start(dev->pdev, priv->fw.catas_bar) +
201 priv->fw.catas_offset;
203 priv->catas_err.map = ioremap(addr, priv->fw.catas_size * 4);
204 if (!priv->catas_err.map) {
205 mlx4_warn(dev, "Failed to map internal error buffer at 0x%lx\n",
210 priv->catas_err.stop = 0;
211 spin_lock_init( &catas_lock );
212 KeInitializeDpc( &priv->catas_err.timer_dpc, timer_dpc, dev );
213 KeInitializeTimer( &priv->catas_err.timer );
214 priv->catas_err.interval.QuadPart = (-10)* (__int64)MLX4_CATAS_POLL_INTERVAL;
215 KeSetTimerEx( &priv->catas_err.timer, priv->catas_err.interval,
216 0, &priv->catas_err.timer_dpc );
219 void mlx4_stop_catas_poll(struct mlx4_dev *dev)
221 struct mlx4_priv *priv = mlx4_priv(dev);
223 spin_lock_irq(&catas_lock);
224 if (priv->catas_err.stop) {
225 spin_unlock_irq(&catas_lock);
228 priv->catas_err.stop = 1;
229 spin_unlock_irq(&catas_lock);
231 KeCancelTimer(&priv->catas_err.timer);
234 if (priv->catas_err.map)
235 iounmap(priv->catas_err.map, priv->fw.catas_size * 4);
237 spin_lock_irq(&catas_lock);
238 list_del(&priv->catas_err.list);
239 spin_unlock_irq(&catas_lock);
242 static int wait4reset(struct ib_event_handler *event_handler)
246 struct ib_event_handler *handler;
247 struct ib_device *ibdev = event_handler->device;
249 spin_lock_irqsave(&ibdev->event_handler_lock, &flags);
251 // mark this handler (=client) reset-ready
252 event_handler->flags |= IB_IVH_RESET_READY;
254 // check the number of still not ready client
256 list_for_each_entry(handler, &ibdev->event_handler_list, list, struct ib_event_handler)
257 if ( handler->flags & IB_IVH_RESET_CB )
258 if ( !(handler->flags & IB_IVH_RESET_READY) )
261 spin_unlock_irqrestore(&ibdev->event_handler_lock, flags);
266 int mlx4_reset_execute( struct ib_event_handler *event_handler )
269 struct ib_event event;
270 struct list_head tlist;
271 struct ib_event_handler *handler, *thandler;
272 struct ib_device *ibdev = event_handler->device;
273 struct pci_dev *pdev = ibdev->dma_device->pdev;
275 // mark client as "ready for reset" and check whether we can do reset
276 if (wait4reset(event_handler))
279 // fully bar the device
280 ibdev->dma_device->flags |= MLX4_FLAG_RESET_STARTED;
282 // get old handler list
283 INIT_LIST_HEAD(&tlist);
284 get_event_handlers(ibdev, &tlist);
286 // restart the device
287 err = mlx4_restart_one(pdev);
289 event.event = IB_EVENT_RESET_FAILED;
292 // recreate interfaces
294 event.event = IB_EVENT_RESET_END;
297 // notify the clients
298 list_for_each_entry_safe(handler, thandler, &tlist,
299 list, struct ib_event_handler, struct ib_event_handler)
301 // because 'handler' will be re-registered during the next call
302 list_del( &handler->list );
303 handler->handler(handler, &event);
311 IN DEVICE_OBJECT* p_dev_obj,
312 IN struct ib_event_handler * event_handler )
314 struct ib_device *ibdev = event_handler->device;
316 UNUSED_PARAM(p_dev_obj);
317 IoFreeWorkItem( event_handler->rsrv_ptr );
319 // notify the clients
320 dispatch_event(ibdev, IB_EVENT_RESET_CLIENT);
323 int mlx4_reset_request( struct ib_event_handler *event_handler )
325 struct ib_device *ibdev = event_handler->device;
326 struct mlx4_dev *dev = ibdev->dma_device;
328 // set device to RESET_PENDING mode
329 if (!mlx4_is_barred(dev)) {
330 PIO_WORKITEM reset_work;
333 dev->flags |= MLX4_FLAG_RESET_CLIENT;
335 // delay reset to a system thread
336 // to allow for end of operations that are in progress
337 reset_work = IoAllocateWorkItem( dev->pdev->p_self_do );
340 event_handler->rsrv_ptr = reset_work;
341 IoQueueWorkItem( reset_work, card_reset_wi, DelayedWorkQueue, event_handler );
347 int mlx4_reset_cb_register( struct ib_event_handler *event_handler )
349 if (mlx4_is_in_reset(event_handler->device->dma_device))
352 return ib_register_event_handler(event_handler);
355 int mlx4_reset_cb_unregister( struct ib_event_handler *event_handler )
357 return ib_unregister_event_handler(event_handler);