Esempio n. 1
0
void render_lodder_sphere(int group, Vertex spherepos, Vertex spherepos2, float diam, float powr, float push, float timex) {
  Vertex *loddata[MAX_LOD_REDUCTION+1];  
  Vertex *v, *n;
  int vc=loddermesh->groups[group]->vc;
  int fc=loddermesh->groups[group]->fc;
  int *i=loddermesh->groups[group]->indices;
  float *c;
  
  unsigned char *lodlevels;

  // assign lod buffers, 0=original
  loddata[0]=loddermesh->groups[group]->vertices;
  for (int i=0; i<MAX_LOD_REDUCTION; i++) loddata[i+1]=lodder_vertices[group][i];

  v=tmpmalloc(sizeof(Vertex)*vc);
  n=tmpmalloc(sizeof(Vertex)*vc);
  c=tmpmalloc(sizeof(float)*vc*4);
  lodlevels=tmpmalloc(vc);
  
  // calc vertices
  for (int x=0; x<vc; x++) {
    Vertex l0pos=loddata[0][x];
    float xx=(l0pos.x-spherepos.x);
    float yy=(l0pos.y-spherepos.y);
    float zz=(l0pos.z-spherepos.z);
    float xx2=(l0pos.x-spherepos2.x);
    float yy2=(l0pos.y-spherepos2.y);
    float zz2=(l0pos.z-spherepos2.z);
    float dist=sqrt(xx*xx+yy*yy+zz*zz);
    float dist2=sqrt(xx2*xx2+yy2*yy2+zz2*zz2);
    float powah=r0(diam-dist)/diam; // 0..1 sphere
    float powah2=r0(diam-dist2)/diam; 
    float lod=clamp((powah+powah2)*powr);
    //lod=clamp(powr);
    float lodfract=lod*(float)MAX_LOD_REDUCTION;
    int bufnum=(int)floor(lodfract);

    lodfract=fmod(lodfract, 1.0);
    
    c[x*3+0]=c[x*3+1]=c[x*3+2]=clamp((lod-0.1)*4.0);
    // calc lodded pos  
    if (lod==0.0) {
      v[x]=l0pos;
      lodlevels[x]=0;
    } else if (lod==1.0) {
      v[x]=loddata[MAX_LOD_REDUCTION][x];
      lodlevels[x]=1;
    } else {
      Vertex l0=loddata[bufnum][x];
      Vertex l1=loddata[bufnum+1][x];
      v[x].x = l0.x*(1.0-lodfract)+l1.x*(lodfract);
      v[x].y = l0.y*(1.0-lodfract)+l1.y*(lodfract);
      v[x].z = l0.z*(1.0-lodfract)+l1.z*(lodfract);
      lodlevels[x]=1;      
    }
    
    // push
    Vertex pd=new_v(v[x].x-spherepos.x, v[x].y-spherepos.y, v[x].z-spherepos.z);
    Vertex pd2=new_v(v[x].x-spherepos2.x, v[x].y-spherepos2.y, v[x].z-spherepos2.z);
    normalize(&pd);
    normalize(&pd2);
    v[x].x+=push*powah*pd.x+push*powah2*pd2.x;
    v[x].y+=push*powah*pd.y+push*powah2*pd2.y;
    v[x].z+=push*powah*pd.z+push*powah2*pd2.z;

    // little something for normal
    n[x]=new_v(0.0, 0.00001, 0.0);
  }

  // calc normals
  for (int x=0; x<fc; x++) {
    Vertex fnorm;
    Vertex *v1, *v2, *v3;
    Vertex *n1, *n2, *n3;
    v1=&v[i[x*3+0]];
    v2=&v[i[x*3+1]];
    v3=&v[i[x*3+2]];
    n1=&n[i[x*3+0]];
    n2=&n[i[x*3+1]];
    n3=&n[i[x*3+2]];
  	calc_fnorm_nn(v1, v2, v3, &fnorm);
    n1->x+=fnorm.x; n1->y+=fnorm.y; n1->z+=fnorm.z;
    n2->x+=fnorm.x; n2->y+=fnorm.y; n2->z+=fnorm.z;
    n3->x+=fnorm.x; n3->y+=fnorm.y; n3->z+=fnorm.z;
  }

  // normalize normals, for lod 0 use original normal
  for (int x=0; x<vc; x++) {
  	if (lodlevels[x]==0) n[x]=loddermesh->groups[group]->normals[x];
  	else normalize(&n[x]);
  }

  // render arrays
//  glUniform1fARB(glGetUniformLocationARB(shader, "depthmult"), 1.0);  
  glue_disableallarrays();
  glEnableClientState(GL_VERTEX_ARRAY);
  glVertexPointer(3, GL_FLOAT, 0, v);
  glEnableClientState(GL_NORMAL_ARRAY);
  glNormalPointer(GL_FLOAT, 0, n);
  /*
  Vertex *t=loddermesh->groups[group]->texcoords;
  if (t) {
    glClientActiveTexture(GL_TEXTURE0_ARB);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(3, GL_FLOAT, 0, t);
  }*/
  
  // alkup. verteksit texturekoordinaateiks
  glClientActiveTexture(GL_TEXTURE1_ARB);
  glActiveTexture(GL_TEXTURE1_ARB);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  glTexCoordPointer(3, GL_FLOAT, 0, loddata[0]);
  
  glDrawElements(GL_TRIANGLES, fc*3, GL_UNSIGNED_INT, i);

/*
  // wireframe  
  //glUniform1fARB(glGetUniformLocationARB(shader, "depthmult"), 0.0);  
  //renderflags(GLUE_BLEND_ALPHAADD|GLUE_CHECK_DEPTH);
  renderflags(GLUE_BLEND|GLUE_CHECK_DEPTH);
  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  glEnable(GL_POLYGON_OFFSET_LINE);
  glPolygonOffset(1.0, 1.0);
  //glEnable(GL_LINE_SMOOTH);
  glLineWidth(glueXres/320);
  glueDisabletexture();
  glDisableClientState(GL_NORMAL_ARRAY);
  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  glEnableClientState(GL_COLOR_ARRAY);
  glColorPointer(3, GL_FLOAT, 0, c);
  glDrawElements(GL_TRIANGLES, fc*3, GL_UNSIGNED_INT, i);
  glue_disableallarrays();
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  glDisable(GL_POLYGON_OFFSET_LINE);
*/
  glue_disableallarrays();

  tmpfree(lodlevels);
  tmpfree(c);  
  tmpfree(n);
  tmpfree(v);  
}
Esempio n. 2
0
arg_t _execve(void)
{
	/* We aren't re-entrant where this matters */
	uint8_t hdr[16];
	staticfast inoptr ino;
	char **nargv;		/* In user space */
	char **nenvp;		/* In user space */
	struct s_argblk *abuf, *ebuf;
	int argc;
	uint16_t progptr;
	uint16_t progload;
	staticfast uint16_t top;
	uint16_t bin_size;	/* Will need to be bigger on some cpus */
	uint16_t bss;

	top = ramtop;

	if (!(ino = n_open_lock(name, NULLINOPTR)))
		return (-1);

	if (!((getperm(ino) & OTH_EX) &&
	      (ino->c_node.i_mode & F_REG) &&
	      (ino->c_node.i_mode & (OWN_EX | OTH_EX | GRP_EX)))) {
		udata.u_error = EACCES;
		goto nogood;
	}

	setftime(ino, A_TIME);

	udata.u_offset = 0;
	udata.u_count = 16;
	udata.u_base = hdr;
	udata.u_sysio = true;

	readi(ino, 0);
	if (udata.u_done != 16) {
		udata.u_error = ENOEXEC;
		goto nogood;
	}

	if (!header_ok(hdr)) {
		udata.u_error = ENOEXEC;
		goto nogood2;
	}

	progload = hdr[7] << 8;
	if (progload == 0)
		progload = PROGLOAD;

	top = *(uint16_t *)(hdr + 8);
	if (top == 0)	/* Legacy 'all space' binary */
		top = ramtop;
	else	/* Requested an amount, so adjust for the base */
		top += progload;

	bss = *(uint16_t *)(hdr + 14);

	/* Binary doesn't fit */
	/* FIXME: review overflows */
	bin_size = ino->c_node.i_size;
	progptr = bin_size + 1024 + bss;
	if (progload < PROGLOAD || top - progload < progptr || progptr < bin_size) {
		udata.u_error = ENOMEM;
		goto nogood2;
	}

	udata.u_ptab->p_status = P_NOSLEEP;

	/* If we made pagemap_realloc keep hold of some defined area we
	   could in theory just move the arguments up or down as part of
	   the process - that would save us all this hassle but replace it
	   with new hassle */

	/* Gather the arguments, and put them in temporary buffers. */
	abuf = (struct s_argblk *) tmpbuf();
	/* Put environment in another buffer. */
	ebuf = (struct s_argblk *) tmpbuf();

	/* Read args and environment from process memory */
	if (rargs(argv, abuf) || rargs(envp, ebuf))
		goto nogood3;	/* SN */

	/* This must be the last test as it makes changes if it works */
	/* FIXME: once we sort out chmem we can make stack and data
	   two elements. We never allocate 'code' as there is no split I/D */
	/* This is only safe from deadlocks providing pagemap_realloc doesn't
	   sleep */
	if (pagemap_realloc(0, top - MAPBASE, 0))
		goto nogood3;

	/* From this point on we are commmited to the exec() completing */

	/* Core dump and ptrace permission logic */
#ifdef CONFIG_LEVEL_2
	/* Q: should uid == 0 mean we always allow core */
	if ((!(getperm(ino) & OTH_RD)) ||
		(ino->c_node.i_mode & (SET_UID | SET_GID)))
		udata.u_flags |= U_FLAG_NOCORE;
	else
		udata.u_flags &= ~U_FLAG_NOCORE;
#endif
	udata.u_top = top;
	udata.u_ptab->p_top = top;

	/* setuid, setgid if executable requires it */
	if (ino->c_node.i_mode & SET_UID)
		udata.u_euid = ino->c_node.i_uid;

	if (ino->c_node.i_mode & SET_GID)
		udata.u_egid = ino->c_node.i_gid;

	/* FIXME: In the execve case we may on some platforms have space
	   below PROGLOAD to clear... */

	/* We are definitely going to succeed with the exec,
	 * so we can start writing over the old program
	 */
	uput(hdr, (uint8_t *)progload, 16);
	/* At this point, we are committed to reading in and
	 * executing the program. This call must not block. */

	close_on_exec();

	/*
	 *  Read in the rest of the program, block by block. We rely upon
	 *  the optimization path in readi to spot this is a big move to user
	 *  space and move it directly.
	 */

	 progptr = progload + 16;
	 if (bin_size > 16) {
		bin_size -= 16;
		udata.u_base = (uint8_t *)progptr;		/* We copied the first block already */
		udata.u_count = bin_size;
		udata.u_sysio = false;
		readi(ino, 0);
		if (udata.u_done != bin_size)
			goto nogood4;
		progptr += bin_size;
	}
	/* Wipe the memory in the BSS. We don't wipe the memory above
	   that on 8bit boxes, but defer it to brk/sbrk() */
	uzero((uint8_t *)progptr, bss);

	/* Set initial break for program */
	udata.u_break = (int)ALIGNUP(progptr + bss);

	/* Turn off caught signals */
	memset(udata.u_sigvec, 0, sizeof(udata.u_sigvec));

	// place the arguments, environment and stack at the top of userspace memory,

	// Write back the arguments and the environment
	nargv = wargs(((char *) top - 2), abuf, &argc);
	nenvp = wargs((char *) (nargv), ebuf, NULL);

	// Fill in udata.u_name with program invocation name
	uget((void *) ugetw(nargv), udata.u_name, 8);
	memcpy(udata.u_ptab->p_name, udata.u_name, 8);

	tmpfree(abuf);
	tmpfree(ebuf);
	i_deref(ino);

	/* Shove argc and the address of argv just below envp
	   FIXME: should flip them in crt0.S of app for R2L setups
	   so we can get rid of the ifdefs */
#ifdef CONFIG_CALL_R2L	/* Arguments are stacked the 'wrong' way around */
	uputw((uint16_t) nargv, nenvp - 2);
	uputw((uint16_t) argc, nenvp - 1);
#else
	uputw((uint16_t) nargv, nenvp - 1);
	uputw((uint16_t) argc, nenvp - 2);
#endif

	/* Set stack pointer for the program */
	udata.u_isp = nenvp - 2;

	/* Start execution (never returns) */
	udata.u_ptab->p_status = P_RUNNING;
	doexec(progload);

	/* tidy up in various failure modes */
nogood4:
	/* Must not run userspace */
	ssig(udata.u_ptab, SIGKILL);
nogood3:
	udata.u_ptab->p_status = P_RUNNING;
	tmpfree(abuf);
	tmpfree(ebuf);
nogood2:
nogood:
	i_unlock_deref(ino);
	return (-1);
}
Esempio n. 3
0
void mbr_parse(char letter)
{
    boot_record_t *br;
    uint8_t i, seen = 0;
    uint32_t ep_offset = 0, br_offset = 0;
    uint8_t next = 0;

    kprintf("hd%c: ", letter);

    /* allocate temporary memory */
    br = (boot_record_t *)tmpbuf();

    blk_op.is_read = true;
    blk_op.is_user = false;
    blk_op.addr = (uint8_t *)br;
    blk_op.lba = 0;

    do{
        blk_op.nblock = 1;
        if(!blk_op.blkdev->transfer() || le16_to_cpu(br->signature) != MBR_SIGNATURE){
#ifdef CONFIG_MBR_OFFSET
            if (blk_op.lba == 0) {
                /* failed to find MBR on block 0. Go round again but this time
                   look at the fall-back location for this badly-behaved media
                */
                blk_op.lba = CONFIG_MBR_OFFSET;
                continue;
            }
#endif
	    break;
        }

	/* avoid an infinite loop where extended boot records form a loop */
	if(seen >= 50)
	    break;

	if(seen == 1){
	    /* we just loaded the first extended boot record */
	    ep_offset = blk_op.lba;
	    next = 4;
	    kputs("< ");
	}

	br_offset = blk_op.lba;
        blk_op.lba = 0;

	for(i=0; i<MBR_ENTRY_COUNT && next < MAX_PARTITIONS; i++){
	    switch(br->partition[i].type_chs_last[0]){
#ifdef CONFIG_GPT
		case MBR_GPT_PROTECTED_TYPE:
		    // TODO assert next is zero (unless hybrid...)
		    parse_gpt((uint8_t *) br, i);
		    goto out;
#endif
		case 0:
		    break;
		case 0x05:
		case 0x0f:
		case 0x85:
		    /* Extended boot record, or chained table; in principle a drive should contain
		       at most one extended partition so this code is OK even for parsing the MBR.
		       Chained EBR addresses are relative to the start of the extended partiton. */
		    blk_op.lba = ep_offset + le32_to_cpu(br->partition[i].lba_first);
		    if(next >= 4)
			break;
		    /* we include all primary partitions but we deliberately knobble the size in
		       order to prevent catastrophic accidents */
		    br->partition[i].lba_count = cpu_to_le32(2L);
		    /* fall through */
		default:
		    /* Regular partition: In EBRs these are relative to the EBR (not the disk, nor
		       the extended partition) */
		    blk_op.blkdev->lba_first[next] = br_offset + le32_to_cpu(br->partition[i].lba_first);
		    blk_op.blkdev->lba_count[next] = le32_to_cpu(br->partition[i].lba_count);
		    next++;
		    kprintf("hd%c%d ", letter, next);
	    }
	}
	seen++;
    }while(blk_op.lba);

    if(ep_offset && next >= 4)
	kputs("> ");

out:
    /* release temporary memory */
    tmpfree(br);
}
Esempio n. 4
0
void glueMpeg2_get(Mpeg2 *mpg, Texture *dst, int sync_channel, float fps, int border, int skip_frames, int reset_on_error) {
  unsigned char *tmpbuf;
  int framecnt=0;
	float curtime;
	
#ifdef USE_FMODEX
	if(sync_channel==-1) // no audio sync
		curtime = timeGetTime();
	else // get time from audio channel
		curtime = fmod_gettick_channel(sync_channel)+(1000.0/fps);
#else
  curtime = timeGetTime();
#endif

  if (mpg->end==1) {
    glueMpeg2_reset(mpg);
  }
  
  if (mpg->prevtime==0) { 
    getframe(mpg, dst); 
    if (mpg->end==2) { glueMpeg2_reset(mpg); return; }
    if (mpg->end==3) { if (reset_on_error) glueMpeg2_reset(mpg); return; }    
  } 
  else if (curtime-mpg->prevtime < 1000.0/fps) return;
  else {
    int x;
    
    framecnt=(curtime-mpg->prevtime)/(1000.0/fps);
    if (skip_frames==0 && framecnt>1) framecnt=1;
    for (x=0; x<framecnt; x++) {
      getframe(mpg, dst);
      if (mpg->end==2) { glueMpeg2_reset(mpg); return; }
      if (mpg->end==3) { if (reset_on_error) glueMpeg2_reset(mpg); return; }
    }
  }
  
  if (mpg->prevtime==0) mpg->prevtime=curtime;
  else mpg->prevtime+=1000.0/fps*framecnt;
  //mpg->prevtime=timeGetTime();
  tmpbuf=tmpmalloc(dst->xres*dst->yres*4);
  
  if (mpg->info->display_fbuf) {
    int w, h;
      
    w=mpg->info->sequence->width;
    h=mpg->info->sequence->height;  
  
    if (dst->xres==w && dst->yres==h && (!border)) {
      glueReloadtexture(dst, mpg->info->display_fbuf->buf[0]);
    } else {
      int x;
      
      memset(tmpbuf, 0, dst->xres*dst->yres*4);
     
      if (dst->xres < w || dst->yres < h) 
        glueErrorf("erreur: ur texture too small for ur videoz (%ix%i vs %ix%i)", w, h, dst->xres, dst->yres);    

      for (x=0; x<h; x++) 
        memcpy(tmpbuf+x*dst->xres*4, mpg->info->display_fbuf->buf[0]+x*w*4, dst->xres*4);

      if (border) {
        for (x=0; x<w; x++) { blask(tmpbuf, x); blask(tmpbuf, x+(h-1)*dst->xres); }
        for (x=0; x<h; x++) { blask(tmpbuf, x*dst->xres); blask(tmpbuf, x*dst->xres+w-1); }
      }
 
      dst->scale.x=(float)w/dst->xres;
      dst->scale.y=(float)h/dst->yres;

      glueReloadtexture(dst, tmpbuf);
    }
  }
  
  tmpfree(tmpbuf);

}
Esempio n. 5
0
arg_t _execve(void)
{
	/* Not ideal on stack */
	struct binfmt_flat binflat;
	inoptr ino;
	char **nargv;		/* In user space */
	char **nenvp;		/* In user space */
	struct s_argblk *abuf, *ebuf;
	int argc;
	uint32_t bin_size;	/* Will need to be bigger on some cpus */
	uaddr_t progbase, top;
	uaddr_t go;
	uint32_t true_brk;

	if (!(ino = n_open_lock(name, NULLINOPTR)))
		return (-1);

	if (!((getperm(ino) & OTH_EX) &&
	      (ino->c_node.i_mode & F_REG) &&
	      (ino->c_node.i_mode & (OWN_EX | OTH_EX | GRP_EX)))) {
		udata.u_error = EACCES;
		goto nogood;
	}

	setftime(ino, A_TIME);

	udata.u_offset = 0;
	udata.u_count = sizeof(struct binfmt_flat);
	udata.u_base = (void *)&binflat;
	udata.u_sysio = true;

	readi(ino, 0);
	if (udata.u_done != sizeof(struct binfmt_flat)) {
		udata.u_error = ENOEXEC;
		goto nogood;
	}

	/* FIXME: ugly - save this as valid_hdr modifies it */
	true_brk = binflat.bss_end;

	/* Hard coded for our 68K format. We don't quite use the ucLinux
	   names, we don't want to load a ucLinux binary in error! */
	if (memcmp(binflat.magic, "bFLT", 4) || !valid_hdr(ino, &binflat)) {
		udata.u_error = ENOEXEC;
		goto nogood2;
	}

	/* Memory needed */
	bin_size = binflat.bss_end + binflat.stack_size;

	/* Overflow ? */
	if (bin_size < binflat.bss_end) {
		udata.u_error = ENOEXEC;
		goto nogood2;
	}
	
	/* Gather the arguments, and put them in temporary buffers. */
	abuf = (struct s_argblk *) tmpbuf();
	/* Put environment in another buffer. */
	ebuf = (struct s_argblk *) tmpbuf();

	/* Read args and environment from process memory */
	if (rargs(argv, abuf) || rargs(envp, ebuf))
		goto nogood3;

	/* This must be the last test as it makes changes if it works */
	/* FIXME: need to update this to support split code/data and to fix
	   stack handling nicely */
	/* FIXME: ENOMEM fix needs to go to 16bit ? */
	if ((udata.u_error = pagemap_realloc(0, bin_size, 0)) != 0)
		goto nogood3;

	/* Core dump and ptrace permission logic */
#ifdef CONFIG_LEVEL_2
	/* Q: should uid == 0 mean we always allow core */
	if ((!(getperm(ino) & OTH_RD)) ||
		(ino->c_node.i_mode & (SET_UID | SET_GID)))
		udata.u_flags |= U_FLAG_NOCORE;
	else
		udata.u_flags &= ~U_FLAG_NOCORE;
#endif

	udata.u_codebase = progbase = pagemap_base();
	/* From this point on we are commmited to the exec() completing
	   so we can start writing over the old program */
	uput(&binflat, (uint8_t *)progbase, sizeof(struct binfmt_flat));

	/* setuid, setgid if executable requires it */
	if (ino->c_node.i_mode & SET_UID)
		udata.u_euid = ino->c_node.i_uid;

	if (ino->c_node.i_mode & SET_GID)
		udata.u_egid = ino->c_node.i_gid;

	top = progbase + bin_size;

	udata.u_top = top;
	udata.u_ptab->p_top = top;

//	kprintf("user space at %p\n", progbase);
//	kprintf("top at %p\n", progbase + bin_size);

	bin_size = binflat.reloc_start + 4 * binflat.reloc_count;
	go = (uint32_t)progbase + binflat.entry;

	close_on_exec();

	/*
	 *  Read in the rest of the program, block by block. We rely upon
	 *  the optimization path in readi to spot this is a big move to user
	 *  space and move it directly.
	 */

	 if (bin_size > sizeof(struct binfmt_flat)) {
		/* We copied the header already */
		bin_size -= sizeof(struct binfmt_flat);
		udata.u_base = (uint8_t *)progbase +
					sizeof(struct binfmt_flat);
		udata.u_count = bin_size;
		udata.u_sysio = false;
		readi(ino, 0);
		if (udata.u_done != bin_size)
			goto nogood4;
	}

	/* Header isn't counted in relocations */
	relocate(&binflat, progbase, bin_size);
	/* This may wipe the relocations */	
	uzero((uint8_t *)progbase + binflat.data_end,
		binflat.bss_end - binflat.data_end + binflat.stack_size);

	/* Use of brk eats into the stack allocation */

	/* Use the temporary we saved (hack) as we mangled bss_end */
	udata.u_break = udata.u_codebase + true_brk;

	/* Turn off caught signals */
	memset(udata.u_sigvec, 0, sizeof(udata.u_sigvec));

	/* place the arguments, environment and stack at the top of userspace memory. */

	/* Write back the arguments and the environment */
	nargv = wargs(((char *) top - 4), abuf, &argc);
	nenvp = wargs((char *) (nargv), ebuf, NULL);

	/* Fill in udata.u_name with Program invocation name */
	uget((void *) ugetl(nargv, NULL), udata.u_name, 8);
	memcpy(udata.u_ptab->p_name, udata.u_name, 8);

	tmpfree(abuf);
	tmpfree(ebuf);
	i_unlock_deref(ino);

	/* Shove argc and the address of argv just below envp */
	uputl((uint32_t) nargv, nenvp - 1);
	uputl((uint32_t) argc, nenvp - 2);

	// Set stack pointer for the program
	udata.u_isp = nenvp - 2;

	/*
	 * Sort of - it's a good way to deal with all the stupidity of
	 * random 68K platforms we will have to handle, and a nice place
	 * to stuff the signal trampoline 8)
	 */
	install_vdso();

//	kprintf("Go = %p ISP = %p\n", go, udata.u_isp);

	doexec(go);

nogood4:
	/* Must not run userspace */
	ssig(udata.u_ptab, SIGKILL);
nogood3:
	tmpfree(abuf);
	tmpfree(ebuf);
nogood2:
nogood:
	i_unlock_deref(ino);
	return (-1);
}
Esempio n. 6
0
void devide_init_drive(uint_fast8_t drive)
{
    blkdev_t *blk;
    uint8_t *buffer;
    uint_fast8_t select;

    select = (drive & 1) ? 0xF0 : 0xE0;

    ide_select(drive);

    devide_writeb(ide_reg_devhead, select);
    kprintf("IDE drive %d: ", drive);

#ifdef IDE_8BIT_ONLY
    if (IDE_IS_8BIT(drive)) {
    /* set 8-bit mode -- mostly only supported by CF cards */
        if (!devide_wait(IDE_STATUS_READY))
            goto out;

        devide_writeb(ide_reg_devhead, select);
        if (!devide_wait(IDE_STATUS_READY))
            goto out;

        devide_writeb(ide_reg_features, 0x01); /* Enable 8-bit PIO transfer mode (CFA feature set only) */
        devide_writeb(ide_reg_command, IDE_CMD_SET_FEATURES);
    }
#endif

    /* confirm drive has LBA support */
    if (!devide_wait(IDE_STATUS_READY))
        goto out;

    /* send identify command */
    devide_writeb(ide_reg_devhead, select);
    devide_writeb(ide_reg_command, IDE_CMD_IDENTIFY);

    /* allocate temporary sector buffer memory */
    buffer = (uint8_t *)tmpbuf();

    if (!devide_wait(IDE_STATUS_DATAREQUEST))
	goto failout;

    blk_op.is_user = false;
    blk_op.addr = buffer;
    blk_op.nblock = 1;
    devide_read_data();

#ifdef CONFIG_IDE_BSWAP
    if(!(buffer[98] & 0x02)) {
#else
    if(!(buffer[99] & 0x02)) {
#endif    
        kputs("LBA unsupported.\n");
        goto failout;
    }

    blk = blkdev_alloc();
    if(!blk)
	goto failout;

    blk->transfer = devide_transfer_sector;
    blk->flush = devide_flush_cache;
    blk->driver_data = drive & IDE_DRIVE_NR_MASK;

    if( !(((uint16_t*)buffer)[82] == 0x0000 && ((uint16_t*)buffer)[83] == 0x0000) ||
         (((uint16_t*)buffer)[82] == 0xFFFF && ((uint16_t*)buffer)[83] == 0xFFFF) ){
	/* command set notification is supported */
	if(buffer[164] & 0x20){
	    /* write cache is supported */
            blk->driver_data |= FLAG_WRITE_CACHE;
	}
    }

    /* read out the drive's sector count */
    blk->drive_lba_count = le32_to_cpu(*((uint32_t*)&buffer[120]));

    /* done with our temporary memory */
    tmpfree(buffer);

    /* Deselect the IDE, as we will re-select it in the partition scan and
       it may not recursively stack de-selections */
    ide_deselect();

    /* scan partitions */
    blkdev_scan(blk, SWAPSCAN);

    return;
failout:
    tmpfree(buffer);
out:
    ide_deselect();
    return;
}

void devide_init(void)
{
    uint_fast8_t d;

#ifdef IDE_HAS_RESET
    devide_reset();
#endif

    for(d=0; d < IDE_DRIVE_COUNT; d++)
        devide_init_drive(d);
}
Esempio n. 7
0
void pathfree(char *tb)
{
	tmpfree(tb);
}