Example #1
0
/*
 * This routine sends a break character out the serial port.
 */
static void send_break(	struct async_struct * info, int duration)
{
	mach_port_t	device_port = info->device_port;

	current->state = TASK_INTERRUPTIBLE;
	current->timeout = jiffies + duration;
	cli();
	device_set_status(device_port, TTY_SET_BREAK, 0, 0);
	schedule();
	device_set_status(device_port, TTY_CLEAR_BREAK, 0, 0);
	sti();
}
int set_promisc (char *dev_name, mach_port_t ether_port, int is_promisc)
{
#ifndef NET_FLAGS
#define NET_FLAGS (('n'<<16) + 4)
#endif
  int flags;
  int ret;
  size_t count;

  debug ("set_promisc is called, is_promisc: %d\n", is_promisc);
  count = 1;
  ret = device_get_status (ether_port, NET_FLAGS, (dev_status_t) &flags, 
                           &count);
  if (ret) 
    {
      error (0, ret, "device_get_status");  
      return -1;
    }  
  if (is_promisc)
    flags |= IFF_PROMISC;
  else
    flags &= ~IFF_PROMISC;
  ret = device_set_status(ether_port, NET_FLAGS, (dev_status_t) &flags, 1);
  if (ret) 
    {
      error (0, ret, "device_set_status");
      return -1;
    }  
  return 0;  
} 
Example #3
0
static void
flush(struct printf_state *state)
{
	int amt;
	int done = 0;

	if(!standalone)
		return ;
	while (done != state->index) {
		if (device_write_inband(console_port,
					   0,
					   0,
					   state->buf+done,
					   state->index-done,
					   &amt) != KERN_SUCCESS)
			done += state->index-done;
		else
			done += amt;
	}
#ifdef	TTY_DRAIN
	{
		int word;
		/* flush console output */
		(void) device_set_status(console_port, TTY_DRAIN, &word, 0);
	}
#endif	/* TTY_DRAIN */
	state->index = 0;
}
Example #4
0
int
machine_disk_revalidate(
	kdev_t			dev,
	mach_port_t		device_port)
{
	kern_return_t		kr;
	int			count;

	switch ((int) MAJOR(dev)) {

	    case SCSI_DISK_MAJOR:
	    case HD_MAJOR:
	    case FLOPPY_MAJOR:
		count = 0;
		kr = device_set_status(device_port,
				       OSFMACH3_V_REMOUNT,
				       &count,
				       count);
		if (kr != D_SUCCESS) {
			MACH3_DEBUG(2, kr,
				    ("machine_disk_revalidate(%s): "
				     "device_get_status(0x%x, V_REMOUNT)",
				     kdevname(dev), device_port));
			return -EINVAL;
		}
		break;
	    default:
		return -EINVAL;
	}
	return 0;
}
Example #5
0
static int set_modem_info(struct async_struct * info, unsigned int cmd,
			  unsigned int *value)
{
	int error;
	unsigned int arg;
	long	result = 0, cur;
	mach_msg_type_number_t	count;
	kern_return_t		kr;

	error = verify_area(VERIFY_READ, value, sizeof(int));
	if (error)
		return error;
	arg = get_user(value);

	if (arg & TIOCM_RTS)
		result |= TM_RTS;

	if (arg & TIOCM_DTR)
		result |= TM_DTR;

	count = TTY_MODEM_COUNT;
	kr = device_get_status(info->device_port,
			       TTY_MODEM,
			       (dev_status_t)&cur,
			       &count);
	if (kr != D_SUCCESS)
		return	-EIO;

	switch (cmd) {
	case TIOCMBIS: 
		cur = cur | result;
		break;

	case TIOCMBIC:
		cur = cur & ~result;
		break;

	case TIOCMSET:
		cur = result;
		break;

	default:
		return -EINVAL;
	}

	kr = device_set_status(info->device_port,
			       TTY_MODEM,
			       (dev_status_t)&cur,
			       TTY_MODEM_COUNT);
	if (kr != D_SUCCESS) 
		return	-EIO;

	return 0;
}
Example #6
0
/* Set device flags (e.g. promiscuous) */
static int
ethernet_change_flags (struct device *dev, short flags)
{
  error_t err = 0;
#ifdef NET_FLAGS
  int status = flags;
  struct ether_device *edev = (struct ether_device *) dev->priv;
  err = device_set_status (edev->ether_port, NET_FLAGS, &status, 1);
  if (err == D_INVALID_OPERATION)
    /* Not supported, ignore.  */
    err = 0;
#endif
  return err;
}
Example #7
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 #8
0
kern_return_t
machine_disk_write_absolute(
	kdev_t		dev,
	mach_port_t	device_port,
	unsigned long	recnum,
	char		*data,
	unsigned long	size)
{
	kern_return_t		kr;
	mach_msg_type_number_t 	count;
	int			abs_sec; /* absolute sector to be written */

	abs_sec = recnum;
	while (size > 0) {
#ifdef	GENDISK_DEBUG
		if (gendisk_debug) {
			printk("machine_disk_write_absolute(dev=%s, "
			       "recnum=0x%lx, size=0x%lx): WRABS(0x%x,0x%x)\n",
			       kdevname(dev),
			       recnum, size, abs_sec, OSFMACH3_DEV_BSIZE);
		}
#endif	/* GENDISK_DEBUG */

		/*
		 * Tell the micro-kernel which sector to write.
		 */
		count = 1;
		kr = device_set_status(device_port,
				       OSFMACH3_V_ABS,
				       (dev_status_t) &abs_sec,
				       count);
		if (kr != KERN_SUCCESS) {
			MACH3_DEBUG(1, kr,
				    ("machine_disk_write_absolute(%s): "
				     "device_set_status(0x%x, V_ABS, 0x%x)",
				     kdevname(dev), device_port, abs_sec));
			return kr;
		}

		/*
		 * Write the sector now.
		 */
		count = OSFMACH3_DEV_BSIZE / sizeof (int);
		server_thread_blocking(FALSE);
		kr = device_set_status(device_port,
				       OSFMACH3_V_WRABS,
				       (dev_status_t) data,
				       count);
		server_thread_unblocking(FALSE);
		if (kr != D_SUCCESS) {
			if (kr != D_INVALID_RECNUM &&
			    kr != D_INVALID_SIZE) {
				MACH3_DEBUG(1, kr,
					    ("machine_disk_write_absolute(%s):"
					     " device_set_status(0x%x, "
					     "V_WRABS(0x%x,%d)",
					     kdevname(dev), device_port,
					     abs_sec, count));
			}
			return kr;
		}
		if ((count * sizeof (int)) > size)
			break;
		size -= count * sizeof (int);
		data += count * sizeof (int);
		abs_sec++;
	}

	return D_SUCCESS;
}
Example #9
0
/*
 * This routine is called to set the UART divisor registers to match
 * the specified baud rate for a serial port.
 */
