Advertisement
Guest User

asr71605 - comminit.c

a guest
Feb 29th, 2020
378
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 27.68 KB | None | 0 0
  1. /*
  2.  *  Adaptec AAC series RAID controller driver
  3.  *  (c) Copyright 2001 Red Hat Inc. <alan@redhat.com>
  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. (aacraid@adaptec.com)
  9.  * Copyright (c) 2010-2015 PMC-Sierra, Inc.
  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.  *  comminit.c
  27.  *
  28.  * Abstract: This supports the initialization of the host adapter commuication interface.
  29.  *    This is a platform dependent module.
  30.  *
  31.  */
  32.  
  33. #include <linux/kernel.h>
  34. #include <linux/init.h>
  35. #include <linux/types.h>
  36. //#include <linux/sched.h>
  37. #include <linux/pci.h>
  38. #include <linux/spinlock.h>
  39. #include <linux/slab.h>
  40. #include <linux/blkdev.h>
  41. #include <linux/version.h>  /* Needed for the following */
  42. #include <linux/delay.h>
  43. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,2))
  44. #include <linux/completion.h>
  45. #endif
  46. #include <linux/mm.h>
  47. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
  48. #include <scsi/scsi_host.h>
  49. #else
  50. #include "scsi.h"
  51. #include "hosts.h"
  52. #endif
  53. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26))
  54. #include <asm/semaphore.h>
  55. #endif
  56.  
  57. #include "aacraid.h"
  58.  
  59. void aac_define_int_mode(struct aac_dev *dev);
  60.  
  61. struct aac_common aac_config = {
  62.     .irq_mod = 1
  63. };
  64.  
  65. /*
  66.  * Check if there is a better method to check if
  67.  * INTX mode is on
  68.  * */
  69. static inline int aac_is_intx_mode(struct aac_dev *dev) {
  70.     u32 status;
  71.     status = src_readl(dev, MUnit.OMR);
  72.     return !(status & AAC_INT_MODE_MSIX);
  73. }
  74.  
  75. static inline int aac_is_msix_mode(struct aac_dev *dev) {
  76.     u32 status;
  77.     status = src_readl(dev, MUnit.OMR);
  78.     return (status & AAC_INT_MODE_MSIX);
  79. }
  80.  
  81. static inline void aac_change_to_intx(struct aac_dev *dev) {
  82.     aac_src_access_devreg(dev, AAC_DISABLE_MSIX);
  83.     aac_src_access_devreg(dev, AAC_ENABLE_INTX);
  84.     udelay(1);
  85. }
  86.  
  87. static inline void aac_change_to_msix(struct aac_dev *dev) {
  88.     aac_src_access_devreg(dev, AAC_ENABLE_MSIX);
  89.     udelay(1);
  90. }
  91.  
  92. static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long commsize, unsigned long commalign)
  93. {
  94.     unsigned char *base;
  95.     unsigned long size, align;
  96.     const unsigned long fibsize = dev->max_fib_size;
  97.     const unsigned long printfbufsiz = 256;
  98.     unsigned long host_rrq_size, aac_init_size;
  99.     union aac_init *init;
  100.     extern int aac_hba_mode;
  101.  
  102. #if (((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100) + __GNUC_PATCHLEVEL__) > 400002)
  103.     dma_addr_t phys;
  104. #else
  105.     dma_addr_t phys = 0;
  106. #endif
  107. #if ((LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)) || !defined(CONFIG_GART_IOMMU))
  108.     unsigned long aac_max_hostphysmempages;
  109. #endif
  110.  
  111.     if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) ||
  112.         (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) ||
  113.         (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3 && !dev->sa_firmware)) {
  114.         host_rrq_size =
  115.             (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) * sizeof(u32);
  116.         aac_init_size = sizeof(union aac_init);
  117.     } else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3 && dev->sa_firmware) {
  118.         host_rrq_size =
  119.             (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) * sizeof(u32) *AAC_MAX_MSIX;
  120.         aac_init_size = sizeof(union aac_init) +
  121.                     (AAC_MAX_HRRQ - 1) * sizeof(struct _rrq);
  122.     } else {
  123.         host_rrq_size = 0;
  124.         aac_init_size = sizeof(union aac_init);
  125.     }
  126.     size = fibsize + aac_init_size + commsize + commalign + printfbufsiz + host_rrq_size;
  127.  
  128. #if 0 && ((defined(CONFIG_X86) || defined(CONFIG_X86_64)) && (KERNEL_VERSION_CODE < KERNEL_VERSION(2,5,0)))
  129.     base = kmalloc(size, GFP_ATOMIC|GFP_KERNEL);
  130.     if (base) {
  131.         phys = pci_map_single(dev->pdev, base, size, DMA_BIDIRECTIONAL);
  132.         if (phys > (0x80000000UL - size)) {
  133.             kfree(base);
  134.             base = NULL;
  135.         }
  136.     }
  137.     if (base == NULL)
  138. #endif
  139.  
  140.     base = pci_alloc_consistent(dev->pdev, size, &phys);
  141.     adbg_init(dev,KERN_INFO,"pci_alloc_consistent(%p,%lu,%p={0x%lx))=%p\n",
  142.            dev->pdev, size, &phys, (unsigned long)phys, base);
  143.  
  144.  
  145.     if(base == NULL)
  146.     {
  147.         aac_err(dev,"aacraid: unable to create mapping.\n");
  148.         return -ENOMEM;
  149.     }
  150.     dev->comm_addr = (void *)base;
  151.     dev->comm_phys = phys;
  152.     dev->comm_size = size;
  153.  
  154.     if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1 ||
  155.         dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 ||
  156.         dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) {
  157.         dev->host_rrq = (u32 *)(base + fibsize);
  158.         dev->host_rrq_pa = phys + fibsize;
  159.         memset(dev->host_rrq, 0, host_rrq_size);
  160.     }
  161.  
  162.     dev->init = (union aac_init *)(base + fibsize + host_rrq_size);
  163.     dev->init_pa = phys + fibsize + host_rrq_size;
  164.     adbg_init(dev,KERN_INFO,"aac->init=%p aac->init_pa=0x%lx\n",
  165.           dev->init, (unsigned long)dev->init_pa);
  166.  
  167.  
  168.     init = dev->init;
  169.  
  170.     if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) {
  171.         int i;
  172.         u64 addr;
  173.  
  174.         init->r8.InitStructRevision =
  175.             cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_8);
  176.         init->r8.InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
  177.             INITFLAGS_DRIVER_USES_UTC_TIME |
  178.             INITFLAGS_DRIVER_SUPPORTS_PM);
  179.         if (aac_hba_mode) {
  180.             printk(KERN_INFO "aacraid: HBA mode enabled\n");
  181.             init->r8.InitFlags |=
  182.                 cpu_to_le32(INITFLAGS_DRIVER_SUPPORTS_HBA_MODE);
  183.         } else {
  184.             printk(KERN_INFO "aacraid: HBA mode NOT enabled\n");
  185.         }
  186.         init->r8.RRQueueCount = cpu_to_le32(dev->max_msix);
  187.         init->r8.MaxIoSize =
  188.             cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
  189.         init->r8.MaxNumAif=init->r8.Reserved1=init->r8.Reserved2 = 0;
  190.         for (i = 0; i < dev->max_msix; i++) {
  191.             addr = (u64)dev->host_rrq_pa + dev->vector_cap * i * sizeof(u32);
  192.             init->r8.rrq[i].Host_AddrHigh = cpu_to_le32(addr >> 32);
  193.             init->r8.rrq[i].Host_AddrLow = cpu_to_le32(addr & 0xffffffff);
  194.             init->r8.rrq[i].MSIX_Id = i;
  195.             init->r8.rrq[i].ElementCount = cpu_to_le16((u16)dev->vector_cap);
  196.             init->r8.rrq[i].Comp_Thresh = init->r8.rrq[i].Unused = 0;
  197.         }
  198.         dprintk((KERN_WARNING"aacraid: New Comm Interface type3 enabled\n"));
  199.     } else {
  200.         init->r7.InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
  201.         if (dev->max_fib_size != sizeof(struct hw_fib))
  202.             init->r7.InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4);
  203.         init->r7.NoOfMSIXVectors = cpu_to_le32(Sa_MINIPORT_REVISION);
  204.         init->r7.fsrev = cpu_to_le32(dev->fsrev);
  205.  
  206.         /*
  207.          *  Adapter Fibs are the first thing allocated so that they
  208.          *  start page aligned
  209.          */
  210.         dev->aif_base_va = (struct hw_fib *)base;
  211.    
  212.         init->r7.AdapterFibsVirtualAddress = 0;
  213.         init->r7.AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
  214.         init->r7.AdapterFibsSize = cpu_to_le32(fibsize);
  215.         init->r7.AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
  216.         /*
  217.          * number of 4k pages of host physical memory. The aacraid fw needs
  218.          * this number to be less than 4gb worth of pages. New firmware doesn't
  219.          * have any issues with the mapping system, but older Firmware did, and
  220.          * had *troubles* dealing with the math overloading past 32 bits, thus
  221.          * we must limit this field.
  222.          */
  223. #if ((LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)) && !defined(__VMKLNX__))
  224.         aac_max_hostphysmempages = dma_get_required_mask(&dev->pdev->dev) >> 12;
  225.         if (aac_max_hostphysmempages < AAC_MAX_HOSTPHYSMEMPAGES)
  226.             init->r7.HostPhysMemPages = cpu_to_le32(aac_max_hostphysmempages);
  227.         else
  228.             init->r7.HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
  229. #elif (defined(CONFIG_GART_IOMMU))
  230.         /*
  231.          * This assumes the memory is mapped zero->n, which isn't
  232.          * always true on real computers. It also has some slight problems
  233.          * with the GART on x86-64. I've btw never tried DMA from PCI space
  234.          * on this platform but don't be surprised if its problematic.
  235.          */
  236.         init->r7.HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
  237. #else
  238.         /* num_physpages is in system page units. */
  239.         aac_max_hostphysmempages = num_physpages << (PAGE_SHIFT - 12);
  240.         if (aac_max_hostphysmempages < AAC_MAX_HOSTPHYSMEMPAGES)
  241.             init->r7.HostPhysMemPages = cpu_to_le32(aac_max_hostphysmempages);
  242.         else
  243.             init->r7.HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
  244. #endif
  245.  
  246.         init->r7.InitFlags = cpu_to_le32(INITFLAGS_DRIVER_USES_UTC_TIME |
  247.             INITFLAGS_DRIVER_SUPPORTS_PM);
  248.         init->r7.MaxIoCommands =
  249.             cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
  250.         init->r7.MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
  251.         init->r7.MaxFibSize = cpu_to_le32(dev->max_fib_size);
  252.         init->r7.MaxNumAif = cpu_to_le32(dev->max_num_aif);
  253.  
  254.         if (dev->comm_interface == AAC_COMM_MESSAGE) {
  255.             init->r7.InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED);
  256.             dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n"));
  257.         } else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) {
  258.             init->r7.InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_6);
  259.             init->r7.InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
  260.                 INITFLAGS_NEW_COMM_TYPE1_SUPPORTED | INITFLAGS_FAST_JBOD_SUPPORTED);
  261.             init->r7.HostRRQ_AddrHigh = cpu_to_le32((u64)dev->host_rrq_pa >> 32);
  262.             init->r7.HostRRQ_AddrLow = cpu_to_le32(dev->host_rrq_pa & 0xffffffff);
  263.             dprintk((KERN_WARNING"aacraid: New Comm Interface type1 enabled\n"));
  264.         } else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
  265.             init->r7.InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_7);
  266.             init->r7.InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
  267.                 INITFLAGS_NEW_COMM_TYPE2_SUPPORTED | INITFLAGS_FAST_JBOD_SUPPORTED);
  268.             init->r7.HostRRQ_AddrHigh = cpu_to_le32((u64)dev->host_rrq_pa >> 32);
  269.             init->r7.HostRRQ_AddrLow = cpu_to_le32(dev->host_rrq_pa & 0xffffffff);
  270.             init->r7.NoOfMSIXVectors = cpu_to_le32(dev->max_msix);      /* number of MSI-X */
  271.             /* must be the COMM_PREFERRED_SETTINGS values */
  272. #if 0
  273.             init->r7.MaxIoSize = cpu_to_le32(256L * 1024L); /* always 256KB */
  274.             init->r7.MaxFibSize = cpu_to_le32(2L * 1024L);      /* always 2KB */
  275. #endif
  276.             printk((KERN_WARNING"aacraid: New Comm Interface type2 enabled\n"));
  277.         }
  278. #if (defined(INITFLAGS_APRE_SUPPORTED) && !defined(CONFIG_COMMUNITY_KERNEL))
  279.         else if (dev->comm_interface == AAC_COMM_APRE) {
  280.             init->r7.InitFlags |= cpu_to_le32(INITFLAGS_APRE_SUPPORTED);
  281.             dprintk((KERN_WARNING"aacraid: APRE Interface enabled\n"));
  282.         }
  283. #endif
  284.     }
  285.  
  286.     /*
  287.      * Increment the base address by the amount already used
  288.      */
  289.     base = base + fibsize + host_rrq_size + aac_init_size;
  290.     phys = (dma_addr_t)((ulong)phys + fibsize + host_rrq_size + aac_init_size);
  291.     /*
  292.      *  Align the beginning of Headers to commalign
  293.      */
  294.     align = (commalign - ((uintptr_t)(base) & (commalign - 1)));
  295.     base = base + align;
  296.     phys = phys + align;
  297.     /*
  298.      *  Fill in addresses of the Comm Area Headers and Queues
  299.      */
  300.     *commaddr = base;
  301.     if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE3)
  302.         init->r7.CommHeaderAddress = cpu_to_le32((u32)phys);
  303.     /*
  304.      *  Increment the base address by the size of the CommArea
  305.      */
  306.     base = base + commsize;
  307.     phys = phys + commsize;
  308.     /*
  309.      *   Place the Printf buffer area after the Fast I/O comm area.
  310.      */
  311.     dev->printfbuf = (void *)base;
  312.     if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE3) {
  313.         init->r7.printfbuf = cpu_to_le32(phys);
  314.         init->r7.printfbufsiz = cpu_to_le32(printfbufsiz);
  315.     }
  316.     memset(base, 0, printfbufsiz);
  317.     return 0;
  318. }
  319.  
  320. static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem, int qsize)
  321. {
  322.     atomic_set(&q->numpending, 0);
  323.     q->dev = dev;
  324. #if ((defined(__VMKERNEL_MODULE__) || defined(__VMKLNX30__)) && !defined(__VMKLNX__))
  325.     q->cmdready = (struct semaphore) __SEMAPHORE_INITIALIZER(q->cmdready, 0);
  326. #else
  327.     init_waitqueue_head(&q->cmdready);
  328. #endif
  329.     INIT_LIST_HEAD(&q->cmdq);
  330.     init_waitqueue_head(&q->qfull);
  331.     spin_lock_init(&q->lockdata);
  332.     q->lock = &q->lockdata;
  333.     q->headers.producer = (__le32 *)mem;
  334.     q->headers.consumer = (__le32 *)(mem+1);
  335.     *(q->headers.producer) = cpu_to_le32(qsize);
  336.     *(q->headers.consumer) = cpu_to_le32(qsize);
  337.     q->entries = qsize;
  338. }
  339.  
  340. /**
  341.  *  aac_send_shutdown       -   shutdown an adapter
  342.  *  @dev: Adapter to shutdown
  343.  *
  344.  *  This routine will send a VM_CloseAll (shutdown) request to the adapter.
  345.  */
  346.  
  347. int aac_send_shutdown(struct aac_dev * dev)
  348. {
  349.     struct fib * fibctx;
  350.     struct aac_close *cmd;
  351.     int status;
  352.  
  353.     fibctx = aac_fib_alloc(dev);
  354.     if (!fibctx)
  355.         return -ENOMEM;
  356.     aac_fib_init(fibctx);
  357.  
  358.     cmd = (struct aac_close *) fib_data(fibctx);
  359.  
  360.     cmd->command = cpu_to_le32(VM_CloseAll);
  361.     cmd->cid = cpu_to_le32(0xfffffffe);
  362.  
  363.     status = aac_fib_send(ContainerCommand,
  364.               fibctx,
  365.               sizeof(struct aac_close),
  366.               FsaNormal,
  367.               -2 /* Timeout silently */, 1,
  368.               NULL, NULL);
  369.  
  370.     if (status >= 0)
  371.         aac_fib_complete(fibctx);
  372.     /* FIB should be freed only after getting the response from the F/W */
  373.     if (status != -ERESTARTSYS)
  374.         aac_fib_free(fibctx);
  375.     dev->adapter_shutdown = 1;
  376.     if ((dev->pdev->device == PMC_DEVICE_S7 ||
  377.          dev->pdev->device == PMC_DEVICE_S8 ||
  378.          dev->pdev->device == PMC_DEVICE_S9) &&
  379.          dev->msi_enabled)
  380.         aac_set_intx_mode(dev);
  381.  
  382.     return status;
  383. }
  384.  
  385. /**
  386.  *  aac_comm_init   -   Initialise FSA data structures
  387.  *  @dev:   Adapter to initialise
  388.  *
  389.  *  Initializes the data structures that are required for the FSA commuication
  390.  *  interface to operate.
  391.  *  Returns
  392.  *      1 - if we were able to init the commuication interface.
  393.  *      0 - If there were errors initing. This is a fatal error.
  394.  */
  395.  
  396. static int aac_comm_init(struct aac_dev * dev)
  397. {
  398.     unsigned long hdrsize = (sizeof(u32) * NUMBER_OF_COMM_QUEUES) * 2;
  399.     unsigned long queuesize = sizeof(struct aac_entry) * TOTAL_QUEUE_ENTRIES;
  400.     u32 *headers;
  401.     struct aac_entry * queues;
  402.     unsigned long size;
  403.     struct aac_queue_block * comm = dev->queues;
  404.     /*
  405.      *  Now allocate and initialize the zone structures used as our
  406.      *  pool of FIB context records.  The size of the zone is based
  407.      *  on the system memory size.  We also initialize the mutex used
  408.      *  to protect the zone.
  409.      */
  410. #if (!defined(__VMKERNEL_MODULE__) && !defined(__VMKLNX30__) && !defined(__VMKLNX__))
  411.     spin_lock_init(&dev->fib_lock);
  412. #endif
  413.  
  414.     /*
  415.      *  Allocate the physically contigous space for the commuication
  416.      *  queue headers.
  417.      */
  418. #if (defined(INITFLAGS_APRE_SUPPORTED) && !defined(CONFIG_COMMUNITY_KERNEL))
  419.     if (dev->comm_interface == AAC_COMM_APRE) {
  420.         hdrsize = sizeof(u32) * 2;
  421.         queuesize = (128 + sizeof(struct donelist_entry))
  422.                   * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)
  423.                   + (sizeof(struct donelist_entry) * 20);
  424.     }
  425. #endif
  426.  
  427.     size = hdrsize + queuesize;
  428.  
  429.     if (aac_alloc_comm(dev, (void * *)&headers, size, QUEUE_ALIGNMENT)) {
  430.         aac_err(dev,"aac_alloc_comm failed\n");
  431.         return -ENOMEM;
  432.     }
  433.  
  434.  
  435.     queues = (struct aac_entry *)(((ulong)headers) + hdrsize);
  436.  
  437.     /* Adapter to Host normal priority Command queue */
  438. #if (defined(INITFLAGS_APRE_SUPPORTED) && !defined(CONFIG_COMMUNITY_KERNEL))
  439.     if (dev->comm_interface == AAC_COMM_APRE) {
  440.         comm->queue[ApreCmdQueue].base = queues;
  441.         aac_queue_init(dev, &comm->queue[ApreCmdQueue], headers,
  442.           dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
  443.         comm->queue[ApreCmdQueue].NxtDoneListEntry =
  444.             comm->queue[ApreCmdQueue].DoneListPool = (void *)queues
  445.                 + (128
  446.                 * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB));
  447.         comm->queue[ApreCmdQueue].Credits = APRE_MAX_CREDITS;
  448.         return 0;
  449.     }
  450. #endif
  451.     comm->queue[HostNormCmdQueue].base = queues;
  452.     aac_queue_init(dev, &comm->queue[HostNormCmdQueue], headers, HOST_NORM_CMD_ENTRIES);
  453.     queues += HOST_NORM_CMD_ENTRIES;
  454.     headers += 2;
  455.  
  456.     /* Adapter to Host high priority command queue */
  457.     comm->queue[HostHighCmdQueue].base = queues;
  458.     aac_queue_init(dev, &comm->queue[HostHighCmdQueue], headers, HOST_HIGH_CMD_ENTRIES);
  459.  
  460.     queues += HOST_HIGH_CMD_ENTRIES;
  461.     headers +=2;
  462.  
  463.     /* Host to adapter normal priority command queue */
  464.     comm->queue[AdapNormCmdQueue].base = queues;
  465.     aac_queue_init(dev, &comm->queue[AdapNormCmdQueue], headers, ADAP_NORM_CMD_ENTRIES);
  466.  
  467.     queues += ADAP_NORM_CMD_ENTRIES;
  468.     headers += 2;
  469.  
  470.     /* host to adapter high priority command queue */
  471.     comm->queue[AdapHighCmdQueue].base = queues;
  472.     aac_queue_init(dev, &comm->queue[AdapHighCmdQueue], headers, ADAP_HIGH_CMD_ENTRIES);
  473.  
  474.     queues += ADAP_HIGH_CMD_ENTRIES;
  475.     headers += 2;
  476.  
  477.     /* adapter to host normal priority response queue */
  478.     comm->queue[HostNormRespQueue].base = queues;
  479.     aac_queue_init(dev, &comm->queue[HostNormRespQueue], headers, HOST_NORM_RESP_ENTRIES);
  480.     queues += HOST_NORM_RESP_ENTRIES;
  481.     headers += 2;
  482.  
  483.     /* adapter to host high priority response queue */
  484.     comm->queue[HostHighRespQueue].base = queues;
  485.     aac_queue_init(dev, &comm->queue[HostHighRespQueue], headers, HOST_HIGH_RESP_ENTRIES);
  486.  
  487.     queues += HOST_HIGH_RESP_ENTRIES;
  488.     headers += 2;
  489.  
  490.     /* host to adapter normal priority response queue */
  491.     comm->queue[AdapNormRespQueue].base = queues;
  492.     aac_queue_init(dev, &comm->queue[AdapNormRespQueue], headers, ADAP_NORM_RESP_ENTRIES);
  493.  
  494.     queues += ADAP_NORM_RESP_ENTRIES;
  495.     headers += 2;
  496.  
  497.     /* host to adapter high priority response queue */
  498.     comm->queue[AdapHighRespQueue].base = queues;
  499.     aac_queue_init(dev, &comm->queue[AdapHighRespQueue], headers, ADAP_HIGH_RESP_ENTRIES);
  500.  
  501.     comm->queue[AdapNormCmdQueue].lock = comm->queue[HostNormRespQueue].lock;
  502.     comm->queue[AdapHighCmdQueue].lock = comm->queue[HostHighRespQueue].lock;
  503.     comm->queue[AdapNormRespQueue].lock = comm->queue[HostNormCmdQueue].lock;
  504.     comm->queue[AdapHighRespQueue].lock = comm->queue[HostHighCmdQueue].lock;
  505.  
  506.     return 0;
  507. }
  508.  
  509. int aac_init_adapter(struct aac_dev *dev)
  510. {
  511.     u32 status[5];
  512.     struct Scsi_Host * host = dev->scsi_host_ptr;
  513.     int ret;
  514.     extern int aac_sync_mode;
  515.  
  516.     /*
  517.      *  Check the preferred comm settings, defaults from template.
  518.      */
  519.     dev->management_fib_count = 0;
  520.     spin_lock_init(&dev->manage_lock);
  521.     spin_lock_init(&dev->sync_lock);
  522.     spin_lock_init(&dev->iq_lock);
  523.     dev->max_fib_size = sizeof(struct hw_fib);
  524.     dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size
  525.         - sizeof(struct aac_fibhdr)
  526.         - sizeof(struct aac_write) + sizeof(struct sgentry))
  527.             / sizeof(struct sgentry);
  528.     dev->comm_interface = AAC_COMM_PRODUCER;
  529.     dev->raw_io_interface = dev->raw_io_64 = 0;
  530. #   if (defined(AAC_DEBUG_INSTRUMENT_INIT))
  531.         status[0] = 0xFFFFFFFF;
  532. #   endif
  533.  
  534.     /*
  535.      * Enable INTX mode, if not already
  536.      * Enabled
  537.      * */
  538.  
  539.     if(aac_is_msix_mode(dev)) {
  540.         aac_change_to_intx(dev);
  541.         aac_info(dev,"Changed Firmware to INTX mode");
  542.     }
  543.  
  544.     if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
  545.         0,0,0,0,0,0, status+0, status+1, status+2, status+3, status+4)) &&
  546.             (status[0] == 0x00000001)) {
  547.         adbg_init(dev,KERN_INFO,"GET_ADAPTER_PROPERTIES: 0x%x 0x%x 0x%x 0x%x\n",
  548.               status[1], status[2], status[3], status[4]);
  549.         dev->doorbell_mask = status[3];
  550.         if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_64))
  551.             dev->raw_io_64 = 1;
  552. #if (defined(INITFLAGS_APRE_SUPPORTED) && !defined(CONFIG_COMMUNITY_KERNEL))
  553.         if (dev->a_ops.adapter_comm) {
  554.             if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM)) {
  555.                 dev->comm_interface = AAC_COMM_MESSAGE;
  556.                 dev_>raw_io_interface = 1; 
  557.             } else if (status[1] & le32_to_cpu(AAC_OPT_APRE)) {
  558.                 dev->comm_interface = AAC_COMM_APRE;
  559.                 dev->raw_io_interface = dev->raw_io_64 = 1;
  560.                 host->sg_tablesize = dev->sg_tablesize = 17;
  561.                 if (host->can_queue > 128)
  562.                     host->can_queue = 128;
  563.             }
  564.         }
  565. #else
  566.         dev->sync_mode = aac_sync_mode;
  567.         if (dev->a_ops.adapter_comm &&
  568.             (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM))) {
  569.             dev->comm_interface = AAC_COMM_MESSAGE;
  570.             dev->raw_io_interface = 1;
  571.             if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE1))) {
  572.                 /* driver supports TYPE1 (Tupelo) */
  573.                 dev->comm_interface = AAC_COMM_MESSAGE_TYPE1;
  574.             } else if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE2))) {
  575.                 /* driver supports TYPE2 (Denali, Yosemite) */
  576.                 dev->comm_interface = AAC_COMM_MESSAGE_TYPE2;
  577.             } else if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE3))) {
  578.                 /* driver supports TYPE3 (Thor) */
  579.                 dev->comm_interface = AAC_COMM_MESSAGE_TYPE3;
  580.             } else if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE4))) {
  581.                 /* not supported TYPE - switch to sync. mode */
  582.                 dev->comm_interface = AAC_COMM_MESSAGE_TYPE2;
  583.                 dev->sync_mode = 1;
  584.             }
  585.         }
  586.         if ((status[1] & le32_to_cpu(AAC_OPT_EXTENDED)) &&
  587.             (status[4] & le32_to_cpu(AAC_EXTOPT_SA_FIRMWARE)))
  588.             dev->sa_firmware = 1;
  589.         else
  590.             dev->sa_firmware = 0;
  591. #endif
  592. #if (defined(__VMKERNEL_MODULE__) || defined(__VMKLNX30__) || defined(__VMKLNX__))
  593.         /*
  594.          * serveraid 8i returns 0x800000 (8MB) for this,
  595.          * which works fine in Linux and the COS, but
  596.          * fails in the VMkernel which imposes a max
  597.          * size of 1MB.  as such, clamp anything over
  598.          * 1MB down to AAC_MIN_FOOTPRINT_SIZE and use
  599.          * the old communications interface.
  600.          *  -gmccready@vmware.com
  601.          */
  602. #       define VMK_MAX_MAP_SIZE 0x100000
  603.  
  604.         if (status[2] > VMK_MAX_MAP_SIZE) {
  605.             printk("aacraid: card asked for %d (0x%x), we truncated to %d (0x%x)\n", status[2], status[2], AAC_MIN_FOOTPRINT_SIZE, AAC_MIN_FOOTPRINT_SIZE);
  606.             dev->comm_interface = AAC_COMM_PRODUCER;
  607.         }
  608. #endif
  609.         if ((dev->comm_interface == AAC_COMM_MESSAGE) &&
  610.             (status[2] > dev->base_size)) {
  611.             aac_adapter_ioremap(dev, 0);
  612.             dev->base_size = status[2];
  613.             if (aac_adapter_ioremap(dev, status[2])) {
  614.                 /* remap failed, go back ... */
  615.                 dev->comm_interface = AAC_COMM_PRODUCER;
  616.                 if (aac_adapter_ioremap(dev, AAC_MIN_FOOTPRINT_SIZE)) {
  617.                     aac_warn(dev,
  618.                       "Unable to map adapter.\n");
  619.                     goto error;
  620.                 }
  621.             }
  622.         }
  623.     } else {
  624.         aac_err(dev, "Driver Init: GET_ADAPTER_PROPERTIES failed-0x%lx\n", (unsigned long)status[0]);
  625.         status[0] = 0xFFFFFFFF;
  626.     }
  627.  
  628.     dev->max_msix = 0;
  629.     dev->msi_enabled = 0;
  630.     dev->adapter_shutdown = 0;
  631.     if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
  632.       0, 0, 0, 0, 0, 0,
  633.       status+0, status+1, status+2, status+3, status+4))
  634.      && (status[0] == 0x00000001)) {
  635.         /*
  636.          *  status[1] >> 16     maximum command size in KB
  637.          *  status[1] & 0xFFFF  maximum FIB size
  638.          *  status[2] >> 16     maximum SG elements to driver
  639.          *  status[2] & 0xFFFF  maximum SG elements from driver
  640.          *  status[3] & 0xFFFF  maximum number FIBs outstanding
  641.          */
  642.         adbg_init(dev,KERN_INFO,"GET_COMM_PREFERRED_SETTINGS: %uKB %uB sg<%u sg<%u queue<%u\n",
  643.               status[1] >> 16, status[1] & 0xFFFF,
  644.               status[2] >> 16, status[2] & 0xFFFF,
  645.               status[3] & 0xFFFF);
  646.         host->max_sectors = (status[1] >> 16) << 1;
  647.         dev->max_fib_size = status[1] & 0xFFE0; /* multiple of 32 for PMC */
  648.         host->sg_tablesize = status[2] >> 16;
  649.         dev->sg_tablesize = status[2] & 0xFFFF;
  650.         if (dev->pdev->device == PMC_DEVICE_S7 ||
  651.             dev->pdev->device == PMC_DEVICE_S8 ||
  652.             dev->pdev->device == PMC_DEVICE_S9) {
  653. #if (defined(AAC_CITRIX))
  654.             if (host->can_queue > 248)
  655.                 host->can_queue = 248;
  656. #elif (defined(CONFIG_XEN) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
  657.             if (host->can_queue > 128)
  658.                 host->can_queue = 128;
  659. #else
  660.             if (host->can_queue > (status[3] >> 16) - AAC_NUM_MGT_FIB)
  661.                 host->can_queue = (status[3] >> 16) - AAC_NUM_MGT_FIB;
  662. #endif
  663.         } else if (host->can_queue > (status[3] & 0xFFFF) - AAC_NUM_MGT_FIB)
  664.             host->can_queue = (status[3] & 0xFFFF) - AAC_NUM_MGT_FIB;
  665.         dev->max_num_aif = status[4] & 0xFFFF;
  666.     } else
  667.         aac_info(dev,
  668.             "Driver Init: GET_COMM_PREFERRED_SETTINGS 0x%lx failed\n",
  669.             (unsigned long)status[0]);
  670.  
  671.     {
  672.         if (numacb > 0) {
  673.             if (numacb < host->can_queue)
  674.                 host->can_queue = numacb;
  675.             else
  676.                 printk("numacb=%d ignored\n", numacb);
  677.         }
  678.     }
  679.  
  680.     if (dev->pdev->device == PMC_DEVICE_S6 ||
  681.         dev->pdev->device == PMC_DEVICE_S7 ||
  682.         dev->pdev->device == PMC_DEVICE_S8 ||
  683.         dev->pdev->device == PMC_DEVICE_S9)
  684.         aac_define_int_mode(dev);
  685.  
  686.     /*
  687.      *  Ok now init the communication subsystem
  688.      */
  689.  
  690. #if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)) && !defined(HAS_KZALLOC))
  691.     dev->queues = kmalloc(sizeof(struct aac_queue_block), GFP_KERNEL);
  692. #else
  693.     dev->queues = kzalloc(sizeof(struct aac_queue_block), GFP_KERNEL);
  694. #endif
  695.     if (!dev->queues) {
  696.         aac_err(dev ,"Could not allocate queues.\n");
  697.         goto error;
  698.     }
  699. #if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)) && !defined(HAS_KZALLOC))
  700.     memset(dev->queues, 0, sizeof(struct aac_queue_block));
  701. #endif
  702.  
  703.     ret = aac_comm_init(dev);
  704.     if (ret < 0){
  705.         aac_err(dev, "aac_comm_init failed-%d\n", ret);
  706.         goto error_free;
  707.     }
  708.     /*
  709.      *  Initialize the list of fibs
  710.      */
  711.     ret = aac_fib_setup(dev);
  712.     if (ret < 0) {
  713.         aac_err(dev, "aac_fib_setup failed-%d\n",ret);
  714.         goto error_free;
  715.     }
  716.  
  717.     INIT_LIST_HEAD(&dev->fib_list);
  718.     INIT_LIST_HEAD(&dev->sync_fib_list);
  719. #if ((LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,5)) && !defined(HAS_KTHREAD))
  720.     init_completion(&dev->aif_completion);
  721. #endif
  722.  
  723.     return 0;
  724.  
  725. error_free:
  726.     kfree(dev->queues);
  727. error:
  728.     return -1;
  729. }
  730.  
  731.  
  732. void aac_define_int_mode(struct aac_dev *dev)
  733. {
  734.     int i, msi_count;
  735.     msi_count = i = 0;
  736.  
  737.     /* max. vectors from GET_COMM_PREFERRED_SETTINGS */
  738.     if (dev->max_msix == 0 || dev->pdev->device == PMC_DEVICE_S6 || dev->sync_mode) {
  739.         dev->max_msix = 1;
  740.         dev->vector_cap = dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB;
  741. #if (defined(AAC_DEBUG_INSTRUMENT_MSIX))
  742.         printk(KERN_INFO "aacraid: dev->msi_enabled %d dev->msi %d dev->vector_cap %d dev->max_msix %d dev->scsi_host_ptr->can_queue %d\n",
  743.               dev->msi_enabled, dev->msi, dev->vector_cap, dev->max_msix, dev->scsi_host_ptr->can_queue);
  744. #endif
  745.         return;
  746.     }
  747.  
  748. #if ((LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)) || defined(PCI_HAS_ENABLE_MSI))
  749. #if ((!defined(CONFIG_XEN) || LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)) || \
  750.      defined(__VMKERNEL_MODULE__) || defined(__VMKLNX30__) || defined(__VMKLNX__))
  751.     /* Don't bother allocating more MSI-X vectors than cpus */
  752.  
  753.  
  754.     msi_count = min(dev->max_msix,
  755.         (unsigned int)num_online_cpus());
  756.    
  757.     if(dev->kdump_msix)
  758.         msi_count = 2;
  759.  
  760.  
  761.     dev->max_msix = msi_count;
  762.  
  763.     if (msi_count > AAC_MAX_MSIX)
  764.         msi_count = AAC_MAX_MSIX;
  765.  
  766.     for (i = 0; i < msi_count; i++)
  767.         dev->msixentry[i].entry = i;
  768.  
  769.     if (msi_count > 1 && pci_find_capability(dev->pdev, PCI_CAP_ID_MSIX)) {
  770.  
  771.         i = pci_enable_msix(dev->pdev, dev->msixentry, msi_count);
  772.         /*
  773.          * Check how many MSIX vectors are allocated
  774.          */
  775.         if (i >= 0) {
  776.             dev->msi_enabled = 1;
  777.             if (i) {
  778.                 msi_count = i;
  779.                 if (pci_enable_msix(dev->pdev, dev->msixentry, msi_count)) {
  780.                     dev->msi_enabled = 0;
  781.                     printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
  782.                             dev->name, dev->id, i);
  783.                 }
  784.             }
  785.         } else {
  786.             dev->msi_enabled = 0;
  787.             printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
  788.                     dev->name, dev->id, i);
  789.         }
  790.     }
  791.  
  792. #if (defined(AAC_ENABLE_MSI_MODE))
  793.     if (!dev->msi_enabled) {
  794.         msi_count = 1;
  795.         i = !pci_enable_msi(dev->pdev);
  796.  
  797.         if (i) {
  798.             dev->msi_enabled = 1;
  799.             dev->msi = 1;
  800.         }
  801.         else
  802.             printk(KERN_ERR "%s%d: MSI not supported!! Will try INTx 0x%x.\n",
  803.                     dev->name, dev->id, i);
  804.     }
  805. #endif
  806. #endif
  807. #endif
  808.  
  809.     if (!dev->msi_enabled)
  810.         dev->max_msix = msi_count = 1;
  811.     else {
  812.         if (dev->max_msix > msi_count)
  813.             dev->max_msix = msi_count;
  814.     }
  815.     if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3 && dev->sa_firmware)
  816.                 dev->vector_cap = (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
  817.     else
  818.                 dev->vector_cap = (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) / msi_count;
  819.        
  820. #if (defined(AAC_DEBUG_INSTRUMENT_MSIX))
  821.         printk(KERN_INFO "aacraid: dev->msi_enabled %d dev->msi %d dev->vector_cap %d dev->max_msix %d dev->scsi_host_ptr->can_queue %d\n",
  822.               dev->msi_enabled, dev->msi, dev->vector_cap, dev->max_msix, dev->scsi_host_ptr->can_queue);
  823. #endif
  824. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement