Ejemplo n.º 1
0
/**
 * mmap_user_to_isp - Maps user memory in to kernel space and then maps
 *			kernel memory to isp address space.
 * @src: Pointer to user buffer info.
 * @dest: Pointer to internal buffer to save map info.
 *
 * Return 0 on success, -1 otherwise.
 **/
int map_user_to_kernel(struct hp3a_buffer *src, struct hp3a_internal_buffer *dest)
{
	dest->pages =  map_user_memory((unsigned long)src->addr,
					src->buffer_size);
	if (likely(dest->pages != NULL)) {
		dest->buffer_size = src->buffer_size;
		dest->user_addr = src->addr;
		dest->isp_addr = 0;

		return 0;
	}

	return -1;
}
Ejemplo n.º 2
0
int main(int argc, char** argv){
  // get an IGAccelGLContext
  gl_context = get_user_client("IOAccelerator", 1);

  // get a IGAccelSharedUserClient
  mach_port_t shared = get_user_client("IOAccelerator", 6);

  // connect the gl_context to the shared UC so we can actually use it:
  kern_return_t err = IOConnectAddClient(gl_context, shared);
  if (err != KERN_SUCCESS){
   printf("IOConnectAddClient error: %x\n", err);
   return 0;
  }

  printf("added client to the shared UC\n");

  handle = map_user_memory(gl_context);

  OSSpinLockLock(&lock);

  pthread_t t;
  pthread_create(&t, NULL, (void*) go, NULL);

  usleep(100000);

  OSSpinLockUnlock(&lock);

  unmap_user_memory(gl_context, handle);
  printf("called unmap from main process thread\n");
  pthread_join(t, NULL);


  return 0;


}
Ejemplo n.º 3
0
int setup_job(ibmuftian_fpga *fpga, void *ioctl_data, unsigned type)
{
    ibmuftian_job * job = kzalloc(sizeof(ibmuftian_job),GFP_KERNEL);
    mem_buff *mem_ioctl = NULL;
    ioctl_inst *inst_ioctl = NULL;
    ibmuftian_engn * engn = NULL;
    int inst_bd = 0, data_bd = 0, total_bd = 0,
        inst_malloc = 0, data_malloc = 0, inst_pg_num = 0,
        data_pg_num = 0, max_bd = 0, loop_var = 0, ret = SUCCESS, dirtied = 0, err = 0, buf_id = 0;
    unsigned long max_data_size;
    sgt_container *sgl_data;
    dma_addr_t inst_dma_addr = 0;
    enum dma_data_direction direction = DMA_BIDIRECTIONAL; //initialization.
    struct page **inst_pgs, **data_pgs;
    void *inst_kernel_ptr, *data_kernel_ptr;
    bd_bookeeping *bd_ptr;
    
    if(type == INST)
    {
        PRINT(DBG_PRAM({IOCTL_DBG}), "inst ioctl");
        inst_ioctl = (ioctl_inst *)ioctl_data;
        mem_ioctl = &inst_ioctl->data;
        job->engn_no = inst_ioctl->eng_num;
    }
    else
    {
        PRINT(DBG_PRAM({IOCTL_DBG}), "data ioctl");
        mem_ioctl = (mem_buff *)ioctl_data;
        job->engn_no = 0;
    }

    
    switch(type)
    {
        case(INST):
        {
            inst_bd = 1;
            if((inst_dma_addr = map_user_memory(fpga->device_info.pdev, 
                                                 (unsigned long) inst_ioctl->inst.host_ptr, 
                                                 (unsigned long) (inst_ioctl->inst.host_ptr + inst_ioctl->inst.buff_size),
                                                 DMA_TO_DEVICE,
                                                 &inst_malloc,
                                                 &inst_pgs,
                                                 &inst_pg_num,
                                                 &inst_kernel_ptr)) == FAILURE)
            {
                PRINT(DBG_PRAM({IOCTL_DBG, ERR_DBG}), "map user memory failed"); 
                return -ENOMEM;
            }
            
        }

        case(WRITE_MEM):
        {
            direction = DMA_TO_DEVICE;
            break;
        }

        case(READ_MEM):
        {
            direction = DMA_FROM_DEVICE;
            dirtied = DIRTY;
            break;
        }
    }
    max_data_size = MAX_DATA_SEGS*DMA_DATA_SIZE;

    if(fpga->fpga_info.bit.board_type == FIN)
        max_bd = TOTAL_FIN_MEM_SIZE/max_data_size;
    else if(fpga->fpga_info.bit.board_type == WRASSE)
        max_bd = TOTAL_WRASSE_MEM_SIZE/max_data_size;
    if((data_bd = map_user_pages(&sgl_data, 
                                  (unsigned long) mem_ioctl->host_ptr,
                                  (unsigned long)(mem_ioctl->host_ptr + mem_ioctl->buff_size),
                                  direction,
                                  max_data_size,
                                  &data_malloc,
                                  &max_bd,
                                  &data_pgs,
                                  &data_pg_num,
                                  &data_kernel_ptr)) == FAILURE)
    {
        PRINT(DBG_PRAM({IOCTL_DBG, ERR_DBG}), "map user pages failed");
        return -ENOMEM;
    }

    total_bd = data_bd + inst_bd;
    PRINT(DBG_PRAM({IOCTL_DBG}), "data bd = %d inst bd %d", data_bd, inst_bd);
    job->pdev = fpga->device_info.pdev;
    job->total_bd = total_bd;
    job->job_type = type;
    init_completion(&(job->job_completion));
    atomic_set(&job->bd_count, total_bd);
    job->bd = kzalloc(sizeof(bd_bookeeping)*total_bd, GFP_KERNEL);
    memset(job->bd, ZERO, total_bd * sizeof(bd_bookeeping));
    bd_ptr = job->bd;
    engn = fpga->engns.engines[job->engn_no];

    if(engn->aborted)
    {
        PRINT(DBG_PRAM({IOCTL_DBG, ERR_DBG}), "Resetting engine from previous abort");
        reset_aborted_engn(engn);
        engn->aborted = 0;
    }

    PRINT(DBG_PRAM({IOCTL_DBG}), "engn id = %d totalbd %d", engn->id, total_bd);
    
    spin_lock(&engn->id_lock);
    if(((unsigned short)(engn->bd_id + total_bd) < engn->bd_id))
        engn->bd_id = 0;

    buf_id = engn->bd_id;
    engn->bd_id = engn->bd_id + total_bd;
    spin_unlock(&engn->id_lock);

    for(loop_var = 0;loop_var < total_bd; loop_var++)
    {
        bd_ptr[loop_var].bd_num = ++buf_id;

        if(!loop_var)
            job->bd_tag_start_id = bd_ptr[loop_var].bd_num;

        bd_ptr[loop_var].bd_state = INIT;

        if((loop_var == BD_IN_INST_IOCTL - LAST_MEM_BD) && inst_bd)
        {
            init_completion((&bd_ptr[loop_var].inst_bookeeping.ibd_completion));
            bd_ptr[loop_var].set_interrupt = SET_INTERRUPT;
            bd_ptr[loop_var].inst_bookeeping.complete = 1;
        }
        
        if(!(bd_ptr[loop_var].bd_num % INTERRUPT_ENABLE) || (loop_var == total_bd - 1))
            bd_ptr[loop_var].set_interrupt = SET_INTERRUPT;
        bd_ptr[loop_var].parent_job = &job;

        bd_ptr[loop_var].bd_type = type;        

        if((loop_var == (total_bd-1)) && inst_bd)
        {
            bd_ptr[loop_var].inst_mem = INST_IOCTL;
            bd_ptr[loop_var].inst_dma_addr = inst_dma_addr;
            bd_ptr[loop_var].mem_addr.inst.count = inst_bd;
            bd_ptr[loop_var].mem_addr.inst.len = inst_ioctl->inst.buff_size;
            bd_ptr[loop_var].mem_addr.inst.offset = 0;
            bd_ptr[loop_var].mem_addr.inst.src = NULL;
            bd_ptr[loop_var].mem_addr.inst.dst = inst_ioctl->inst.host_ptr;
        }
        else
        {
            bd_ptr[loop_var].inst_mem = MEM_IOCTL;
            bd_ptr[loop_var].sg_data = sgl_data[loop_var].sgt;
            bd_ptr[loop_var].mem_addr.data.count = data_bd;
            bd_ptr[loop_var].mem_addr.data.offset = 0;
            bd_ptr[loop_var].mem_addr.data.len = sgl_data[loop_var].sgt_len;

            if(type == READ_MEM)
            {
                bd_ptr[loop_var].mem_addr.data.src = (void *)(mem_ioctl->uta_ptr + sgl_data[loop_var].sgt_offset);
                bd_ptr[loop_var].mem_addr.data.dst = NULL;
                if((ret = dma_map_sg(&fpga->device_info.pdev->dev,
                                      bd_ptr[loop_var].sg_data->sgl,
                                      bd_ptr[loop_var].sg_data->nents,
              		                  DMA_FROM_DEVICE)) <= 0)
                {
                    PRINT(DBG_PRAM({IOCTL_DBG, ERR_DBG}), "dma map sg failed");
                    return ret;
                }
            }
            else 
            {
                bd_ptr[loop_var].mem_addr.data.dst = (void *)(mem_ioctl->uta_ptr + sgl_data[loop_var].sgt_offset);
                bd_ptr[loop_var].mem_addr.data.src = NULL;
                if((ret = dma_map_sg(&fpga->device_info.pdev->dev,
                                      bd_ptr[loop_var].sg_data->sgl,
                                      bd_ptr[loop_var].sg_data->nents,
              		                  DMA_TO_DEVICE)) <= 0)
                {
                    PRINT(DBG_PRAM({IOCTL_DBG, ERR_DBG}), "dma map sg failed");
                    return ret;
                }
            }
        }
        if(type == INST)
        {
            bd_ptr[loop_var].gprs.enable_mask = inst_ioctl->reg_init.enable_mask;
            bd_ptr[loop_var].gprs.reg_val = inst_ioctl->reg_init.reg_val;
        }

        bd_ptr[loop_var].done = IN_PROGRESS;
        setup_timer(&(bd_ptr[loop_var].bd_timer), &bd_timed_out, (unsigned long)&bd_ptr[loop_var]);
    }

    spin_lock_bh(&engn->jobs.job_queue_lock);
    list_add(&(job->list), &(engn->jobs.job_queue));
    spin_unlock_bh(&engn->jobs.job_queue_lock);

    if(build_send_bd(engn, job))
    {
        PRINT(DBG_PRAM({IOCTL_DBG, ERR_DBG}), "failed to build bd and ring door bell");
        goto clean_exit;
    }

    PRINT(DBG_PRAM({IOCTL_DBG}), "ibd sent waiting for it to complete");
    
    if((ret = wait_for_completion_interruptible_timeout(&job->job_completion,JOB_COMP_TIMEOUT)) <= ZERO)
    {
        if(ret < ZERO)
        {
            PRINT(DBG_PRAM({IOCTL_DBG, ERR_DBG}), "wait returned negative value restart system");

            for(loop_var = 0;loop_var < total_bd; loop_var++)
            {
                if(bd_ptr[loop_var].done != DONE)
                {
                    del_timer(&bd_ptr[loop_var].bd_timer);
                }
            }
            spin_lock_bh(&engn->jobs.job_queue_lock);
            list_del(&job->list);
            complete_all(&job->job_completion);
            spin_unlock_bh(&engn->jobs.job_queue_lock);
            engn->aborted = 1;
            ret = -ERESTARTSYS;
            err = FAILURE;
        }
        else
        {
            PRINT(DBG_PRAM({IOCTL_DBG, ERR_DBG}), "timer expired job with bd id %d and length %d probably stuck", job->bd_tag_start_id, job->total_bd);
            ret = -ETIMEDOUT; 
            err = FAILURE;
        }
        
    }

clean_exit:
    for(loop_var = 0; loop_var < total_bd; loop_var++)
    {
        if(bd_ptr[loop_var].inst_mem == MEM_IOCTL)
        {
            if(bd_ptr[loop_var].bd_type == READ_MEM)
            {
                dma_unmap_sg(&fpga->device_info.pdev->dev,
                             bd_ptr[loop_var].sg_data->sgl,
                             bd_ptr[loop_var].sg_data->nents,
              		         DMA_FROM_DEVICE);
            }
            else
            { 
                dma_map_sg(&fpga->device_info.pdev->dev,
                           bd_ptr[loop_var].sg_data->sgl,
                           bd_ptr[loop_var].sg_data->nents,
              		       DMA_TO_DEVICE);
            }
        }
    }

    if(type == INST)
    {
        unmap_user_memory(fpga->device_info.pdev,
                          inst_dma_addr,
                          direction,
                          inst_malloc,
                          inst_pgs,
                          inst_pg_num,
                          inst_kernel_ptr,
                          inst_ioctl->inst.buff_size);
    }

    unmap_user_pages(sgl_data,
                     dirtied,
                     data_bd,
                     data_malloc,
                     max_bd,
                     data_pgs,
                     data_pg_num,
                     data_kernel_ptr);

    if(type == READ_MEM)
        del_timer(&engn->bar0->interrupt_service.obd_comp_timer);
    else
        del_timer(&engn->bar0->interrupt_service.ibd_comp_timer);

    ZERO_AND_FREE(job->bd);
    ZERO_AND_FREE(job);

    if(err)
        return ret;
    else
        return SUCCESS;
//retry_job:
//    return FAILURE; // space holder change later
    //do not delete job here we will write the logic to redeploy the job for number of times if the thing fails.
}