Example #1
0
static void
cmd_shutdown(int argc, char **argv)
{
	device_t pm_dev;
	int error, state = PWR_OFF;

	if ((error = device_open("pm", 0, &pm_dev)) == 0) {
		error = device_ioctl(pm_dev, PMIOC_SET_POWER, &state);
		device_close(pm_dev);
	}
	if (error)
		printf("Error %d\n", error);
}
Example #2
0
static void
printf_init (device_t master)
{
  mach_port_t cons;
  kern_return_t rc;
  rc = device_open (master, D_READ|D_WRITE, "console", &cons);
  if (rc)
    error (2, rc, "cannot open kernel console device");
  stdin = mach_open_devstream (cons, "r");
  stdout = stderr = mach_open_devstream (cons, "w");
  mach_port_deallocate (mach_task_self (), cons);
  setbuf (stdout, 0);
}
Example #3
0
static bool fb3110_serial_open(struct gn_statemachine *state)
{
	if (!state)
		return false;

	/* Open device. */
	if (!device_open(state->config.port_device, false, false, false, GN_CT_Serial, state)) {
		perror(_("Couldn't open FBUS device"));
		return false;
	}
	device_changespeed(115200, state);

	return true;
}
// See of the device is ok and connected, if not, try reconnecting
static bool checkDevice(bool usbOk)
{
	if(!usbOk || !device_valid())
	{
		device_close();
		device_open();
		actions_showConnectionStatus();
		if(!device_valid())
			return false;
		actions_showCurrentSettings();
		actions_setTransitionTime();
	}
	return true;
}
Example #5
0
int
main(int argc , char *argv[])
{
  mach_port_t device;
  mach_port_t master_device;
  error_t err;

  err = get_privileged_ports (0, &master_device);
  if (err)
    error (2, err, "cannot get device master port");

  err = device_open (master_device, D_READ | D_WRITE, "eth0", &device);
  if (err)
    error (1, err, "device_open");
  printf ("the device port is %d\n", device);

  err = device_open (master_device, D_READ | D_WRITE, "eth0", &device);
  if (err)
    error (1, err, "device_open");
  printf ("the device port is %d\n", device);

  return 0;
}
Example #6
0
int
reboot(int howto)
{
    device_t pm_dev;
    int err, mode;

    mode = (howto & RB_POWERDOWN) ? POWER_OFF : POWER_REBOOT;

    if ((err = device_open("pm", 0, &pm_dev)) == 0) {
        err = device_ioctl(pm_dev, PMIOC_SET_POWER, &mode);
        device_close(pm_dev);
    }
    return err;
}
Example #7
0
int LUKS_read_phdr(struct luks_phdr *hdr,
		   int require_luks_device,
		   int repair,
		   struct crypt_device *ctx)
{
	struct device *device = crypt_metadata_device(ctx);
	ssize_t hdr_size = sizeof(struct luks_phdr);
	int devfd = 0, r = 0;

	/* LUKS header starts at offset 0, first keyslot on LUKS_ALIGN_KEYSLOTS */
	assert(sizeof(struct luks_phdr) <= LUKS_ALIGN_KEYSLOTS);

	/* Stripes count cannot be changed without additional code fixes yet */
	assert(LUKS_STRIPES == 4000);

	if (repair && !require_luks_device)
		return -EINVAL;

	log_dbg("Reading LUKS header of size %zu from device %s",
		hdr_size, device_path(device));

	devfd = device_open(device, O_RDONLY);
	if (devfd < 0) {
		log_err(ctx, _("Cannot open device %s."), device_path(device));
		return -EINVAL;
	}

	if (read_blockwise(devfd, device_block_size(device), device_alignment(device),
			   hdr, hdr_size) < hdr_size)
		r = -EIO;
	else
		r = _check_and_convert_hdr(device_path(device), hdr, require_luks_device,
					   repair, ctx);

	if (!r)
		r = LUKS_check_device_size(ctx, hdr, 0);

	/*
	 * Cryptsetup 1.0.0 did not align keyslots to 4k (very rare version).
	 * Disable direct-io to avoid possible IO errors if underlying device
	 * has bigger sector size.
	 */
	if (!r && hdr->keyblock[0].keyMaterialOffset * SECTOR_SIZE < LUKS_ALIGN_KEYSLOTS) {
		log_dbg("Old unaligned LUKS keyslot detected, disabling direct-io.");
		device_disable_direct_io(device);
	}

