コード例 #1
0
ファイル: serial.c プロジェクト: rohsaini/mkunity
static int
get_modem_info(struct async_struct *info, unsigned int *result)
{
	mach_msg_type_number_t	count;
	kern_return_t		kr;
	unsigned long		value, status = 0;
	
	count = TTY_MODEM_COUNT;
	kr = device_get_status(info->device_port,
			       TTY_MODEM,
			       (dev_status_t)&status,
			       &count);
	if (kr != D_SUCCESS)
		return -EIO;

	value = 0;
	if (status & TM_RTS)
		value |= TIOCM_RTS;

	if (status & TM_DTR)
		value |= TIOCM_DTR;

	if (status & TM_CAR)
		value |= TIOCM_CAR;

	put_user(value, result);
	return 0;
}
コード例 #2
0
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;  
} 
コード例 #3
0
ファイル: serial.c プロジェクト: rohsaini/mkunity
static void
serial_handle_oob_event(struct async_struct *info,
			mach_port_t	device_port)
{
	kern_return_t			kr;
	mach_msg_type_number_t	count;
	struct tty_out_of_band	toob;

	count = TTY_OUT_OF_BAND_COUNT;
	kr = device_get_status(device_port, TTY_OUT_OF_BAND,
				(dev_status_t) &toob, &count);

	if (kr != D_SUCCESS) {
		MACH3_DEBUG(1, kr,
			    ("serial_handle_oob_event(%d):device_get_status",kr ));
		return;
	}

	switch (toob.toob_event) {
	case TOOB_NO_EVENT:
		break;

	case TOOB_BREAK:
		serial_put_status_byte(info, TTY_BREAK);
		break;

	case TOOB_BAD_PARITY:
		serial_put_status_byte(info, TTY_PARITY);
		break;

	case TOOB_FLUSHED:
		break;

	case TOOB_CARRIER:
		if (toob.toob_arg) {
			info->flags |= ASYNC_DCD_PRESENT;
			wake_up_interruptible(&info->open_wait);
		} else {
			info->flags &= ~ASYNC_DCD_PRESENT;

			if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
			(info->flags & ASYNC_CALLOUT_NOHUP))) {
#ifdef SERIAL_DEBUG_OPEN
				printk("scheduling hangup...");
#endif
                        	queue_task_irq_off(&info->tqueue_hangup, &tq_scheduler);
			}
		}
		break;

	default:
		printk("serial_handle_oob_event: unknown event 0x%x\n",
		       toob.toob_event);
		break;
	}

	return;
}
コード例 #4
0
ファイル: serial.c プロジェクト: rohsaini/mkunity
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;
}
コード例 #5
0
ファイル: flipc_epgroup.c プロジェクト: rohsaini/mkunity
/*
 * Retrieve the semaphore associated with an endpoint group.
 */
