1*80c94ecdSKeith M Wesolowski /* 2*80c94ecdSKeith M Wesolowski * This file and its contents are supplied under the terms of the 3*80c94ecdSKeith M Wesolowski * Common Development and Distribution License ("CDDL"), version 1.0. 4*80c94ecdSKeith M Wesolowski * You may only use this file in accordance with the terms of version 5*80c94ecdSKeith M Wesolowski * 1.0 of the CDDL. 6*80c94ecdSKeith M Wesolowski * 7*80c94ecdSKeith M Wesolowski * A full copy of the text of the CDDL should have accompanied this 8*80c94ecdSKeith M Wesolowski * source. A copy of the CDDL is also available via the Internet at 9*80c94ecdSKeith M Wesolowski * http://www.illumos.org/license/CDDL. 10*80c94ecdSKeith M Wesolowski */ 11*80c94ecdSKeith M Wesolowski 12*80c94ecdSKeith M Wesolowski /* 13*80c94ecdSKeith M Wesolowski * Copyright (C) 2013 Hewlett-Packard Development Company, L.P. 14*80c94ecdSKeith M Wesolowski */ 15*80c94ecdSKeith M Wesolowski 16*80c94ecdSKeith M Wesolowski #include <sys/sdt.h> 17*80c94ecdSKeith M Wesolowski #include "cpqary3.h" 18*80c94ecdSKeith M Wesolowski 19*80c94ecdSKeith M Wesolowski /* 20*80c94ecdSKeith M Wesolowski * Local Functions Definitions 21*80c94ecdSKeith M Wesolowski */ 22*80c94ecdSKeith M Wesolowski uint8_t cleanstatus = 0; 23*80c94ecdSKeith M Wesolowski 24*80c94ecdSKeith M Wesolowski /* 25*80c94ecdSKeith M Wesolowski * The Driver DMA Limit structure. 26*80c94ecdSKeith M Wesolowski */ 27*80c94ecdSKeith M Wesolowski static ddi_dma_attr_t cpqary3_ctlr_dma_attr = { 28*80c94ecdSKeith M Wesolowski DMA_ATTR_V0, /* ddi_dma_attr version */ 29*80c94ecdSKeith M Wesolowski 0, /* low address */ 30*80c94ecdSKeith M Wesolowski 0xFFFFFFFF, /* high address */ 31*80c94ecdSKeith M Wesolowski 0x00FFFFFF, /* Max DMA Counter register */ 32*80c94ecdSKeith M Wesolowski 0x20, /* Byte Alignment */ 33*80c94ecdSKeith M Wesolowski 0x20, /* burst sizes */ 34*80c94ecdSKeith M Wesolowski DMA_UNIT_8, /* minimum DMA xfer Size */ 35*80c94ecdSKeith M Wesolowski 0xFFFFFFFF, /* maximum DMA xfer Size */ 36*80c94ecdSKeith M Wesolowski 0x0000FFFF, /* segment boundary restrictions */ 37*80c94ecdSKeith M Wesolowski 1, /* scatter/gather list length */ 38*80c94ecdSKeith M Wesolowski 512, /* device granularity */ 39*80c94ecdSKeith M Wesolowski 0 /* DMA flags */ 40*80c94ecdSKeith M Wesolowski }; 41*80c94ecdSKeith M Wesolowski 42*80c94ecdSKeith M Wesolowski /* 43*80c94ecdSKeith M Wesolowski * Driver device access attr struct 44*80c94ecdSKeith M Wesolowski */ 45*80c94ecdSKeith M Wesolowski extern ddi_device_acc_attr_t cpqary3_dev_attributes; 46*80c94ecdSKeith M Wesolowski 47*80c94ecdSKeith M Wesolowski /* 48*80c94ecdSKeith M Wesolowski * Function : cpqary3_meminit 49*80c94ecdSKeith M Wesolowski * Description : This routine initialises memory for the command list. 50*80c94ecdSKeith M Wesolowski * Allocation of Physical contigous blocks and maintenance 51*80c94ecdSKeith M Wesolowski * of lists to these. 52*80c94ecdSKeith M Wesolowski * Called By : cpqary3_init_ctlr_resource() 53*80c94ecdSKeith M Wesolowski * Parameters : per_controller 54*80c94ecdSKeith M Wesolowski * Calls : cpqary3_alloc_phyctgs_mem, cpqary3_memfini 55*80c94ecdSKeith M Wesolowski * Return Values: SUCCESS / FAILURE 56*80c94ecdSKeith M Wesolowski * [If the required initialization and setup of memory 57*80c94ecdSKeith M Wesolowski * is successful, send back a success. Else, failure] 58*80c94ecdSKeith M Wesolowski */ 59*80c94ecdSKeith M Wesolowski int16_t 60*80c94ecdSKeith M Wesolowski cpqary3_meminit(cpqary3_t *cpqary3p) 61*80c94ecdSKeith M Wesolowski { 62*80c94ecdSKeith M Wesolowski size_t mempool_size; 63*80c94ecdSKeith M Wesolowski caddr_t mempool_addr; 64*80c94ecdSKeith M Wesolowski uint16_t i = 0; 65*80c94ecdSKeith M Wesolowski uint32_t mem_size = 0; 66*80c94ecdSKeith M Wesolowski uint32_t no_cmds = 0; 67*80c94ecdSKeith M Wesolowski uint32_t cntr; 68*80c94ecdSKeith M Wesolowski uint32_t maxmemcnt; 69*80c94ecdSKeith M Wesolowski uint32_t phyaddr; 70*80c94ecdSKeith M Wesolowski uint32_t temp_phyaddr; 71*80c94ecdSKeith M Wesolowski uint32_t size_of_cmdlist = 0; 72*80c94ecdSKeith M Wesolowski uint32_t size_of_HRE = 0; /* Header + Request + Error */ 73*80c94ecdSKeith M Wesolowski uint32_t unused_mem = 0; 74*80c94ecdSKeith M Wesolowski uint32_t mempoolnum; 75*80c94ecdSKeith M Wesolowski uint32_t CmdsOutMax; 76*80c94ecdSKeith M Wesolowski CommandList_t *cmdlist_memaddr; 77*80c94ecdSKeith M Wesolowski cpqary3_phyctg_t *cpqary3_phyctgp; 78*80c94ecdSKeith M Wesolowski cpqary3_cmdpvt_t *ptr; 79*80c94ecdSKeith M Wesolowski cpqary3_cmdpvt_t *head_pvtp; 80*80c94ecdSKeith M Wesolowski cpqary3_cmdpvt_t *tail_pvtp; 81*80c94ecdSKeith M Wesolowski cpqary3_cmdmemlist_t *memlistp = NULL; 82*80c94ecdSKeith M Wesolowski cpqary3_phys_hdl_addr_t *blk_ptr = NULL; 83*80c94ecdSKeith M Wesolowski 84*80c94ecdSKeith M Wesolowski RETURN_FAILURE_IF_NULL(cpqary3p); 85*80c94ecdSKeith M Wesolowski 86*80c94ecdSKeith M Wesolowski CmdsOutMax = cpqary3p->ctlr_maxcmds; 87*80c94ecdSKeith M Wesolowski 88*80c94ecdSKeith M Wesolowski 89*80c94ecdSKeith M Wesolowski /* 90*80c94ecdSKeith M Wesolowski * Allocate memory for the Structure to hold details about the 91*80c94ecdSKeith M Wesolowski * Command Memory Pool. 92*80c94ecdSKeith M Wesolowski * Update per_controller pointer to this. 93*80c94ecdSKeith M Wesolowski */ 94*80c94ecdSKeith M Wesolowski 95*80c94ecdSKeith M Wesolowski cpqary3p->cmdmemlistp = memlistp = 96*80c94ecdSKeith M Wesolowski MEM_ZALLOC(sizeof (cpqary3_cmdmemlist_t)); 97*80c94ecdSKeith M Wesolowski 98*80c94ecdSKeith M Wesolowski if (!cpqary3p->cmdmemlistp) { 99*80c94ecdSKeith M Wesolowski cmn_err(CE_NOTE, "CPQary3: Memory Initialization: " 100*80c94ecdSKeith M Wesolowski "Low Kernel Memory"); 101*80c94ecdSKeith M Wesolowski return (CPQARY3_FAILURE); 102*80c94ecdSKeith M Wesolowski } 103*80c94ecdSKeith M Wesolowski cleanstatus |= CPQARY3_MEMLIST_DONE; /* For cleaning purpose. */ 104*80c94ecdSKeith M Wesolowski 105*80c94ecdSKeith M Wesolowski /* 106*80c94ecdSKeith M Wesolowski * Allocate a Virtual Memory Pool of size 107*80c94ecdSKeith M Wesolowski * NO_OF_CMDLIST_BLKS * NO_OF_CMDLIST_IN_A_BLK * sizeof (cmdmem_pvt_t) 108*80c94ecdSKeith M Wesolowski * to store details of the above allocated Memory for 109*80c94ecdSKeith M Wesolowski * NO_OF_CMDLIST_BLKS * NO_OF_CMDLIST_IN_A_BLK Commands 110*80c94ecdSKeith M Wesolowski * Initialize this memory to act as a linked list to parse 111*80c94ecdSKeith M Wesolowski * thru the entire list 112*80c94ecdSKeith M Wesolowski * Initialize the Memory Mutex 113*80c94ecdSKeith M Wesolowski */ 114*80c94ecdSKeith M Wesolowski no_cmds = (uint32_t)((CmdsOutMax / 3) * NO_OF_CMDLIST_IN_A_BLK); 115*80c94ecdSKeith M Wesolowski mem_size = (uint32_t)(no_cmds * sizeof (cpqary3_cmdpvt_t)); 116*80c94ecdSKeith M Wesolowski 117*80c94ecdSKeith M Wesolowski head_pvtp = ptr = (cpqary3_cmdpvt_t *)(MEM_ZALLOC(mem_size)); 118*80c94ecdSKeith M Wesolowski if (NULL == head_pvtp) { 119*80c94ecdSKeith M Wesolowski MEM_SFREE(cpqary3p->cmdmemlistp, sizeof (cpqary3_cmdmemlist_t)); 120*80c94ecdSKeith M Wesolowski cpqary3p->cmdmemlistp = NULL; 121*80c94ecdSKeith M Wesolowski cleanstatus &= ~CPQARY3_MEMLIST_DONE; /* For cleaning. */ 122*80c94ecdSKeith M Wesolowski cmn_err(CE_NOTE, "CPQary3: Memory Initialization: " 123*80c94ecdSKeith M Wesolowski "Low Kernel Memory"); 124*80c94ecdSKeith M Wesolowski return (CPQARY3_FAILURE); 125*80c94ecdSKeith M Wesolowski } 126*80c94ecdSKeith M Wesolowski 127*80c94ecdSKeith M Wesolowski tail_pvtp = &ptr[no_cmds - 1]; 128*80c94ecdSKeith M Wesolowski cleanstatus |= CPQARY3_CMDMEM_DONE; /* For cleaning purpose. */ 129*80c94ecdSKeith M Wesolowski 130*80c94ecdSKeith M Wesolowski DTRACE_PROBE4(cmd_init_start, uint32_t, no_cmds, uint32_t, mem_size, 131*80c94ecdSKeith M Wesolowski cpqary3_cmdpvt_t *, head_pvtp, cpqary3_cmdpvt_t *, tail_pvtp); 132*80c94ecdSKeith M Wesolowski 133*80c94ecdSKeith M Wesolowski for (i = 0; i < no_cmds; i++) { 134*80c94ecdSKeith M Wesolowski ptr = &head_pvtp[i]; 135*80c94ecdSKeith M Wesolowski ptr->occupied = CPQARY3_FREE; 136*80c94ecdSKeith M Wesolowski ptr->tag.tag_value = i; 137*80c94ecdSKeith M Wesolowski ptr->cmdlist_phyaddr = 0; 138*80c94ecdSKeith M Wesolowski ptr->cmdlist_erraddr = 0; 139*80c94ecdSKeith M Wesolowski ptr->cmdpvt_flag = 0; 140*80c94ecdSKeith M Wesolowski ptr->cmdlist_memaddr = (CommandList_t *)NULL; 141*80c94ecdSKeith M Wesolowski ptr->errorinfop = (ErrorInfo_t *)NULL; 142*80c94ecdSKeith M Wesolowski ptr->next = (cpqary3_cmdpvt_t *)((i == (no_cmds - 1)) ? 143*80c94ecdSKeith M Wesolowski NULL : &head_pvtp[i+1]); 144*80c94ecdSKeith M Wesolowski ptr->prev = (cpqary3_cmdpvt_t *)((i == 0) ? 145*80c94ecdSKeith M Wesolowski NULL : &head_pvtp[i-1]); 146*80c94ecdSKeith M Wesolowski ptr->ctlr = cpqary3p; 147*80c94ecdSKeith M Wesolowski ptr->pvt_pkt = (cpqary3_pkt_t *)NULL; 148*80c94ecdSKeith M Wesolowski ptr->sprev = (cpqary3_cmdpvt_t *)NULL; 149*80c94ecdSKeith M Wesolowski ptr->snext = (cpqary3_cmdpvt_t *)NULL; 150*80c94ecdSKeith M Wesolowski } 151*80c94ecdSKeith M Wesolowski cpqary3p->cmdmemlistp->head = head_pvtp; /* head Command Memory List */ 152*80c94ecdSKeith M Wesolowski cpqary3p->cmdmemlistp->tail = tail_pvtp; /* tail Command Memory List */ 153*80c94ecdSKeith M Wesolowski cpqary3p->cmdmemlistp->pool = head_pvtp; /* head Command Memory List */ 154*80c94ecdSKeith M Wesolowski cpqary3p->cmdmemlistp->max_memcnt = 0; /* Maximum commands for ctlr */ 155*80c94ecdSKeith M Wesolowski 156*80c94ecdSKeith M Wesolowski ptr = head_pvtp; 157*80c94ecdSKeith M Wesolowski 158*80c94ecdSKeith M Wesolowski DTRACE_PROBE(memlist_init_done); 159*80c94ecdSKeith M Wesolowski 160*80c94ecdSKeith M Wesolowski /* 161*80c94ecdSKeith M Wesolowski * We require the size of the commandlist and the combined 162*80c94ecdSKeith M Wesolowski * size of the Command Header, Request Block and the Error Desriptor 163*80c94ecdSKeith M Wesolowski * In CPQary3, it is 564 and 52 respectively. 164*80c94ecdSKeith M Wesolowski */ 165*80c94ecdSKeith M Wesolowski size_of_cmdlist = sizeof (CommandList_t); 166*80c94ecdSKeith M Wesolowski size_of_HRE = size_of_cmdlist - 167*80c94ecdSKeith M Wesolowski (sizeof (SGDescriptor_t) * CISS_MAXSGENTRIES); 168*80c94ecdSKeith M Wesolowski 169*80c94ecdSKeith M Wesolowski /* 170*80c94ecdSKeith M Wesolowski * uint32_t alignment of cmdlist 171*80c94ecdSKeith M Wesolowski * In CPQary3, after alignment, the size of each commandlist is 576 172*80c94ecdSKeith M Wesolowski */ 173*80c94ecdSKeith M Wesolowski if (size_of_cmdlist & 0x1F) 174*80c94ecdSKeith M Wesolowski size_of_cmdlist = ((size_of_cmdlist + 31) / 32) * 32; 175*80c94ecdSKeith M Wesolowski 176*80c94ecdSKeith M Wesolowski /* 177*80c94ecdSKeith M Wesolowski * The CmdsOutMax member in the Configuration Table states the maximum 178*80c94ecdSKeith M Wesolowski * outstanding commands supported by this controller. 179*80c94ecdSKeith M Wesolowski * The following code allocates memory in blocks; each block holds 180*80c94ecdSKeith M Wesolowski * 3 commands. 181*80c94ecdSKeith M Wesolowski */ 182*80c94ecdSKeith M Wesolowski 183*80c94ecdSKeith M Wesolowski for (mempoolnum = 0; mempoolnum < ((CmdsOutMax / 3)); mempoolnum++) { 184*80c94ecdSKeith M Wesolowski /* Allocate Memory for handle to maintain the Cmd Lists */ 185*80c94ecdSKeith M Wesolowski cpqary3_phyctgp = (cpqary3_phyctg_t *) 186*80c94ecdSKeith M Wesolowski MEM_ZALLOC(sizeof (cpqary3_phyctg_t)); 187*80c94ecdSKeith M Wesolowski if (!cpqary3_phyctgp) { 188*80c94ecdSKeith M Wesolowski cpqary3_memfini(cpqary3p, cleanstatus); 189*80c94ecdSKeith M Wesolowski cmn_err(CE_NOTE, "CPQary3: Mem Initialization: " 190*80c94ecdSKeith M Wesolowski "Low Kernel Memory"); 191*80c94ecdSKeith M Wesolowski return (CPQARY3_FAILURE); 192*80c94ecdSKeith M Wesolowski } 193*80c94ecdSKeith M Wesolowski 194*80c94ecdSKeith M Wesolowski /* 195*80c94ecdSKeith M Wesolowski * Get the Physically Contiguous Memory 196*80c94ecdSKeith M Wesolowski * Allocate 32 extra bytes of memory such as to get atleast 197*80c94ecdSKeith M Wesolowski * 2 Command Blocks from every allocation even if we add any 198*80c94ecdSKeith M Wesolowski * extra bytes after the initial allocation to make it 32 bit 199*80c94ecdSKeith M Wesolowski * aligned. 200*80c94ecdSKeith M Wesolowski */ 201*80c94ecdSKeith M Wesolowski if (mempoolnum == 0) { /* Head of Memory Blocks' Linked List */ 202*80c94ecdSKeith M Wesolowski memlistp->cpqary3_phyctgp = blk_ptr = 203*80c94ecdSKeith M Wesolowski (cpqary3_phys_hdl_addr_t *) 204*80c94ecdSKeith M Wesolowski MEM_ZALLOC(sizeof (cpqary3_phys_hdl_addr_t)); 205*80c94ecdSKeith M Wesolowski blk_ptr->blk_addr = cpqary3_phyctgp; 206*80c94ecdSKeith M Wesolowski blk_ptr->next = NULL; 207*80c94ecdSKeith M Wesolowski } else { 208*80c94ecdSKeith M Wesolowski blk_ptr->next = (cpqary3_phys_hdl_addr_t *) 209*80c94ecdSKeith M Wesolowski MEM_ZALLOC(sizeof (cpqary3_phys_hdl_addr_t)); 210*80c94ecdSKeith M Wesolowski blk_ptr = blk_ptr->next; 211*80c94ecdSKeith M Wesolowski blk_ptr->blk_addr = cpqary3_phyctgp; 212*80c94ecdSKeith M Wesolowski blk_ptr->next = NULL; 213*80c94ecdSKeith M Wesolowski } 214*80c94ecdSKeith M Wesolowski 215*80c94ecdSKeith M Wesolowski phyaddr = 0; 216*80c94ecdSKeith M Wesolowski mempool_size = (size_of_cmdlist * NO_OF_CMDLIST_IN_A_BLK) + 32; 217*80c94ecdSKeith M Wesolowski mempool_addr = cpqary3_alloc_phyctgs_mem(cpqary3p, 218*80c94ecdSKeith M Wesolowski mempool_size, &phyaddr, cpqary3_phyctgp); 219*80c94ecdSKeith M Wesolowski 220*80c94ecdSKeith M Wesolowski if (!mempool_addr) { 221*80c94ecdSKeith M Wesolowski if (!mempoolnum) { /* Failue in the first attempt */ 222*80c94ecdSKeith M Wesolowski MEM_SFREE(blk_ptr, 223*80c94ecdSKeith M Wesolowski sizeof (cpqary3_phys_hdl_addr_t)); 224*80c94ecdSKeith M Wesolowski memlistp->cpqary3_phyctgp = NULL; 225*80c94ecdSKeith M Wesolowski cmn_err(CE_WARN, "CPQary3 : Memory " 226*80c94ecdSKeith M Wesolowski "Initialization : Low Kernel Memory"); 227*80c94ecdSKeith M Wesolowski return (CPQARY3_FAILURE); 228*80c94ecdSKeith M Wesolowski } 229*80c94ecdSKeith M Wesolowski 230*80c94ecdSKeith M Wesolowski /* 231*80c94ecdSKeith M Wesolowski * Some memory allocation has already been suucessful. 232*80c94ecdSKeith M Wesolowski * The driver shall continue its initialization and 233*80c94ecdSKeith M Wesolowski * working with whatever memory has been allocated. 234*80c94ecdSKeith M Wesolowski * 235*80c94ecdSKeith M Wesolowski * Free the latest virtual memory allocated. 236*80c94ecdSKeith M Wesolowski * NULLify the last node created to maintain the memory 237*80c94ecdSKeith M Wesolowski * block list. 238*80c94ecdSKeith M Wesolowski * Terminate the Memory Q here by marking the Tail. 239*80c94ecdSKeith M Wesolowski */ 240*80c94ecdSKeith M Wesolowski blk_ptr->blk_addr = NULL; 241*80c94ecdSKeith M Wesolowski ptr--; 242*80c94ecdSKeith M Wesolowski ptr->next = NULL; 243*80c94ecdSKeith M Wesolowski memlistp->tail = ptr; 244*80c94ecdSKeith M Wesolowski return (CPQARY3_SUCCESS); 245*80c94ecdSKeith M Wesolowski } 246*80c94ecdSKeith M Wesolowski cleanstatus |= CPQARY3_PHYCTGS_DONE; 247*80c94ecdSKeith M Wesolowski 248*80c94ecdSKeith M Wesolowski bzero(mempool_addr, cpqary3_phyctgp->real_size); 249*80c94ecdSKeith M Wesolowski 250*80c94ecdSKeith M Wesolowski /* 251*80c94ecdSKeith M Wesolowski * The 32 bit alignment is stated in the attribute structure. 252*80c94ecdSKeith M Wesolowski * In case, it is not aligned as per requirement, we align it. 253*80c94ecdSKeith M Wesolowski * uint32_t alignment of the first CMDLIST in the memory list 254*80c94ecdSKeith M Wesolowski */ 255*80c94ecdSKeith M Wesolowski temp_phyaddr = phyaddr; 256*80c94ecdSKeith M Wesolowski if (phyaddr & 0x1F) { 257*80c94ecdSKeith M Wesolowski phyaddr = (uint32_t)(((phyaddr + 31) / 32) * 32); 258*80c94ecdSKeith M Wesolowski unused_mem = (uint32_t)(phyaddr - temp_phyaddr); 259*80c94ecdSKeith M Wesolowski } 260*80c94ecdSKeith M Wesolowski 261*80c94ecdSKeith M Wesolowski /* 262*80c94ecdSKeith M Wesolowski * If the memory allocated is not 32 byte aligned then unused 263*80c94ecdSKeith M Wesolowski * will give the total no of bytes that must remain unused to 264*80c94ecdSKeith M Wesolowski * make it 32 byte aligned memory 265*80c94ecdSKeith M Wesolowski */ 266*80c94ecdSKeith M Wesolowski mempool_addr = (char *)((char *)mempool_addr + unused_mem); 267*80c94ecdSKeith M Wesolowski 268*80c94ecdSKeith M Wesolowski /* 269*80c94ecdSKeith M Wesolowski * Update Counter for no. of Command Blocks. 270*80c94ecdSKeith M Wesolowski */ 271*80c94ecdSKeith M Wesolowski maxmemcnt = 0; 272*80c94ecdSKeith M Wesolowski maxmemcnt = ((uint32_t) 273*80c94ecdSKeith M Wesolowski (cpqary3_phyctgp->real_size - (uint32_t)unused_mem)) / 274*80c94ecdSKeith M Wesolowski size_of_cmdlist; 275*80c94ecdSKeith M Wesolowski memlistp->max_memcnt = memlistp->max_memcnt + maxmemcnt; 276*80c94ecdSKeith M Wesolowski 277*80c94ecdSKeith M Wesolowski /* 278*80c94ecdSKeith M Wesolowski * Get the base of mempool which is 32 Byte aligned 279*80c94ecdSKeith M Wesolowski * Initialize each Command Block with its corresponding 280*80c94ecdSKeith M Wesolowski * Physical Address, Virtual address and the Physical Addres 281*80c94ecdSKeith M Wesolowski * of the Error Info Descriptor 282*80c94ecdSKeith M Wesolowski */ 283*80c94ecdSKeith M Wesolowski cmdlist_memaddr = (CommandList_t *)mempool_addr; 284*80c94ecdSKeith M Wesolowski 285*80c94ecdSKeith M Wesolowski for (cntr = 0; cntr < maxmemcnt; cntr++) { 286*80c94ecdSKeith M Wesolowski ptr->cmdlist_phyaddr = phyaddr; 287*80c94ecdSKeith M Wesolowski ptr->cmdlist_memaddr = cmdlist_memaddr; 288*80c94ecdSKeith M Wesolowski ptr->cmdlist_erraddr = phyaddr + size_of_HRE; 289*80c94ecdSKeith M Wesolowski ptr->errorinfop = (ErrorInfo_t *) 290*80c94ecdSKeith M Wesolowski ((ulong_t)cmdlist_memaddr + size_of_HRE); 291*80c94ecdSKeith M Wesolowski phyaddr += size_of_cmdlist; 292*80c94ecdSKeith M Wesolowski cmdlist_memaddr = (CommandList_t *) 293*80c94ecdSKeith M Wesolowski ((ulong_t)cmdlist_memaddr + size_of_cmdlist); 294*80c94ecdSKeith M Wesolowski ptr++; 295*80c94ecdSKeith M Wesolowski } 296*80c94ecdSKeith M Wesolowski } 297*80c94ecdSKeith M Wesolowski 298*80c94ecdSKeith M Wesolowski #ifdef MEM_DEBUG 299*80c94ecdSKeith M Wesolowski ptr = memlistp->head; 300*80c94ecdSKeith M Wesolowski cmn_err(CE_CONT, "CPQary3 : _meminit : max_memcnt = %d \n", 301*80c94ecdSKeith M Wesolowski memlistp->max_memcnt); 302*80c94ecdSKeith M Wesolowski for (cntr = 0; cntr <= memlistp->max_memcnt; cntr++) { 303*80c94ecdSKeith M Wesolowski cmn_err(CE_CONT, "CPQary3: %d %x |", 304*80c94ecdSKeith M Wesolowski cntr, ptr->cmdlist_phyaddr); 305*80c94ecdSKeith M Wesolowski if (cntr == 0) 306*80c94ecdSKeith M Wesolowski debug_enter(""); 307*80c94ecdSKeith M Wesolowski ptr++; 308*80c94ecdSKeith M Wesolowski } 309*80c94ecdSKeith M Wesolowski cmn_err(CE_CONT, "\nCPQary3 : _meminit : " 310*80c94ecdSKeith M Wesolowski "cpqary3_cmdpvt starts at %x \n", memlistp->head); 311*80c94ecdSKeith M Wesolowski cmn_err(CE_CONT, "CPQary3 : _meminit : cpqary3_cmdpvt ends at %x \n", 312*80c94ecdSKeith M Wesolowski memlistp->tail); 313*80c94ecdSKeith M Wesolowski cmn_err(CE_CONT, "CPQary3 : _meminit : Leaving Successfully \n"); 314*80c94ecdSKeith M Wesolowski #endif 315*80c94ecdSKeith M Wesolowski 316*80c94ecdSKeith M Wesolowski return (CPQARY3_SUCCESS); 317*80c94ecdSKeith M Wesolowski } 318*80c94ecdSKeith M Wesolowski 319*80c94ecdSKeith M Wesolowski /* 320*80c94ecdSKeith M Wesolowski * Function : cpqary3_cmdlist_occupy 321*80c94ecdSKeith M Wesolowski * Description : This routine fetches a command block from the 322*80c94ecdSKeith M Wesolowski * initialised memory pool. 323*80c94ecdSKeith M Wesolowski * Called By : cpqary3_transport(), cpqary3_send_NOE_command(), 324*80c94ecdSKeith M Wesolowski * cpqary3_disable_NOE_command(), cpqary3_synccmd_alloc() 325*80c94ecdSKeith M Wesolowski * Parameters : per_controller 326*80c94ecdSKeith M Wesolowski * Calls : None 327*80c94ecdSKeith M Wesolowski * Return Values: pointer to a valid Command Block / 328*80c94ecdSKeith M Wesolowski * NULL if none is available 329*80c94ecdSKeith M Wesolowski */ 330*80c94ecdSKeith M Wesolowski cpqary3_cmdpvt_t * 331*80c94ecdSKeith M Wesolowski cpqary3_cmdlist_occupy(cpqary3_t *ctlr) 332*80c94ecdSKeith M Wesolowski { 333*80c94ecdSKeith M Wesolowski cpqary3_cmdpvt_t *memp = NULL; 334*80c94ecdSKeith M Wesolowski cpqary3_cmdmemlist_t *memlistp; 335*80c94ecdSKeith M Wesolowski 336*80c94ecdSKeith M Wesolowski RETURN_NULL_IF_NULL(ctlr); 337*80c94ecdSKeith M Wesolowski memlistp = ctlr->cmdmemlistp; 338*80c94ecdSKeith M Wesolowski 339*80c94ecdSKeith M Wesolowski /* 340*80c94ecdSKeith M Wesolowski * If pointer is NULL, we have no Command Memory Blocks available now. 341*80c94ecdSKeith M Wesolowski * Else, occupy it and 342*80c94ecdSKeith M Wesolowski * zero the commandlist so that old data is not existent. 343*80c94ecdSKeith M Wesolowski * update tag, Error descriptor address & length in the CommandList 344*80c94ecdSKeith M Wesolowski */ 345*80c94ecdSKeith M Wesolowski 346*80c94ecdSKeith M Wesolowski mutex_enter(&ctlr->sw_mutex); 347*80c94ecdSKeith M Wesolowski memp = memlistp->head; 348*80c94ecdSKeith M Wesolowski if (NULL == memp) { 349*80c94ecdSKeith M Wesolowski mutex_exit(&ctlr->sw_mutex); 350*80c94ecdSKeith M Wesolowski return ((cpqary3_cmdpvt_t *)NULL); 351*80c94ecdSKeith M Wesolowski } 352*80c94ecdSKeith M Wesolowski 353*80c94ecdSKeith M Wesolowski memp->occupied = CPQARY3_OCCUPIED; 354*80c94ecdSKeith M Wesolowski bzero(memp->cmdlist_memaddr, sizeof (CommandList_t)); 355*80c94ecdSKeith M Wesolowski memp->cmdlist_memaddr->Header.Tag.tag_value = memp->tag.tag_value; 356*80c94ecdSKeith M Wesolowski memp->cmdlist_memaddr->ErrDesc.Addr = memp->cmdlist_erraddr; 357*80c94ecdSKeith M Wesolowski memp->cmdlist_memaddr->ErrDesc.Len = sizeof (ErrorInfo_t); 358*80c94ecdSKeith M Wesolowski memlistp->head = memp->next; 359*80c94ecdSKeith M Wesolowski 360*80c94ecdSKeith M Wesolowski DTRACE_PROBE1(cmdlist_occupy, cpqary3_cmdpvt_t *, memp); 361*80c94ecdSKeith M Wesolowski 362*80c94ecdSKeith M Wesolowski if (memlistp->head) /* Atleast one more item is left in the Memory Q */ 363*80c94ecdSKeith M Wesolowski memp->next->prev = NULL; 364*80c94ecdSKeith M Wesolowski else /* No more items left in the Memory q */ 365*80c94ecdSKeith M Wesolowski memlistp->tail = NULL; 366*80c94ecdSKeith M Wesolowski 367*80c94ecdSKeith M Wesolowski mutex_exit(&ctlr->sw_mutex); 368*80c94ecdSKeith M Wesolowski return (memp); 369*80c94ecdSKeith M Wesolowski } 370*80c94ecdSKeith M Wesolowski 371*80c94ecdSKeith M Wesolowski /* 372*80c94ecdSKeith M Wesolowski * Function : cpqary3_cmdlist_release 373*80c94ecdSKeith M Wesolowski * Description : This routine releases a command block back to the 374*80c94ecdSKeith M Wesolowski * initialised memory pool. 375*80c94ecdSKeith M Wesolowski * Called By : cpqary3_transport(), cpqary3_process_pkt(), 376*80c94ecdSKeith M Wesolowski * cpqary3_send_NOE_command(), cpqary3_NOE_handler() 377*80c94ecdSKeith M Wesolowski * cpqary3_transport(), cpqary3_handle_flag_nointr() 378*80c94ecdSKeith M Wesolowski * cpqary3_synccmd_cleanup() 379*80c94ecdSKeith M Wesolowski * Parameters : pointer to Command Memory 380*80c94ecdSKeith M Wesolowski * flag to specify if mutex is to be held 381*80c94ecdSKeith M Wesolowski * Calls : None 382*80c94ecdSKeith M Wesolowski * Return Values: None 383*80c94ecdSKeith M Wesolowski */ 384*80c94ecdSKeith M Wesolowski void 385*80c94ecdSKeith M Wesolowski cpqary3_cmdlist_release(cpqary3_cmdpvt_t *memp, uint8_t flag) 386*80c94ecdSKeith M Wesolowski { 387*80c94ecdSKeith M Wesolowski cpqary3_cmdmemlist_t *memlistp; 388*80c94ecdSKeith M Wesolowski 389*80c94ecdSKeith M Wesolowski if (memp == NULL) 390*80c94ecdSKeith M Wesolowski return; 391*80c94ecdSKeith M Wesolowski 392*80c94ecdSKeith M Wesolowski /* 393*80c94ecdSKeith M Wesolowski * Hold The mutex ONLY if asked to (Else it means it is already held!) 394*80c94ecdSKeith M Wesolowski * If both head & tail of the per-controller-memory-list are NULL, 395*80c94ecdSKeith M Wesolowski * add this command list to the Available Q and Update head & tail. 396*80c94ecdSKeith M Wesolowski * Else, append it to the Available Q. 397*80c94ecdSKeith M Wesolowski */ 398*80c94ecdSKeith M Wesolowski 399*80c94ecdSKeith M Wesolowski memlistp = 400*80c94ecdSKeith M Wesolowski (cpqary3_cmdmemlist_t *)((cpqary3_t *)memp->ctlr)->cmdmemlistp; 401*80c94ecdSKeith M Wesolowski 402*80c94ecdSKeith M Wesolowski if (CPQARY3_HOLD_SW_MUTEX == flag) 403*80c94ecdSKeith M Wesolowski mutex_enter(&memp->ctlr->sw_mutex); 404*80c94ecdSKeith M Wesolowski 405*80c94ecdSKeith M Wesolowski if (memlistp->head == NULL) { /* obviously, tail is also NULL */ 406*80c94ecdSKeith M Wesolowski memlistp->head = memp; 407*80c94ecdSKeith M Wesolowski memlistp->tail = memp; 408*80c94ecdSKeith M Wesolowski memp->next = NULL; 409*80c94ecdSKeith M Wesolowski memp->prev = NULL; 410*80c94ecdSKeith M Wesolowski } else { 411*80c94ecdSKeith M Wesolowski memlistp->tail->next = memp; 412*80c94ecdSKeith M Wesolowski memp->prev = memlistp->tail; 413*80c94ecdSKeith M Wesolowski memp->next = NULL; 414*80c94ecdSKeith M Wesolowski memlistp->tail = memp; 415*80c94ecdSKeith M Wesolowski } 416*80c94ecdSKeith M Wesolowski 417*80c94ecdSKeith M Wesolowski memp->occupied = CPQARY3_FREE; 418*80c94ecdSKeith M Wesolowski memp->cmdpvt_flag = 0; 419*80c94ecdSKeith M Wesolowski memp->pvt_pkt = NULL; 420*80c94ecdSKeith M Wesolowski 421*80c94ecdSKeith M Wesolowski if (CPQARY3_HOLD_SW_MUTEX == flag) 422*80c94ecdSKeith M Wesolowski mutex_exit(&memp->ctlr->sw_mutex); 423*80c94ecdSKeith M Wesolowski } 424*80c94ecdSKeith M Wesolowski 425*80c94ecdSKeith M Wesolowski /* 426*80c94ecdSKeith M Wesolowski * Function : cpqary3_memfini 427*80c94ecdSKeith M Wesolowski * Description : This routine frees all command blocks that was 428*80c94ecdSKeith M Wesolowski * initialised for the Command Memory Pool. 429*80c94ecdSKeith M Wesolowski * It also fress any related memory that was occupied. 430*80c94ecdSKeith M Wesolowski * Called By : cpqary3_cleanup(), cpqary3_meminit(), 431*80c94ecdSKeith M Wesolowski * cpqary3_init_ctlr_resource() 432*80c94ecdSKeith M Wesolowski * Parameters : per-controller, identifier(what all to clean up) 433*80c94ecdSKeith M Wesolowski * Calls : cpqary3_free_phyctgs_mem 434*80c94ecdSKeith M Wesolowski * Return Values: None 435*80c94ecdSKeith M Wesolowski */ 436*80c94ecdSKeith M Wesolowski void 437*80c94ecdSKeith M Wesolowski cpqary3_memfini(cpqary3_t *ctlr, uint8_t level) 438*80c94ecdSKeith M Wesolowski { 439*80c94ecdSKeith M Wesolowski uint32_t mem_size; 440*80c94ecdSKeith M Wesolowski uint32_t CmdsOutMax; 441*80c94ecdSKeith M Wesolowski cpqary3_cmdpvt_t *memp; 442*80c94ecdSKeith M Wesolowski cpqary3_phys_hdl_addr_t *blk_ptr; 443*80c94ecdSKeith M Wesolowski cpqary3_phys_hdl_addr_t *tptr; 444*80c94ecdSKeith M Wesolowski 445*80c94ecdSKeith M Wesolowski ASSERT(ctlr != NULL); 446*80c94ecdSKeith M Wesolowski blk_ptr = (cpqary3_phys_hdl_addr_t *)ctlr->cmdmemlistp->cpqary3_phyctgp; 447*80c94ecdSKeith M Wesolowski 448*80c94ecdSKeith M Wesolowski CmdsOutMax = ctlr->ctlr_maxcmds; 449*80c94ecdSKeith M Wesolowski 450*80c94ecdSKeith M Wesolowski DTRACE_PROBE1(memfini_start, uint32_t, CmdsOutMax); 451*80c94ecdSKeith M Wesolowski 452*80c94ecdSKeith M Wesolowski /* 453*80c94ecdSKeith M Wesolowski * Depending upon the identifier, 454*80c94ecdSKeith M Wesolowski * Free Physical memory & Memory allocated to hold Block Details 455*80c94ecdSKeith M Wesolowski * Virtual Memory used to maintain linked list of Command Memory Pool 456*80c94ecdSKeith M Wesolowski * Memory which stores data relating to the Command Memory Pool 457*80c94ecdSKeith M Wesolowski */ 458*80c94ecdSKeith M Wesolowski 459*80c94ecdSKeith M Wesolowski mutex_enter(&ctlr->sw_mutex); 460*80c94ecdSKeith M Wesolowski if (level & CPQARY3_PHYCTGS_DONE) { 461*80c94ecdSKeith M Wesolowski if (blk_ptr) { 462*80c94ecdSKeith M Wesolowski while (blk_ptr->next) { 463*80c94ecdSKeith M Wesolowski tptr = blk_ptr; 464*80c94ecdSKeith M Wesolowski blk_ptr = blk_ptr->next; 465*80c94ecdSKeith M Wesolowski cpqary3_free_phyctgs_mem( 466*80c94ecdSKeith M Wesolowski tptr->blk_addr, CPQARY3_FREE_PHYCTG_MEM); 467*80c94ecdSKeith M Wesolowski MEM_SFREE(tptr, 468*80c94ecdSKeith M Wesolowski sizeof (cpqary3_phys_hdl_addr_t)); 469*80c94ecdSKeith M Wesolowski } 470*80c94ecdSKeith M Wesolowski cpqary3_free_phyctgs_mem( 471*80c94ecdSKeith M Wesolowski blk_ptr->blk_addr, CPQARY3_FREE_PHYCTG_MEM); 472*80c94ecdSKeith M Wesolowski MEM_SFREE(blk_ptr, sizeof (cpqary3_phys_hdl_addr_t)); 473*80c94ecdSKeith M Wesolowski } 474*80c94ecdSKeith M Wesolowski } 475*80c94ecdSKeith M Wesolowski 476*80c94ecdSKeith M Wesolowski if (level & CPQARY3_CMDMEM_DONE) { 477*80c94ecdSKeith M Wesolowski mem_size = (uint32_t)((CmdsOutMax / 3) * 478*80c94ecdSKeith M Wesolowski NO_OF_CMDLIST_IN_A_BLK * sizeof (cpqary3_cmdpvt_t)); 479*80c94ecdSKeith M Wesolowski memp = ctlr->cmdmemlistp->pool; 480*80c94ecdSKeith M Wesolowski 481*80c94ecdSKeith M Wesolowski DTRACE_PROBE2(memfini, uint32_t, mem_size, void *, memp); 482*80c94ecdSKeith M Wesolowski MEM_SFREE(memp, mem_size); 483*80c94ecdSKeith M Wesolowski } 484*80c94ecdSKeith M Wesolowski mutex_exit(&ctlr->sw_mutex); 485*80c94ecdSKeith M Wesolowski 486*80c94ecdSKeith M Wesolowski if (level & CPQARY3_MEMLIST_DONE) { 487*80c94ecdSKeith M Wesolowski mutex_enter(&ctlr->hw_mutex); 488*80c94ecdSKeith M Wesolowski MEM_SFREE(ctlr->cmdmemlistp, sizeof (cpqary3_cmdmemlist_t)); 489*80c94ecdSKeith M Wesolowski mutex_exit(&ctlr->hw_mutex); 490*80c94ecdSKeith M Wesolowski } 491*80c94ecdSKeith M Wesolowski } 492*80c94ecdSKeith M Wesolowski 493*80c94ecdSKeith M Wesolowski /* 494*80c94ecdSKeith M Wesolowski * Function : cpqary3_alloc_phyctgs_mem 495*80c94ecdSKeith M Wesolowski * Description : This routine allocates Physically Contiguous Memory 496*80c94ecdSKeith M Wesolowski * for Commands or Scatter/Gather. 497*80c94ecdSKeith M Wesolowski * Called By : cpqary3_meminit(), cpqary3_send_NOE_command() 498*80c94ecdSKeith M Wesolowski * cpqary3_synccmd_alloc() 499*80c94ecdSKeith M Wesolowski * Parameters : per-controller, size, 500*80c94ecdSKeith M Wesolowski * physical address that is sent back, per-physical 501*80c94ecdSKeith M Wesolowski * Calls : cpqary3_free_phyctgs_mem(), ddi_dma_addr_bind_handle(), 502*80c94ecdSKeith M Wesolowski * ddi_dma_alloc_handle(), ddi_dma_mem_alloc() 503*80c94ecdSKeith M Wesolowski * Return Values: Actually, this function sends back 2 values, one as an 504*80c94ecdSKeith M Wesolowski * explicit return and the other by updating a 505*80c94ecdSKeith M Wesolowski * pointer-parameter: 506*80c94ecdSKeith M Wesolowski * Virtual Memory Pointer to the allocated Memory(caddr_t), 507*80c94ecdSKeith M Wesolowski * Physical Address of the allocated Memory(phyaddr) 508*80c94ecdSKeith M Wesolowski */ 509*80c94ecdSKeith M Wesolowski caddr_t 510*80c94ecdSKeith M Wesolowski cpqary3_alloc_phyctgs_mem(cpqary3_t *ctlr, size_t size_mempool, 511*80c94ecdSKeith M Wesolowski uint32_t *phyaddr, cpqary3_phyctg_t *phyctgp) 512*80c94ecdSKeith M Wesolowski { 513*80c94ecdSKeith M Wesolowski size_t real_len; 514*80c94ecdSKeith M Wesolowski int32_t retvalue; 515*80c94ecdSKeith M Wesolowski caddr_t mempool = NULL; 516*80c94ecdSKeith M Wesolowski uint8_t cleanstat = 0; 517*80c94ecdSKeith M Wesolowski uint32_t cookiecnt; 518*80c94ecdSKeith M Wesolowski 519*80c94ecdSKeith M Wesolowski RETURN_NULL_IF_NULL(ctlr); 520*80c94ecdSKeith M Wesolowski RETURN_NULL_IF_NULL(phyctgp); 521*80c94ecdSKeith M Wesolowski 522*80c94ecdSKeith M Wesolowski /* 523*80c94ecdSKeith M Wesolowski * Allocation of Physical Contigous Memory follws: 524*80c94ecdSKeith M Wesolowski * allocate a handle for this memory 525*80c94ecdSKeith M Wesolowski * Use this handle in allocating memory 526*80c94ecdSKeith M Wesolowski * bind the handle to this memory 527*80c94ecdSKeith M Wesolowski * If any of the above fails, return a FAILURE. 528*80c94ecdSKeith M Wesolowski * If all succeed, update phyaddr to the physical address of the 529*80c94ecdSKeith M Wesolowski * allocated memory and return the pointer to the virtul allocated 530*80c94ecdSKeith M Wesolowski * memory. 531*80c94ecdSKeith M Wesolowski */ 532*80c94ecdSKeith M Wesolowski 533*80c94ecdSKeith M Wesolowski if (DDI_SUCCESS != 534*80c94ecdSKeith M Wesolowski (retvalue = ddi_dma_alloc_handle((dev_info_t *)ctlr->dip, 535*80c94ecdSKeith M Wesolowski &cpqary3_ctlr_dma_attr, DDI_DMA_DONTWAIT, 0, 536*80c94ecdSKeith M Wesolowski &phyctgp->cpqary3_dmahandle))) { 537*80c94ecdSKeith M Wesolowski switch (retvalue) { 538*80c94ecdSKeith M Wesolowski case DDI_DMA_NORESOURCES: 539*80c94ecdSKeith M Wesolowski cmn_err(CE_CONT, "CPQary3: No resources are available " 540*80c94ecdSKeith M Wesolowski "to allocate the DMA Handle\n"); 541*80c94ecdSKeith M Wesolowski break; 542*80c94ecdSKeith M Wesolowski 543*80c94ecdSKeith M Wesolowski case DDI_DMA_BADATTR: 544*80c94ecdSKeith M Wesolowski cmn_err(CE_CONT, "CPQary3: Bad attributes in " 545*80c94ecdSKeith M Wesolowski "ddi_dma_attr cannot allocate the DMA Handle \n"); 546*80c94ecdSKeith M Wesolowski break; 547*80c94ecdSKeith M Wesolowski 548*80c94ecdSKeith M Wesolowski default: 549*80c94ecdSKeith M Wesolowski cmn_err(CE_CONT, "CPQary3: Unexpected Value %x from " 550*80c94ecdSKeith M Wesolowski "call to allocate the DMA Handle \n", retvalue); 551*80c94ecdSKeith M Wesolowski } 552*80c94ecdSKeith M Wesolowski /* Calling MEM_SFREE to free the memory */ 553*80c94ecdSKeith M Wesolowski MEM_SFREE(phyctgp, sizeof (cpqary3_phyctg_t)); 554*80c94ecdSKeith M Wesolowski return (NULL); 555*80c94ecdSKeith M Wesolowski } 556*80c94ecdSKeith M Wesolowski 557*80c94ecdSKeith M Wesolowski cleanstat |= CPQARY3_DMA_ALLOC_HANDLE_DONE; 558*80c94ecdSKeith M Wesolowski 559*80c94ecdSKeith M Wesolowski retvalue = ddi_dma_mem_alloc(phyctgp->cpqary3_dmahandle, 560*80c94ecdSKeith M Wesolowski size_mempool, &cpqary3_dev_attributes, 561*80c94ecdSKeith M Wesolowski DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, 0, &mempool, &real_len, 562*80c94ecdSKeith M Wesolowski &phyctgp->cpqary3_acchandle); 563*80c94ecdSKeith M Wesolowski 564*80c94ecdSKeith M Wesolowski if (DDI_SUCCESS != retvalue) { 565*80c94ecdSKeith M Wesolowski cmn_err(CE_WARN, "CPQary3: Memory Allocation Failed: " 566*80c94ecdSKeith M Wesolowski "Increase System Memory"); 567*80c94ecdSKeith M Wesolowski cpqary3_free_phyctgs_mem(phyctgp, cleanstat); 568*80c94ecdSKeith M Wesolowski return (NULL); 569*80c94ecdSKeith M Wesolowski } 570*80c94ecdSKeith M Wesolowski 571*80c94ecdSKeith M Wesolowski phyctgp->real_size = real_len; 572*80c94ecdSKeith M Wesolowski 573*80c94ecdSKeith M Wesolowski cleanstat |= CPQARY3_DMA_ALLOC_MEM_DONE; 574*80c94ecdSKeith M Wesolowski 575*80c94ecdSKeith M Wesolowski retvalue = ddi_dma_addr_bind_handle(phyctgp->cpqary3_dmahandle, 576*80c94ecdSKeith M Wesolowski NULL, mempool, real_len, 577*80c94ecdSKeith M Wesolowski DDI_DMA_CONSISTENT | DDI_DMA_RDWR, DDI_DMA_DONTWAIT, 0, 578*80c94ecdSKeith M Wesolowski &phyctgp->cpqary3_dmacookie, &cookiecnt); 579*80c94ecdSKeith M Wesolowski 580*80c94ecdSKeith M Wesolowski if (DDI_DMA_MAPPED == retvalue) { 581*80c94ecdSKeith M Wesolowski *phyaddr = phyctgp->cpqary3_dmacookie.dmac_address; 582*80c94ecdSKeith M Wesolowski return (mempool); 583*80c94ecdSKeith M Wesolowski } 584*80c94ecdSKeith M Wesolowski 585*80c94ecdSKeith M Wesolowski switch (retvalue) { 586*80c94ecdSKeith M Wesolowski case DDI_DMA_PARTIAL_MAP: 587*80c94ecdSKeith M Wesolowski cmn_err(CE_CONT, "CPQary3: Allocated the resources for part " 588*80c94ecdSKeith M Wesolowski "of the object\n"); 589*80c94ecdSKeith M Wesolowski break; 590*80c94ecdSKeith M Wesolowski 591*80c94ecdSKeith M Wesolowski case DDI_DMA_INUSE: 592*80c94ecdSKeith M Wesolowski cmn_err(CE_CONT, "CPQary3: Another I/O transaction is using " 593*80c94ecdSKeith M Wesolowski "the DMA handle cannot bind to the DMA Handle\n"); 594*80c94ecdSKeith M Wesolowski break; 595*80c94ecdSKeith M Wesolowski 596*80c94ecdSKeith M Wesolowski case DDI_DMA_NORESOURCES: 597*80c94ecdSKeith M Wesolowski cmn_err(CE_CONT, "CPQary3: No resources are available cannot " 598*80c94ecdSKeith M Wesolowski "bind to the DMA Handle\n"); 599*80c94ecdSKeith M Wesolowski break; 600*80c94ecdSKeith M Wesolowski 601*80c94ecdSKeith M Wesolowski case DDI_DMA_NOMAPPING: 602*80c94ecdSKeith M Wesolowski cmn_err(CE_CONT, "CPQary3: Object cannot be reached by the " 603*80c94ecdSKeith M Wesolowski "device cannot bind to the DMA Handle\n"); 604*80c94ecdSKeith M Wesolowski break; 605*80c94ecdSKeith M Wesolowski 606*80c94ecdSKeith M Wesolowski case DDI_DMA_TOOBIG: 607*80c94ecdSKeith M Wesolowski cmn_err(CE_CONT, "CPQary3: The object is too big cannot bind " 608*80c94ecdSKeith M Wesolowski "to the DMA Handle\n"); 609*80c94ecdSKeith M Wesolowski cmn_err(CE_WARN, "CPQary3: Mem Scarce : " 610*80c94ecdSKeith M Wesolowski "Increase System Memory/lomempages"); 611*80c94ecdSKeith M Wesolowski break; 612*80c94ecdSKeith M Wesolowski 613*80c94ecdSKeith M Wesolowski default: 614*80c94ecdSKeith M Wesolowski cmn_err(CE_WARN, "CPQary3 : Unexpected Return Value %x " 615*80c94ecdSKeith M Wesolowski "from call to bind the DMA Handle", retvalue); 616*80c94ecdSKeith M Wesolowski } 617*80c94ecdSKeith M Wesolowski 618*80c94ecdSKeith M Wesolowski cpqary3_free_phyctgs_mem(phyctgp, cleanstat); 619*80c94ecdSKeith M Wesolowski 620*80c94ecdSKeith M Wesolowski mempool = NULL; 621*80c94ecdSKeith M Wesolowski return (mempool); 622*80c94ecdSKeith M Wesolowski } 623*80c94ecdSKeith M Wesolowski 624*80c94ecdSKeith M Wesolowski /* 625*80c94ecdSKeith M Wesolowski * Function : cpqary3_free_phyctg_mem () 626*80c94ecdSKeith M Wesolowski * Description : This routine frees the Physically contigous memory 627*80c94ecdSKeith M Wesolowski * that was allocated using ddi_dma operations. 628*80c94ecdSKeith M Wesolowski * It also fress any related memory that was occupied. 629*80c94ecdSKeith M Wesolowski * Called By : cpqary3_alloc_phyctgs_mem(), cpqary3_memfini(), 630*80c94ecdSKeith M Wesolowski * cpqary3_send_NOE_command(), cpqary3_NOE_handler(), 631*80c94ecdSKeith M Wesolowski * cpqary3_synccmd_alloc(), cpqary3_synccmd_cleanup() 632*80c94ecdSKeith M Wesolowski * Parameters : per-physical, identifier(what all to free) 633*80c94ecdSKeith M Wesolowski * Calls : None 634*80c94ecdSKeith M Wesolowski */ 635*80c94ecdSKeith M Wesolowski void 636*80c94ecdSKeith M Wesolowski cpqary3_free_phyctgs_mem(cpqary3_phyctg_t *cpqary3_phyctgp, uint8_t cleanstat) 637*80c94ecdSKeith M Wesolowski { 638*80c94ecdSKeith M Wesolowski 639*80c94ecdSKeith M Wesolowski if (cpqary3_phyctgp == NULL) 640*80c94ecdSKeith M Wesolowski return; 641*80c94ecdSKeith M Wesolowski 642*80c94ecdSKeith M Wesolowski /* 643*80c94ecdSKeith M Wesolowski * Following the reverse prcess that was followed 644*80c94ecdSKeith M Wesolowski * in allocating physical contigous memory 645*80c94ecdSKeith M Wesolowski */ 646*80c94ecdSKeith M Wesolowski 647*80c94ecdSKeith M Wesolowski if (cleanstat & CPQARY3_DMA_BIND_ADDR_DONE) { 648*80c94ecdSKeith M Wesolowski (void) ddi_dma_unbind_handle( 649*80c94ecdSKeith M Wesolowski cpqary3_phyctgp->cpqary3_dmahandle); 650*80c94ecdSKeith M Wesolowski } 651*80c94ecdSKeith M Wesolowski 652*80c94ecdSKeith M Wesolowski if (cleanstat & CPQARY3_DMA_ALLOC_MEM_DONE) { 653*80c94ecdSKeith M Wesolowski ddi_dma_mem_free(&cpqary3_phyctgp->cpqary3_acchandle); 654*80c94ecdSKeith M Wesolowski } 655*80c94ecdSKeith M Wesolowski 656*80c94ecdSKeith M Wesolowski if (cleanstat & CPQARY3_DMA_ALLOC_HANDLE_DONE) { 657*80c94ecdSKeith M Wesolowski ddi_dma_free_handle(&cpqary3_phyctgp->cpqary3_dmahandle); 658*80c94ecdSKeith M Wesolowski } 659*80c94ecdSKeith M Wesolowski 660*80c94ecdSKeith M Wesolowski MEM_SFREE(cpqary3_phyctgp, sizeof (cpqary3_phyctg_t)); 661*80c94ecdSKeith M Wesolowski } 662