~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/scsi/aacraid/src.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno
  • Date: 2011-06-07 12:14:05 UTC
  • mfrom: (43.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110607121405-i3h1rd7nrnd2b73h
Tags: 2.6.39-2
[ Ben Hutchings ]
* [x86] Enable BACKLIGHT_APPLE, replacing BACKLIGHT_MBP_NVIDIA
  (Closes: #627492)
* cgroups: Disable memory resource controller by default. Allow it
  to be enabled using kernel parameter 'cgroup_enable=memory'.
* rt2800usb: Enable support for more USB devices including
  Linksys WUSB600N (Closes: #596626) (this change was accidentally
  omitted from 2.6.39-1)
* [x86] Remove Celeron from list of processors supporting PAE. Most
  'Celeron M' models do not.
* Update debconf template translations:
  - Swedish (Martin Bagge) (Closes: #628932)
  - French (David Prévot) (Closes: #628191)
* aufs: Update for 2.6.39 (Closes: #627837)
* Add stable 2.6.39.1, including:
  - ext4: dont set PageUptodate in ext4_end_bio()
  - pata_cmd64x: fix boot crash on parisc (Closes: #622997, #622745)
  - ext3: Fix fs corruption when make_indexed_dir() fails
  - netfilter: nf_ct_sip: validate Content-Length in TCP SIP messages
  - sctp: fix race between sctp_bind_addr_free() and
    sctp_bind_addr_conflict()
  - sctp: fix memory leak of the ASCONF queue when free asoc
  - md/bitmap: fix saving of events_cleared and other state
  - cdc_acm: Fix oops when Droids MuIn LCD is connected
  - cx88: Fix conversion from BKL to fine-grained locks (Closes: #619827)
  - keys: Set cred->user_ns in key_replace_session_keyring (CVE-2011-2184)
  - tmpfs: fix race between truncate and writepage
  - nfs41: Correct offset for LAYOUTCOMMIT
  - xen/mmu: fix a race window causing leave_mm BUG()
  - ext4: fix possible use-after-free in ext4_remove_li_request()
  For the complete list of changes, see:
   http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.39.1
* Bump ABI to 2
* netfilter: Enable IP_SET, IP_SET_BITMAP_IP, IP_SET_BITMAP_IPMAC,
  IP_SET_BITMAP_PORT, IP_SET_HASH_IP, IP_SET_HASH_IPPORT,
  IP_SET_HASH_IPPORTIP, IP_SET_HASH_IPPORTNET, IP_SET_HASH_NET,
  IP_SET_HASH_NETPORT, IP_SET_LIST_SET, NETFILTER_XT_SET as modules
  (Closes: #629401)

[ Aurelien Jarno ]
* [mipsel/loongson-2f] Disable_SCSI_LPFC to workaround GCC ICE.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      Adaptec AAC series RAID controller driver
 
3
 *      (c) Copyright 2001 Red Hat Inc.
 
4
 *
 
5
 * based on the old aacraid driver that is..
 
6
 * Adaptec aacraid device driver for Linux.
 
7
 *
 
8
 * Copyright (c) 2000-2010 Adaptec, Inc.
 
9
 *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
 
10
 *
 
11
 * This program is free software; you can redistribute it and/or modify
 
12
 * it under the terms of the GNU General Public License as published by
 
13
 * the Free Software Foundation; either version 2, or (at your option)
 
14
 * any later version.
 
15
 *
 
16
 * This program is distributed in the hope that it will be useful,
 
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
 * GNU General Public License for more details.
 
20
 *
 
21
 * You should have received a copy of the GNU General Public License
 
22
 * along with this program; see the file COPYING.  If not, write to
 
23
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
24
 *
 
25
 * Module Name:
 
26
 *  src.c
 
27
 *
 
28
 * Abstract: Hardware Device Interface for PMC SRC based controllers
 
29
 *
 
30
 */
 
31
 
 
32
#include <linux/kernel.h>
 
33
#include <linux/init.h>
 
34
#include <linux/types.h>
 
35
#include <linux/pci.h>
 
36
#include <linux/spinlock.h>
 
37
#include <linux/slab.h>
 
38
#include <linux/blkdev.h>
 
39
#include <linux/delay.h>
 
40
#include <linux/version.h>
 
41
#include <linux/completion.h>
 
42
#include <linux/time.h>
 
43
#include <linux/interrupt.h>
 
44
#include <scsi/scsi_host.h>
 
45
 
 
46
#include "aacraid.h"
 
47
 
 
48
static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
 
49
{
 
50
        struct aac_dev *dev = dev_id;
 
51
        unsigned long bellbits, bellbits_shifted;
 
52
        int our_interrupt = 0;
 
53
        int isFastResponse;
 
54
        u32 index, handle;
 
55
 
 
56
        bellbits = src_readl(dev, MUnit.ODR_R);
 
57
        if (bellbits & PmDoorBellResponseSent) {
 
58
                bellbits = PmDoorBellResponseSent;
 
59
                /* handle async. status */
 
60
                our_interrupt = 1;
 
61
                index = dev->host_rrq_idx;
 
62
                if (dev->host_rrq[index] == 0) {
 
63
                        u32 old_index = index;
 
64
                        /* adjust index */
 
65
                        do {
 
66
                                index++;
 
67
                                if (index == dev->scsi_host_ptr->can_queue +
 
68
                                                        AAC_NUM_MGT_FIB)
 
69
                                        index = 0;
 
70
                                if (dev->host_rrq[index] != 0)
 
71
                                        break;
 
72
                        } while (index != old_index);
 
73
                        dev->host_rrq_idx = index;
 
74
                }
 
75
                for (;;) {
 
76
                        isFastResponse = 0;
 
77
                        /* remove toggle bit (31) */
 
78
                        handle = (dev->host_rrq[index] & 0x7fffffff);
 
79
                        /* check fast response bit (30) */
 
80
                        if (handle & 0x40000000)
 
81
                                isFastResponse = 1;
 
82
                        handle &= 0x0000ffff;
 
83
                        if (handle == 0)
 
84
                                break;
 
85
 
 
86
                        aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
 
87
 
 
88
                        dev->host_rrq[index++] = 0;
 
89
                        if (index == dev->scsi_host_ptr->can_queue +
 
90
                                                AAC_NUM_MGT_FIB)
 
91
                                index = 0;
 
92
                        dev->host_rrq_idx = index;
 
93
                }
 
94
        } else {
 
95
                bellbits_shifted = (bellbits >> SRC_ODR_SHIFT);
 
96
                if (bellbits_shifted & DoorBellAifPending) {
 
97
                        our_interrupt = 1;
 
98
                        /* handle AIF */
 
99
                        aac_intr_normal(dev, 0, 2, 0, NULL);
 
100
                }
 
101
        }
 
102
 
 
103
        if (our_interrupt) {
 
104
                src_writel(dev, MUnit.ODR_C, bellbits);
 
105
                return IRQ_HANDLED;
 
106
        }
 
107
        return IRQ_NONE;
 
108
}
 
109
 
 
110
/**
 
111
 *      aac_src_disable_interrupt       -       Disable interrupts
 
112
 *      @dev: Adapter
 
113
 */
 
114
 
 
115
static void aac_src_disable_interrupt(struct aac_dev *dev)
 
116
{
 
117
        src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff);
 
118
}
 
119
 
 
120
/**
 
121
 *      aac_src_enable_interrupt_message        -       Enable interrupts
 
122
 *      @dev: Adapter
 
123
 */
 
124
 
 
125
static void aac_src_enable_interrupt_message(struct aac_dev *dev)
 
126
{
 
127
        src_writel(dev, MUnit.OIMR, dev->OIMR = 0xfffffff8);
 
128
}
 
129
 
 
130
/**
 
131
 *      src_sync_cmd    -       send a command and wait
 
132
 *      @dev: Adapter
 
133
 *      @command: Command to execute
 
134
 *      @p1: first parameter
 
135
 *      @ret: adapter status
 
136
 *
 
137
 *      This routine will send a synchronous command to the adapter and wait
 
138
 *      for its completion.
 
139
 */
 
140
 
 
141
static int src_sync_cmd(struct aac_dev *dev, u32 command,
 
142
        u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
 
143
        u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
 
144
{
 
145
        unsigned long start;
 
146
        int ok;
 
147
 
 
148
        /*
 
149
         *      Write the command into Mailbox 0
 
150
         */
 
151
        writel(command, &dev->IndexRegs->Mailbox[0]);
 
152
        /*
 
153
         *      Write the parameters into Mailboxes 1 - 6
 
154
         */
 
155
        writel(p1, &dev->IndexRegs->Mailbox[1]);
 
156
        writel(p2, &dev->IndexRegs->Mailbox[2]);
 
157
        writel(p3, &dev->IndexRegs->Mailbox[3]);
 
158
        writel(p4, &dev->IndexRegs->Mailbox[4]);
 
159
 
 
160
        /*
 
161
         *      Clear the synch command doorbell to start on a clean slate.
 
162
         */
 
163
        src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
 
164
 
 
165
        /*
 
166
         *      Disable doorbell interrupts
 
167
         */
 
168
        src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff);
 
169
 
 
170
        /*
 
171
         *      Force the completion of the mask register write before issuing
 
172
         *      the interrupt.
 
173
         */
 
174
        src_readl(dev, MUnit.OIMR);
 
175
 
 
176
        /*
 
177
         *      Signal that there is a new synch command
 
178
         */
 
179
        src_writel(dev, MUnit.IDR, INBOUNDDOORBELL_0 << SRC_IDR_SHIFT);
 
180
 
 
181
        ok = 0;
 
182
        start = jiffies;
 
183
 
 
184
        /*
 
185
         *      Wait up to 30 seconds
 
186
         */
 
187
        while (time_before(jiffies, start+30*HZ)) {
 
188
                /* Delay 5 microseconds to let Mon960 get info. */
 
189
                udelay(5);
 
190
 
 
191
                /* Mon960 will set doorbell0 bit
 
192
                 * when it has completed the command
 
193
                 */
 
194
                if ((src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT) & OUTBOUNDDOORBELL_0) {
 
195
                        /* Clear the doorbell */
 
196
                        src_writel(dev,
 
197
                                MUnit.ODR_C,
 
198
                                OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
 
199
                        ok = 1;
 
200
                        break;
 
201
                }
 
202
 
 
203
                 /* Yield the processor in case we are slow */
 
204
                msleep(1);
 
205
        }
 
206
        if (unlikely(ok != 1)) {
 
207
                 /* Restore interrupt mask even though we timed out */
 
208
                aac_adapter_enable_int(dev);
 
209
                return -ETIMEDOUT;
 
210
        }
 
211
 
 
212
         /* Pull the synch status from Mailbox 0 */
 
213
        if (status)
 
214
                *status = readl(&dev->IndexRegs->Mailbox[0]);
 
215
        if (r1)
 
216
                *r1 = readl(&dev->IndexRegs->Mailbox[1]);
 
217
        if (r2)
 
218
                *r2 = readl(&dev->IndexRegs->Mailbox[2]);
 
219
        if (r3)
 
220
                *r3 = readl(&dev->IndexRegs->Mailbox[3]);
 
221
        if (r4)
 
222
                *r4 = readl(&dev->IndexRegs->Mailbox[4]);
 
223
 
 
224
         /* Clear the synch command doorbell */
 
225
        src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
 
226
 
 
227
         /* Restore interrupt mask */
 
228
        aac_adapter_enable_int(dev);
 
229
        return 0;
 
230
 
 
231
}
 
232
 
 
233
/**
 
234
 *      aac_src_interrupt_adapter       -       interrupt adapter
 
235
 *      @dev: Adapter
 
236
 *
 
237
 *      Send an interrupt to the i960 and breakpoint it.
 
238
 */
 
239
 
 
240
static void aac_src_interrupt_adapter(struct aac_dev *dev)
 
241
{
 
242
        src_sync_cmd(dev, BREAKPOINT_REQUEST,
 
243
                0, 0, 0, 0, 0, 0,
 
244
                NULL, NULL, NULL, NULL, NULL);
 
245
}
 
246
 
 
247
/**
 
248
 *      aac_src_notify_adapter          -       send an event to the adapter
 
249
 *      @dev: Adapter
 
250
 *      @event: Event to send
 
251
 *
 
252
 *      Notify the i960 that something it probably cares about has
 
253
 *      happened.
 
254
 */
 
255
 
 
256
static void aac_src_notify_adapter(struct aac_dev *dev, u32 event)
 
257
{
 
258
        switch (event) {
 
259
 
 
260
        case AdapNormCmdQue:
 
261
                src_writel(dev, MUnit.ODR_C,
 
262
                        INBOUNDDOORBELL_1 << SRC_ODR_SHIFT);
 
263
                break;
 
264
        case HostNormRespNotFull:
 
265
                src_writel(dev, MUnit.ODR_C,
 
266
                        INBOUNDDOORBELL_4 << SRC_ODR_SHIFT);
 
267
                break;
 
268
        case AdapNormRespQue:
 
269
                src_writel(dev, MUnit.ODR_C,
 
270
                        INBOUNDDOORBELL_2 << SRC_ODR_SHIFT);
 
271
                break;
 
272
        case HostNormCmdNotFull:
 
273
                src_writel(dev, MUnit.ODR_C,
 
274
                        INBOUNDDOORBELL_3 << SRC_ODR_SHIFT);
 
275
                break;
 
276
        case FastIo:
 
277
                src_writel(dev, MUnit.ODR_C,
 
278
                        INBOUNDDOORBELL_6 << SRC_ODR_SHIFT);
 
279
                break;
 
280
        case AdapPrintfDone:
 
281
                src_writel(dev, MUnit.ODR_C,
 
282
                        INBOUNDDOORBELL_5 << SRC_ODR_SHIFT);
 
283
                break;
 
284
        default:
 
285
                BUG();
 
286
                break;
 
287
        }
 
288
}
 
289
 
 
290
/**
 
291
 *      aac_src_start_adapter           -       activate adapter
 
292
 *      @dev:   Adapter
 
293
 *
 
294
 *      Start up processing on an i960 based AAC adapter
 
295
 */
 
296
 
 
297
static void aac_src_start_adapter(struct aac_dev *dev)
 
298
{
 
299
        struct aac_init *init;
 
300
 
 
301
        init = dev->init;
 
302
        init->HostElapsedSeconds = cpu_to_le32(get_seconds());
 
303
 
 
304
        /* We can only use a 32 bit address here */
 
305
        src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
 
306
          0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
 
307
}
 
308
 
 
309
/**
 
310
 *      aac_src_check_health
 
311
 *      @dev: device to check if healthy
 
312
 *
 
313
 *      Will attempt to determine if the specified adapter is alive and
 
314
 *      capable of handling requests, returning 0 if alive.
 
315
 */
 
316
static int aac_src_check_health(struct aac_dev *dev)
 
317
{
 
318
        u32 status = src_readl(dev, MUnit.OMR);
 
319
 
 
320
        /*
 
321
         *      Check to see if the board failed any self tests.
 
322
         */
 
323
        if (unlikely(status & SELF_TEST_FAILED))
 
324
                return -1;
 
325
 
 
326
        /*
 
327
         *      Check to see if the board panic'd.
 
328
         */
 
329
        if (unlikely(status & KERNEL_PANIC))
 
330
                return (status >> 16) & 0xFF;
 
331
        /*
 
332
         *      Wait for the adapter to be up and running.
 
333
         */
 
334
        if (unlikely(!(status & KERNEL_UP_AND_RUNNING)))
 
335
                return -3;
 
336
        /*
 
337
         *      Everything is OK
 
338
         */
 
339
        return 0;
 
340
}
 
341
 
 
342
/**
 
343
 *      aac_src_deliver_message
 
344
 *      @fib: fib to issue
 
345
 *
 
346
 *      Will send a fib, returning 0 if successful.
 
347
 */
 
348
static int aac_src_deliver_message(struct fib *fib)
 
349
{
 
350
        struct aac_dev *dev = fib->dev;
 
351
        struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
 
352
        unsigned long qflags;
 
353
        u32 fibsize;
 
354
        u64 address;
 
355
        struct aac_fib_xporthdr *pFibX;
 
356
 
 
357
        spin_lock_irqsave(q->lock, qflags);
 
358
        q->numpending++;
 
359
        spin_unlock_irqrestore(q->lock, qflags);
 
360
 
 
361
        /* Calculate the amount to the fibsize bits */
 
362
        fibsize = (sizeof(struct aac_fib_xporthdr) +
 
363
                fib->hw_fib_va->header.Size + 127) / 128 - 1;
 
364
        if (fibsize > (ALIGN32 - 1))
 
365
                fibsize = ALIGN32 - 1;
 
366
 
 
367
    /* Fill XPORT header */
 
368
        pFibX = (struct aac_fib_xporthdr *)
 
369
                ((unsigned char *)fib->hw_fib_va -
 
370
                sizeof(struct aac_fib_xporthdr));
 
371
        pFibX->Handle = fib->hw_fib_va->header.SenderData + 1;
 
372
        pFibX->HostAddress = fib->hw_fib_pa;
 
373
        pFibX->Size = fib->hw_fib_va->header.Size;
 
374
        address = fib->hw_fib_pa - (u64)sizeof(struct aac_fib_xporthdr);
 
375
 
 
376
        src_writel(dev, MUnit.IQ_H, (u32)(address >> 32));
 
377
        src_writel(dev, MUnit.IQ_L, (u32)(address & 0xffffffff) + fibsize);
 
378
        return 0;
 
379
}
 
380
 
 
381
/**
 
382
 *      aac_src_ioremap
 
383
 *      @size: mapping resize request
 
384
 *
 
385
 */
 
386
static int aac_src_ioremap(struct aac_dev *dev, u32 size)
 
387
{
 
388
        if (!size) {
 
389
                iounmap(dev->regs.src.bar0);
 
390
                dev->regs.src.bar0 = NULL;
 
391
                iounmap(dev->base);
 
392
                dev->base = NULL;
 
393
                return 0;
 
394
        }
 
395
        dev->regs.src.bar1 = ioremap(pci_resource_start(dev->pdev, 2),
 
396
                AAC_MIN_SRC_BAR1_SIZE);
 
397
        dev->base = NULL;
 
398
        if (dev->regs.src.bar1 == NULL)
 
399
                return -1;
 
400
        dev->base = dev->regs.src.bar0 = ioremap(dev->scsi_host_ptr->base,
 
401
                                size);
 
402
        if (dev->base == NULL) {
 
403
                iounmap(dev->regs.src.bar1);
 
404
                dev->regs.src.bar1 = NULL;
 
405
                return -1;
 
406
        }
 
407
        dev->IndexRegs = &((struct src_registers __iomem *)
 
408
                dev->base)->IndexRegs;
 
409
        return 0;
 
410
}
 
411
 
 
412
static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
 
413
{
 
414
        u32 var, reset_mask;
 
415
 
 
416
        if (bled >= 0) {
 
417
                if (bled)
 
418
                        printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
 
419
                                dev->name, dev->id, bled);
 
420
                bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
 
421
                        0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
 
422
                        if (bled || (var != 0x00000001))
 
423
                                bled = -EINVAL;
 
424
                if (dev->supplement_adapter_info.SupportedOptions2 &
 
425
                        AAC_OPTION_DOORBELL_RESET) {
 
426
                        src_writel(dev, MUnit.IDR, reset_mask);
 
427
                        msleep(5000); /* Delay 5 seconds */
 
428
                }
 
429
        }
 
430
 
 
431
        if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC)
 
432
                return -ENODEV;
 
433
 
 
434
        if (startup_timeout < 300)
 
435
                startup_timeout = 300;
 
436
 
 
437
        return 0;
 
438
}
 
439
 
 
440
/**
 
441
 *      aac_src_select_comm     -       Select communications method
 
442
 *      @dev: Adapter
 
443
 *      @comm: communications method
 
444
 */
 
445
int aac_src_select_comm(struct aac_dev *dev, int comm)
 
446
{
 
447
        switch (comm) {
 
448
        case AAC_COMM_MESSAGE:
 
449
                dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
 
450
                dev->a_ops.adapter_intr = aac_src_intr_message;
 
451
                dev->a_ops.adapter_deliver = aac_src_deliver_message;
 
452
                break;
 
453
        default:
 
454
                return 1;
 
455
        }
 
456
        return 0;
 
457
}
 
458
 
 
459
/**
 
460
 *  aac_src_init        -       initialize an Cardinal Frey Bar card
 
461
 *  @dev: device to configure
 
462
 *
 
463
 */
 
464
 
 
465
int aac_src_init(struct aac_dev *dev)
 
466
{
 
467
        unsigned long start;
 
468
        unsigned long status;
 
469
        int restart = 0;
 
470
        int instance = dev->id;
 
471
        const char *name = dev->name;
 
472
 
 
473
        dev->a_ops.adapter_ioremap = aac_src_ioremap;
 
474
        dev->a_ops.adapter_comm = aac_src_select_comm;
 
475
 
 
476
        dev->base_size = AAC_MIN_SRC_BAR0_SIZE;
 
477
        if (aac_adapter_ioremap(dev, dev->base_size)) {
 
478
                printk(KERN_WARNING "%s: unable to map adapter.\n", name);
 
479
                goto error_iounmap;
 
480
        }
 
481
 
 
482
        /* Failure to reset here is an option ... */
 
483
        dev->a_ops.adapter_sync_cmd = src_sync_cmd;
 
484
        dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
 
485
        if ((aac_reset_devices || reset_devices) &&
 
486
                !aac_src_restart_adapter(dev, 0))
 
487
                ++restart;
 
488
        /*
 
489
         *      Check to see if the board panic'd while booting.
 
490
         */
 
491
        status = src_readl(dev, MUnit.OMR);
 
492
        if (status & KERNEL_PANIC) {
 
493
                if (aac_src_restart_adapter(dev, aac_src_check_health(dev)))
 
494
                        goto error_iounmap;
 
495
                ++restart;
 
496
        }
 
497
        /*
 
498
         *      Check to see if the board failed any self tests.
 
499
         */
 
500
        status = src_readl(dev, MUnit.OMR);
 
501
        if (status & SELF_TEST_FAILED) {
 
502
                printk(KERN_ERR "%s%d: adapter self-test failed.\n",
 
503
                        dev->name, instance);
 
504
                goto error_iounmap;
 
505
        }
 
506
        /*
 
507
         *      Check to see if the monitor panic'd while booting.
 
508
         */
 
509
        if (status & MONITOR_PANIC) {
 
510
                printk(KERN_ERR "%s%d: adapter monitor panic.\n",
 
511
                        dev->name, instance);
 
512
                goto error_iounmap;
 
513
        }
 
514
        start = jiffies;
 
515
        /*
 
516
         *      Wait for the adapter to be up and running. Wait up to 3 minutes
 
517
         */
 
518
        while (!((status = src_readl(dev, MUnit.OMR)) &
 
519
                KERNEL_UP_AND_RUNNING)) {
 
520
                if ((restart &&
 
521
                  (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
 
522
                  time_after(jiffies, start+HZ*startup_timeout)) {
 
523
                        printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
 
524
                                        dev->name, instance, status);
 
525
                        goto error_iounmap;
 
526
                }
 
527
                if (!restart &&
 
528
                  ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
 
529
                  time_after(jiffies, start + HZ *
 
530
                  ((startup_timeout > 60)
 
531
                    ? (startup_timeout - 60)
 
532
                    : (startup_timeout / 2))))) {
 
533
                        if (likely(!aac_src_restart_adapter(dev,
 
534
                            aac_src_check_health(dev))))
 
535
                                start = jiffies;
 
536
                        ++restart;
 
537
                }
 
538
                msleep(1);
 
539
        }
 
540
        if (restart && aac_commit)
 
541
                aac_commit = 1;
 
542
        /*
 
543
         *      Fill in the common function dispatch table.
 
544
         */
 
545
        dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
 
546
        dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
 
547
        dev->a_ops.adapter_notify = aac_src_notify_adapter;
 
548
        dev->a_ops.adapter_sync_cmd = src_sync_cmd;
 
549
        dev->a_ops.adapter_check_health = aac_src_check_health;
 
550
        dev->a_ops.adapter_restart = aac_src_restart_adapter;
 
551
 
 
552
        /*
 
553
         *      First clear out all interrupts.  Then enable the one's that we
 
554
         *      can handle.
 
555
         */
 
556
        aac_adapter_comm(dev, AAC_COMM_MESSAGE);
 
557
        aac_adapter_disable_int(dev);
 
558
        src_writel(dev, MUnit.ODR_C, 0xffffffff);
 
559
        aac_adapter_enable_int(dev);
 
560
 
 
561
        if (aac_init_adapter(dev) == NULL)
 
562
                goto error_iounmap;
 
563
        if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1)
 
564
                goto error_iounmap;
 
565
 
 
566
        dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
 
567
 
 
568
        if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
 
569
                        IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) {
 
570
 
 
571
                if (dev->msi)
 
572
                        pci_disable_msi(dev->pdev);
 
573
 
 
574
                printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
 
575
                        name, instance);
 
576
                goto error_iounmap;
 
577
        }
 
578
        dev->dbg_base = pci_resource_start(dev->pdev, 2);
 
579
        dev->dbg_base_mapped = dev->regs.src.bar1;
 
580
        dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE;
 
581
 
 
582
        aac_adapter_enable_int(dev);
 
583
        /*
 
584
         *      Tell the adapter that all is configured, and it can
 
585
         * start accepting requests
 
586
         */
 
587
        aac_src_start_adapter(dev);
 
588
 
 
589
        return 0;
 
590
 
 
591
error_iounmap:
 
592
 
 
593
        return -1;
 
594
}