	close(devfd);
	return r;
}
Example #8
0
static int __init touch_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	struct lge_touch_driver *touch = NULL;

	DO_F(create_touch_object(&touch), err_kzalloc_probe);
	
	DO_F(device_open(&touch->h_touch, client, (u32)touch), err_Device_Open_probe);
	
	init_touch_inputdev(touch->h_touch, touch->h_inputDev);
	init_touch_task(touch->h_touch, touch->h_task);
	init_touch_power(touch->h_touch, touch->h_powerCtrl);
	init_touch_interrupt(touch->h_touch, touch->h_interrupt);
	init_touch_finger_data(touch->h_touch, touch->h_fingerData);
	init_touch_device_caps(touch->h_touch, touch->h_caps);
	
	DO_F(touch->h_powerCtrl->on(touch->h_touch), err_powerCtrl_probe);
	DO_F(touch->h_inputDev->open(touch->h_touch), err_inputDev_probe);
	DO_F(touch->h_interrupt->open(touch->h_touch), err_interrupt_probe);	
	DO_F(init_touch_device_setting(touch->h_touch, true), err_Device_Open_probe);
	DO_F(touch->h_task->open(touch->h_touch), err_task_probe);
	DO_F(touch->h_task->start(touch->h_touch), err_inputDev_probe);

	i2c_set_clientdata(client, touch);

#ifdef CONFIG_HAS_EARLYSUSPEND
	touch->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 1;
	touch->early_suspend.suspend = touch_early_suspend;
	touch->early_suspend.resume = touch_late_resume;
	register_early_suspend(&touch->early_suspend);
#endif

	DEBUG_MSG(M, "[TOUCH] touch_driver is initialized.\n");

	return 0;

err_inputDev_probe:
	touch->h_inputDev->close(touch->h_touch);
err_task_probe:
	touch->h_task->close(touch->h_touch);
err_interrupt_probe:
	touch->h_interrupt->close(touch->h_touch);
err_powerCtrl_probe:
	touch->h_powerCtrl->off(touch->h_touch);
err_Device_Open_probe:
	device_close(touch->h_touch);
err_kzalloc_probe:
	remove_touch_object(touch);
	return -1;
}
Example #9
0
/**************************************************************************
 * Video Memory Mapping section                                            
 ***************************************************************************/
static void *
mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int Flags)
{
    mach_port_t device, mem_dev;
    memory_object_t mem_obj;
    kern_return_t err;
    vm_address_t addr = (vm_address_t) 0;

    err = get_privileged_ports(NULL, &device);
    if (err) {
        errno = err;
        FatalError("xf86MapVidMem() can't get_privileged_ports. (%s)\n",
                   strerror(errno));
    }
    err = device_open(device, D_READ | D_WRITE, "mem", &mem_dev);
    mach_port_deallocate(mach_task_self(), device);
    if (err) {
        errno = err;
        FatalError("xf86MapVidMem() can't device_open. (%s)\n",
                   strerror(errno));
    }

    err =
        device_map(mem_dev, VM_PROT_READ | VM_PROT_WRITE, Base, Size, &mem_obj,
                   0);
    if (err) {
        errno = err;
        FatalError("xf86MapVidMem() can't device_map. (%s)\n", strerror(errno));
    }
    err = vm_map(mach_task_self(), &addr, Size, 0,      /* mask */
                 TRUE,          /* anywhere */
                 mem_obj, (vm_offset_t) Base, FALSE,    /* copy on write */
                 VM_PROT_READ | VM_PROT_WRITE,
                 VM_PROT_READ | VM_PROT_WRITE, VM_INHERIT_SHARE);
    mach_port_deallocate(mach_task_self(), mem_obj);
    if (err) {
        errno = err;
        FatalError("xf86MapVidMem() can't vm_map.(mem_obj) (%s)\n",
                   strerror(errno));
    }
    mach_port_deallocate(mach_task_self(), mem_dev);
    if (err) {
        errno = err;
        FatalError
            ("xf86MapVidMem() can't mach_port_deallocate.(mem_dev) (%s)\n",
             strerror(errno));
    }
    return (void *) addr;
}
Example #10
0
static Device *
setup_device(void)
{
    Device *device;
    char *device_name = NULL;

    device_name = vstralloc("file:", device_path, NULL);
    device = device_open(device_name);
    if (device->status != DEVICE_STATUS_SUCCESS) {
	g_critical("Could not open device %s: %s\n", device_name, device_error(device));
    }

    amfree(device_name);
    return device;
}
Example #11
0
/**
 * This function will set a device as console device.
 * After set a device to console, all output of rt_kprintf will be
 * redirected to this new device.
 *
 * @param name the name of new console device
 *
 * @return the old console device handler
 */
