Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Adaptec AAC series RAID controller driver
0004  *  (c) Copyright 2001 Red Hat Inc.
0005  *
0006  * based on the old aacraid driver that is..
0007  * Adaptec aacraid device driver for Linux.
0008  *
0009  * Copyright (c) 2000-2010 Adaptec, Inc.
0010  *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
0011  *       2016-2017 Microsemi Corp. (aacraid@microsemi.com)
0012  *
0013  * Module Name:
0014  *  src.c
0015  *
0016  * Abstract: Hardware Device Interface for PMC SRC based controllers
0017  */
0018 
0019 #include <linux/kernel.h>
0020 #include <linux/init.h>
0021 #include <linux/types.h>
0022 #include <linux/pci.h>
0023 #include <linux/spinlock.h>
0024 #include <linux/slab.h>
0025 #include <linux/blkdev.h>
0026 #include <linux/delay.h>
0027 #include <linux/completion.h>
0028 #include <linux/time.h>
0029 #include <linux/interrupt.h>
0030 #include <scsi/scsi_host.h>
0031 
0032 #include "aacraid.h"
0033 
0034 static int aac_src_get_sync_status(struct aac_dev *dev);
0035 
0036 static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
0037 {
0038     struct aac_msix_ctx *ctx;
0039     struct aac_dev *dev;
0040     unsigned long bellbits, bellbits_shifted;
0041     int vector_no;
0042     int isFastResponse, mode;
0043     u32 index, handle;
0044 
0045     ctx = (struct aac_msix_ctx *)dev_id;
0046     dev = ctx->dev;
0047     vector_no = ctx->vector_no;
0048 
0049     if (dev->msi_enabled) {
0050         mode = AAC_INT_MODE_MSI;
0051         if (vector_no == 0) {
0052             bellbits = src_readl(dev, MUnit.ODR_MSI);
0053             if (bellbits & 0x40000)
0054                 mode |= AAC_INT_MODE_AIF;
0055             if (bellbits & 0x1000)
0056                 mode |= AAC_INT_MODE_SYNC;
0057         }
0058     } else {
0059         mode = AAC_INT_MODE_INTX;
0060         bellbits = src_readl(dev, MUnit.ODR_R);
0061         if (bellbits & PmDoorBellResponseSent) {
0062             bellbits = PmDoorBellResponseSent;
0063             src_writel(dev, MUnit.ODR_C, bellbits);
0064             src_readl(dev, MUnit.ODR_C);
0065         } else {
0066             bellbits_shifted = (bellbits >> SRC_ODR_SHIFT);
0067             src_writel(dev, MUnit.ODR_C, bellbits);
0068             src_readl(dev, MUnit.ODR_C);
0069 
0070             if (bellbits_shifted & DoorBellAifPending)
0071                 mode |= AAC_INT_MODE_AIF;
0072             else if (bellbits_shifted & OUTBOUNDDOORBELL_0)
0073                 mode |= AAC_INT_MODE_SYNC;
0074         }
0075     }
0076 
0077     if (mode & AAC_INT_MODE_SYNC) {
0078         unsigned long sflags;
0079         struct list_head *entry;
0080         int send_it = 0;
0081         extern int aac_sync_mode;
0082 
0083         if (!aac_sync_mode && !dev->msi_enabled) {
0084             src_writel(dev, MUnit.ODR_C, bellbits);
0085             src_readl(dev, MUnit.ODR_C);
0086         }
0087 
0088         if (dev->sync_fib) {
0089             if (dev->sync_fib->callback)
0090                 dev->sync_fib->callback(dev->sync_fib->callback_data,
0091                     dev->sync_fib);
0092             spin_lock_irqsave(&dev->sync_fib->event_lock, sflags);
0093             if (dev->sync_fib->flags & FIB_CONTEXT_FLAG_WAIT) {
0094                 dev->management_fib_count--;
0095                 complete(&dev->sync_fib->event_wait);
0096             }
0097             spin_unlock_irqrestore(&dev->sync_fib->event_lock,
0098                         sflags);
0099             spin_lock_irqsave(&dev->sync_lock, sflags);
0100             if (!list_empty(&dev->sync_fib_list)) {
0101                 entry = dev->sync_fib_list.next;
0102                 dev->sync_fib = list_entry(entry,
0103                                struct fib,
0104                                fiblink);
0105                 list_del(entry);
0106                 send_it = 1;
0107             } else {
0108                 dev->sync_fib = NULL;
0109             }
0110             spin_unlock_irqrestore(&dev->sync_lock, sflags);
0111             if (send_it) {
0112                 aac_adapter_sync_cmd(dev, SEND_SYNCHRONOUS_FIB,
0113                     (u32)dev->sync_fib->hw_fib_pa,
0114                     0, 0, 0, 0, 0,
0115                     NULL, NULL, NULL, NULL, NULL);
0116             }
0117         }
0118         if (!dev->msi_enabled)
0119             mode = 0;
0120 
0121     }
0122 
0123     if (mode & AAC_INT_MODE_AIF) {
0124         /* handle AIF */
0125         if (dev->sa_firmware) {
0126             u32 events = src_readl(dev, MUnit.SCR0);
0127 
0128             aac_intr_normal(dev, events, 1, 0, NULL);
0129             writel(events, &dev->IndexRegs->Mailbox[0]);
0130             src_writel(dev, MUnit.IDR, 1 << 23);
0131         } else {
0132             if (dev->aif_thread && dev->fsa_dev)
0133                 aac_intr_normal(dev, 0, 2, 0, NULL);
0134         }
0135         if (dev->msi_enabled)
0136             aac_src_access_devreg(dev, AAC_CLEAR_AIF_BIT);
0137         mode = 0;
0138     }
0139 
0140     if (mode) {
0141         index = dev->host_rrq_idx[vector_no];
0142 
0143         for (;;) {
0144             isFastResponse = 0;
0145             /* remove toggle bit (31) */
0146             handle = le32_to_cpu((dev->host_rrq[index])
0147                 & 0x7fffffff);
0148             /* check fast response bits (30, 1) */
0149             if (handle & 0x40000000)
0150                 isFastResponse = 1;
0151             handle &= 0x0000ffff;
0152             if (handle == 0)
0153                 break;
0154             handle >>= 2;
0155             if (dev->msi_enabled && dev->max_msix > 1)
0156                 atomic_dec(&dev->rrq_outstanding[vector_no]);
0157             aac_intr_normal(dev, handle, 0, isFastResponse, NULL);
0158             dev->host_rrq[index++] = 0;
0159             if (index == (vector_no + 1) * dev->vector_cap)
0160                 index = vector_no * dev->vector_cap;
0161             dev->host_rrq_idx[vector_no] = index;
0162         }
0163         mode = 0;
0164     }
0165 
0166     return IRQ_HANDLED;
0167 }
0168 
0169 /**
0170  *  aac_src_disable_interrupt   -   Disable interrupts
0171  *  @dev: Adapter
0172  */
0173 
0174 static void aac_src_disable_interrupt(struct aac_dev *dev)
0175 {
0176     src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff);
0177 }
0178 
0179 /**
0180  *  aac_src_enable_interrupt_message    -   Enable interrupts
0181  *  @dev: Adapter
0182  */
0183 
0184 static void aac_src_enable_interrupt_message(struct aac_dev *dev)
0185 {
0186     aac_src_access_devreg(dev, AAC_ENABLE_INTERRUPT);
0187 }
0188 
0189 /**
0190  *  src_sync_cmd    -   send a command and wait
0191  *  @dev: Adapter
0192  *  @command: Command to execute
0193  *  @p1: first parameter
0194  *  @p2: second parameter
0195  *  @p3: third parameter
0196  *  @p4: forth parameter
0197  *  @p5: fifth parameter
0198  *  @p6: sixth parameter
0199  *  @status: adapter status
0200  *  @r1: first return value
0201  *  @r2: second return valu
0202  *  @r3: third return value
0203  *  @r4: forth return value
0204  *
0205  *  This routine will send a synchronous command to the adapter and wait
0206  *  for its completion.
0207  */
0208 
0209 static int src_sync_cmd(struct aac_dev *dev, u32 command,
0210     u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6,
0211     u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
0212 {
0213     unsigned long start;
0214     unsigned long delay;
0215     int ok;
0216 
0217     /*
0218      *  Write the command into Mailbox 0
0219      */
0220     writel(command, &dev->IndexRegs->Mailbox[0]);
0221     /*
0222      *  Write the parameters into Mailboxes 1 - 6
0223      */
0224     writel(p1, &dev->IndexRegs->Mailbox[1]);
0225     writel(p2, &dev->IndexRegs->Mailbox[2]);
0226     writel(p3, &dev->IndexRegs->Mailbox[3]);
0227     writel(p4, &dev->IndexRegs->Mailbox[4]);
0228 
0229     /*
0230      *  Clear the synch command doorbell to start on a clean slate.
0231      */
0232     if (!dev->msi_enabled)
0233         src_writel(dev,
0234                MUnit.ODR_C,
0235                OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
0236 
0237     /*
0238      *  Disable doorbell interrupts
0239      */
0240     src_writel(dev, MUnit.OIMR, dev->OIMR = 0xffffffff);
0241 
0242     /*
0243      *  Force the completion of the mask register write before issuing
0244      *  the interrupt.
0245      */
0246     src_readl(dev, MUnit.OIMR);
0247 
0248     /*
0249      *  Signal that there is a new synch command
0250      */
0251     src_writel(dev, MUnit.IDR, INBOUNDDOORBELL_0 << SRC_IDR_SHIFT);
0252 
0253     if ((!dev->sync_mode || command != SEND_SYNCHRONOUS_FIB) &&
0254         !dev->in_soft_reset) {
0255         ok = 0;
0256         start = jiffies;
0257 
0258         if (command == IOP_RESET_ALWAYS) {
0259             /* Wait up to 10 sec */
0260             delay = 10*HZ;
0261         } else {
0262             /* Wait up to 5 minutes */
0263             delay = 300*HZ;
0264         }
0265         while (time_before(jiffies, start+delay)) {
0266             udelay(5);  /* Delay 5 microseconds to let Mon960 get info. */
0267             /*
0268              *  Mon960 will set doorbell0 bit when it has completed the command.
0269              */
0270             if (aac_src_get_sync_status(dev) & OUTBOUNDDOORBELL_0) {
0271                 /*
0272                  *  Clear the doorbell.
0273                  */
0274                 if (dev->msi_enabled)
0275                     aac_src_access_devreg(dev,
0276                         AAC_CLEAR_SYNC_BIT);
0277                 else
0278                     src_writel(dev,
0279                         MUnit.ODR_C,
0280                         OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
0281                 ok = 1;
0282                 break;
0283             }
0284             /*
0285              *  Yield the processor in case we are slow
0286              */
0287             msleep(1);
0288         }
0289         if (unlikely(ok != 1)) {
0290             /*
0291              *  Restore interrupt mask even though we timed out
0292              */
0293             aac_adapter_enable_int(dev);
0294             return -ETIMEDOUT;
0295         }
0296         /*
0297          *  Pull the synch status from Mailbox 0.
0298          */
0299         if (status)
0300             *status = readl(&dev->IndexRegs->Mailbox[0]);
0301         if (r1)
0302             *r1 = readl(&dev->IndexRegs->Mailbox[1]);
0303         if (r2)
0304             *r2 = readl(&dev->IndexRegs->Mailbox[2]);
0305         if (r3)
0306             *r3 = readl(&dev->IndexRegs->Mailbox[3]);
0307         if (r4)
0308             *r4 = readl(&dev->IndexRegs->Mailbox[4]);
0309         if (command == GET_COMM_PREFERRED_SETTINGS)
0310             dev->max_msix =
0311                 readl(&dev->IndexRegs->Mailbox[5]) & 0xFFFF;
0312         /*
0313          *  Clear the synch command doorbell.
0314          */
0315         if (!dev->msi_enabled)
0316             src_writel(dev,
0317                 MUnit.ODR_C,
0318                 OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
0319     }
0320 
0321     /*
0322      *  Restore interrupt mask
0323      */
0324     aac_adapter_enable_int(dev);
0325     return 0;
0326 }
0327 
0328 /**
0329  *  aac_src_interrupt_adapter   -   interrupt adapter
0330  *  @dev: Adapter
0331  *
0332  *  Send an interrupt to the i960 and breakpoint it.
0333  */
0334 
0335 static void aac_src_interrupt_adapter(struct aac_dev *dev)
0336 {
0337     src_sync_cmd(dev, BREAKPOINT_REQUEST,
0338         0, 0, 0, 0, 0, 0,
0339         NULL, NULL, NULL, NULL, NULL);
0340 }
0341 
0342 /**
0343  *  aac_src_notify_adapter      -   send an event to the adapter
0344  *  @dev: Adapter
0345  *  @event: Event to send
0346  *
0347  *  Notify the i960 that something it probably cares about has
0348  *  happened.
0349  */
0350 
0351 static void aac_src_notify_adapter(struct aac_dev *dev, u32 event)
0352 {
0353     switch (event) {
0354 
0355     case AdapNormCmdQue:
0356         src_writel(dev, MUnit.ODR_C,
0357             INBOUNDDOORBELL_1 << SRC_ODR_SHIFT);
0358         break;
0359     case HostNormRespNotFull:
0360         src_writel(dev, MUnit.ODR_C,
0361             INBOUNDDOORBELL_4 << SRC_ODR_SHIFT);
0362         break;
0363     case AdapNormRespQue:
0364         src_writel(dev, MUnit.ODR_C,
0365             INBOUNDDOORBELL_2 << SRC_ODR_SHIFT);
0366         break;
0367     case HostNormCmdNotFull:
0368         src_writel(dev, MUnit.ODR_C,
0369             INBOUNDDOORBELL_3 << SRC_ODR_SHIFT);
0370         break;
0371     case FastIo:
0372         src_writel(dev, MUnit.ODR_C,
0373             INBOUNDDOORBELL_6 << SRC_ODR_SHIFT);
0374         break;
0375     case AdapPrintfDone:
0376         src_writel(dev, MUnit.ODR_C,
0377             INBOUNDDOORBELL_5 << SRC_ODR_SHIFT);
0378         break;
0379     default:
0380         BUG();
0381         break;
0382     }
0383 }
0384 
0385 /**
0386  *  aac_src_start_adapter       -   activate adapter
0387  *  @dev:   Adapter
0388  *
0389  *  Start up processing on an i960 based AAC adapter
0390  */
0391 
0392 static void aac_src_start_adapter(struct aac_dev *dev)
0393 {
0394     union aac_init *init;
0395     int i;
0396 
0397      /* reset host_rrq_idx first */
0398     for (i = 0; i < dev->max_msix; i++) {
0399         dev->host_rrq_idx[i] = i * dev->vector_cap;
0400         atomic_set(&dev->rrq_outstanding[i], 0);
0401     }
0402     atomic_set(&dev->msix_counter, 0);
0403     dev->fibs_pushed_no = 0;
0404 
0405     init = dev->init;
0406     if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) {
0407         init->r8.host_elapsed_seconds =
0408             cpu_to_le32(ktime_get_real_seconds());
0409         src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS,
0410             lower_32_bits(dev->init_pa),
0411             upper_32_bits(dev->init_pa),
0412             sizeof(struct _r8) +
0413             (AAC_MAX_HRRQ - 1) * sizeof(struct _rrq),
0414             0, 0, 0, NULL, NULL, NULL, NULL, NULL);
0415     } else {
0416         init->r7.host_elapsed_seconds =
0417             cpu_to_le32(ktime_get_real_seconds());
0418         // We can only use a 32 bit address here
0419         src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS,
0420             (u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0,
0421             NULL, NULL, NULL, NULL, NULL);
0422     }
0423 
0424 }
0425 
0426 /**
0427  *  aac_src_check_health
0428  *  @dev: device to check if healthy
0429  *
0430  *  Will attempt to determine if the specified adapter is alive and
0431  *  capable of handling requests, returning 0 if alive.
0432  */
0433 static int aac_src_check_health(struct aac_dev *dev)
0434 {
0435     u32 status = src_readl(dev, MUnit.OMR);
0436 
0437     /*
0438      *  Check to see if the board panic'd.
0439      */
0440     if (unlikely(status & KERNEL_PANIC))
0441         goto err_blink;
0442 
0443     /*
0444      *  Check to see if the board failed any self tests.
0445      */
0446     if (unlikely(status & SELF_TEST_FAILED))
0447         goto err_out;
0448 
0449     /*
0450      *  Check to see if the board failed any self tests.
0451      */
0452     if (unlikely(status & MONITOR_PANIC))
0453         goto err_out;
0454 
0455     /*
0456      *  Wait for the adapter to be up and running.
0457      */
0458     if (unlikely(!(status & KERNEL_UP_AND_RUNNING)))
0459         return -3;
0460     /*
0461      *  Everything is OK
0462      */
0463     return 0;
0464 
0465 err_out:
0466     return -1;
0467 
0468 err_blink:
0469     return (status >> 16) & 0xFF;
0470 }
0471 
0472 static inline u32 aac_get_vector(struct aac_dev *dev)
0473 {
0474     return atomic_inc_return(&dev->msix_counter)%dev->max_msix;
0475 }
0476 
0477 /**
0478  *  aac_src_deliver_message
0479  *  @fib: fib to issue
0480  *
0481  *  Will send a fib, returning 0 if successful.
0482  */
0483 static int aac_src_deliver_message(struct fib *fib)
0484 {
0485     struct aac_dev *dev = fib->dev;
0486     struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
0487     u32 fibsize;
0488     dma_addr_t address;
0489     struct aac_fib_xporthdr *pFibX;
0490     int native_hba;
0491 #if !defined(writeq)
0492     unsigned long flags;
0493 #endif
0494 
0495     u16 vector_no;
0496 
0497     atomic_inc(&q->numpending);
0498 
0499     native_hba = (fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA) ? 1 : 0;
0500 
0501 
0502     if (dev->msi_enabled && dev->max_msix > 1 &&
0503         (native_hba || fib->hw_fib_va->header.Command != AifRequest)) {
0504 
0505         if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE3)
0506             && dev->sa_firmware)
0507             vector_no = aac_get_vector(dev);
0508         else
0509             vector_no = fib->vector_no;
0510 
0511         if (native_hba) {
0512             if (fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF) {
0513                 struct aac_hba_tm_req *tm_req;
0514 
0515                 tm_req = (struct aac_hba_tm_req *)
0516                         fib->hw_fib_va;
0517                 if (tm_req->iu_type ==
0518                     HBA_IU_TYPE_SCSI_TM_REQ) {
0519                     ((struct aac_hba_tm_req *)
0520                         fib->hw_fib_va)->reply_qid
0521                             = vector_no;
0522                     ((struct aac_hba_tm_req *)
0523                         fib->hw_fib_va)->request_id
0524                             += (vector_no << 16);
0525                 } else {
0526                     ((struct aac_hba_reset_req *)
0527                         fib->hw_fib_va)->reply_qid
0528                             = vector_no;
0529                     ((struct aac_hba_reset_req *)
0530                         fib->hw_fib_va)->request_id
0531                             += (vector_no << 16);
0532                 }
0533             } else {
0534                 ((struct aac_hba_cmd_req *)
0535                     fib->hw_fib_va)->reply_qid
0536                         = vector_no;
0537                 ((struct aac_hba_cmd_req *)
0538                     fib->hw_fib_va)->request_id
0539                         += (vector_no << 16);
0540             }
0541         } else {
0542             fib->hw_fib_va->header.Handle += (vector_no << 16);
0543         }
0544     } else {
0545         vector_no = 0;
0546     }
0547 
0548     atomic_inc(&dev->rrq_outstanding[vector_no]);
0549 
0550     if (native_hba) {
0551         address = fib->hw_fib_pa;
0552         fibsize = (fib->hbacmd_size + 127) / 128 - 1;
0553         if (fibsize > 31)
0554             fibsize = 31;
0555         address |= fibsize;
0556 #if defined(writeq)
0557         src_writeq(dev, MUnit.IQN_L, (u64)address);
0558 #else
0559         spin_lock_irqsave(&fib->dev->iq_lock, flags);
0560         src_writel(dev, MUnit.IQN_H,
0561             upper_32_bits(address) & 0xffffffff);
0562         src_writel(dev, MUnit.IQN_L, address & 0xffffffff);
0563         spin_unlock_irqrestore(&fib->dev->iq_lock, flags);
0564 #endif
0565     } else {
0566         if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 ||
0567             dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) {
0568             /* Calculate the amount to the fibsize bits */
0569             fibsize = (le16_to_cpu(fib->hw_fib_va->header.Size)
0570                 + 127) / 128 - 1;
0571             /* New FIB header, 32-bit */
0572             address = fib->hw_fib_pa;
0573             fib->hw_fib_va->header.StructType = FIB_MAGIC2;
0574             fib->hw_fib_va->header.SenderFibAddress =
0575                 cpu_to_le32((u32)address);
0576             fib->hw_fib_va->header.u.TimeStamp = 0;
0577             WARN_ON(upper_32_bits(address) != 0L);
0578         } else {
0579             /* Calculate the amount to the fibsize bits */
0580             fibsize = (sizeof(struct aac_fib_xporthdr) +
0581                 le16_to_cpu(fib->hw_fib_va->header.Size)
0582                 + 127) / 128 - 1;
0583             /* Fill XPORT header */
0584             pFibX = (struct aac_fib_xporthdr *)
0585                 ((unsigned char *)fib->hw_fib_va -
0586                 sizeof(struct aac_fib_xporthdr));
0587             pFibX->Handle = fib->hw_fib_va->header.Handle;
0588             pFibX->HostAddress =
0589                 cpu_to_le64((u64)fib->hw_fib_pa);
0590             pFibX->Size = cpu_to_le32(
0591                 le16_to_cpu(fib->hw_fib_va->header.Size));
0592             address = fib->hw_fib_pa -
0593                 (u64)sizeof(struct aac_fib_xporthdr);
0594         }
0595         if (fibsize > 31)
0596             fibsize = 31;
0597         address |= fibsize;
0598 
0599 #if defined(writeq)
0600         src_writeq(dev, MUnit.IQ_L, (u64)address);
0601 #else
0602         spin_lock_irqsave(&fib->dev->iq_lock, flags);
0603         src_writel(dev, MUnit.IQ_H,
0604             upper_32_bits(address) & 0xffffffff);
0605         src_writel(dev, MUnit.IQ_L, address & 0xffffffff);
0606         spin_unlock_irqrestore(&fib->dev->iq_lock, flags);
0607 #endif
0608     }
0609     return 0;
0610 }
0611 
0612 /**
0613  *  aac_src_ioremap
0614  *  @dev: device ioremap
0615  *  @size: mapping resize request
0616  *
0617  */
0618 static int aac_src_ioremap(struct aac_dev *dev, u32 size)
0619 {
0620     if (!size) {
0621         iounmap(dev->regs.src.bar1);
0622         dev->regs.src.bar1 = NULL;
0623         iounmap(dev->regs.src.bar0);
0624         dev->base = dev->regs.src.bar0 = NULL;
0625         return 0;
0626     }
0627     dev->regs.src.bar1 = ioremap(pci_resource_start(dev->pdev, 2),
0628         AAC_MIN_SRC_BAR1_SIZE);
0629     dev->base = NULL;
0630     if (dev->regs.src.bar1 == NULL)
0631         return -1;
0632     dev->base = dev->regs.src.bar0 = ioremap(dev->base_start, size);
0633     if (dev->base == NULL) {
0634         iounmap(dev->regs.src.bar1);
0635         dev->regs.src.bar1 = NULL;
0636         return -1;
0637     }
0638     dev->IndexRegs = &((struct src_registers __iomem *)
0639         dev->base)->u.tupelo.IndexRegs;
0640     return 0;
0641 }
0642 
0643 /**
0644  *  aac_srcv_ioremap
0645  *  @dev: device ioremap
0646  *  @size: mapping resize request
0647  *
0648  */
0649 static int aac_srcv_ioremap(struct aac_dev *dev, u32 size)
0650 {
0651     if (!size) {
0652         iounmap(dev->regs.src.bar0);
0653         dev->base = dev->regs.src.bar0 = NULL;
0654         return 0;
0655     }
0656 
0657     dev->regs.src.bar1 =
0658     ioremap(pci_resource_start(dev->pdev, 2), AAC_MIN_SRCV_BAR1_SIZE);
0659     dev->base = NULL;
0660     if (dev->regs.src.bar1 == NULL)
0661         return -1;
0662     dev->base = dev->regs.src.bar0 = ioremap(dev->base_start, size);
0663     if (dev->base == NULL) {
0664         iounmap(dev->regs.src.bar1);
0665         dev->regs.src.bar1 = NULL;
0666         return -1;
0667     }
0668     dev->IndexRegs = &((struct src_registers __iomem *)
0669         dev->base)->u.denali.IndexRegs;
0670     return 0;
0671 }
0672 
0673 void aac_set_intx_mode(struct aac_dev *dev)
0674 {
0675     if (dev->msi_enabled) {
0676         aac_src_access_devreg(dev, AAC_ENABLE_INTX);
0677         dev->msi_enabled = 0;
0678         msleep(5000); /* Delay 5 seconds */
0679     }
0680 }
0681 
0682 static void aac_clear_omr(struct aac_dev *dev)
0683 {
0684     u32 omr_value = 0;
0685 
0686     omr_value = src_readl(dev, MUnit.OMR);
0687 
0688     /*
0689      * Check for PCI Errors or Kernel Panic
0690      */
0691     if ((omr_value == INVALID_OMR) || (omr_value & KERNEL_PANIC))
0692         omr_value = 0;
0693 
0694     /*
0695      * Preserve MSIX Value if any
0696      */
0697     src_writel(dev, MUnit.OMR, omr_value & AAC_INT_MODE_MSIX);
0698     src_readl(dev, MUnit.OMR);
0699 }
0700 
0701 static void aac_dump_fw_fib_iop_reset(struct aac_dev *dev)
0702 {
0703     __le32 supported_options3;
0704 
0705     if (!aac_fib_dump)
0706         return;
0707 
0708     supported_options3  = dev->supplement_adapter_info.supported_options3;
0709     if (!(supported_options3 & AAC_OPTION_SUPPORTED3_IOP_RESET_FIB_DUMP))
0710         return;
0711 
0712     aac_adapter_sync_cmd(dev, IOP_RESET_FW_FIB_DUMP,
0713             0, 0, 0,  0, 0, 0, NULL, NULL, NULL, NULL, NULL);
0714 }
0715 
0716 static bool aac_is_ctrl_up_and_running(struct aac_dev *dev)
0717 {
0718     bool ctrl_up = true;
0719     unsigned long status, start;
0720     bool is_up = false;
0721 
0722     start = jiffies;
0723     do {
0724         schedule();
0725         status = src_readl(dev, MUnit.OMR);
0726 
0727         if (status == 0xffffffff)
0728             status = 0;
0729 
0730         if (status & KERNEL_BOOTING) {
0731             start = jiffies;
0732             continue;
0733         }
0734 
0735         if (time_after(jiffies, start+HZ*SOFT_RESET_TIME)) {
0736             ctrl_up = false;
0737             break;
0738         }
0739 
0740         is_up = status & KERNEL_UP_AND_RUNNING;
0741 
0742     } while (!is_up);
0743 
0744     return ctrl_up;
0745 }
0746 
0747 static void aac_src_drop_io(struct aac_dev *dev)
0748 {
0749     if (!dev->soft_reset_support)
0750         return;
0751 
0752     aac_adapter_sync_cmd(dev, DROP_IO,
0753             0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
0754 }
0755 
0756 static void aac_notify_fw_of_iop_reset(struct aac_dev *dev)
0757 {
0758     aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS, 0, 0, 0, 0, 0, 0, NULL,
0759                         NULL, NULL, NULL, NULL);
0760     aac_src_drop_io(dev);
0761 }
0762 
0763 static void aac_send_iop_reset(struct aac_dev *dev)
0764 {
0765     aac_dump_fw_fib_iop_reset(dev);
0766 
0767     aac_notify_fw_of_iop_reset(dev);
0768 
0769     aac_set_intx_mode(dev);
0770 
0771     aac_clear_omr(dev);
0772 
0773     src_writel(dev, MUnit.IDR, IOP_SRC_RESET_MASK);
0774 
0775     msleep(5000);
0776 }
0777 
0778 static void aac_send_hardware_soft_reset(struct aac_dev *dev)
0779 {
0780     u_int32_t val;
0781 
0782     aac_clear_omr(dev);
0783     val = readl(((char *)(dev->base) + IBW_SWR_OFFSET));
0784     val |= 0x01;
0785     writel(val, ((char *)(dev->base) + IBW_SWR_OFFSET));
0786     msleep_interruptible(20000);
0787 }
0788 
0789 static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type)
0790 {
0791     bool is_ctrl_up;
0792     int ret = 0;
0793 
0794     if (bled < 0)
0795         goto invalid_out;
0796 
0797     if (bled)
0798         dev_err(&dev->pdev->dev, "adapter kernel panic'd %x.\n", bled);
0799 
0800     /*
0801      * When there is a BlinkLED, IOP_RESET has not effect
0802      */
0803     if (bled >= 2 && dev->sa_firmware && reset_type & HW_IOP_RESET)
0804         reset_type &= ~HW_IOP_RESET;
0805 
0806     dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
0807 
0808     dev_err(&dev->pdev->dev, "Controller reset type is %d\n", reset_type);
0809 
0810     if (reset_type & HW_IOP_RESET) {
0811         dev_info(&dev->pdev->dev, "Issuing IOP reset\n");
0812         aac_send_iop_reset(dev);
0813 
0814         /*
0815          * Creates a delay or wait till up and running comes thru
0816          */
0817         is_ctrl_up = aac_is_ctrl_up_and_running(dev);
0818         if (!is_ctrl_up)
0819             dev_err(&dev->pdev->dev, "IOP reset failed\n");
0820         else {
0821             dev_info(&dev->pdev->dev, "IOP reset succeeded\n");
0822             goto set_startup;
0823         }
0824     }
0825 
0826     if (!dev->sa_firmware) {
0827         dev_err(&dev->pdev->dev, "ARC Reset attempt failed\n");
0828         ret = -ENODEV;
0829         goto out;
0830     }
0831 
0832     if (reset_type & HW_SOFT_RESET) {
0833         dev_info(&dev->pdev->dev, "Issuing SOFT reset\n");
0834         aac_send_hardware_soft_reset(dev);
0835         dev->msi_enabled = 0;
0836 
0837         is_ctrl_up = aac_is_ctrl_up_and_running(dev);
0838         if (!is_ctrl_up) {
0839             dev_err(&dev->pdev->dev, "SOFT reset failed\n");
0840             ret = -ENODEV;
0841             goto out;
0842         } else
0843             dev_info(&dev->pdev->dev, "SOFT reset succeeded\n");
0844     }
0845 
0846 set_startup:
0847     if (startup_timeout < 300)
0848         startup_timeout = 300;
0849 
0850 out:
0851     return ret;
0852 
0853 invalid_out:
0854     if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC)
0855         ret = -ENODEV;
0856 goto out;
0857 }
0858 
0859 /**
0860  *  aac_src_select_comm -   Select communications method
0861  *  @dev: Adapter
0862  *  @comm: communications method
0863  */
0864 static int aac_src_select_comm(struct aac_dev *dev, int comm)
0865 {
0866     switch (comm) {
0867     case AAC_COMM_MESSAGE:
0868         dev->a_ops.adapter_intr = aac_src_intr_message;
0869         dev->a_ops.adapter_deliver = aac_src_deliver_message;
0870         break;
0871     default:
0872         return 1;
0873     }
0874     return 0;
0875 }
0876 
0877 /**
0878  *  aac_src_init    -   initialize an Cardinal Frey Bar card
0879  *  @dev: device to configure
0880  *
0881  */
0882 
0883 int aac_src_init(struct aac_dev *dev)
0884 {
0885     unsigned long start;
0886     unsigned long status;
0887     int restart = 0;
0888     int instance = dev->id;
0889     const char *name = dev->name;
0890 
0891     dev->a_ops.adapter_ioremap = aac_src_ioremap;
0892     dev->a_ops.adapter_comm = aac_src_select_comm;
0893 
0894     dev->base_size = AAC_MIN_SRC_BAR0_SIZE;
0895     if (aac_adapter_ioremap(dev, dev->base_size)) {
0896         printk(KERN_WARNING "%s: unable to map adapter.\n", name);
0897         goto error_iounmap;
0898     }
0899 
0900     /* Failure to reset here is an option ... */
0901     dev->a_ops.adapter_sync_cmd = src_sync_cmd;
0902     dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
0903 
0904     if (dev->init_reset) {
0905         dev->init_reset = false;
0906         if (!aac_src_restart_adapter(dev, 0, IOP_HWSOFT_RESET))
0907             ++restart;
0908     }
0909 
0910     /*
0911      *  Check to see if the board panic'd while booting.
0912      */
0913     status = src_readl(dev, MUnit.OMR);
0914     if (status & KERNEL_PANIC) {
0915         if (aac_src_restart_adapter(dev,
0916             aac_src_check_health(dev), IOP_HWSOFT_RESET))
0917             goto error_iounmap;
0918         ++restart;
0919     }
0920     /*
0921      *  Check to see if the board failed any self tests.
0922      */
0923     status = src_readl(dev, MUnit.OMR);
0924     if (status & SELF_TEST_FAILED) {
0925         printk(KERN_ERR "%s%d: adapter self-test failed.\n",
0926             dev->name, instance);
0927         goto error_iounmap;
0928     }
0929     /*
0930      *  Check to see if the monitor panic'd while booting.
0931      */
0932     if (status & MONITOR_PANIC) {
0933         printk(KERN_ERR "%s%d: adapter monitor panic.\n",
0934             dev->name, instance);
0935         goto error_iounmap;
0936     }
0937     start = jiffies;
0938     /*
0939      *  Wait for the adapter to be up and running. Wait up to 3 minutes
0940      */
0941     while (!((status = src_readl(dev, MUnit.OMR)) &
0942         KERNEL_UP_AND_RUNNING)) {
0943         if ((restart &&
0944           (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
0945           time_after(jiffies, start+HZ*startup_timeout)) {
0946             printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
0947                     dev->name, instance, status);
0948             goto error_iounmap;
0949         }
0950         if (!restart &&
0951           ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
0952           time_after(jiffies, start + HZ *
0953           ((startup_timeout > 60)
0954             ? (startup_timeout - 60)
0955             : (startup_timeout / 2))))) {
0956             if (likely(!aac_src_restart_adapter(dev,
0957                 aac_src_check_health(dev), IOP_HWSOFT_RESET)))
0958                 start = jiffies;
0959             ++restart;
0960         }
0961         msleep(1);
0962     }
0963     if (restart && aac_commit)
0964         aac_commit = 1;
0965     /*
0966      *  Fill in the common function dispatch table.
0967      */
0968     dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
0969     dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
0970     dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
0971     dev->a_ops.adapter_notify = aac_src_notify_adapter;
0972     dev->a_ops.adapter_sync_cmd = src_sync_cmd;
0973     dev->a_ops.adapter_check_health = aac_src_check_health;
0974     dev->a_ops.adapter_restart = aac_src_restart_adapter;
0975     dev->a_ops.adapter_start = aac_src_start_adapter;
0976 
0977     /*
0978      *  First clear out all interrupts.  Then enable the one's that we
0979      *  can handle.
0980      */
0981     aac_adapter_comm(dev, AAC_COMM_MESSAGE);
0982     aac_adapter_disable_int(dev);
0983     src_writel(dev, MUnit.ODR_C, 0xffffffff);
0984     aac_adapter_enable_int(dev);
0985 
0986     if (aac_init_adapter(dev) == NULL)
0987         goto error_iounmap;
0988     if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1)
0989         goto error_iounmap;
0990 
0991     dev->msi = !pci_enable_msi(dev->pdev);
0992 
0993     dev->aac_msix[0].vector_no = 0;
0994     dev->aac_msix[0].dev = dev;
0995 
0996     if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
0997             IRQF_SHARED, "aacraid", &(dev->aac_msix[0]))  < 0) {
0998 
0999         if (dev->msi)
1000             pci_disable_msi(dev->pdev);
1001 
1002         printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
1003             name, instance);
1004         goto error_iounmap;
1005     }
1006     dev->dbg_base = pci_resource_start(dev->pdev, 2);
1007     dev->dbg_base_mapped = dev->regs.src.bar1;
1008     dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE;
1009     dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
1010 
1011     aac_adapter_enable_int(dev);
1012 
1013     if (!dev->sync_mode) {
1014         /*
1015          * Tell the adapter that all is configured, and it can
1016          * start accepting requests
1017          */
1018         aac_src_start_adapter(dev);
1019     }
1020     return 0;
1021 
1022 error_iounmap:
1023 
1024     return -1;
1025 }
1026 
1027 static int aac_src_wait_sync(struct aac_dev *dev, int *status)
1028 {
1029     unsigned long start = jiffies;
1030     unsigned long usecs = 0;
1031     int delay = 5 * HZ;
1032     int rc = 1;
1033 
1034     while (time_before(jiffies, start+delay)) {
1035         /*
1036          * Delay 5 microseconds to let Mon960 get info.
1037          */
1038         udelay(5);
1039 
1040         /*
1041          * Mon960 will set doorbell0 bit when it has completed the
1042          * command.
1043          */
1044         if (aac_src_get_sync_status(dev) & OUTBOUNDDOORBELL_0) {
1045             /*
1046              * Clear: the doorbell.
1047              */
1048             if (dev->msi_enabled)
1049                 aac_src_access_devreg(dev, AAC_CLEAR_SYNC_BIT);
1050             else
1051                 src_writel(dev, MUnit.ODR_C,
1052                     OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT);
1053             rc = 0;
1054 
1055             break;
1056         }
1057 
1058         /*
1059          * Yield the processor in case we are slow
1060          */
1061         usecs = 1 * USEC_PER_MSEC;
1062         usleep_range(usecs, usecs + 50);
1063     }
1064     /*
1065      * Pull the synch status from Mailbox 0.
1066      */
1067     if (status && !rc) {
1068         status[0] = readl(&dev->IndexRegs->Mailbox[0]);
1069         status[1] = readl(&dev->IndexRegs->Mailbox[1]);
1070         status[2] = readl(&dev->IndexRegs->Mailbox[2]);
1071         status[3] = readl(&dev->IndexRegs->Mailbox[3]);
1072         status[4] = readl(&dev->IndexRegs->Mailbox[4]);
1073     }
1074 
1075     return rc;
1076 }
1077 
1078 /**
1079  *  aac_src_soft_reset  -   perform soft reset to speed up
1080  *  access
1081  *
1082  *  Assumptions: That the controller is in a state where we can
1083  *  bring it back to life with an init struct. We can only use
1084  *  fast sync commands, as the timeout is 5 seconds.
1085  *
1086  *  @dev: device to configure
1087  *
1088  */
1089 
1090 static int aac_src_soft_reset(struct aac_dev *dev)
1091 {
1092     u32 status_omr = src_readl(dev, MUnit.OMR);
1093     u32 status[5];
1094     int rc = 1;
1095     int state = 0;
1096     char *state_str[7] = {
1097         "GET_ADAPTER_PROPERTIES Failed",
1098         "GET_ADAPTER_PROPERTIES timeout",
1099         "SOFT_RESET not supported",
1100         "DROP_IO Failed",
1101         "DROP_IO timeout",
1102         "Check Health failed"
1103     };
1104 
1105     if (status_omr == INVALID_OMR)
1106         return 1;       // pcie hosed
1107 
1108     if (!(status_omr & KERNEL_UP_AND_RUNNING))
1109         return 1;       // not up and running
1110 
1111     /*
1112      * We go into soft reset mode to allow us to handle response
1113      */
1114     dev->in_soft_reset = 1;
1115     dev->msi_enabled = status_omr & AAC_INT_MODE_MSIX;
1116 
1117     /* Get adapter properties */
1118     rc = aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES, 0, 0, 0,
1119         0, 0, 0, status+0, status+1, status+2, status+3, status+4);
1120     if (rc)
1121         goto out;
1122 
1123     state++;
1124     if (aac_src_wait_sync(dev, status)) {
1125         rc = 1;
1126         goto out;
1127     }
1128 
1129     state++;
1130     if (!(status[1] & le32_to_cpu(AAC_OPT_EXTENDED) &&
1131         (status[4] & le32_to_cpu(AAC_EXTOPT_SOFT_RESET)))) {
1132         rc = 2;
1133         goto out;
1134     }
1135 
1136     if ((status[1] & le32_to_cpu(AAC_OPT_EXTENDED)) &&
1137         (status[4] & le32_to_cpu(AAC_EXTOPT_SA_FIRMWARE)))
1138         dev->sa_firmware = 1;
1139 
1140     state++;
1141     rc = aac_adapter_sync_cmd(dev, DROP_IO, 0, 0, 0, 0, 0, 0,
1142          status+0, status+1, status+2, status+3, status+4);
1143 
1144     if (rc)
1145         goto out;
1146 
1147     state++;
1148     if (aac_src_wait_sync(dev, status)) {
1149         rc = 3;
1150         goto out;
1151     }
1152 
1153     if (status[1])
1154         dev_err(&dev->pdev->dev, "%s: %d outstanding I/O pending\n",
1155             __func__, status[1]);
1156 
1157     state++;
1158     rc = aac_src_check_health(dev);
1159 
1160 out:
1161     dev->in_soft_reset = 0;
1162     dev->msi_enabled = 0;
1163     if (rc)
1164         dev_err(&dev->pdev->dev, "%s: %s status = %d", __func__,
1165             state_str[state], rc);
1166 
1167     return rc;
1168 }
1169 /**
1170  *  aac_srcv_init   -   initialize an SRCv card
1171  *  @dev: device to configure
1172  *
1173  */
1174 
1175 int aac_srcv_init(struct aac_dev *dev)
1176 {
1177     unsigned long start;
1178     unsigned long status;
1179     int restart = 0;
1180     int instance = dev->id;
1181     const char *name = dev->name;
1182 
1183     dev->a_ops.adapter_ioremap = aac_srcv_ioremap;
1184     dev->a_ops.adapter_comm = aac_src_select_comm;
1185 
1186     dev->base_size = AAC_MIN_SRCV_BAR0_SIZE;
1187     if (aac_adapter_ioremap(dev, dev->base_size)) {
1188         printk(KERN_WARNING "%s: unable to map adapter.\n", name);
1189         goto error_iounmap;
1190     }
1191 
1192     /* Failure to reset here is an option ... */
1193     dev->a_ops.adapter_sync_cmd = src_sync_cmd;
1194     dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
1195 
1196     if (dev->init_reset) {
1197         dev->init_reset = false;
1198         if (aac_src_soft_reset(dev)) {
1199             aac_src_restart_adapter(dev, 0, IOP_HWSOFT_RESET);
1200             ++restart;
1201         }
1202     }
1203 
1204     /*
1205      *  Check to see if flash update is running.
1206      *  Wait for the adapter to be up and running. Wait up to 5 minutes
1207      */
1208     status = src_readl(dev, MUnit.OMR);
1209     if (status & FLASH_UPD_PENDING) {
1210         start = jiffies;
1211         do {
1212             status = src_readl(dev, MUnit.OMR);
1213             if (time_after(jiffies, start+HZ*FWUPD_TIMEOUT)) {
1214                 printk(KERN_ERR "%s%d: adapter flash update failed.\n",
1215                     dev->name, instance);
1216                 goto error_iounmap;
1217             }
1218         } while (!(status & FLASH_UPD_SUCCESS) &&
1219              !(status & FLASH_UPD_FAILED));
1220         /* Delay 10 seconds.
1221          * Because right now FW is doing a soft reset,
1222          * do not read scratch pad register at this time
1223          */
1224         ssleep(10);
1225     }
1226     /*
1227      *  Check to see if the board panic'd while booting.
1228      */
1229     status = src_readl(dev, MUnit.OMR);
1230     if (status & KERNEL_PANIC) {
1231         if (aac_src_restart_adapter(dev,
1232             aac_src_check_health(dev), IOP_HWSOFT_RESET))
1233             goto error_iounmap;
1234         ++restart;
1235     }
1236     /*
1237      *  Check to see if the board failed any self tests.
1238      */
1239     status = src_readl(dev, MUnit.OMR);
1240     if (status & SELF_TEST_FAILED) {
1241         printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance);
1242         goto error_iounmap;
1243     }
1244     /*
1245      *  Check to see if the monitor panic'd while booting.
1246      */
1247     if (status & MONITOR_PANIC) {
1248         printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance);
1249         goto error_iounmap;
1250     }
1251 
1252     start = jiffies;
1253     /*
1254      *  Wait for the adapter to be up and running. Wait up to 3 minutes
1255      */
1256     do {
1257         status = src_readl(dev, MUnit.OMR);
1258         if (status == INVALID_OMR)
1259             status = 0;
1260 
1261         if ((restart &&
1262           (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) ||
1263           time_after(jiffies, start+HZ*startup_timeout)) {
1264             printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n",
1265                     dev->name, instance, status);
1266             goto error_iounmap;
1267         }
1268         if (!restart &&
1269           ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) ||
1270           time_after(jiffies, start + HZ *
1271           ((startup_timeout > 60)
1272             ? (startup_timeout - 60)
1273             : (startup_timeout / 2))))) {
1274             if (likely(!aac_src_restart_adapter(dev,
1275                 aac_src_check_health(dev), IOP_HWSOFT_RESET)))
1276                 start = jiffies;
1277             ++restart;
1278         }
1279         msleep(1);
1280     } while (!(status & KERNEL_UP_AND_RUNNING));
1281 
1282     if (restart && aac_commit)
1283         aac_commit = 1;
1284     /*
1285      *  Fill in the common function dispatch table.
1286      */
1287     dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
1288     dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
1289     dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
1290     dev->a_ops.adapter_notify = aac_src_notify_adapter;
1291     dev->a_ops.adapter_sync_cmd = src_sync_cmd;
1292     dev->a_ops.adapter_check_health = aac_src_check_health;
1293     dev->a_ops.adapter_restart = aac_src_restart_adapter;
1294     dev->a_ops.adapter_start = aac_src_start_adapter;
1295 
1296     /*
1297      *  First clear out all interrupts.  Then enable the one's that we
1298      *  can handle.
1299      */
1300     aac_adapter_comm(dev, AAC_COMM_MESSAGE);
1301     aac_adapter_disable_int(dev);
1302     src_writel(dev, MUnit.ODR_C, 0xffffffff);
1303     aac_adapter_enable_int(dev);
1304 
1305     if (aac_init_adapter(dev) == NULL)
1306         goto error_iounmap;
1307     if ((dev->comm_interface != AAC_COMM_MESSAGE_TYPE2) &&
1308         (dev->comm_interface != AAC_COMM_MESSAGE_TYPE3))
1309         goto error_iounmap;
1310     if (dev->msi_enabled)
1311         aac_src_access_devreg(dev, AAC_ENABLE_MSIX);
1312 
1313     if (aac_acquire_irq(dev))
1314         goto error_iounmap;
1315 
1316     dev->dbg_base = pci_resource_start(dev->pdev, 2);
1317     dev->dbg_base_mapped = dev->regs.src.bar1;
1318     dev->dbg_size = AAC_MIN_SRCV_BAR1_SIZE;
1319     dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
1320 
1321     aac_adapter_enable_int(dev);
1322 
1323     if (!dev->sync_mode) {
1324         /*
1325          * Tell the adapter that all is configured, and it can
1326          * start accepting requests
1327          */
1328         aac_src_start_adapter(dev);
1329     }
1330     return 0;
1331 
1332 error_iounmap:
1333 
1334     return -1;
1335 }
1336 
1337 void aac_src_access_devreg(struct aac_dev *dev, int mode)
1338 {
1339     u_int32_t val;
1340 
1341     switch (mode) {
1342     case AAC_ENABLE_INTERRUPT:
1343         src_writel(dev,
1344                MUnit.OIMR,
1345                dev->OIMR = (dev->msi_enabled ?
1346                     AAC_INT_ENABLE_TYPE1_MSIX :
1347                     AAC_INT_ENABLE_TYPE1_INTX));
1348         break;
1349 
1350     case AAC_DISABLE_INTERRUPT:
1351         src_writel(dev,
1352                MUnit.OIMR,
1353                dev->OIMR = AAC_INT_DISABLE_ALL);
1354         break;
1355 
1356     case AAC_ENABLE_MSIX:
1357         /* set bit 6 */
1358         val = src_readl(dev, MUnit.IDR);
1359         val |= 0x40;
1360         src_writel(dev,  MUnit.IDR, val);
1361         src_readl(dev, MUnit.IDR);
1362         /* unmask int. */
1363         val = PMC_ALL_INTERRUPT_BITS;
1364         src_writel(dev, MUnit.IOAR, val);
1365         val = src_readl(dev, MUnit.OIMR);
1366         src_writel(dev,
1367                MUnit.OIMR,
1368                val & (~(PMC_GLOBAL_INT_BIT2 | PMC_GLOBAL_INT_BIT0)));
1369         break;
1370 
1371     case AAC_DISABLE_MSIX:
1372         /* reset bit 6 */
1373         val = src_readl(dev, MUnit.IDR);
1374         val &= ~0x40;
1375         src_writel(dev, MUnit.IDR, val);
1376         src_readl(dev, MUnit.IDR);
1377         break;
1378 
1379     case AAC_CLEAR_AIF_BIT:
1380         /* set bit 5 */
1381         val = src_readl(dev, MUnit.IDR);
1382         val |= 0x20;
1383         src_writel(dev, MUnit.IDR, val);
1384         src_readl(dev, MUnit.IDR);
1385         break;
1386 
1387     case AAC_CLEAR_SYNC_BIT:
1388         /* set bit 4 */
1389         val = src_readl(dev, MUnit.IDR);
1390         val |= 0x10;
1391         src_writel(dev, MUnit.IDR, val);
1392         src_readl(dev, MUnit.IDR);
1393         break;
1394 
1395     case AAC_ENABLE_INTX:
1396         /* set bit 7 */
1397         val = src_readl(dev, MUnit.IDR);
1398         val |= 0x80;
1399         src_writel(dev, MUnit.IDR, val);
1400         src_readl(dev, MUnit.IDR);
1401         /* unmask int. */
1402         val = PMC_ALL_INTERRUPT_BITS;
1403         src_writel(dev, MUnit.IOAR, val);
1404         src_readl(dev, MUnit.IOAR);
1405         val = src_readl(dev, MUnit.OIMR);
1406         src_writel(dev, MUnit.OIMR,
1407                 val & (~(PMC_GLOBAL_INT_BIT2)));
1408         break;
1409 
1410     default:
1411         break;
1412     }
1413 }
1414 
1415 static int aac_src_get_sync_status(struct aac_dev *dev)
1416 {
1417     int msix_val = 0;
1418     int legacy_val = 0;
1419 
1420     msix_val = src_readl(dev, MUnit.ODR_MSI) & SRC_MSI_READ_MASK ? 1 : 0;
1421 
1422     if (!dev->msi_enabled) {
1423         /*
1424          * if Legacy int status indicates cmd is not complete
1425          * sample MSIx register to see if it indiactes cmd complete,
1426          * if yes set the controller in MSIx mode and consider cmd
1427          * completed
1428          */
1429         legacy_val = src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT;
1430         if (!(legacy_val & 1) && msix_val)
1431             dev->msi_enabled = 1;
1432         return legacy_val;
1433     }
1434 
1435     return msix_val;
1436 }