/** * @brief Clone all memory for a module * * @param modld - * * <long-description> * * @return <ReturnValue> */ InsLibModlDesc *InsLibCloneModule(InsLibModlDesc *modld) { InsLibModlDesc *modld_clone = NULL; int sz; if (modld) { modld_clone = (InsLibModlDesc *) sysbrk(sizeof(InsLibModlDesc)); if (!modld_clone) { //pseterr(ENOMEM); printk("InsLib: not enough memory for modld_clone\n"); return NULL; } copy_mem((void *) modld_clone, (void *) modld, sizeof(InsLibModlDesc)); if (modld->BusType == InsLibBusTypeCARRIER) { modld_clone->ModuleAddress = InsLibCloneCar(modld->ModuleAddress); } else if (modld->BusType == InsLibBusTypeVME) { modld_clone->ModuleAddress = InsLibCloneVme(modld->ModuleAddress); } else if ((modld->BusType == InsLibBusTypePMC) || (modld->BusType == InsLibBusTypePCI)) { modld_clone->ModuleAddress = InsLibClonePci(modld->ModuleAddress); } if (modld->Extra) { sz = strlen(modld_clone->Extra) +1; modld_clone->Extra = (char *) sysbrk(sz); if (modld_clone->Extra) copy_mem((void *) modld_clone->Extra, (void *) modld->Extra, sz); } if (modld->Isr) { modld_clone->Isr = (InsLibIntrDesc *) sysbrk(sizeof(InsLibIntrDesc)); if (modld_clone->Isr) copy_mem((void *) modld_clone->Isr, (void *)modld->Isr, sizeof(InsLibIntrDesc)); } modld_clone->Next = InsLibCloneModule(modld->Next); return modld_clone; } return NULL; }
InsLibHostDesc *InsLibCloneHost(InsLibHostDesc *hostd) { InsLibHostDesc *hostd_clone = NULL; if (hostd) { hostd_clone = (InsLibHostDesc *) sysbrk(sizeof(InsLibHostDesc)); if (!hostd_clone) return NULL; copy_mem((void *) hostd_clone, (void *) hostd, sizeof(InsLibHostDesc)); hostd_clone->Drivers = InsLibCloneDriver(hostd->Drivers); return hostd_clone; } return NULL; }
/** * @brief Clone all memory for all the host drivers * * @param drvrd - driver description to start cloning from. * * <long-description> * * @return <ReturnValue> */ InsLibDrvrDesc *InsLibCloneDriver(InsLibDrvrDesc *drvrd) { InsLibDrvrDesc *drvrd_clone = NULL; if (drvrd) { drvrd_clone = (InsLibDrvrDesc *) sysbrk(sizeof(InsLibDrvrDesc)); if (!drvrd_clone) return NULL; copy_mem((void *) drvrd_clone, (void *) drvrd, sizeof(InsLibDrvrDesc)); drvrd_clone->Modules = InsLibCloneModule(drvrd->Modules); drvrd_clone->Next = InsLibCloneDriver(drvrd->Next); return drvrd_clone; } return NULL; }
/** * @brief * * @param vmema - * * <long-description> * * @return <ReturnValue> */ InsLibVmeModuleAddress *InsLibCloneVme(InsLibVmeModuleAddress *vmema) { InsLibVmeModuleAddress *vmema_clone = NULL; if (vmema) { vmema_clone = (InsLibVmeModuleAddress *) sysbrk(sizeof(InsLibVmeModuleAddress)); if (!vmema_clone) return NULL; copy_mem((void *) vmema_clone, (void *) vmema, sizeof(InsLibVmeModuleAddress)); vmema_clone->VmeAddressSpace = InsLibCloneVmeSpace(vmema->VmeAddressSpace); return vmema_clone; } return NULL; }
InsLibPciAddressSpace *InsLibClonePciSpace(InsLibPciAddressSpace *pcias) { InsLibPciAddressSpace *pcias_clone = NULL; if (pcias) { pcias_clone = (InsLibPciAddressSpace *) sysbrk(sizeof(InsLibPciAddressSpace)); if (!pcias_clone) return NULL; copy_mem((void *) pcias_clone, (void *) pcias, sizeof(InsLibPciAddressSpace)); pcias_clone->Next = InsLibClonePciSpace(pcias->Next); return pcias_clone; } return NULL; }
InsLibVmeAddressSpace *InsLibCloneVmeSpace(InsLibVmeAddressSpace *vmeas) { InsLibVmeAddressSpace *vmeas_clone = NULL; if (vmeas) { vmeas_clone = (InsLibVmeAddressSpace *) sysbrk(sizeof(InsLibVmeAddressSpace)); if (!vmeas_clone) return NULL; copy_mem((void *) vmeas_clone, (void *) vmeas, sizeof(InsLibVmeAddressSpace)); vmeas_clone->Next = InsLibCloneVmeSpace(vmeas->Next); return vmeas_clone; } return NULL; }
InsLibCarAddressSpace *InsLibCloneCarSpace(InsLibCarAddressSpace *caras) { InsLibCarAddressSpace *caras_clone = NULL; if (caras) { caras_clone = (InsLibCarAddressSpace *) sysbrk(sizeof(InsLibCarAddressSpace)); if (!caras_clone) return NULL; copy_mem((void *) caras_clone, (void *) caras, sizeof(InsLibCarAddressSpace)); caras_clone->Next = InsLibCloneCarSpace(caras->Next); return caras_clone; } return NULL; }
InsLibPciModuleAddress *InsLibClonePci(InsLibPciModuleAddress *pcima) { InsLibPciModuleAddress *pcima_clone = NULL; if (pcima) { pcima_clone = (InsLibPciModuleAddress *) sysbrk(sizeof(InsLibPciModuleAddress)); if (!pcima_clone) return NULL; copy_mem((void *) pcima_clone, (void *) pcima, sizeof(InsLibPciModuleAddress)); pcima_clone->PciAddressSpace = InsLibClonePciSpace(pcima->PciAddressSpace); return pcima_clone; } return NULL; }
InsLibCarModuleAddress *InsLibCloneCar(InsLibCarModuleAddress *carma) { InsLibCarModuleAddress *carma_clone = NULL; if (carma) { carma_clone = (InsLibCarModuleAddress *) sysbrk(sizeof(InsLibCarModuleAddress)); if (!carma_clone) return NULL; copy_mem((void *) carma_clone, (void *) carma, sizeof(InsLibCarModuleAddress)); carma_clone->CarAddressSpace = InsLibCloneCarSpace(carma->CarAddressSpace); return carma_clone; } return NULL; }
SkelUserReturn SkelUserModuleInit(SkelDrvrModuleContext *mcon) { struct udata *udata; udata = (void *)sysbrk(sizeof(struct udata)); if (udata == NULL) { report_module(mcon, SkelDrvrDebugFlagASSERTION, "Not enough memory for the module's data"); pseterr(ENOMEM); return SkelUserReturnFAILED; } bzero((void *)udata, sizeof(struct udata)); mcon->UserData = udata; /* initialise the iomap address */ udata->iomap = get_vmemap_addr(mcon, 0x39, 32); if (!udata->iomap) { SK_WARN("Could not find VME address space (0x39, 32)"); goto out_free; } /* initialise the jtag address */ udata->jtag = get_vmemap_addr(mcon, 0x29, 16); if (!udata->jtag) { SK_WARN("Could not find VME address space (0x29, 16)"); goto out_free; } /* initialise locking fields */ cdcm_spin_lock_init(&udata->iolock); cdcm_mutex_init(&udata->lock); /* initialise the tasks */ mtt_tasks_init(udata); /* module software reset */ SkelUserHardwareReset(mcon); return SkelUserReturnOK; out_free: sysfree((void*)udata, sizeof(struct udata)); return SkelUserReturnFAILED; }
static SkelUserReturn mtt_gs_program(struct udata *udata, MttDrvrInstruction *u_prog, MttDrvrInstruction *io_prog, unsigned int elems, int set) { void *bounce; ssize_t size = elems * sizeof(MttDrvrInstruction); bounce = (void *)sysbrk(size); if (bounce == NULL) { SK_ERROR("%s: -ENOMEM", __FUNCTION__); pseterr(ENOMEM); goto out_err; } if (set) { if (cdcm_copy_from_user(bounce, u_prog, size)) { pseterr(EFAULT); goto out_err; } cdcm_mutex_lock(&udata->lock); __mtt_set_program(udata, io_prog, bounce, elems); cdcm_mutex_unlock(&udata->lock); } else { cdcm_mutex_lock(&udata->lock); __mtt_get_program(udata, bounce, io_prog, elems); cdcm_mutex_unlock(&udata->lock); if (cdcm_copy_to_user(u_prog, bounce, size)) { pseterr(EFAULT); goto out_err; } } sysfree(bounce, size); return SkelUserReturnOK; out_err: if (bounce) sysfree(bounce, size); return SkelUserReturnFAILED; }
/** * @brief Clone all memory for a single host driver * * @param drvrd - * * <long-description> * * @return <ReturnValue> */ InsLibDrvrDesc *InsLibCloneOneDriver(InsLibDrvrDesc *drvrd) { InsLibDrvrDesc *drvrd_clone = NULL; if (drvrd) { drvrd_clone = (InsLibDrvrDesc *) sysbrk(sizeof(InsLibDrvrDesc)); if (!drvrd_clone) { printk("InsLib: Not enough memory for drvrd_clone\n"); return NULL; } copy_mem((void *) drvrd_clone, (void *) drvrd, sizeof(InsLibDrvrDesc)); drvrd_clone->Modules = InsLibCloneModule(drvrd->Modules); drvrd_clone->Next = NULL; return drvrd_clone; } return NULL; }
static SkelUserReturn __mtt_io(SkelDrvrModuleContext *mcon, void *u_addr, void *ioaddr, ssize_t size, int write) { struct udata *udata = mcon->UserData; void *bounce; bounce = (void *)sysbrk(size); if (bounce == NULL) { report_module(mcon, SkelDrvrDebugFlagASSERTION, "%s: -ENOMEM", __FUNCTION__); pseterr(ENOMEM); goto out_err; } if (write) { if (cdcm_copy_from_user(bounce, u_addr, size)) { pseterr(EFAULT); goto out_err; } cdcm_mutex_lock(&udata->lock); mtt_iowritew_r(ioaddr, bounce, size); cdcm_mutex_unlock(&udata->lock); } else { cdcm_mutex_lock(&udata->lock); mtt_ioreadw_r(bounce, ioaddr, size); cdcm_mutex_unlock(&udata->lock); if (cdcm_copy_to_user(u_addr, bounce, size)) { pseterr(EFAULT); goto out_err; } } sysfree(bounce, size); return SkelUserReturnOK; out_err: if (bounce) sysfree(bounce, size); return SkelUserReturnFAILED; }
/** * @brief User entry point in driver/simulator installation routine. * * @param proceed -- if standard code execution should be proceed * @param info -- driver info table * @param sptr -- statics table * * It's up to user to set kernel-level errno (by means of @e pseterr call). * @e proceed parameter denotes if further standard actions should be proceed * after function returns. @b FALSE - means that user-desired operation done * all that user wants and there is no further necessaty to perfom any standard * operations that follow function call. @b TRUE - means that code that follows * function call will be executed. * * @return return value is the same as in entry point function.\n * pointer to a statics data structure - if succeed.\n * SYSERR - in case of failure. */ char* CvorbUserInst(int *proceed, register DevInfo_t *info, register CVORBStatics_t *sptr) { CVORBUserStatics_t *usp = sptr->usrst; /* user statistics table */ int iVec = 0; /* interrupt vector */ int m, c; iVec = info->iVector; /* set up interrupt vector */ /* map submodule address pointers */ usp->md = (struct cvorb_module *)sysbrk(sizeof(_m)); usp->md[0].md = (mod *)sptr->card->block00; usp->md[1].md = (mod *)((long)sptr->card->block00 + 0x200); if (!firmware_ok(usp, info->mlun)) { sysfree((char *)usp->md, sizeof(_m)); return (char *)SYSERR; } for (m = 0; m < SMAM; m++) { /* reset subModules */ _wr(m, SOFT_PULSE, SPR_FGR); /* initialize iolock mutex */ cdcm_mutex_init(&usp->md[m].iol); /* set submodule channels addresses */ for (c = 0; c < CHAM; c++) usp->md[m].cd[c] = (chd *) ((long)usp->md[m].md + _ch_offset[c]); } /* init on-board DAC */ ad9516o_init(usp); /* disable on-board clock generator */ _wr(0, CLK_GEN_CNTL, AD9516_OFF); /* set normal mode operation, enable all channels and set recurrent cycles to 1 (i.e. play function once) */ enable_modules(usp); /* Uncomment the following code to register ISR */ #if 0 if (iVec > 0) { int cc = 0; /* completion code */ kkprintf("ISR ( vector number [%d] ) installation - ", iVec); #ifdef __Lynx__ #ifdef __powerpc__ /* in this case we are using CES BSP */ cc = vme_intset(iVec, (int (*)())CvorbISR, (char*)sptr, 0); #else /* use standard system call otherwise */ cc = iointset(iVec, (int (*)())CvorbISR, (char*)sptr); #endif #else /* __linux__ */ cc = vme_request_irq(iVec, (int (*)(void *))CvorbISR, (char *)sptr, "CvorbD"); #endif /* __Lynx__ */ if (cc < 0) { kkprintf("Failed.\n"); pseterr(EFAULT); /* TODO. what error to set? */ return (char*)SYSERR; /* -1 */ } kkprintf("interrupt vector managed.\n"); } #endif if (proceed) *proceed = TRUE; /* continue standard code execution */ return (char *)sptr; /* succeed */ }
void * btk_mem_alloc( size_t size, bt_data32_t flags ) { void * kmem_p = NULL; FUNCTION("btk_mem_alloc"); LOG_UNKNOWN_UNIT; FENTRY; #if defined (_AIX) kmem_p = xmalloc(size, ALIGN_LONG, (flags & BTK_ALLOC_SWAPPABLE) ? 0 : pinned_heap); #elif defined(__hpux) /* ** sys_memall() allocates a number of virtual memory pages (NBPG=4K). ** Since the driver calls btk_mem_alloc() to get each interrupt ** registration structure this is wasteful of lockable system memory. ** Eventually it would be a good idea to add another layer of memory ** management to clean this up. */ kmem_p = sys_memall(size); #elif defined(__sun) kmem_p = kmem_alloc( size, KM_NOSLEEP); #elif defined(__sgi) /* ** Does not request cache-aligned or physically contiguous memory. ** If the memory is going to be DMA'd in to or out of (i.e. write ** or read respectively) then kmem_alloc() must be called directly ** with the appropriate flag for cache-alignment. In addition to ** cache-aligning the buffer, cache flushing issues must be taken ** into consideration and are unique for the platform in question. */ kmem_p = kmem_alloc(size, 0); #elif defined(__vxworks) kmem_p = malloc(size); #elif defined(BT_uCOS) kmem_p = malloc(size); #elif defined(_NTDDK_) /* The requested memory is not cache aligned or physically contiguous. Don't use for DMA. Also, don't use for a buffer to be shared with user space unless size < physical page size because the user virtual address won't be valid across non-contiguous pages. */ kmem_p = ExAllocatePool( (flags & BTK_ALLOC_SWAPPABLE) ? PagedPool : NonPagedPool, size); #elif defined(__linux__) kmem_p = kmalloc(size, GFP_KERNEL); #elif defined(__lynxos) kmem_p = sysbrk(size); #endif /* _AIX, __hpux, __sun, __sgi, __vxworks, _NTDDK_ */ /* Protect btk_alloc_total_g accesses. This mutex may not be held during the preceeding memory allocation to avoid doing the allocations at a raised interrupt level. */ btk_mutex_enter(&kmem_mutex); btk_alloc_total_g += size; /* running total of kmem */ if (btk_alloc_total_g < 0) { FATAL_STR("Allocated kernel memory went negative.\n"); } TRC_MSG((BT_TRC_ALLOC), (LOG_FMT "ptr " PTR_FMT "; size %d; total %d.\n", LOG_ARG, kmem_p, (int) size, btk_alloc_total_g)); btk_mutex_exit(&kmem_mutex); FEXIT(kmem_p); return(kmem_p); }