device_t console_init(const char *name)
{
	device_t dev;

	/* find new console device */
	dev = device_find_by_name(name);
	if (dev != WM_NULL) {
		/* set new console device */
		_console_device = dev;
		_console_default = dev;
		device_open(_console_device, DEVICE_OFLAG_RDWR);
	}

	return dev;
}
Example #12
0
File: device.c Project: yndi/keusb
int
keusb_connect(int type, char *path)
{
   char *name;
   device_name = path ? path : airbag;

   if (type == CONNECT_FILE)
      return (device_open(path)
              && keusb_request("$KE"))
         || die("keusb_connect: can't open device");

   while ((name = device_gen_name()))
   {
      if (!device_open(name))
         continue;

      if (!keusb_request("$KE"))
      {
         device_close();
         continue;
      }

      if (type == CONNECT_SIG
          && strcmp(keusb_get_signature(), str_to_lower(path)))
      {
         device_close();
         continue;
      }

      device_name = name;
      atexit(device_close);
      return 1;
   }

   return die("keusb_connect: can't find device");
}
Example #13
0
File: reset.c Project: AndrewD/prex
int
main(int argc, char *argv[])
{
	device_t pm_dev;
	int state;

	timer_sleep(2000, 0);

	if (device_open("pm", 0, &pm_dev) != 0)
		exit(1);
	state = POWER_REBOOT;
	device_ioctl(pm_dev, PMIOC_SET_POWER, &state);
	device_close(pm_dev);
	exit(1);
}
Example #14
0
void 
awacs_mksound(unsigned int hz, unsigned int ticks)
{
	kern_return_t		kr;  
	int			speed;
	int			count;

	if (_awacs_busy)
		return;  /* 'Sound' driver using device */
	if (_awacs_device_port == (mach_port_t)NULL) {
		kr = device_open( device_server_port,
				  MACH_PORT_NULL,
				  D_READ | D_WRITE,
				  server_security_token,
				  awacs_dev_name,
				  &_awacs_device_port );

		if ( kr != KERN_SUCCESS ) {
			/* Ignore errors, just 'bag' ringing the bell */
			return;
		}

		device_reply_register( &_awacs_reply_port,
				       (char *) &_awacs_param, 
				       (dev_reply_t) _awacs_read_reply,
				       (dev_reply_t) _awacs_write_reply );
	}
	/* Set port speed */
	speed = KBEEP_SPEED;
	count = KBEEP_BUFSIZE;
	kr = device_set_status(_awacs_device_port,
			       AWACS_DEVCMD_RATE,
			       &speed,
			       1);

	if (kr != D_SUCCESS) {
		return;
	}
	/* Write the 'bell' data */
	kr = serv_device_write_async((mach_port_t)            _awacs_device_port,
				     (mach_port_t)            _awacs_reply_port,
				     (dev_mode_t)             D_WRITE,
				     (recnum_t)               0,
				     (caddr_t)                kbeep_buf,
				     (mach_msg_type_number_t) count,
				     (boolean_t)              FALSE);
}
Example #15
0
int device_find_byname(char *name) {
	int fd, i, rc;
	char buf[1024];

	for (i = 0; i < 32; i++) {
		fd = device_open(i);
		if (fd > 0) {
		        rc = ioctl(fd,EVIOCGNAME(sizeof(buf)),buf);
			if (rc >= 0 && strcmp(name, buf) == 0) {
				close(fd);
				return i;
			}
		}
		close(fd);
	}
	return -1;
}
Example #16
0
int device_find_byphys(char *phys) {
	int fd, i, rc;
	char buf[1024];

	for (i = 0; i < 32; i++) {
		fd = device_open(i);
		if (fd > 0) {
		        rc = ioctl(fd,EVIOCGPHYS(sizeof(buf)),buf);
			if (rc >= 0 && strcmp(phys, buf) == 0) {
				close(fd);
				return i;
			}
		}
		close(fd);
	}
	return -1;
}
Example #17
0
/*
 * You can use this default handler if you don't want
 * to support your own file types with the fill_wave()
 * extension
 */