static void change_speed(struct async_struct *info)
{
	unsigned cflag;
	int			line;
	mach_port_t		device_port;
	kern_return_t		kr;
	struct tty_status	ttstat;
	mach_msg_type_number_t	ttstat_count;

	if (!info->tty || !info->tty->termios)
		return;

	cflag = info->tty->termios->c_cflag;

	line = MINOR(info->tty->device) - info->tty->driver.minor_start;
	device_port = info->device_port;
	ttstat_count = TTY_STATUS_COUNT;
	if (device_port != MACH_PORT_NULL) {
		kr = device_get_status(device_port,
				       TTY_STATUS_NEW,
				       (dev_status_t) &ttstat,
				       &ttstat_count);
		if (kr != D_SUCCESS) {
			MACH3_DEBUG(1, kr,
				    ("change_speed(dev 0x%x): "
				     "device_get_status(TTY_STATUS_NEW)",
				     info->tty->device));
			return;
		}
	}
	/* Mach break handling is obsolete with "new" out-of-band. */
	ttstat.tt_breakc = 0;
	ttstat.tt_flags &= ~(TF_ODDP | TF_EVENP | TF_LITOUT | TF_NOHANG |
			     TF_8BIT | TF_READ | TF_HUPCLS | TF_OUT_OF_BAND | 
			     TF_INPCK | TF_CRTSCTS);
	ttstat.tt_flags |= TF_OUT_OF_BAND;	/* we always want OUT_OF_BAND */

	/* Convert from POSIX to MACH speed */

	if ((cflag & CBAUD) < (sizeof(baud_table)/sizeof(baud_table[0])))
		ttstat.tt_ispeed = ttstat.tt_ospeed = 
			baud_table[cflag & CBAUD];
	else	/* Largest possible baud rate (for the moment) */
		ttstat.tt_ispeed = ttstat.tt_ospeed = 230400;

	if (cflag & CRTSCTS) {
		info->flags |= ASYNC_CTS_FLOW;
	} else
		info->flags &= ~ASYNC_CTS_FLOW;

	if (cflag & CLOCAL)
		info->flags &= ~ASYNC_CHECK_CD;
	else {
		info->flags |= ASYNC_CHECK_CD;
	}

#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))

	if (I_INPCK(info->tty))
		info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;

	if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
		info->read_status_mask |= UART_LSR_BI;
	
	info->ignore_status_mask = 0;
	if (I_IGNPAR(info->tty)) {
		info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
		info->read_status_mask |= UART_LSR_PE | UART_LSR_FE;
	}
	if (I_IGNBRK(info->tty)) {
		info->ignore_status_mask |= UART_LSR_BI;
		info->read_status_mask |= UART_LSR_BI;
		/*
		 * If we're ignore parity and break indicators, ignore 
		 * overruns too.  (For real raw support).
		 */
		if (I_IGNPAR(info->tty)) {
			info->ignore_status_mask |= UART_LSR_OE;
			info->read_status_mask |= UART_LSR_OE;
		}
	}
	
	if (cflag & PARENB) {
		ttstat.tt_flags |= TF_INPCK;
		ttstat.tt_flags |= (cflag & PARODD) ? TF_ODDP : TF_EVENP;
	}

	if ((cflag & CSIZE) != CS7) { 	/* assume CS8 */
		ttstat.tt_flags |= TF_LITOUT | TF_8BIT;
	}

	if (cflag & CLOCAL)
		ttstat.tt_flags |= TF_NOHANG;

	if (cflag & CREAD)
		ttstat.tt_flags |= TF_READ;

	if (cflag & HUPCL)
		ttstat.tt_flags |= TF_HUPCLS;

	if (cflag & CRTSCTS)
		ttstat.tt_flags |= TF_CRTSCTS;

	if (device_port != MACH_PORT_NULL) {
		kr = device_set_status(device_port,
				       TTY_STATUS_NEW,
				       (dev_status_t) &ttstat,
				       ttstat_count);
		if (kr != D_SUCCESS) {
			MACH3_DEBUG(1, kr,
				    ("change_speed(dev 0x%x): "
				     "device_set_status(TTY_STATUS_NEW)",
				     info->tty->device));
		}
	}
}
Example #10
0
/*
 * This routine is called whenever a serial port is opened.  It
 * enables interrupts for a serial port, linking in its async structure into
 * the IRQ chain.   It also performs the serial-specific
 * initialization for the tty structure.
 */
