]> Pileus Git - ~andy/linux/blob - drivers/scsi/aacraid/src.c
Merge branch 'for_3.5/fixes/pm' of git://git.kernel.org/pub/scm/linux/kernel/git...
[~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.bar1);
428                 dev->regs.src.bar1 = NULL;
429                 iounmap(dev->regs.src.bar0);
430                 dev->base = dev->regs.src.bar0 = NULL;
431                 return 0;
432         }
433         dev->regs.src.bar1 = ioremap(pci_resource_start(dev->pdev, 2),
434                 AAC_MIN_SRC_BAR1_SIZE);
435         dev->base = NULL;
436         if (dev->regs.src.bar1 == NULL)
437                 return -1;
438         dev->base = dev->regs.src.bar0 = ioremap(dev->scsi_host_ptr->base,
439                                 size);
440         if (dev->base == NULL) {
441                 iounmap(dev->regs.src.bar1);
442                 dev->regs.src.bar1 = NULL;
443                 return -1;
444         }
445         dev->IndexRegs = &((struct src_registers __iomem *)
446                 dev->base)->u.tupelo.IndexRegs;
447         return 0;
448 }
449
450 /**
451  *  aac_srcv_ioremap
452  *      @size: mapping resize request
453  *
454  */
455 static int aac_srcv_ioremap(struct aac_dev *dev, u32 size)
456 {
457         if (!size) {
458                 iounmap(dev->regs.src.bar0);
459                 dev->base = dev->regs.src.bar0 = NULL;
460                 return 0;
461         }
462         dev->base = dev->regs.src.bar0 = ioremap(dev->scsi_host_ptr->base, size);
463         if (dev->base == NULL)
464                 return -1;
465         dev->IndexRegs = &((struct src_registers __iomem *)
466                 dev->base)->u.denali.IndexRegs;
467         return 0;
468 }
469
470 static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
471 {
472         u32 var, reset_mask;
473
474         if (bled >= 0) {
475                 if (bled)
476                         printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
477                                 dev->name, dev->id, bled);
478                 bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
479                         0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
480                         if (bled || (var != 0x00000001))
481                                 return -EINVAL;
482                 if (dev->supplement_adapter_info.SupportedOptions2 &
483                         AAC_OPTION_DOORBELL_RESET) {
484                         src_writel(dev, MUnit.IDR, reset_mask);
485                         msleep(5000); /* Delay 5 seconds */
486                 }
487         }
488
489         if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC)
490                 return -ENODEV;
491
492         if (startup_timeout < 300)
493                 startup_timeout = 300;
494
495         return 0;
496 }
497
498 /**
499  *      aac_src_select_comm     -       Select communications method
500  *      @dev: Adapter
501  *      @comm: communications method
502  */
503 int aac_src_select_comm(struct aac_dev *dev, int comm)
504 {
505         switch (comm) {
506         case AAC_COMM_MESSAGE:
507                 dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
508                 dev->a_ops.adapter_intr = aac_src_intr_message;
509                 dev->a_ops.adapter_deliver = aac_src_deliver_message;
510                 break;
511         default:
512                 return 1;
513         }
514         return 0;
515 }
516
517 /**
518  *  aac_src_init        -       initialize an Cardinal Frey Bar card
519  *  @dev: device to configure
520  *
521  */
522
523 int aac_src_init(struct aac_dev *dev)
524 {
525         unsigned long start;
526         unsigned long status;
527         int restart = 0;
528         int instance = dev->id;
529         const char *name = dev->name;
530
531         dev->a_ops.adapter_ioremap = aac_src_ioremap;
532         dev->a_ops.adapter_comm = aac_src_select_comm;
533
534         dev->base_size = AAC_MIN_SRC_BAR0_SIZE;
535         if (aac_adapter_ioremap(dev, dev->base_size)) {
536                 printk(KERN_WARNING "%s: unable to map adapter.\n", name);
537                 goto error_iounmap;
538         }
539
540         /* Failure to reset here is an option ... */
541         dev->a_ops.adapter_sync_cmd = src_sync_cmd;
542         dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
543         if ((aac_reset_devices || reset_devices) &&
544                 !aac_src_restart_adapter(dev, 0))
545                 ++restart;
546         /*
547          *      Check to see if the board panic'd while booting.
548          */
549         status = src_readl(dev, MUnit.OMR);
550         if (status & KERNEL_PANIC) {
551                 if (aac_src_restart_adapter(dev, aac_src_check_health(dev)))
552                         goto error_iounmap;
553                 ++restart;
554         }
555         /*
556          *      Check to see if the board failed any self tests.
557          */
558         status = src_readl(dev, MUnit.OMR);
559         if (status & SELF_TEST_FAILED) {
560                 printk(KERN_ERR "%s%d: adapter self-test failed.\n",
561                         dev->name, instance);
562                 goto error_iounmap;
563         }
564         /*
565          *      Check to see if the monitor panic'd while booting.
566          */
567         if (status & MONITOR_PANIC) {
568                 printk(KERN_ERR "%s%d: adapter monitor panic.\n",
569                         dev->name, instance);
570                 goto error_iounmap;
571         }
572         start = jiffies;
573         /*
574          *      Wait for the adapter to be up and running. Wait up to 3 minutes
575          */
576         while (!((status = src_readl(dev, MUnit.OMR)) &
577                 KERNEL_UP_AND_RUNNING)) {
578                 if ((restart &&
579                   (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
580                   time_after(jiffies, start+HZ*startup_timeout)) {
581                         printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
582                                         dev->name, instance, status);
583                         goto error_iounmap;
584                 }
585                 if (!restart &&
586                   ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
587                   time_after(jiffies, start + HZ *
588                   ((startup_timeout > 60)
589                     ? (startup_timeout - 60)
590                     : (startup_timeout / 2))))) {
591                         if (likely(!aac_src_restart_adapter(dev,
592                             aac_src_check_health(dev))))
593                                 start = jiffies;
594                         ++restart;
595                 }
596                 msleep(1);
597         }
598         if (restart && aac_commit)
599                 aac_commit = 1;
600         /*
601          *      Fill in the common function dispatch table.
602          */
603         dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
604         dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
605         dev->a_ops.adapter_notify = aac_src_notify_adapter;
606         dev->a_ops.adapter_sync_cmd = src_sync_cmd;
607         dev->a_ops.adapter_check_health = aac_src_check_health;
608         dev->a_ops.adapter_restart = aac_src_restart_adapter;
609
610         /*
611          *      First clear out all interrupts.  Then enable the one's that we
612          *      can handle.
613          */
614         aac_adapter_comm(dev, AAC_COMM_MESSAGE);
615         aac_adapter_disable_int(dev);
616         src_writel(dev, MUnit.ODR_C, 0xffffffff);
617         aac_adapter_enable_int(dev);
618
619         if (aac_init_adapter(dev) == NULL)
620                 goto error_iounmap;
621         if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1)
622                 goto error_iounmap;
623
624         dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
625
626         if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
627                         IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) {
628
629                 if (dev->msi)
630                         pci_disable_msi(dev->pdev);
631
632                 printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
633                         name, instance);
634                 goto error_iounmap;
635         }
636         dev->dbg_base = pci_resource_start(dev->pdev, 2);
637         dev->dbg_base_mapped = dev->regs.src.bar1;
638         dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE;
639
640         aac_adapter_enable_int(dev);
641
642         if (!dev->sync_mode) {
643                 /*
644                  * Tell the adapter that all is configured, and it can
645                  * start accepting requests
646                  */
647                 aac_src_start_adapter(dev);
648         }
649         return 0;
650
651 error_iounmap:
652
653         return -1;
654 }
655
656 /**
657  *  aac_srcv_init       -       initialize an SRCv card
658  *  @dev: device to configure
659  *
660  */
661
662 int aac_srcv_init(struct aac_dev *dev)
663 {
664         unsigned long start;
665         unsigned long status;
666         int restart = 0;
667         int instance = dev->id;
668         const char *name = dev->name;
669
670         dev->a_ops.adapter_ioremap = aac_srcv_ioremap;
671         dev->a_ops.adapter_comm = aac_src_select_comm;
672
673         dev->base_size = AAC_MIN_SRCV_BAR0_SIZE;
674         if (aac_adapter_ioremap(dev, dev->base_size)) {
675                 printk(KERN_WARNING "%s: unable to map adapter.\n", name);
676                 goto error_iounmap;
677         }
678
679         /* Failure to reset here is an option ... */
680         dev->a_ops.adapter_sync_cmd = src_sync_cmd;
681         dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
682         if ((aac_reset_devices || reset_devices) &&
683                 !aac_src_restart_adapter(dev, 0))
684                 ++restart;
685         /*
686          *      Check to see if the board panic'd while booting.
687          */
688         status = src_readl(dev, MUnit.OMR);
689         if (status & KERNEL_PANIC) {
690                 if (aac_src_restart_adapter(dev, aac_src_check_health(dev)))
691                         goto error_iounmap;
692                 ++restart;
693         }
694         /*
695          *      Check to see if the board failed any self tests.
696          */
697         status = src_readl(dev, MUnit.OMR);
698         if (status & SELF_TEST_FAILED) {
699                 printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance);
700                 goto error_iounmap;
701         }
702         /*
703          *      Check to see if the monitor panic'd while booting.
704          */
705         if (status & MONITOR_PANIC) {
706                 printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance);
707                 goto error_iounmap;
708         }
709         start = jiffies;
710         /*
711          *      Wait for the adapter to be up and running. Wait up to 3 minutes
712          */
713         while (!((status = src_readl(dev, MUnit.OMR)) & KERNEL_UP_AND_RUNNING)) {
714                 if ((restart &&
715                   (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
716                   time_after(jiffies, start+HZ*startup_timeout)) {
717                         printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
718                                         dev->name, instance, status);
719                         goto error_iounmap;
720                 }
721                 if (!restart &&
722                   ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
723                   time_after(jiffies, start + HZ *
724                   ((startup_timeout > 60)
725                     ? (startup_timeout - 60)
726                     : (startup_timeout / 2))))) {
727                         if (likely(!aac_src_restart_adapter(dev, aac_src_check_health(dev))))
728                                 start = jiffies;
729                         ++restart;
730                 }
731                 msleep(1);
732         }
733         if (restart && aac_commit)
734                 aac_commit = 1;
735         /*
736          *      Fill in the common function dispatch table.
737          */
738         dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
739         dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
740         dev->a_ops.adapter_notify = aac_src_notify_adapter;
741         dev->a_ops.adapter_sync_cmd = src_sync_cmd;
742         dev->a_ops.adapter_check_health = aac_src_check_health;
743         dev->a_ops.adapter_restart = aac_src_restart_adapter;
744
745         /*
746          *      First clear out all interrupts.  Then enable the one's that we
747          *      can handle.
748          */
749         aac_adapter_comm(dev, AAC_COMM_MESSAGE);
750         aac_adapter_disable_int(dev);
751         src_writel(dev, MUnit.ODR_C, 0xffffffff);
752         aac_adapter_enable_int(dev);
753
754         if (aac_init_adapter(dev) == NULL)
755                 goto error_iounmap;
756         if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1)
757                 goto error_iounmap;
758         dev->msi = aac_msi && !pci_enable_msi(dev->pdev);
759         if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
760                 IRQF_SHARED|IRQF_DISABLED, "aacraid", dev) < 0) {
761                 if (dev->msi)
762                         pci_disable_msi(dev->pdev);
763                 printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
764                         name, instance);
765                 goto error_iounmap;
766         }
767         dev->dbg_base = dev->scsi_host_ptr->base;
768         dev->dbg_base_mapped = dev->base;
769         dev->dbg_size = dev->base_size;
770
771         aac_adapter_enable_int(dev);
772
773         if (!dev->sync_mode) {
774                 /*
775                  * Tell the adapter that all is configured, and it can
776                  * start accepting requests
777                  */
778                 aac_src_start_adapter(dev);
779         }
780         return 0;
781
782 error_iounmap:
783
784         return -1;
785 }
786