int wave_init(int id, const char *name)
{
	void *file;
	if( !name || strlen(name) == 0 )
		return INIT_OK;
	file = osd_fopen(Machine->gamedrv->name, name, OSD_FILETYPE_IMAGE_RW, OSD_FOPEN_READ);
	if( file )
	{
		struct wave_args wa = {0,};
		wa.file = file;
		wa.display = 1;
		if( device_open(IO_CASSETTE,id,0,&wa) )
			return INIT_FAILED;
		return INIT_OK;
    }
	return INIT_FAILED;
}
Example #18
0
static void message(char *fmt, ...)
{
	va_list arguments;
	int fd;
	FILE *fp = stderr;

	if ((fd = device_open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY|O_NDELAY)) >= 0) {
		fp = fdopen(fd, "w");
		if (!fp)
			fp = stderr;
	}
	va_start(arguments, fmt);
	vfprintf(stderr, fmt, arguments);
	va_end(arguments);
	if (fp != stderr)
		fclose(fp);
}
Example #19
0
int
main(int argc, char *argv[])
{
	device_t console_dev;
	char buf[] = "ABCDEFGHIJKLMN";
	int i, error;
	size_t len;

	sys_log("console test program\n");
	error = device_open("console", 0, &console_dev);
	if (error)
		sys_log("device open error!\n");

	/*
	 * Display 'ABCDE'
	 */
	len = 5;
	device_write(console_dev, buf, &len, 0);

	/*
	 * Display 'AAAA...'
	 */
	len = 1;
	for (i = 0; i < 100; i++)
		device_write(console_dev, buf, &len, 0);

	/*
	 * Try to pass invalid pointer.
	 * It will cause a fault, and get EFAULT.
	 */
	sys_log("\ntest an invalid pointer.\n");
	len = 100;
	error = device_write(console_dev, 0, &len, 0);
	if (error)
		sys_log("OK!\n");
	else
		sys_log("Bad!\n");

	error = device_close(console_dev);
	if (error)
		sys_log("device close error!\n");

       	sys_log("Completed\n");
	return 0;
}
Example #20
0
int internal_main( output_callback_func_ptr callback_ptr )
{
  output = OUTPUT_CALLBACK;

  output_callback_ptr = callback_ptr;

  device_open();
  init_device();
  start_capturing();
 
  capture_loop();
 
  stop_capturing();
  uninit_device();
  device_close();

  return 0;
}
Example #21
0
static vbi_bool
open_device			(vbi_capture_dvb *	dvb,
				 const char *		device_name,
				 char **		errstr)
{
	int saved_errno;
	struct stat st;

	if (-1 == stat (device_name, &st))
		goto io_error;

	if (!S_ISCHR (st.st_mode)) {
		asprintf (errstr, _("%s is not a device."),
			  device_name);
		saved_errno = 0;
		goto failed;
	}

	/* XXX Can we check if this is really a DVB demux device? */

	dvb->fd = device_open (dvb->capture.sys_log_fp,
			       device_name,
			       O_RDONLY | O_NONBLOCK,
			       /* mode */ 0);
	if (-1 == dvb->fd)
		goto io_error;

	return TRUE;

 io_error:
	saved_errno = errno;

	asprintf (errstr, _("Cannot open '%s': %s."),
		  device_name, strerror (saved_errno));

	/* fall through */	

 failed:
	dvb->fd = -1;

	errno = saved_errno;

	return FALSE;
}
Example #22
0
/* Get our stderr set up to print on the console, in case we have to
   panic or something.  */