int rs_open(struct tty_struct *tty, struct file * filp)
{
	struct async_struct	*info;
	int 			retval, line;

	line = MINOR(tty->device) - tty->driver.minor_start;
	if ((line < 0) || (line >= NR_PORTS))
		return -ENODEV;
	info = rs_table + line;
	if (serial_paranoia_check(info, tty->device, "rs_open"))
		return -ENODEV;

#ifdef SERIAL_DEBUG_OPEN
	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
	       info->count);
#endif
	if (!(info->flags & ASYNC_INITIALIZED)) {
		char		device_name[25];
		mach_port_t	device_port;
		dev_mode_t	device_mode;
		kern_return_t	kr;
		int		word, count;

		sprintf(device_name, "com%d", line);

		device_mode = D_READ | D_WRITE;

		kr = device_open(device_server_port,
				 MACH_PORT_NULL,
				 device_mode,
				 server_security_token,
				 device_name,
				 &device_port);

		if (kr != D_SUCCESS) {
			if (kr != D_NO_SUCH_DEVICE) {
				MACH3_DEBUG(2, kr,
					    ("rs_open(dev 0x%x): "
					     "device_open(\"%s\")",
					     tty->device,
					     device_name));
			}
			return -ENODEV;
		}

		info->flags &= ~ASYNC_DCD_PRESENT;

		count = TTY_MODEM_COUNT;
		kr = device_get_status(device_port, 
				TTY_MODEM, &word, &count);

		if (kr == D_SUCCESS && (word & TM_CAR) != 0) 
			info->flags |= ASYNC_DCD_PRESENT;
		else
			info->flags &= ~ASYNC_DCD_PRESENT;

		/* Flush any garbage data which might be left over.. */
		count = TTY_FLUSH_COUNT;
		word = D_READ|D_WRITE;
		kr = device_set_status(device_port, TTY_FLUSH, &word, count);

		info->device_port = device_port;
		tty->flip.char_buf_ptr = tty->flip.char_buf;
		tty->flip.flag_buf_ptr = tty->flip.flag_buf;
		tty->flip.count = 0;

		/* Now register a few asynchronous routines.. */
		device_reply_register(&info->reply_port,
               			(char *) info, serial_read_reply,
				serial_write_reply);

	}
	ASSERT(MACH_PORT_VALID(info->device_port));

	info->count++;
	tty->driver_data = info;
	info->tty = tty;

	/*
	 * Start up serial port
	 */
	retval = startup(info);
	if (retval)
		return retval;

	if (info->count == 1)
		server_thread_start(serial_read_thread, (void *) line);

	retval = block_til_ready(tty, filp, info);
	if (retval) {
#ifdef SERIAL_DEBUG_OPEN
		printk("rs_open returning after block_til_ready with %d\n",
		       retval);
#endif
		return retval;
	}

	if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
			*tty->termios = info->normal_termios;
		else 
			*tty->termios = info->callout_termios;
		change_speed(info);

	}

	info->session = current->session;
	info->pgrp = current->pgrp;


#ifdef SERIAL_DEBUG_OPEN
	printk("rs_open ttys%d successful...", info->line);
#endif
	return 0;
}