]> Pileus Git - ~andy/linux/blob - drivers/scsi/aacraid/src.c
Merge tag 'stable/for-linus-3.4-tag' of git://git.kernel.org/pub/scm/linux/kernel...
[~andy/linux] / drivers / scsi / aacraid / src.c
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/completion.h>
41 #include <linux/time.h>
42 #include <linux/interrupt.h>
43 #include <scsi/scsi_host.h>
44
45 #include "aacraid.h"
46
47 static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
48 {
49         struct aac_dev *dev = dev_id;
50         unsigned long bellbits, bellbits_shifted;
51         int our_interrupt = 0;
52         int isFastResponse;
53         u32 index, handle;
54
55         bellbits = src_readl(dev, MUnit.ODR_R);
56         if (bellbits & PmDoorBellResponseSent) {
57                 bellbits = PmDoorBellResponseSent;
58                 /* handle async. status */
59                 our_interrupt = 1;
60                 index = dev->host_rrq_idx;
61                 if (dev->host_rrq[index] == 0) {
62                         u32 old_index = index;
63                         /* adjust index */
64                         do {
65                                 index++;
66                                 if (index == dev->scsi_host_ptr->can_queue +
67                                                         AAC_NUM_MGT_FIB)
68                                         index = 0;
69                                 if (dev->host_rrq[index] != 0)
70                                         break;
71                         } while (index != old_index);
72                         dev->host_rrq_idx = index;
73                 }
74                 for (;;) {
75                         isFastResponse = 0;
76                         /* remove toggle bit (31) */
77                         handle = (dev->host_rrq[index] & 0x7fffffff);
78                         /* check fast response bit (30) */
79                         if (handle & 0x40000000)
80                                 isFastResponse = 1;
81                         handle &= 0x0000ffff;
82                         if (handle == 0)
83                                 break;
84
85                         aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
86
87                         dev->host_rrq[index++] = 0;
88                         if (index == dev->scsi_host_ptr->can_queue +
89                                                 AAC_NUM_MGT_FIB)
90                                 index = 0;
91                         dev->host_rrq_idx = index;
92                 }
93         } else {
94                 bellbits_shifted = (bellbits >> SRC_ODR_SHIFT);
95                 if (bellbits_shifted & DoorBellAifPending) {
96                         our_interrupt = 1;
97                         /* handle AIF */
98                         aac_intr_normal(dev, 0, 2, 0, NULL);
99                 } else if (bellbits_shifted & OUTBOUNDDOORBELL_0) {
100                         unsigned long sflags;
101                         struct list_head *entry;
102                         int send_it = 0;
103
104                         if (dev->sync_fib) {
105                                 our_interrupt = 1;
106                                 if (dev->sync_fib->callback)
107                                         dev->sync_fib->callback(dev->sync_fib->callback_data,
108                                                 dev->sync_fib);
109                                 spin_lock_irqsave(&dev->sync_fib->event_lock, sflags);
110                                 if (dev->sync_fib->flags & FIB_CONTEXT_FLAG_WAIT) {
111                                         dev->management_fib_count--;
112                                         up(&dev->sync_fib->event_wait);
113                                 }
114                                 spin_unlock_irqrestore(&dev->sync_fib->event_lock, sflags);
115                                 spin_lock_irqsave(&dev->sync_lock, sflags);
116                                 if (!list_empty(&dev->sync_fib_list)) {
117                                         entry = dev->sync_fib_list.next;
118                                         dev->sync_fib = list_entry(entry, struct fib, fiblink);
119                                         list_del(entry);
120                                         send_it = 1;
121                                 } else {
122                                         dev->sync_fib = NULL;
123                                 }
124                                 spin_unlock_irqrestore(&dev->sync_lock, sflags);
125                                 if (send_it) {
126                                         aac_adapter_sync_cmd(dev, SEND_SYNCHRONOUS_FIB,
127                                                 (u32)dev->sync_fib->hw_fib_pa, 0, 0, 0, 0, 0,
128                                                 NULL, NULL, NULL, NULL, NULL);
129                                 }
130                         }
131                 }
132         }
133
134         if (our_interrupt) {
135                 src_writel(dev, MUnit.ODR_C, bellbits);
136                 return IRQ_HANDLED;
137         }
138         return IRQ_NONE;
139 }
140
141 /**
142  *      aac_src_disable_interrupt       -       Disable interrupts
143  *      @dev: Adapter
144  */
145
146 static void aac_src_disable_interrupt(struct aac_dev *dev)
147 {
148         src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff);
149 }
150
151 /**
152  *      aac_src_enable_interrupt_message        -       Enable interrupts
153  *      @dev: Adapter
154  */
155
156 static void aac_src_enable_interrupt_message(struct aac_dev *dev)
157 {
158         src_writel(dev, MUnit.OIMR, dev->OIMR = 0xfffffff8);
159 }
160
161 /**
162  *      src_sync_cmd    -       send a command and wait
163  *      @dev: Adapter
164  *      @command: Command to execute
165  *      @p1: first parameter
166  *      @ret: adapter status
167  *
168  *      This routine will send a synchronous command to the adapter and wait
169  *      for its completion.
170  */
171
172 static int src_sync_cmd(struct aac_dev *dev, u32 command,
173         u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
174         u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
175 {
176         unsigned long start;
177         int ok;
178
179         /*
180          *      Write the command into Mailbox 0
181          */
182         writel(command, &dev->IndexRegs->Mailbox[0]);
183         /*
184          *      Write the parameters into Mailboxes 1 - 6
185          */
186         writel(p1, &dev->IndexRegs->Mailbox[1]);
187         writel(p2, &dev->IndexRegs->Mailbox[2]);
188         writel(p3, &dev->IndexRegs->Mailbox[3]);
189         writel(p4, &dev->IndexRegs->Mailbox[4]);
190
191         /*
192          *      Clear the synch command doorbell to start on a clean slate.
193          */
194         src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
195
196         /*
197          *      Disable doorbell interrupts
198          */
199         src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff);
200
201         /*
202          *      Force the completion of the mask register write before issuing
203          *      the interrupt.
204          */
205         src_readl(dev, MUnit.OIMR);
206
207         /*
208          *      Signal that there is a new synch command
209          */
210         src_writel(dev, MUnit.IDR, INBOUNDDOORBELL_0 << SRC_IDR_SHIFT);
211
212         if (!dev->sync_mode || command != SEND_SYNCHRONOUS_FIB) {
213                 ok = 0;
214                 start = jiffies;
215
216                 /*
217                  *      Wait up to 5 minutes
218                  */
219                 while (time_before(jiffies, start+300*HZ)) {
220                         udelay(5);      /* Delay 5 microseconds to let Mon960 get info. */
221                         /*
222                          *      Mon960 will set doorbell0 bit when it has completed the command.
223                          */
224                         if ((src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT) & OUTBOUNDDOORBELL_0) {
225                                 /*
226                                  *      Clear the doorbell.
227                                  */
228                                 src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
229                                 ok = 1;
230                                 break;
231                         }
232                         /*
233                          *      Yield the processor in case we are slow
234                          */
235                         msleep(1);
236                 }
237                 if (unlikely(ok != 1)) {
238                         /*
239                          *      Restore interrupt mask even though we timed out
240                          */
241                         aac_adapter_enable_int(dev);
242                         return -ETIMEDOUT;
243                 }
244                 /*
245                  *      Pull the synch status from Mailbox 0.
246                  */
247                 if (status)
248                         *status = readl(&dev->IndexRegs->Mailbox[0]);
249                 if (r1)
250                         *r1 = readl(&dev->IndexRegs->Mailbox[1]);
251                 if (r2)
252                         *r2 = readl(&dev->IndexRegs->Mailbox[2]);
253                 if (r3)
254                         *r3 = readl(&dev->IndexRegs->Mailbox[3]);
255                 if (r4)
256                         *r4 = readl(&dev->IndexRegs->Mailbox[4]);
257
258                 /*
259                  *      Clear the synch command doorbell.
260                  */
261                 src_writel(dev, MUnit.ODR_C, OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
262         }
263
264         /*
265          *      Restore interrupt mask
266          */
267         aac_adapter_enable_int(dev);
268         return 0;
269 }
270
271 /**
272  *      aac_src_interrupt_adapter       -       interrupt adapter
273  *      @dev: Adapter
274  *
275  *      Send an interrupt to the i960 and breakpoint it.
276  */
277
278 static void aac_src_interrupt_adapter(struct aac_dev *dev)
279 {
280         src_sync_cmd(dev, BREAKPOINT_REQUEST,
281                 0, 0, 0, 0, 0, 0,
282                 NULL, NULL, NULL, NULL, NULL);
283 }
284
285 /**
286  *      aac_src_notify_adapter          -       send an event to the adapter
287  *      @dev: Adapter
288  *      @event: Event to send
289  *
290  *      Notify the i960 that something it probably cares about has
291  *      happened.
292  */
293
294 static void aac_src_notify_adapter(struct aac_dev *dev, u32 event)
295 {
296         switch (event) {
297
298         case AdapNormCmdQue:
299                 src_writel(dev, MUnit.ODR_C,
300                         INBOUNDDOORBELL_1 << SRC_ODR_SHIFT);
301                 break;
302         case HostNormRespNotFull:
303                 src_writel(dev, MUnit.ODR_C,
304                         INBOUNDDOORBELL_4 << SRC_ODR_SHIFT);
305                 break;
306         case AdapNormRespQue:
307                 src_writel(dev, MUnit.ODR_C,
308                         INBOUNDDOORBELL_2 << SRC_ODR_SHIFT);
309                 break;
310         case HostNormCmdNotFull:
311                 src_writel(dev, MUnit.ODR_C,
312                         INBOUNDDOORBELL_3 << SRC_ODR_SHIFT);
313                 break;
314         case FastIo:
315                 src_writel(dev, MUnit.ODR_C,
316                         INBOUNDDOORBELL_6 << SRC_ODR_SHIFT);
317                 break;
318         case AdapPrintfDone:
319                 src_writel(dev, MUnit.ODR_C,
320                         INBOUNDDOORBELL_5 << SRC_ODR_SHIFT);
321                 break;
322         default:
323                 BUG();
324                 break;
325         }
326 }
327
328 /**
329  *      aac_src_start_adapter           -       activate adapter
330  *      @dev:   Adapter
331  *
332  *      Start up processing on an i960 based AAC adapter
333  */
334
335 static void aac_src_start_adapter(struct aac_dev *dev)
336 {
337         struct aac_init *init;
338
339         init = dev->init;
340         init->HostElapsedSeconds = cpu_to_le32(get_seconds());
341
342         /* We can only use a 32 bit address here */
343         src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
344           0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
345 }
346
347 /**
348  *      aac_src_check_health
349  *      @dev: device to check if healthy
350  *
351  *      Will attempt to determine if the specified adapter is alive and
352  *      capable of handling requests, returning 0 if alive.
353  */
354 static int aac_src_check_health(struct aac_dev *dev)
355 {
356         u32 status = src_readl(dev, MUnit.OMR);
357
358         /*
359          *      Check to see if the board failed any self tests.
360          */
361         if (unlikely(status & SELF_TEST_FAILED))
362                 return -1;
363
364         /*
365          *      Check to see if the board panic'd.
366          */
367         if (unlikely(status & KERNEL_PANIC))
368                 return (status >> 16) & 0xFF;
369         /*
370          *      Wait for the adapter to be up and running.
371          */
372         if (unlikely(!(status & KERNEL_UP_AND_RUNNING)))
373                 return -3;
374         /*
375          *      Everything is OK
376          */
377         return 0;
378 }
379
380 /**
381  *      aac_src_deliver_message
382  *      @fib: fib to issue
383  *
384  *      Will send a fib, returning 0 if successful.
385  */
386 static int aac_src_deliver_message(struct fib *fib)
387 {
388         struct aac_dev *dev = fib->dev;
389         struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
390         unsigned long qflags;
391         u32 fibsize;
392         u64 address;
393         struct aac_fib_xporthdr *pFibX;
394
395         spin_lock_irqsave(q->lock, qflags);
396         q->numpending++;
397         spin_unlock_irqrestore(q->lock, qflags);
398
399         /* Calculate the amount to the fibsize bits */
400         fibsize = (sizeof(struct aac_fib_xporthdr) +
401                 fib->hw_fib_va->header.Size + 127) / 128 - 1;
402         if (fibsize > (ALIGN32 - 1))
403                 fibsize = ALIGN32 - 1;
404
405     /* Fill XPORT header */
406         pFibX = (struct aac_fib_xporthdr *)
407                 ((unsigned char *)fib->hw_fib_va -
408                 sizeof(struct aac_fib_xporthdr));
409         pFibX->Handle = fib->hw_fib_va->header.SenderData + 1;
410         pFibX->HostAddress = fib->hw_fib_pa;
411         pFibX->Size = fib->hw_fib_va->header.Size;
412         address = fib->hw_fib_pa - (u64)sizeof(struct aac_fib_xporthdr);
413
414         src_writel(dev, MUnit.IQ_H, (u32)(address >> 32));
415         src_writel(dev, MUnit.IQ_L, (u32)(address & 0xffffffff) + fibsize);
416         return 0;
417 }
418
419 /**
420  *      aac_src_ioremap
421  *      @size: mapping resize request
422  *
423  */
424 static int aac_src_ioremap(struct aac_dev *dev, u32 size)
425 {
426         if (!size) {
427                 iounmap(dev->regs.src.bar0);
428                 dev->base = dev->regs.src.bar0 = NULL;
429                 return 0;
430         }
431         dev->regs.src.bar1 = ioremap(pci_resource_start(dev->pdev, 2),
432                 AAC_MIN_SRC_BAR1_SIZE);
433         dev->base = NULL;
434         if (dev->regs.src.bar1 == NULL)
435                 return -1;
436         dev->base = dev->regs.src.bar0 = ioremap(dev->scsi_host_ptr->base,
437                                 size);
438         if (dev->base == NULL) {
439                 iounmap(dev->regs.src.bar1);
440                 dev->regs.src.bar1 = NULL;
441                 return -1;
442         }
443         dev->IndexRegs = &((struct src_registers __iomem *)
444                 dev->base)->u.tupelo.IndexRegs;
445         return 0;
446 }
447
448 /**
449  *  aac_srcv_ioremap
450  *      @size: mapping resize request
451  *
452  */
453 static int aac_srcv_ioremap(struct aac_dev *dev, u32 size)
454 {
455         if (!size) {
456                 iounmap(dev->regs.src.bar0);
457                 dev->base = dev->regs.src.bar0 = NULL;
458                 return 0;
459         }
460         dev->base = dev->regs.src.bar0 = ioremap(dev->scsi_host_ptr->base, size);
461         if (dev->base == NULL)
462                 return -1;
463         dev->IndexRegs = &((struct src_registers __iomem *)
464                 dev->base)->u.denali.IndexRegs;
465         return 0;
466 }
467
468 static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
469 {
470         u32 var, reset_mask;
471
472         if (bled >= 0) {
473                 if (bled)
474                         printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
475                                 dev->name, dev->id, bled);
476                 bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
477                         0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
478                         if (bled || (var != 0x00000001))
479                                 return -EINVAL;
480                 if (dev->supplement_adapter_info.SupportedOptions2 &
481                         AAC_OPTION_DOORBELL_RESET) {
482                         src_writel(dev, MUnit.IDR, reset_mask);
483                         msleep(5000); /* Delay 5 seconds */
484                 }
485         }
486
487         if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC)
488                 return -ENODEV;
489
490         if (startup_timeout < 300)
491                 startup_timeout = 300;
492
493         return 0;
494 }
495
496 /**
497  *      aac_src_select_comm     -       Select communications method
498  *      @dev: Adapter
499  *      @comm: communications method
500  */
501 int aac_src_select_comm(struct aac_dev *dev, int comm)
502 {
503         switch (comm) {
504         case AAC_COMM_MESSAGE:
505                 dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
506                 dev->a_ops.adapter_intr = aac_src_intr_message;
507                 dev->a_ops.adapter_deliver = aac_src_deliver_message;
508                 break;
509         default:
510                 return 1;
511         }
512         return 0;
513 }
514
515 /**
516  *  aac_src_init        -       initialize an Cardinal Frey Bar card
517  *  @dev: device to configure
518  *
519  */
520
521 int aac_src_init(struct aac_dev *dev)
522 {
523         unsigned long start;
524         unsigned long status;
525         int restart = 0;
526         int instance = dev->id;
527         const char *name = dev->name;
528
529         dev->a_ops.adapter_ioremap = aac_src_ioremap;
530         dev->a_ops.adapter_comm = aac_src_select_comm;
531
532         dev->base_size = AAC_MIN_SRC_BAR0_SIZE;
533         if (aac_adapter_ioremap(dev, dev->base_size)) {
534                 printk(KERN_WARNING "%s: unable to map adapter.\n", name);
535                 goto error_iounmap;
536         }
537
538         /* Failure to reset here is an option ... */
539         dev->a_ops.adapter_sync_cmd = src_sync_cmd;
540         dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
541         if ((aac_reset_devices || reset_devices) &&
542                 !aac_src_restart_adapter(dev, 0))
543                 ++restart;
544         /*
545          *      Check to see if the board panic'd while booting.
546          */
547         status = src_readl(dev, MUnit.OMR);
548         if (status & KERNEL_PANIC) {
549                 if (aac_src_restart_adapter(dev, aac_src_check_health(dev)))
550                         goto error_iounmap;
551                 ++restart;
552         }
553         /*
554          *      Check to see if the board failed any self tests.
555          */
556         status = src_readl(dev, MUnit.OMR);
557         if (status & SELF_TEST_FAILED) {
558                 printk(KERN_ERR "%s%d: adapter self-test failed.\n",
559                         dev->name, instance);
560                 goto error_iounmap;
561         }
562         /*
563          *      Check to see if the monitor panic'd while booting.
564          */
565         if (status & MONITOR_PANIC) {
566                 printk(KERN_ERR "%s%d: adapter monitor panic.\n",
567                         dev->name, instance);
568                 goto error_iounmap;
569         }
570         start = jiffies;
571         /*
572          *      Wait for the adapter to be up and running. Wait up to 3 minutes
573          */
574         while (!((status = src_readl(dev, MUnit.OMR)) &
575                 KERNEL_UP_AND_RUNNING)) {
576                 if ((restart &&
577                   (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
578                   time_after(jiffies, start+HZ*startup_timeout)) {
579                         printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
580                                         dev->name, instance, status);
581                         goto error_iounmap;
582                 }
583                 if (!restart &&
584                   ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
585                   time_after(jiffies, start + HZ *
586                   ((startup_timeout > 60)
587                     ? (startup_timeout - 60)
588                     : (startup_timeout / 2))))) {
589                         if (likely(!aac_src_restart_adapter(dev,
590                             aac_src_check_health(dev))))
591                                 start = jiffies;
592                         ++restart;
593                 }
594                 msleep(1);
595         }
596         if (restart && aac_commit)
597                 aac_commit = 1;
598         /*
599          *      Fill in the common function dispatch table.
600          */
601         dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
602         dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
603         dev->a_ops.adapter_notify = aac_src_notify_adapter;
604         dev->a_ops.adapter_sync_cmd = src_sync_cmd;
605         dev->a_ops.adapter_check_health = aac_src_check_health;
606         dev->a_ops.adapter_restart = aac_src_restart_adapter;
607
608         /*
609          *      First clear out all interrupts.  Then enable the one's that we
610          *      can handle.
611          */
612         aac_adapter_comm(dev, AAC_COMM_MESSAGE);
613         aac_adapter_disable_int(dev);
614         src_writel(dev, MUnit.ODR_C, 0xffffffff);
615         aac_adapter_enable_int(dev);
616
617         if (aac_init_adapter(dev) == NULL)
618                 goto error_iounmap;
619         if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1)
620                 goto error_iounmap;
621
622         dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
623
624         if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
625                         IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) {
626
627                 if (dev->msi)
628                         pci_disable_msi(dev->pdev);
629
630                 printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
631                         name, instance);
632                 goto error_iounmap;
633         }
634         dev->dbg_base = pci_resource_start(dev->pdev, 2);
635         dev->dbg_base_mapped = dev->regs.src.bar1;
636         dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE;
637
638         aac_adapter_enable_int(dev);
639
640         if (!dev->sync_mode) {
641                 /*
642                  * Tell the adapter that all is configured, and it can
643                  * start accepting requests
644                  */
645                 aac_src_start_adapter(dev);
646         }
647         return 0;
648
649 error_iounmap:
650
651         return -1;
652 }
653
654 /**
655  *  aac_srcv_init       -       initialize an SRCv card
656  *  @dev: device to configure
657  *
658  */
659
660 int aac_srcv_init(struct aac_dev *dev)
661 {
662         unsigned long start;
663         unsigned long status;
664         int restart = 0;
665         int instance = dev->id;
666         const char *name = dev->name;
667
668         dev->a_ops.adapter_ioremap = aac_srcv_ioremap;
669         dev->a_ops.adapter_comm = aac_src_select_comm;
670
671         dev->base_size = AAC_MIN_SRCV_BAR0_SIZE;
672         if (aac_adapter_ioremap(dev, dev->base_size)) {
673                 printk(KERN_WARNING "%s: unable to map adapter.\n", name);
674                 goto error_iounmap;
675         }
676
677         /* Failure to reset here is an option ... */
678         dev->a_ops.adapter_sync_cmd = src_sync_cmd;
679         dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
680         if ((aac_reset_devices || reset_devices) &&
681                 !aac_src_restart_adapter(dev, 0))
682                 ++restart;
683         /*
684          *      Check to see if the board panic'd while booting.
685          */
686         status = src_readl(dev, MUnit.OMR);
687         if (status & KERNEL_PANIC) {
688                 if (aac_src_restart_adapter(dev, aac_src_check_health(dev)))
689                         goto error_iounmap;
690                 ++restart;
691         }
692         /*
693          *      Check to see if the board failed any self tests.
694          */
695         status = src_readl(dev, MUnit.OMR);
696         if (status & SELF_TEST_FAILED) {
697                 printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance);
698                 goto error_iounmap;
699         }
700         /*
701          *      Check to see if the monitor panic'd while booting.
702          */
703         if (status & MONITOR_PANIC) {
704                 printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance);
705                 goto error_iounmap;
706         }
707         start = jiffies;
708         /*
709          *      Wait for the adapter to be up and running. Wait up to 3 minutes
710          */
711         while (!((status = src_readl(dev, MUnit.OMR)) & KERNEL_UP_AND_RUNNING)) {
712                 if ((restart &&
713                   (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
714                   time_after(jiffies, start+HZ*startup_timeout)) {
715                         printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
716                                         dev->name, instance, status);
717                         goto error_iounmap;
718                 }
719                 if (!restart &&
720                   ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
721                   time_after(jiffies, start + HZ *
722                   ((startup_timeout > 60)
723                     ? (startup_timeout - 60)
724                     : (startup_timeout / 2))))) {
725                         if (likely(!aac_src_restart_adapter(dev, aac_src_check_health(dev))))
726                                 start = jiffies;
727                         ++restart;
728                 }
729                 msleep(1);
730         }
731         if (restart && aac_commit)
732                 aac_commit = 1;
733         /*
734          *      Fill in the common function dispatch table.
735          */
736         dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
737         dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
738         dev->a_ops.adapter_notify = aac_src_notify_adapter;
739         dev->a_ops.adapter_sync_cmd = src_sync_cmd;
740         dev->a_ops.adapter_check_health = aac_src_check_health;
741         dev->a_ops.adapter_restart = aac_src_restart_adapter;
742
743         /*
744          *      First clear out all interrupts.  Then enable the one's that we
745          *      can handle.
746          */
747         aac_adapter_comm(dev, AAC_COMM_MESSAGE);
748         aac_adapter_disable_int(dev);
749         src_writel(dev, MUnit.ODR_C, 0xffffffff);
750         aac_adapter_enable_int(dev);
751
752         if (aac_init_adapter(dev) == NULL)
753                 goto error_iounmap;
754         if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1)
755                 goto error_iounmap;
756         dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
757         if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
758                 IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) {
759                 if (dev->msi)
760                         pci_disable_msi(dev->pdev);
761                 printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
762                         name, instance);
763                 goto error_iounmap;
764         }
765         dev->dbg_base = dev->scsi_host_ptr->base;
766         dev->dbg_base_mapped = dev->base;
767         dev->dbg_size = dev->base_size;
768
769         aac_adapter_enable_int(dev);
770
771         if (!dev->sync_mode) {
772                 /*
773                  * Tell the adapter that all is configured, and it can
774                  * start accepting requests
775                  */
776                 aac_src_start_adapter(dev);
777         }
778         return 0;
779
780 error_iounmap:
781
782         return -1;
783 }
784