error_t
open_console (mach_port_t device_master)
{
  static int got_console = 0;
  mach_port_t cons;
  error_t err;

  if (got_console)
    return 0;

  err = device_open (device_master, D_READ|D_WRITE, "console", &cons);
  if (err)
    return err;

  stdin = mach_open_devstream (cons, "r");
  stdout = stderr = mach_open_devstream (cons, "w");

  got_console = 1;
  mach_port_deallocate (mach_task_self (), cons);
  return 0;
}
Example #23
0
File: tty.c Project: AndrewD/prex
/*
 * Initialize TTY.
 *
 * Since we manage the process group only in the process
 * server, the TTY driver can not know anything about the
 * process group.  However, POSIX specification requires TTY
 * driver to send a signal to the specific process group.
 * So, we will catch all TTY related signals by this server
 * and forward them to the actual process or process group.
 */
void
tty_init(void)
{
	task_t self;

	/*
	 * Setup exception to receive signals from tty.
	 */
	exception_setup(exception_handler);

	if (device_open("tty", 0, &ttydev) != 0)
		ttydev = DEVICE_NULL;
	else {
		/*
		 * Notify the TTY driver to send all tty related
		 * signals in system to this task.
		 */
		self = task_self();
		device_ioctl(ttydev, TIOCSETSIGT, &self);
	}
}
Example #24
0
error_t module_device (system_state_t _state)
{
    static device_handle_t console_handle;

    if (STATE_INITIALIZING == _state) {
        static device_console_t g_device_console;
        error_t ecode;
        
        device_interrupt_handler_install (device_interrupt_handler);
        
        // make the Console ready and open it as soon as possible
        ecode = console_driver_install ("/dev/uart/");
        if (ecode != 0) {
            return ecode;
        }
        ecode = console_device_register ("/dev/uart/com0", &g_device_console);
        if (ecode != 0) {
            return ecode;
        }
        ecode = device_open (&console_handle, "/dev/uart/com0", 0);
        if (ecode != 0) {
            return ecode;
        }
        console_handle_set (console_handle);
        
        (void) device_registration_main ();
    }
    else if (STATE_DESTROYING == _state) {
        for (int idx = 1; idx <= DRIVER_LAST_INDEX; idx ++) {
            if ((MAGIC_NUMBER_DRIVER != g_driver_pool [idx].magic_number_) ||
                (0 == g_driver_pool [idx].count_opened_)) {
                continue;
            }
            console_print ("Error: device(s) on driver \"%s\" is/are not closed\n", 
                g_driver_pool [idx].name_);
        }
        (void) device_close (console_handle);
    }
    return 0;
}
Example #25
0
struct uio_handle *
uio_init(void)
{
	struct uio_handle *uio_handle;
	int err;

	uio_handle = malloc(sizeof(struct uio_handle));
	if (!uio_handle)
		return NULL;

	err = device_open("uio", 0, &uio_handle->uio_dev);
	if (err)
		goto err_free_uio;

	list_init(&uio_handle->mem);
	list_init(&uio_handle->irqs);
	return uio_handle;

err_free_uio:
	free(uio_handle);
	return NULL;
}
Example #26
0
static int
vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
    uint64_t *ashift)
{
	struct vdev_disk *dvd;
	int error;

	/*
	 * We must have a pathname, and it must be absolute.
	 */
	if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') {
		vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
		return (EINVAL);
	}

	/*
	 * Open the device if it's not currently open, otherwise just update
	 * the physical size of the device.
	 */
	if (vd->vdev_tsd == NULL) {
		dvd = vd->vdev_tsd = kmem_zalloc(sizeof(struct vdev_disk), KM_SLEEP);

		error = device_open(vd->vdev_path + 5, DO_RDWR, &dvd->device);
		if (error) {
			vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED;
			return error;
		}
	} else {
		ASSERT(vd->vdev_reopening);
		dvd = vd->vdev_tsd;
	}

	/*
	 * Determine the actual size of the device.
	 */
	*max_psize = *psize = dvd->device->size;
	*ashift = highbit(MAX(DEV_BSIZE, SPA_MINBLOCKSIZE)) - 1;
	return 0;
}
Example #27
0
static struct inode *open_ext4_db(char *file)
{
	int fd;
	struct ext4_extent_header *ihdr;
	struct inode *inode;
	struct db_handle *db;
	struct block_device *bdev;

	fd = device_open(file);

	bdev = bdev_alloc(fd, 12);
	inode = inode_alloc(bdev->bd_super);