FLIPC_return_t FLIPC_epgroup_semaphore(FLIPC_epgroup_t epgroup_arg,
				       semaphore_port_t *semaphore)
{
    flipc_epgroup_t epgroup = epgroup_arg;
    kern_return_t kr;
    domain_lookup_t dl = domain_pointer_lookup(epgroup);
    flipc_comm_buffer_ctl_t cb_ctl;
    int dev_status[1];
    unsigned int dev_status_count;
    
    if (!dl)
	/* No domain pointer means that we were passed a bad
	   epgroup_arg.  */
	return FLIPC_INVALID_ARGUMENTS;

    cb_ctl = (flipc_comm_buffer_ctl_t) dl->comm_buffer_base;

    /* No point in checking if structure's enabled, as it might be
       disabled before we get out of the kernel.  */

    /* Get the semaphore.  */
    dev_status_count = 1;
    kr = device_get_status(dl->device_port,
			   FLIPC_DEVICE_FLAVOR(usermsg_Get_Epgroup_Semaphore,
					       (epgroup - FLIPC_EPGROUP_PTR(cb_ctl->epgroup.start))),
			   dev_status,
			   &dev_status_count);
    if (kr != KERN_SUCCESS) {
	switch (kr) {
	  case D_INVALID_OPERATION:
	    return FLIPC_INVALID_ARGUMENTS;
	  case D_DEVICE_DOWN:
	    return FLIPC_DOMAIN_NOT_INITIALIZED;
	  default:
	    return FLIPC_KERNEL_TRANSLATION_ERR;
	}
    }

    *semaphore = (semaphore_port_t) dev_status[0];

    return FLIPC_SUCCESS;
}
コード例 #6
0
ファイル: ethernet.c プロジェクト: GNUHurdTR/hurd
void
setup_ethernet_device (char *name, struct device **device)
{
  struct net_status netstat;
  size_t count;
  int net_address[2];
  error_t err;
  struct ether_device *edev;
  struct device *dev;

  edev = calloc (1, sizeof (struct ether_device));
  if (!edev)
    error (2, ENOMEM, "%s", name);
  edev->next = ether_dev;
  ether_dev = edev;

  *device = dev = &edev->dev;

  dev->name = strdup (name);
  /* Functions.  These ones are the true "hardware layer" in Linux.  */
  dev->open = 0;		/* We set up before calling dev_open.  */
  dev->stop = ethernet_stop;
  dev->hard_start_xmit = ethernet_xmit;
  dev->get_stats = ethernet_get_stats;
  dev->set_multicast_list = ethernet_set_multi;

  /* These are the ones set by drivers/net/net_init.c::ether_setup.  */
  dev->hard_header = eth_header;
  dev->rebuild_header = eth_rebuild_header;
  dev->hard_header_cache = eth_header_cache;
  dev->header_cache_update = eth_header_cache_update;
  dev->hard_header_parse = eth_header_parse;
  /* We can't do these two (and we never try anyway).  */
  /* dev->change_mtu = eth_change_mtu; */
  /* dev->set_mac_address = eth_mac_addr; */

  /* Some more fields */
  dev->priv = edev;         /* For reverse lookup.  */
  dev->type = ARPHRD_ETHER;
  dev->hard_header_len = ETH_HLEN;
  dev->addr_len = ETH_ALEN;
  memset (dev->broadcast, 0xff, ETH_ALEN);
  dev->flags = IFF_BROADCAST | IFF_MULTICAST;

  /* FIXME: Receive all multicast to fix IPv6, until we implement
     ethernet_set_multi.  */
  dev->flags |= IFF_ALLMULTI;

  dev->change_flags = ethernet_change_flags;

  dev_init_buffers (dev);

  ethernet_open (dev);

  /* Fetch hardware information */
  count = NET_STATUS_COUNT;
  err = device_get_status (edev->ether_port, NET_STATUS,
			   (dev_status_t) &netstat, &count);
  if (err)
    error (2, err, "%s: Cannot get device status", name);
  dev->mtu = netstat.max_packet_size - dev->hard_header_len;
  assert (netstat.header_format == HDR_ETHERNET);
  assert (netstat.header_size == ETH_HLEN);
  assert (netstat.address_size == ETH_ALEN);

  count = 2;
  assert (count * sizeof (int) >= ETH_ALEN);
  err = device_get_status (edev->ether_port, NET_ADDRESS, net_address, &count);
  if (err)
    error (2, err, "%s: Cannot get hardware Ethernet address", name);
  net_address[0] = ntohl (net_address[0]);
  net_address[1] = ntohl (net_address[1]);
  memcpy (dev->dev_addr, net_address, ETH_ALEN);

  /* That should be enough.  */

  /* This call adds the device to the `dev_base' chain,
     initializes its `ifindex' member (which matters!),
     and tells the protocol stacks about the device.  */
  err = - register_netdevice (dev);
  assert_perror (err);
}
コード例 #7
0
ファイル: gen_disk.c プロジェクト: andreiw/mkunity
int
machine_disk_get_params(
	kdev_t			dev,
	mach_port_t		device_port,
	struct hd_geometry	*loc,
	boolean_t		partition_only)
{
	kern_return_t		kr;
	struct disk_parms	dp;
#if 0
	struct disklabel	dl;
#endif
	unsigned int		count;
	unsigned char		heads;
	unsigned char		sectors;
	unsigned short		cylinders;
	long			start;

	switch ((int) MAJOR(dev)) {

	    case SCSI_DISK_MAJOR:
#if 0
		count = sizeof (struct disklabel) / sizeof (int);
		kr = device_get_status(device_port,
				       DIOCGDINFO,
				       (dev_status_t) &dl,
				       &count);
		if (kr != D_SUCCESS) {
			MACH3_DEBUG(2, kr,
				    ("machine_get_disk_params(%s): "
				     "device_get_status(0x%x, DIOCGDINFO)",
				     kdevname(dev), device_port));
			return -EINVAL;
		}
		heads = (unsigned char) dl.d_ntracks;
		sectors = (unsigned char) dl.d_nsectors;	/* XXX */
		cylinders = (unsigned short) dl.d_ncylinders;
		start = 0;	/* XXX */
		break;
#endif

	    case HD_MAJOR:
	    case FLOPPY_MAJOR:
		count = sizeof (struct disk_parms) / sizeof (int);
		kr = device_get_status(device_port,
				       OSFMACH3_V_GETPARMS,
				       (dev_status_t) &dp,
				       &count);
		if (kr != D_SUCCESS) {
			MACH3_DEBUG(2, kr,
				    ("machine_get_disk_params(%s): "
				     "device_get_status(0x%x, V_GETPARMS)",
				     kdevname(dev), device_port));
			return -EINVAL;
		}
		heads = dp.dp_dosheads;
		cylinders = dp.dp_doscyls;
		sectors = dp.dp_dossectors;
		if (partition_only) {
#if 0
			sectors = (dp.dp_pnumsec * dp.dp_secsiz) / 512;
#endif
			start = (dp.dp_pstartsec * dp.dp_secsiz) / 512;
		} else {
			start = 0;
		}
		break;

	    default:
		return -EINVAL;
	}

#ifdef	GENDISK_DEBUG
	if (gendisk_debug) {
		printk("machine_disk_get_params(dev=%s, part_only=%d): "
		       "%d heads, %d cylinders, %d sectors, start at %ld\n",
		       kdevname(dev), partition_only,
		       heads, cylinders, sectors, start);
	}
#endif	/* GENDISK_DEBUG */

	put_fs_byte(heads, (char *) &loc->heads);
	put_fs_byte(sectors, (char *) &loc->sectors);
	put_fs_word(cylinders, (short *) &loc->cylinders);
	put_fs_long(start, (long *) &loc->start);

	return 0;
}
コード例 #8
0
ファイル: gen_disk.c プロジェクト: andreiw/mkunity
kern_return_t
machine_disk_read_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 read */

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

		/*
		 * Tell the micro-kernel which sector to read.
		 */
		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_read_absolute(%s): "
					    "device_set_status(0x%x, V_ABS, "
					    "0x%x)",
					    kdevname(dev),
					    device_port, abs_sec));
			return kr;
		}

		/*
		 * Read the sector now.
		 */
		count = OSFMACH3_DEV_BSIZE / sizeof (int);
		server_thread_blocking(FALSE);
		kr = device_get_status(device_port,
				       OSFMACH3_V_RDABS,
				       (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_read_absolute(%s): "
					     "device_get_status(0x%x, "
					     "V_RDABS(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;
}
コード例 #9
0
ファイル: serial.c プロジェクト: rohsaini/mkunity
/*
 * 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));
		}
	}
}
コード例 #10
0
ファイル: serial.c プロジェクト: rohsaini/mkunity
/*
 * 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;
}