	/* For testing purpose, those data is hard-coded. */
	inode->i_writeback = inode_sb_writeback;
	memset(inode->i_uuid, 0xCC, sizeof(inode->i_uuid));
	inode->i_inum = 45;
	inode->i_csum = ext4_crc32c(~0, inode->i_uuid, sizeof(inode->i_uuid));
	inode->i_csum =
	    ext4_crc32c(inode->i_csum, &inode->i_inum, sizeof(inode->i_inum));
	inode->i_csum = ext4_crc32c(inode->i_csum, &inode->i_generation,
				    sizeof(inode->i_generation));

	if (!device_size(bdev))
		exit(EXIT_FAILURE);

	db = db_open(inode->i_sb);
	ihdr = ext4_ext_inode_hdr(inode);
	memcpy(ihdr, db->db_header->db_tree_base, sizeof(inode->i_data));

	if (ihdr->eh_magic != EXT4_EXT_MAGIC) {
		ext4_ext_init_i_blocks(ihdr);
		inode->i_data_dirty = 1;
	}

	inode->i_db = db;

	return inode;
}
Example #28
0
int LUKS_read_phdr(struct luks_phdr *hdr,
		   int require_luks_device,
		   int repair,
		   struct crypt_device *ctx)
{
	struct device *device = crypt_metadata_device(ctx);
	ssize_t hdr_size = sizeof(struct luks_phdr);
	int devfd = 0, r = 0;

	/* LUKS header starts at offset 0, first keyslot on LUKS_ALIGN_KEYSLOTS */
	assert(sizeof(struct luks_phdr) <= LUKS_ALIGN_KEYSLOTS);

	/* Stripes count cannot be changed without additional code fixes yet */
	assert(LUKS_STRIPES == 4000);

	if (repair && !require_luks_device)
		return -EINVAL;

	log_dbg("Reading LUKS header of size %zu from device %s",
		hdr_size, device_path(device));

	devfd = device_open(device, O_RDONLY);
	if (devfd == -1) {
		log_err(ctx, _("Cannot open device %s.\n"), device_path(device));
		return -EINVAL;
	}

	if (read_blockwise(devfd, device_block_size(device), hdr, hdr_size) < hdr_size)
		r = -EIO;
	else
		r = _check_and_convert_hdr(device_path(device), hdr, require_luks_device,
					   repair, ctx);

	if (!r)
		r = LUKS_check_device_size(ctx, hdr->keyBytes);

	close(devfd);
	return r;
}
Example #29
0
/*
 * Initialize TTY.
 *
 * Since we manage the process group only in the process
 * server, the TTY driver can not know anything about the
 * process group.  However, POSIX specification requires TTY
 * driver to send a signal to the specific process group.
 * So, we will catch all TTY related signals by this server
 * and forward them to the actual process or process group.
 */
void
tty_init(void)
{
	task_t self;

	/*
	 * Setup exception to receive signals from tty.
	 */
	exception_setup(exception_handler);

	if (device_open("tty", 0, &ttydev) != 0) {
		DPRINTF(("proc: no tty found\n"));
		ttydev = NODEV;
	} else {
		/*
		 * Notify the TTY driver to send all tty related
		 * signals in system to this task.
		 */
		self = task_self();
		device_ioctl(ttydev, TIOCSETSIGT, &self);
	}
}
Example #30
0
int
main(int argc, char *argv[])
{
	struct winsize ws;
	int rows, cols, i;
	device_t cons;

	/* Get screen size */
	device_open("tty", 0, &cons);
	if (device_ioctl(cons, TIOCGWINSZ, &ws) == 0) {
		rows = (int)ws.ws_row;
		cols = (int)ws.ws_col;
	} else {
		/* Use default screen setting */
		rows = 25;
		cols = 80;
	}
	device_close(cons);

	max_x = (cols - 1) * 10;
	max_y = (rows - 2) * 10;

	/* Clear screen */
	printf("\33[2J");

	/* Create threads and run them. */
	for (i = 0; i < NBALLS; i++) {
		if (thread_run(move_ball, stack[i]+STACKLEN) == 0)
			panic("failed to create thread");
	}

	/* Don't return */
	for (;;)
		thread_yield();

	/* NOTREACHED */
	return 0;
}