/**
 * gserial_disconnect - notify TTY I/O glue that USB link is inactive
 * @gser: the function, on which gserial_connect() was called
 * Context: any (usually from irq)
 *
 * This is called to deactivate endpoints and let the TTY layer know
 * that the connection went inactive ... not unlike "hangup".
 *
 * On return, the state is as if gserial_connect() had never been called;
 * there is no active USB I/O on these endpoints.
 */
void gserial_disconnect(struct gserial *gser)
{
	struct gs_port	*port = gser->ioport;
	unsigned long	flags;
	pr_vdebug("%s\n", __func__);

	if (!port)
		return;

	/* tell the TTY glue not to do I/O here any more */
	spin_lock_irqsave(&port->port_lock, flags);

	/* REVISIT as above: how best to track this? */
	port->port_line_coding = gser->port_line_coding;

	port->port_usb = NULL;
	gser->ioport = NULL;
#if 0
	if (port->open_count > 0 || port->openclose) {
		wake_up_interruptible(&port->drain_wait);
		if (port->port_tty)
			tty_hangup(port->port_tty);
	}
#endif
	spin_unlock_irqrestore(&port->port_lock, flags);

	/* disable endpoints, aborting down any active I/O */
	usb_ep_fifo_flush(gser->out);
	usb_ep_fifo_flush(gser->in);
	usb_ep_disable(gser->out);
	gser->out->driver_data = NULL;

	usb_ep_disable(gser->in);
	gser->in->driver_data = NULL;

	/* finally, free any unused/unusable I/O buffers */
	spin_lock_irqsave(&port->port_lock, flags);
	if (port->open_count == 0 && !port->openclose)
		gs_buf_free(&port->port_write_buf);
	gs_free_requests(gser->out, &port->read_pool);
	gs_free_requests(gser->out, &port->read_queue);
	gs_free_requests(gser->in, &port->write_pool);
	spin_unlock_irqrestore(&port->port_lock, flags);
}
Beispiel #2
0
static void capincci_free(struct capidev *cdev, __u32 ncci)
{
	struct capincci *np, **pp;
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
	struct capiminor *mp;
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */

	pp=&cdev->nccis;
	while (*pp) {
		np = *pp;
		if (ncci == 0xffffffff || np->ncci == ncci) {
			*pp = (*pp)->next;
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
			if ((mp = np->minorp) != 0) {
#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
				capifs_free_ncci('r', mp->minor);
				capifs_free_ncci(0, mp->minor);
#endif
				if (mp->tty) {
					mp->nccip = 0;
#ifdef _DEBUG_REFCOUNT
					printk(KERN_DEBUG "reset mp->nccip\n");
#endif
					tty_hangup(mp->tty);
				} else if (mp->file) {
					mp->nccip = 0;
#ifdef _DEBUG_REFCOUNT
					printk(KERN_DEBUG "reset mp->nccip\n");
#endif
					wake_up_interruptible(&mp->recvwait);
					wake_up_interruptible(&mp->sendwait);
				} else {
					capiminor_free(mp);
				}
			}
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
			kmem_cache_free(capincci_cachep, np);
			if (*pp == 0) return;
		} else {
			pp = &(*pp)->next;
		}
	}
}
void
ctc_tty_setcarrier(struct net_device *netdev, int on)
{
	int i;

	DBF_TEXT(trace, 4, __FUNCTION__);
	if ((!driver) || ctc_tty_shuttingdown)
		return;
	for (i = 0; i < CTC_TTY_MAX_DEVICES; i++)
		if (driver->info[i].netdev == netdev) {
			ctc_tty_info *info = &driver->info[i];
			if (on)
				info->msr |= UART_MSR_DCD;
			else
				info->msr &= ~UART_MSR_DCD;
			if ((info->flags & CTC_ASYNC_CHECK_CD) && (!on))
				tty_hangup(info->tty);
		}
}
Beispiel #4
0
/**
 * gserial_disconnect - notify TTY I/O glue that USB link is inactive
 * @gser: the function, on which gserial_connect() was called
 * Context: any (usually from irq)
 *
 * This is called to deactivate endpoints and let the TTY layer know
 * that the connection went inactive ... not unlike "hangup".
 *
 * On return, the state is as if gserial_connect() had never been called;
 * there is no active USB I/O on these endpoints.
 */
void gserial_disconnect(struct gserial *gser)
{
	struct gs_port	*port = gser->ioport;
	unsigned long	flags;

	if (!port)
		return;

	/* tell the TTY glue not to do I/O here any more */
	spin_lock_irqsave(&port->port_lock, flags);

	/* REVISIT as above: how best to track this? */
	port->port_line_coding = gser->port_line_coding;

	port->port_usb = NULL;
	gser->ioport = NULL;
	if (atomic_read(&port->port.count) > 0 || port->openclose) {
		wake_up_interruptible(&port->drain_wait);
		if (port->port.tty)
			tty_hangup(port->port.tty);
	}
	spin_unlock_irqrestore(&port->port_lock, flags);

	/* disable endpoints, aborting down any active I/O */
	usb_ep_disable(gser->out);
	gser->out->driver_data = NULL;

	usb_ep_disable(gser->in);
	gser->in->driver_data = NULL;

	/* finally, free any unused/unusable I/O buffers */
	spin_lock_irqsave(&port->port_lock, flags);
	if (atomic_read(&port->port.count) == 0 && !port->openclose)
		gs_buf_free(&port->port_write_buf);
	gs_free_requests(gser->out, &port->read_pool, NULL);
	gs_free_requests(gser->out, &port->read_queue, NULL);
	gs_free_requests(gser->in, &port->write_pool, NULL);

	port->read_allocated = port->read_started =
		port->write_allocated = port->write_started = 0;

	spin_unlock_irqrestore(&port->port_lock, flags);
}
Beispiel #5
0
static void acm_disconnect(struct usb_interface *intf)
{
	struct acm *acm = usb_get_intfdata(intf);
	struct usb_device *usb_dev = interface_to_usbdev(intf);

	mutex_lock(&open_mutex);
	if (!acm || !acm->dev) {
		mutex_unlock(&open_mutex);
		return;
	}
	if (acm->country_codes){
		device_remove_file(&acm->control->dev,
				&dev_attr_wCountryCodes);
		device_remove_file(&acm->control->dev,
				&dev_attr_iCountryCodeRelDate);
	}
	device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities);
	acm->dev = NULL;
	usb_set_intfdata(acm->control, NULL);
	usb_set_intfdata(acm->data, NULL);

	stop_data_traffic(acm);

	acm_write_buffers_free(acm);
	usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
	acm_read_buffers_free(acm);

	usb_driver_release_interface(&acm_driver, intf == acm->control ?
					acm->data : acm->control);

	if (!acm->used) {
		acm_tty_unregister(acm);
		mutex_unlock(&open_mutex);
		return;
	}

	mutex_unlock(&open_mutex);

	if (acm->tty)
		tty_hangup(acm->tty);
}
Beispiel #6
0
int tty_ioctl(uint8_t minor, uint16_t request, char *data)
{				/* Data in User Space */
	if (!minor)
		minor = udata.u_ptab->p_tty;
	if (minor < 1 || minor > NUM_DEV_TTY + 1) {
		udata.u_error = ENODEV;
		return -1;
	}
	if (deadflag[minor]) {
	        udata.u_error = ENXIO;
	        return -1;
        }
	switch (request) {
	case TCGETS:
		uput(&ttydata[minor], data, sizeof(struct termios));
		break;
	case TCSETSW:
		/* We don't have an output queue really so for now drop
		   through */
	case TCSETS:
	case TCSETSF:
		uget(data, &ttydata[minor], sizeof(struct termios));
		if (request == TCSETSF)
			clrq(&ttyinq[minor]);
                tty_setup(minor);
		break;
	case TIOCINQ:
		uput(&ttyinq[minor].q_count, data, 2);
		break;
	case TIOCFLUSH:
		clrq(&ttyinq[minor]);
		break;
        case TIOCHANGUP:
                tty_hangup(minor);
                return 0;
	default:
		udata.u_error = ENOTTY;
		return (-1);
	}
	return (0);
}
Beispiel #7
0
void gserial_disconnect(struct gserial *gser)
{
	struct gs_port	*port = gser->ioport;
	unsigned long	flags;

	if (!port)
		return;

	
	spin_lock_irqsave(&port->port_lock, flags);

	
	port->port_line_coding = gser->port_line_coding;

	port->port_usb = NULL;
	gser->ioport = NULL;
	if (port->open_count > 0 || port->openclose) {
		wake_up_interruptible(&port->drain_wait);
		if (port->port_tty)
			tty_hangup(port->port_tty);
	}
	spin_unlock_irqrestore(&port->port_lock, flags);

	
	usb_ep_fifo_flush(gser->out);
	usb_ep_fifo_flush(gser->in);
	usb_ep_disable(gser->out);
	gser->out->driver_data = NULL;

	usb_ep_disable(gser->in);
	gser->in->driver_data = NULL;

	
	spin_lock_irqsave(&port->port_lock, flags);
	if (port->open_count == 0 && !port->openclose)
		gs_buf_free(&port->port_write_buf);
	gs_free_requests(gser->out, &port->read_pool);
	gs_free_requests(gser->out, &port->read_queue);
	gs_free_requests(gser->in, &port->write_pool);
	spin_unlock_irqrestore(&port->port_lock, flags);
}
Beispiel #8
0
void
ipwireless_tty_notify_control_line_change(struct ipw_tty *tty,
					  unsigned int channel_idx,
					  unsigned int control_lines,
					  unsigned int changed_mask)
{
	unsigned int old_control_lines = tty->control_lines;

	tty->control_lines = (tty->control_lines & ~changed_mask)
		| (control_lines & changed_mask);

	/*
	 * If DCD is de-asserted, we close the tty so pppd can tell that we
	 * have gone offline.
	 */
	if ((old_control_lines & IPW_CONTROL_LINE_DCD)
			&& !(tty->control_lines & IPW_CONTROL_LINE_DCD)
			&& tty->linux_tty) {
		tty_hangup(tty->linux_tty);
	}
}
Beispiel #9
0
/**
 * usb_serial_handle_dcd_change - handle a change of carrier detect state
 * @port: usb-serial port
 * @tty: tty for the port
 * @status: new carrier detect status, nonzero if active
 */
void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port,
				struct tty_struct *tty, unsigned int status)
{
	struct tty_port *port = &usb_port->port;

	dev_dbg(&usb_port->dev, "%s - status %d\n", __func__, status);

	if (tty) {
		struct tty_ldisc *ld = tty_ldisc_ref(tty);

		if (ld) {
			if (ld->ops->dcd_change)
				ld->ops->dcd_change(tty, status);
			tty_ldisc_deref(ld);
		}
	}

	if (status)
		wake_up_interruptible(&port->open_wait);
	else if (tty && !C_CLOCAL(tty))
		tty_hangup(tty);
}
int cctdev_release(struct inode *inode, struct file *filp)
{

	struct cctdev_dev *dev = filp->private_data;

	/* remove this filp from the asynchronously notified filp's */
	cctdev_fasync(-1, filp, 0);
	down(&dev->sem);
	if (filp->f_mode & FMODE_READ)
		dev->nreaders--;
	if (filp->f_mode & FMODE_WRITE)
		dev->nwriters--;
	if (dev->nreaders == 0 && dev->nwriters == 0) {
		int minor_num = MINOR(dev->cdev.dev);
		struct citty_port *citty = citty_table[minor_num];
		if (citty && citty->port->tty)
			tty_hangup(citty->port->tty);
	}
	up(&dev->sem);

	return 0;
}
Beispiel #11
0
static int acm_reset_resume(struct usb_interface *intf)
{
	struct acm *acm = usb_get_intfdata(intf);
	struct tty_struct *tty;

	if (!acm) {
		pr_err("%s: !acm\n", __func__);
		return -ENODEV;
	}

	mutex_lock(&acm->mutex);
	if (acm->port.count) {
		tty = tty_port_tty_get(&acm->port);
		if (tty) {
			if (!acm->no_hangup_in_reset_resume)
				tty_hangup(tty);
			tty_kref_put(tty);
		}
	}
	mutex_unlock(&acm->mutex);
	return acm_resume(intf);
}
Beispiel #12
0
static void ipw_disconnect(struct usb_serial *serial)
{
	struct usb_serial_port *port;
	struct ipw_private *priv;

	if (serial) {
		port = &serial->port[0];
		if (port->tty)
			tty_hangup(port->tty);
		priv = usb_get_serial_port_data(port);
		kfree(priv);
		usb_set_serial_port_data(port, NULL);
		if (serial->dev) {
                /* shutdown any bulk reads that might be going on */
			if (serial->num_bulk_out)
				usb_unlink_urb (port->write_urb);
			if (serial->num_bulk_in)
				usb_unlink_urb (port->read_urb);
		}
//2.6		usb_serial_generic_shutdown(serial);
		kfree(serial);
	}
}
Beispiel #13
0
/* control interface reports status changes with "interrupt" transfers */
static void acm_ctrl_irq(struct urb *urb)
{
	struct acm *acm = urb->context;
	struct usb_cdc_notification *dr = urb->transfer_buffer;
	struct tty_struct *tty;
	unsigned char *data;
	int newctrl;
	int retval;
	int status = urb->status;

	switch (status) {
	case 0:
		/* success */
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/* this urb is terminated, clean up */
		dev_dbg(&acm->control->dev,
				"%s - urb shutting down with status: %d\n",
				__func__, status);
		return;
	default:
		dev_dbg(&acm->control->dev,
				"%s - nonzero urb status received: %d\n",
				__func__, status);
		goto exit;
	}

	if (!ACM_READY(acm))
		goto exit;

	usb_mark_last_busy(acm->dev);

	data = (unsigned char *)(dr + 1);
	switch (dr->bNotificationType) {
	case USB_CDC_NOTIFY_NETWORK_CONNECTION:
		dev_dbg(&acm->control->dev, "%s - network connection: %d\n",
							__func__, dr->wValue);
		break;

	case USB_CDC_NOTIFY_SERIAL_STATE:
		tty = tty_port_tty_get(&acm->port);
		newctrl = get_unaligned_le16(data);

		if (tty) {
			if (!acm->clocal &&
				(acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
				dev_dbg(&acm->control->dev,
					"%s - calling hangup\n", __func__);
				tty_hangup(tty);
			}
			tty_kref_put(tty);
		}

		acm->ctrlin = newctrl;

		dev_dbg(&acm->control->dev,
			"%s - input control lines: dcd%c dsr%c break%c "
			"ring%c framing%c parity%c overrun%c\n",
			__func__,
			acm->ctrlin & ACM_CTRL_DCD ? '+' : '-',
			acm->ctrlin & ACM_CTRL_DSR ? '+' : '-',
			acm->ctrlin & ACM_CTRL_BRK ? '+' : '-',
			acm->ctrlin & ACM_CTRL_RI  ? '+' : '-',
			acm->ctrlin & ACM_CTRL_FRAMING ? '+' : '-',
			acm->ctrlin & ACM_CTRL_PARITY ? '+' : '-',
			acm->ctrlin & ACM_CTRL_OVERRUN ? '+' : '-');
			break;

	default:
		dev_dbg(&acm->control->dev,
			"%s - unknown notification %d received: index %d "
			"len %d data0 %d data1 %d\n",
			__func__,
			dr->bNotificationType, dr->wIndex,
			dr->wLength, data[0], data[1]);
		break;
	}
exit:
	retval = usb_submit_urb(urb, GFP_ATOMIC);
	if (retval)
		dev_err(&acm->control->dev, "%s - usb_submit_urb failed: %d\n",
							__func__, retval);
}
Beispiel #14
0
static void check_modem_status(struct serial_state *info)
{
	struct tty_port *port = &info->tport;
	unsigned char status = ciab.pra & (SER_DCD | SER_CTS | SER_DSR);
	unsigned char dstatus;
	struct	async_icount *icount;

	/* Determine bits that have changed */
	dstatus = status ^ current_ctl_bits;
	current_ctl_bits = status;

	if (dstatus) {
		icount = &info->icount;
		/* update input line counters */
		if (dstatus & SER_DSR)
			icount->dsr++;
		if (dstatus & SER_DCD) {
			icount->dcd++;
#ifdef CONFIG_HARD_PPS
			if ((port->flags & ASYNC_HARDPPS_CD) &&
			    !(status & SER_DCD))
				hardpps();
#endif
		}
		if (dstatus & SER_CTS)
			icount->cts++;
		wake_up_interruptible(&port->delta_msr_wait);
	}

	if ((port->flags & ASYNC_CHECK_CD) && (dstatus & SER_DCD)) {
#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
		printk("ttyS%d CD now %s...", info->line,
		       (!(status & SER_DCD)) ? "on" : "off");
#endif
		if (!(status & SER_DCD))
			wake_up_interruptible(&port->open_wait);
		else {
#ifdef SERIAL_DEBUG_OPEN
			printk("doing serial hangup...");
#endif
			if (port->tty)
				tty_hangup(port->tty);
		}
	}
	if (port->flags & ASYNC_CTS_FLOW) {
		if (port->tty->hw_stopped) {
			if (!(status & SER_CTS)) {
#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
				printk("CTS tx start...");
#endif
				port->tty->hw_stopped = 0;
				info->IER |= UART_IER_THRI;
				custom.intena = IF_SETCLR | IF_TBE;
				mb();
				/* set a pending Tx Interrupt, transmitter should restart now */
				custom.intreq = IF_SETCLR | IF_TBE;
				mb();
				tty_wakeup(port->tty);
				return;
			}
		} else {
			if ((status & SER_CTS)) {
#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
				printk("CTS tx stop...");
#endif
				port->tty->hw_stopped = 1;
				info->IER &= ~UART_IER_THRI;
				/* disable Tx interrupt and remove any pending interrupts */
				custom.intena = IF_TBE;
				mb();
				custom.intreq = IF_TBE;
				mb();
			}
		}
	}
}
Beispiel #15
0
static irqreturn_t a2232_vbl_inter(int irq, void *data)
{
#if A2232_IOBUFLEN != 256
#error "Re-Implement a2232_vbl_inter()!"
#endif

struct a2232_port *port;
volatile struct a2232memory *mem;
volatile struct a2232status *status;
unsigned char newhead;
unsigned char bufpos; /* Must be unsigned char. We need the modulo-256 arithmetics */
unsigned char ncd, ocd, ccd; /* names consistent with the NetBSD driver */
volatile u_char *ibuf, *cbuf, *obuf;
int ch, err, n, p;
	for (n = 0; n < nr_a2232; n++){		/* for every completely initialized A2232 board */
		mem = a2232mem(n);
		for (p = 0; p < NUMLINES; p++){	/* for every port on this board */
			err = 0;
			port = &a2232_ports[n*NUMLINES+p];
			if ( port->gs.port.flags & GS_ACTIVE ){ /* if the port is used */

				status = a2232stat(n,p);

				if (!port->disable_rx && !port->throttle_input){ /* If input is not disabled */
					newhead = status->InHead;               /* 65EC02 write pointer */
					bufpos = status->InTail;

					/* check for input for this port */
					if (newhead != bufpos) {
						/* buffer for input chars/events */
						ibuf = mem->InBuf[p];
 
						/* data types of bytes in ibuf */
						cbuf = mem->InCtl[p];
 
						/* do for all chars */
						while (bufpos != newhead) {
							/* which type of input data? */
							switch (cbuf[bufpos]) {
								/* switch on input event (CD, BREAK, etc.) */
							case A2232INCTL_EVENT:
								switch (ibuf[bufpos++]) {
								case A2232EVENT_Break:
									/* TODO: Handle BREAK signal */
									break;
									/*	A2232EVENT_CarrierOn and A2232EVENT_CarrierOff are
										handled in a separate queue and should not occur here. */
								case A2232EVENT_Sync:
									printk("A2232: 65EC02 software sent SYNC event, don't know what to do. Ignoring.");
									break;
								default:
									printk("A2232: 65EC02 software broken, unknown event type %d occurred.\n",ibuf[bufpos-1]);
								} /* event type switch */
								break;
 							case A2232INCTL_CHAR:
								/* Receive incoming char */
								a2232_receive_char(port, ibuf[bufpos], err);
								bufpos++;
								break;
 							default:
								printk("A2232: 65EC02 software broken, unknown data type %d occurred.\n",cbuf[bufpos]);
								bufpos++;
							} /* switch on input data type */
						} /* while there's something in the buffer */

						status->InTail = bufpos;            /* tell 65EC02 what we've read */
						
					} /* if there was something in the buffer */                          
				} /* If input is not disabled */

				/* Now check if there's something to output */
				obuf = mem->OutBuf[p];
				bufpos = status->OutHead;
				while ( (port->gs.xmit_cnt > 0)		&&
					(!port->gs.port.tty->stopped)	&&
					(!port->gs.port.tty->hw_stopped) ){	/* While there are chars to transmit */
					if (((bufpos+1) & A2232_IOBUFLENMASK) != status->OutTail) { /* If the A2232 buffer is not full */
						ch = port->gs.xmit_buf[port->gs.xmit_tail];					/* get the next char to transmit */
						port->gs.xmit_tail = (port->gs.xmit_tail+1) & (SERIAL_XMIT_SIZE-1); /* modulo-addition for the gs.xmit_buf ring-buffer */
						obuf[bufpos++] = ch;																/* put it into the A2232 buffer */
						port->gs.xmit_cnt--;
					}
					else{																									/* If A2232 the buffer is full */
						break;																							/* simply stop filling it. */
					}													
				}					
				status->OutHead = bufpos;
					
				/* WakeUp if output buffer runs low */
				if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.port.tty) {
					tty_wakeup(port->gs.port.tty);
				}
			} // if the port is used
		} // for every port on the board
			
		/* Now check the CD message queue */
		newhead = mem->Common.CDHead;
		bufpos = mem->Common.CDTail;
		if (newhead != bufpos){				/* There are CD events in queue */
			ocd = mem->Common.CDStatus; 		/* get old status bits */
			while (newhead != bufpos){		/* read all events */
				ncd = mem->CDBuf[bufpos++]; 	/* get one event */
				ccd = ncd ^ ocd; 		/* mask of changed lines */
				ocd = ncd; 			/* save new status bits */
				for(p=0; p < NUMLINES; p++){	/* for all ports */
					if (ccd & 1){		/* this one changed */

						struct a2232_port *port = &a2232_ports[n*7+p];
						port->cd_status = !(ncd & 1); /* ncd&1 <=> CD is now off */

						if (!(port->gs.port.flags & ASYNC_CHECK_CD))
							;	/* Don't report DCD changes */
						else if (port->cd_status) { // if DCD on: DCD went UP!
							
							/* Are we blocking in open?*/
							wake_up_interruptible(&port->gs.port.open_wait);
						}
						else { // if DCD off: DCD went DOWN!
							if (port->gs.port.tty)
								tty_hangup (port->gs.port.tty);
						}
						
					} // if CD changed for this port
					ccd >>= 1;
					ncd >>= 1;									/* Shift bits for next line */
				} // for every port
			} // while CD events in queue
			mem->Common.CDStatus = ocd; /* save new status */
			mem->Common.CDTail = bufpos; /* remove events */
		} // if events in CD queue
		
	} // for every completely initialized A2232 board
Beispiel #16
0
int tty_ioctl(uint8_t minor, uarg_t request, char *data)
{				/* Data in User Space */
        struct tty *t;
	if (minor > NUM_DEV_TTY + 1) {
		udata.u_error = ENODEV;
		return -1;
	}
        t = &ttydata[minor];
	if (t->flag & TTYF_DEAD) {
	        udata.u_error = ENXIO;
	        return -1;
        }
        jobcontrol_in(minor, t);
	switch (request) {
	case TCGETS:
		return uput(&t->termios, data, sizeof(struct termios));
		break;
	case TCSETSF:
		clrq(&ttyinq[minor]);
		/* Fall through for now */
	case TCSETSW:
		/* We don't have an output queue really so for now drop
		   through */
	case TCSETS:
		if (uget(data, &t->termios, sizeof(struct termios)) == -1)
		        return -1;
                tty_setup(minor);
		break;
	case TIOCINQ:
		return uput(&ttyinq[minor].q_count, data, 2);
	case TIOCFLUSH:
		clrq(&ttyinq[minor]);
		break;
        case TIOCHANGUP:
                tty_hangup(minor);
                return 0;
	case TIOCOSTOP:
		t->flag |= TTYF_STOP;
		break;
	case TIOCOSTART:
		t->flag &= ~TTYF_STOP;
		break;
        case TIOCGWINSZ:
                return uput(&t->winsize, data, sizeof(struct winsize));
        case TIOCSWINSZ:
                if (uget(&t->winsize, data, sizeof(struct winsize)))
                        return -1;
                sgrpsig(t->pgrp, SIGWINCH);
                return 0;
        case TIOCGPGRP:
                return uputw(t->pgrp, data);
#ifdef CONFIG_LEVEL_2
        case TIOCSPGRP:
                /* Only applicable via controlling terminal */
                if (minor != udata.u_ptab->p_tty) {
                        udata.u_error = ENOTTY;
                        return -1;
                }
                return tcsetpgrp(t, data);
#endif
	default:
		udata.u_error = ENOTTY;
		return -1;
	}
	return 0;
}
Beispiel #17
0
/*
** Incoming command on the COMMAND_RUP to be processed.
*/
static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struct PKT __iomem *PacketP)
{
	struct PktCmd __iomem *PktCmdP = (struct PktCmd __iomem *)PacketP->data;
	struct Port *PortP;
	struct UnixRup *UnixRupP;
	unsigned short SysPort;
	unsigned short ReportedModemStatus;
	unsigned short rup;
	unsigned short subCommand;
	unsigned long flags;

	func_enter();

	/*
	 ** 16 port RTA note:
	 ** Command rup packets coming from the RTA will have pkt->data[1] (which
	 ** translates to PktCmdP->PhbNum) set to the host port number for the
	 ** particular unit. To access the correct BaseSysPort for a 16 port RTA,
	 ** we can use PhbNum to get the rup number for the appropriate 8 port
	 ** block (for the first block, this should be equal to 'Rup').
	 */
	rup = readb(&PktCmdP->PhbNum) / (unsigned short) PORTS_PER_RTA;
	UnixRupP = &HostP->UnixRups[rup];
	SysPort = UnixRupP->BaseSysPort + (readb(&PktCmdP->PhbNum) % (unsigned short) PORTS_PER_RTA);
	rio_dprintk(RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort);

	if (UnixRupP->BaseSysPort == NO_PORT) {
		rio_dprintk(RIO_DEBUG_CMD, "OBSCURE ERROR!\n");
		rio_dprintk(RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n");
		rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: Host number %Zd, name ``%s''\n", HostP - p->RIOHosts, HostP->Name);
		rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: Rup number  0x%x\n", rup);

		if (Rup < (unsigned short) MAX_RUP) {
			rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n", HostP->Mapping[Rup].Name);
		} else
			rio_dprintk(RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", ('A' + Rup - MAX_RUP), HostP->Name);

		rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n", readb(&PacketP->dest_unit), readb(&PacketP->dest_port));
		rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Source	  0x%x:0x%x\n", readb(&PacketP->src_unit), readb(&PacketP->src_port));
		rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Length	  0x%x (%d)\n", readb(&PacketP->len), readb(&PacketP->len));
		rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Control	 0x%x (%d)\n", readb(&PacketP->control), readb(&PacketP->control));
		rio_dprintk(RIO_DEBUG_CMD, "PACKET information: Check	   0x%x (%d)\n", readw(&PacketP->csum), readw(&PacketP->csum));
		rio_dprintk(RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, " "Command Code 0x%x\n", readb(&PktCmdP->PhbNum), readb(&PktCmdP->Command));
		return 1;
	}
	PortP = p->RIOPortp[SysPort];
	rio_spin_lock_irqsave(&PortP->portSem, flags);
	switch (readb(&PktCmdP->Command)) {
	case BREAK_RECEIVED:
		rio_dprintk(RIO_DEBUG_CMD, "Received a break!\n");
		/* If the current line disc. is not multi-threading and
		   the current processor is not the default, reset rup_intr
		   and return 0 to ensure that the command packet is
		   not freed. */
		/* Call tmgr HANGUP HERE */
		/* Fix this later when every thing works !!!! RAMRAJ */
		gs_got_break(&PortP->gs);
		break;

	case COMPLETE:
		rio_dprintk(RIO_DEBUG_CMD, "Command complete on phb %d host %Zd\n", readb(&PktCmdP->PhbNum), HostP - p->RIOHosts);
		subCommand = 1;
		switch (readb(&PktCmdP->SubCommand)) {
		case MEMDUMP:
			rio_dprintk(RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n", readb(&PktCmdP->SubCommand), readw(&PktCmdP->SubAddr));
			break;
		case READ_REGISTER:
			rio_dprintk(RIO_DEBUG_CMD, "Read register (0x%x)\n", readw(&PktCmdP->SubAddr));
			p->CdRegister = (readb(&PktCmdP->ModemStatus) & MSVR1_HOST);
			break;
		default:
			subCommand = 0;
			break;
		}
		if (subCommand)
			break;
		rio_dprintk(RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n", readb(&PktCmdP->PortStatus), PortP->PortState);
		if (PortP->PortState != readb(&PktCmdP->PortStatus)) {
			rio_dprintk(RIO_DEBUG_CMD, "Mark status & wakeup\n");
			PortP->PortState = readb(&PktCmdP->PortStatus);
			/* What should we do here ...
			   wakeup( &PortP->PortState );
			 */
		} else
			rio_dprintk(RIO_DEBUG_CMD, "No change\n");

		/* FALLTHROUGH */
	case MODEM_STATUS:
		/*
		 ** Knock out the tbusy and tstop bits, as these are not relevant
		 ** to the check for modem status change (they're just there because
		 ** it's a convenient place to put them!).
		 */
		ReportedModemStatus = readb(&PktCmdP->ModemStatus);
		if ((PortP->ModemState & MSVR1_HOST) == (ReportedModemStatus & MSVR1_HOST)) {
			rio_dprintk(RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState);
			/*
			 ** Update ModemState just in case tbusy or tstop states have
			 ** changed.
			 */
			PortP->ModemState = ReportedModemStatus;
		} else {
			rio_dprintk(RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%x\n", PortP->ModemState, ReportedModemStatus);
			PortP->ModemState = ReportedModemStatus;
#ifdef MODEM_SUPPORT
			if (PortP->Mapped) {
				/***********************************************************\
				*************************************************************
				***													   ***
				***		  M O D E M   S T A T E   C H A N G E		  ***
				***													   ***
				*************************************************************
				\***********************************************************/
				/*
				 ** If the device is a modem, then check the modem
				 ** carrier.
				 */
				if (PortP->gs.tty == NULL)
					break;
				if (PortP->gs.tty->termios == NULL)
					break;

				if (!(PortP->gs.tty->termios->c_cflag & CLOCAL) && ((PortP->State & (RIO_MOPEN | RIO_WOPEN)))) {

					rio_dprintk(RIO_DEBUG_CMD, "Is there a Carrier?\n");
					/*
					 ** Is there a carrier?
					 */
					if (PortP->ModemState & MSVR1_CD) {
						/*
						 ** Has carrier just appeared?
						 */
						if (!(PortP->State & RIO_CARR_ON)) {
							rio_dprintk(RIO_DEBUG_CMD, "Carrier just came up.\n");
							PortP->State |= RIO_CARR_ON;
							/*
							 ** wakeup anyone in WOPEN
							 */
							if (PortP->State & (PORT_ISOPEN | RIO_WOPEN))
								wake_up_interruptible(&PortP->gs.open_wait);
						}
					} else {
						/*
						 ** Has carrier just dropped?
						 */
						if (PortP->State & RIO_CARR_ON) {
							if (PortP->State & (PORT_ISOPEN | RIO_WOPEN | RIO_MOPEN))
								tty_hangup(PortP->gs.tty);
							PortP->State &= ~RIO_CARR_ON;
							rio_dprintk(RIO_DEBUG_CMD, "Carrirer just went down\n");
						}
					}
				}
			}
#endif
		}
		break;

	default:
		rio_dprintk(RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %Zd\n", readb(&PktCmdP->Command), HostP - p->RIOHosts);
		break;
	}
	rio_spin_unlock_irqrestore(&PortP->portSem, flags);

	func_exit();

	return 1;
}
Beispiel #18
0
/* control interface reports status changes with "interrupt" transfers */
static void acm_ctrl_irq(struct urb *urb, struct pt_regs *regs)
{
	struct acm *acm = urb->context;
	struct usb_ctrlrequest *dr = urb->transfer_buffer;
	unsigned char *data = (unsigned char *)(dr + 1);
	int newctrl;
	int status;

	switch (urb->status) {
	case 0:
		/* success */
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/* this urb is terminated, clean up */
		dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
		return;
	default:
		dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
		goto exit;
	}

	if (!ACM_READY(acm))
		goto exit;

	switch (dr->bRequest) {

		case ACM_IRQ_NETWORK:

			dbg("%s network", dr->wValue ? "connected to" : "disconnected from");
			break;

		case ACM_IRQ_LINE_STATE:

			newctrl = le16_to_cpup((__u16 *) data);

			if (acm->tty && !acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
				dbg("calling hangup");
				tty_hangup(acm->tty);
			}

			acm->ctrlin = newctrl;

			dbg("input control lines: dcd%c dsr%c break%c ring%c framing%c parity%c overrun%c",
				acm->ctrlin & ACM_CTRL_DCD ? '+' : '-',	acm->ctrlin & ACM_CTRL_DSR ? '+' : '-',
				acm->ctrlin & ACM_CTRL_BRK ? '+' : '-',	acm->ctrlin & ACM_CTRL_RI  ? '+' : '-',
				acm->ctrlin & ACM_CTRL_FRAMING ? '+' : '-',	acm->ctrlin & ACM_CTRL_PARITY ? '+' : '-',
				acm->ctrlin & ACM_CTRL_OVERRUN ? '+' : '-');

			break;

		default:
			dbg("unknown control event received: request %d index %d len %d data0 %d data1 %d",
				dr->bRequest, dr->wIndex, dr->wLength, data[0], data[1]);
			break;
	}
exit:
	status = usb_submit_urb (urb, GFP_ATOMIC);
	if (status)
		err ("%s - usb_submit_urb failed with result %d",
		     __FUNCTION__, status);
}
Beispiel #19
0
void tty_carrier_drop(uint8_t minor)
{
        if (ttydata[minor].c_cflag & HUPCL)
                tty_hangup(minor);
}
Beispiel #20
0
static void __exit rin_exit(void)
{
	int i;
	struct net_device *dev;
	struct rin_st *sl;
	unsigned long timeout = jiffies + HZ;
	int busy = 0;

	if (rin_devs == NULL)
		return;

	/* First of all: check for active disciplines and hangup them.
	 */
	do {
		if (busy)
			msleep_interruptible(100);

		busy = 0;
		for (i = 0; i < rin_maxdev; i++) {
			dev = rin_devs[i];
			if (!dev)
				continue;
			sl = netdev_priv(dev);
			spin_lock_bh(&sl->lock);
			if (sl->tty) {
				busy++;
				tty_hangup(sl->tty);
			}
			spin_unlock_bh(&sl->lock);
		}
	} while (busy && time_before(jiffies, timeout));


	for (i = 0; i < rin_maxdev; i++) {
		dev = rin_devs[i];
		if (!dev)
			continue;
		rin_devs[i] = NULL;

		sl = netdev_priv(dev);
		if (sl->tty) {
			if(DEBUG) printk(KERN_ERR "%s: tty discipline still running\n",
			       dev->name);
			/* Intentionally leak the control block. */
			dev->destructor = NULL;
		}

		unregister_netdev(dev);
	}

	kfree(rin_devs);
	rin_devs = NULL;

	i = tty_unregister_ldisc(N_RIN);
	if (i != 0)
		if(DEBUG) printk(KERN_ERR "RIN: can't unregister line discipline (err = %d)\n", i);

	if (rin_tx_wq){
		flush_workqueue(rin_tx_wq);
		destroy_workqueue(rin_tx_wq);
		rin_tx_wq = NULL;
	}
}
Beispiel #21
0
int sysbef (char *befbuf)
//*************************************************************************
//
//*************************************************************************
{
  static char shutdown_reason[23];
  char xbuf[20];
  static char *beftab[] =
    {
      "CONNECT", "LOGIN", "CALL", "OSHELL",
#ifdef __DOS16__
#ifdef _TNC
      "TNC",
#endif
      "W2", "UWIN", "TWIN",
#ifdef _AUTOTRCWIN
      "TRWIN",
#endif
#endif
      "RTEXT", "CAT", "RPRG", "WTEXT", "WPRG", "RBIN", "WBIN",
      "SLR", "CLOG", "REORG",
      "LIFETIME", "MKBOARD", "RMBOARD", "MVBOARD", "SHUTDOWN", "NEW",
      "KILL", "TEST", "IMPORT", "DISABLE", "ENABLE",
#ifdef DIEBOX_UIMPORT
      "UIMPORT",
#endif
#ifdef OLDMAILIMPORT
      "OLDMAILIMPORT",
#endif
      "SETUSER", "BEACON", "GREP", "TGREP", "TAIL", "BEGIN", "BATCH",
      "EXPORT", "PWGEN", "POSTFWD", "MONITOR", "NOTE", "MACRO", "CFGFLEX",
      "ORM", "OMV", "OCP", "OMD", "APPEND",
#ifdef DF3VI_EXTRACT
      "EXTRACT",
#endif
      "HOLD", "SETPW",
#ifdef FEATURE_YAPP
      "WYAPP", "RYAPP",
#endif
#ifdef FEATURE_DIDADIT
      "WDIDADIT", "RDIDADIT",
#endif
#if defined FEATURE_SERIAL || defined _TELEPHONE
      "TTYINIT",
#endif
#ifdef _TELEPHONE // JJ
      "TTYCMD", "TTYDIAL", "TTYHANGUP", "TTYSTATUS", "TTYWIN",
      "TTYCOUNTERRESET",
#endif
#ifdef _AUTOFWD
      "AFWDLIST",
#endif
#ifdef FEATURE_MDPW
      "MD2SUM", "MD5SUM",
#endif
#ifdef FEATURE_EDITOR
      "EDIT", "FEDIT", "REDIT",
#else
 #ifdef DF3VI_FWD_EDIT
      "FEDIT", "FWDEDIT",
 #endif
 #ifdef DF3VI_REJ_EDIT
      "REDIT", "REJECTEDIT",
 #endif
 #ifdef DF3VI_CONV_EDIT
      "CEDIT", "CONVEDIT",
 #endif
#endif
#ifdef _FILEFWD
      "FWDIMPORT", "FWDEXPORT",
#endif
      "YMBTEST",
      "SCMDLIST", // Dies ist immer das letzte Kommando!
      NULL
    };

  enum befnum
    { unsinn, connect_, login, call_, oshell_,
#ifdef __DOS16__
#ifdef _TNC
      tnc,
#endif
      w2, uwin, twin,
#ifdef _AUTOTRCWIN
      trwin,
#endif
#endif
      rtext, rtext_, rprg, wtext, wprg, rbin, wbin,
      slr, clog, reorg,
      life_, mkb, rmb, mvb, shutdown_, new_,
      kill_, test, import, disable_, enable_,
#ifdef DIEBOX_UIMPORT
      uimport_,
#endif
#ifdef OLDMAILIMPORT
      oldmailimport_,
#endif
      setuser, beacon, grep_, tgrep, tail, begin, batch,
      export_, pwgen, postfwd_, monitor_, note, macro, cfgflex_,
      orm, omv, ocp, omd, _append,
#ifdef DF3VI_EXTRACT
      extract_,
#endif
      hold, setpw,
#ifdef FEATURE_YAPP
      wyapp, ryapp,
#endif
#ifdef FEATURE_DIDADIT
      wdidadit, rdidadit,
#endif
#if defined FEATURE_SERIAL || defined _TELEPHONE
      ttyinit,
#endif
#ifdef _TELEPHONE // JJ
      ttycmd, ttydial, ttyhangup, ttystatus, ttywin_,
      ttycounterreset,
#endif
#ifdef _AUTOFWD
      afwdlist_,
#endif
#ifdef FEATURE_MDPW
      md2sum, md5sum,
#endif
#ifdef FEATURE_EDITOR
      edit, fedit, redit,
#else
 #ifdef DF3VI_FWD_EDIT
      fedit, fwdedit,
 #endif
 #ifdef DF3VI_REJ_EDIT
      redit, rejectedit,
 #endif
 #ifdef DF3VI_CONV_EDIT
      cedit, convedit_,
 #endif
#endif
#ifdef _FILEFWD
      fwdimport, fwdexport,
#endif
      ymbtest,
      scmdlist // Dies ist immer das letzte Kommando!
    } cmd = unsinn;
  befbuf += blkill(befbuf);
  cmd = (befnum) readcmd(beftab, &befbuf, 0);
  switch (cmd)
  {
#ifdef FEATURE_YAPP
    case ryapp:
#endif
#ifdef FEATURE_DIDADIT
    case rdidadit:
#endif
#if defined(FEATURE_YAPP) || defined(FEATURE_DIDADIT)
      break;
#endif
    default:
      if (u->lf != 6)
        putv(LF);
      leerzeile(); // Sends the number of CRs stored in "ALTER LF"
  }

  switch (cmd)
  {
    case unsinn:
      if (   mbinitbef(befbuf, 0)
      #ifdef _TELEPHONE // JJ
          || ttyinitbef(befbuf, 0)
      #endif
         )
      {
        strcpy(xbuf, "^");
        mbparsave();
#ifdef _TELEPHONE // JJ
        ttyparsave();
#endif
        strncpy(xbuf + 1, befbuf, 18);
        xbuf[19] = 0;
        subst1(xbuf, ' ', 0);
        subst1(xbuf, '=', 0);
        grep(MBINITNAME, xbuf, o_i);
#ifdef _TELEPHONE // JJ
        grep(INITTTYNAME, xbuf, o_i);
#endif
        return OK;
      }
      else return NO;
    case note: trace(replog, "note", "%s", befbuf); break;
#ifdef DF3VI_EXTRACT
    case extract_: mbchange(befbuf, w_extract, 1); break;
#endif
    case hold: mbchange(befbuf, w_hold, 1); break;
    case omv:
    {
      char f1[50], f2[50];
      befbuf = nexttoken(befbuf, f1, 49);
      befbuf = nexttoken(befbuf, f2, 49);
      if (! *f1 || ! *f2 || xrename(f1, f2))
        putf(ms(m_error));
      else
      {
        putf(ms(m_moving));
        putf(ms(m_nach), f1, f2);
      }
      break;
    }
    case ocp:
    {
      char f1[50], f2[50];
      befbuf = nexttoken(befbuf, f1, 49);
      befbuf = nexttoken(befbuf, f2, 49);
      if (! *f1 || ! *f2 || filecopy(f1, f2))
        putf(ms(m_error));
      else
      {
        putf(ms(m_copying));
        putf(ms(m_nach), f1, f2);
      }
      break;
    }
    case orm:
    {
      char f1[50];
      befbuf = nexttoken(befbuf, f1, 49);
      if (! *f1 || xunlink(f1))
        putf(ms(m_filecantdeleted), f1);
      else
        putf(ms(m_filedeleted), f1);
      break;
    }
    case omd:
    {
      char f1[50];
      befbuf = nexttoken(befbuf, f1, 49);
      killbackslash(f1);
      if (! *f1 || xmkdir(f1))
        putf(ms(m_directorycantcreated), f1);
      else
        putf(ms(m_directorycreated), f1);
      break;
    }
    case _append:
    {
      char textline[LINELEN+1];
      befbuf = nexttoken(befbuf, textline, LINELEN);
      if (! *befbuf)
      {
        putf("Syntax: APPEND <textline> <filename>\n");
        break;
      }
      FILE *f = s_fopen(befbuf, "sat");
      if (f)
      {
        fprintf(f, "%s\n", textline);
        s_fclose(f);
      }
      else putf(ms(m_filenotfound), befbuf);
    } break;
    case macro:
    {
      mk_start(befbuf);
    } break;
    case setuser:
    {
      char call[CALLEN+1];
      befbuf = nexttoken(befbuf, call, CALLEN+1);
      strupr(call);
      if (mbcallok(call) && *befbuf)
      {
        trace(report, "setuser", "%s", befbuf);
        {
          if (! mbalter(NULL, befbuf, call))
            putf(ms(m_isunknown), call);
          b->msg_loadnum = 0; //reload msg
          loaduser(b->logincall, u, 1);
        }
      }
      else
        putf("Syntax: SETUSER <call> <option> <value>\n");
    } break;
    case setpw: //automatisierte Passwort-Vergabe
    {
      char call[CALLEN+1];
      char passwd[40];
      int i, pwline = 0;
      FILE *upwf;
      befbuf = nexttoken(befbuf, call, CALLEN+1);
      strupr(call);
      pwline = atoi(befbuf);
      if (! mbcallok(call) || ! pwline)
      {
        putf("Syntax: SETPW <call> <number>\n");
        break;
      }
      if (! loaduser(call, u, 0))
      {
        putf(ms(m_isunknown), call);
        break;
      }
      upwf = s_fopen("userpw.bcm", "sr");
      if (! upwf)
      {
        putf(ms(m_filenotfound), "userpw.bcm");
        break;
      }
      for (i = 0; i < pwline && ! feof(upwf); i++)
        fgets(passwd, sizeof(passwd) - 1, upwf);
      s_fclose(upwf);
      if (i < pwline)
      {
        putf(ms(m_userpwlines), i - 1);
        break;
      }
      strcpy(u->password, passwd);
      saveuser(u);
      pwline = strlen(u->password);
      putf(ms(m_loginpw), pwtypestr(u->loginpwtype), pwtypestr(u->sfpwtype));
      putf(" ");
      putf(ms(m_pwdlength), pwline);
      sprintf(passwd, "pw set to %i char", pwline);
      pwlog(call, b->logincall, passwd);
      b->msg_loadnum = 0; //reload msg
      loaduser(b->logincall, u, 1);
    } break;
#ifdef DIEBOX_UIMPORT
    case uimport_:
    {
      putf(ms(m_dieboximport));
      uimport();
    } break;
#endif
#ifdef OLDMAILIMPORT
    case oldmailimport_:
    {
      scanoptions(befbuf);
      formoptions();
      befbuf += blkill(befbuf);
      if (isdir(befbuf))
      {
        putf(ms(m_omi_started), befbuf);
        putflush();
        oldmailimport(befbuf);
      }
      else
        putf(ms(m_dirunknown), befbuf);
    } break;
#endif
    case disable_:
    {
      putf(ms(m_boxdisabled));
      m.disable = 1;
      mbparsave();
    } break;
    case enable_:
    {
      putf(ms(m_boxenabled));
      m.disable = 0;
      mbparsave();
    } break;
    case test:
    {
      if (*befbuf == 'W') { while (1); } // for testing watchdog
      else if (*befbuf == 'S') { trace(fatal, "test", "abort"); }
      else if (*befbuf == 'V') { *(char *)0 = 1; }
      else mk_start(befbuf);
    } break;
    case batch:
    {
      runbatch(befbuf);
    } break;
    case rtext:
    case rtext_:
    {
      fileio_text fio;
      fio.usefile(befbuf);
      fio.tx();
      putf("\032\n"); // CTRL-Z
    } break;
    case wtext:
    {
      fileio_text fio;
      fio.usefile(befbuf);
      fio.rx();
    } break;
    case rbin:
    case rprg:
    {
      fileio_abin fio;
      fio.usefile(befbuf);
      fio.tx();
    } break;
    case wbin:
    case wprg:
    {
      fileio_abin fio;
      fio.usefile(befbuf);
      fio.rx();
    } break;
#ifdef FEATURE_YAPP
    case ryapp:
    {
      fileio_yapp fio;
      fio.usefile(befbuf);
      fio.tx();
    } break;
    case wyapp:
    {
      fileio_yapp fio;
      fio.usefile(befbuf);
      fio.rx();
    } break;
#endif // FEATURE_YAPP
#ifdef FEATURE_DIDADIT
    case rdidadit:
    {
      fileio_dida fio;
      fio.usefile(befbuf);
      fio.tx();
    } break;
    case wdidadit:
    {
      fileio_dida fio;
      if (! *befbuf) fio.usefile("dummy");
      else
      {
        if (befbuf[strlen(befbuf) - 1] != '/') strcat(befbuf, "/");
        strcat(befbuf, "dummy");
        fio.usefile(befbuf);
      }
      fio.rx();
    } break;
#endif // FEATURE_DIDADIT
    case slr:
    {
      scanoptions(befbuf);
      putlog(TRACEPATH "/" SYSLOGRNAME, befbuf);
    } break;
    case clog:
    {
      scanoptions(befbuf);
      putlog(TRACEPATH "/" CMDLOGNAME, befbuf);
    } break;
    case tail:
    {
      scanoptions(befbuf);
      befbuf += blkill(befbuf);
      if (b->optplus&o_f && *befbuf)
      {
        int a;
        FILE *f = s_fopen(befbuf, "lrt");
        if (f)
        {
          fseek(f, 0, SEEK_END);
          do
          {
            while ((a = fgetc(f)) != EOF) putv(a);
            wdelay(349);
          }
          while (! testabbruch());
          s_fclose(f);
        }
      }
      else
      {
        fileio_text fio;
        fio.usefile(befbuf);
        fio.settail(-2000);
        fio.tx();
      }
    } break;
    case begin:
    {
      fileio_text fio;
      fio.usefile(befbuf);
      fio.settail(2000);
      fio.tx();
    } break;
    case monitor_:
    {
      if (*befbuf)
      {
        scanoptions(befbuf);
        b->continous = 1;
        monitor(atoi(befbuf), b->optplus);
      }
      else
        putf("Syntax: MONITOR [-iords] <task-id>\n");
    } break;
    case tgrep:
    {
      char string[61];
      char name[40];
      scanoptions(befbuf);
      if (b->optminus & o_i) b->optplus |= o_i;
      //wenn nicht explizit "-i-", ist "-i" default
      b->usermail = 0;
      if (! *befbuf)
      {
        putf("Syntax: TGREP [pattern] <fwd-bbs>\n");
        break;
      }
      befbuf = nexttoken(befbuf, string, 60);
      if (*befbuf)
      {
        sprintf(name, TRACEPATH "/t_%s.bcm", befbuf);
        grep(name, string, b->optplus);
      }
      else
      {
        sprintf(name, TRACEPATH "/t_%s.bcm", string);
        putlog(name, "");
      }
    } break;
    case grep_:
    {
      char string[61];
      scanoptions(befbuf);
      if (b->optminus & o_i) b->optplus |= o_i;
      //wenn nicht explizit "-i-", ist "-i" default
      b->usermail = 0;
      befbuf = nexttoken(befbuf, string, 60);
      grep(befbuf, string, b->optplus);
    } break;
#ifdef _AUTOFWD
    case afwdlist_:
    {
      afwdlist(befbuf);
    } break;
#endif
    case life_:
    {
      if (*befbuf)
      {
        strupr(befbuf);
        char *life = skip(befbuf);
        int board = finddir(befbuf, b->sysop);
        if (board > 0)
        {
          board -= 1;
          if (life && *life)
          {
            tree[board].lifetime_max = atoi(life);
            tree[board].lifetime_min = 1;
            if (tree[board].lifetime_max > 999)
              tree[board].lifetime_max = 999;
            if (tree[board].lifetime_max < 1)
              tree[board].lifetime_max = 1;
            char *life_min = skip(life);
            if (life_min && *life_min)
            {
              tree[board].lifetime_min = atoi(life_min);
              if (tree[board].lifetime_min > 999)
                tree[board].lifetime_min = 999;
              if (tree[board].lifetime_min < 1)
                tree[board].lifetime_min = 1;
            }
            mbtreesave();
          }
          putf(ms(m_lifetimestat), b->boardfullname, tree[board].lifetime_max,
                                                     tree[board].lifetime_min);
        }
        else
          putf(ms(m_notfound), befbuf);
      }
      else
        putf("Syntax: LIFETIME <board> <days_maximum> [<days_minimum>]\n"
             "            (with 1 <= days_maximum/days_minimum <= 999)\n\n");
    } break;
#ifdef _TNC
    case tnc:
    {
      control_tnc(befbuf);
    } break;
#endif
    case connect_:
    {
      termqso(befbuf);
    } break;
    case login:
    {
      if (mbcallok(befbuf))
      {
        mblogin(befbuf, login_standard, b->uplink);
        cmdlog("login changed");
        putf(ms(m_loginchanged));
      }
      else
        putf("Syntax: LOGIN <new logincall>\n");
    } break;
    case call_:
    {
      if (mbcallok(befbuf))
      {
        mblogin(befbuf, login_silent, b->uplink);
        b->msg_loadnum--; //Sonst wird falsche Sprache benutzt
        cmdlog("call changed");
      }
      else
        putf("Syntax: CALL <new logincall>\n");
    } break;
    case oshell_:
    {
      if (t->input == io_file || t->output == io_file)
        oshell(befbuf, sh_noinput);
      else oshell(befbuf, m.dosinput ? sh_forceinput : sh_ifmultitask);
    } break;
    case reorg:
    {
      if (sema_test("purgereorg") == 1)
        putf(ms(m_purgeallstarted));
      else
      {
        putf(ms(m_reorginvoked));
        fork(P_BACK | P_MAIL, 0, mbreorg, befbuf);
      }
    } break;
    case postfwd_:
    {
      putf(ms(m_postfwdinvoked));
      fork(P_BACK | P_MAIL, 0, postfwd, "Postfwd");
    } break;
#ifdef FEATURE_EDITOR
    case edit:
    {
      fork(P_WIND | P_KEYB, 0, editfile, befbuf);
    } break;
    case fedit:
    {
      fork(P_WIND | P_KEYB, 0, editfile, FWDLISTNAME);
    } break;
    case redit:
    {
      fork(P_WIND | P_KEYB, 0, editfile, REJECTNAME);
    } break;
#else
 #ifdef DF3VI_FWD_EDIT
    case fedit: //wenn kein editor vorhanden remote-editor aufrufen
    case fwdedit:
    {
      fwdlistedit(befbuf);
    } break;
 #endif
 #ifdef DF3VI_REJ_EDIT
    case redit:
    case rejectedit:
    {
      rejectlistedit(befbuf);
    } break;
 #endif
 #ifdef DF3VI_CONV_EDIT
    case cedit:
    case convedit_:
    {
      convedit(befbuf);
    } break;
 #endif
#endif
    case new_:
    {
      scanoptions(befbuf);
      mbinit();
      initfwdlist();
#ifdef _AUTOFWD
      initafwdlist();
#endif
      if (! (b->optplus & o_q)) // skip statistics on "new -q"
      {
        b->optplus = o_s | o_f | o_c;
        putf(ms(m_hadrstat));
        browse_hadr("");
      }
      mbcvtload();
#ifdef RUNUTILS
      read_runfile();
#endif
      msg_dealloc(1);
      mk_read_jobs();
    } break;
    case kill_:
    {
      if (atoi(befbuf))
      {
        while (atoi(befbuf))
        {
          if (! killtask(nextdez(&befbuf), 1))
            putf(ms(m_cantkilltask));
        }
      }
      else
        putf("Syntax: KILL <task-id>\n");
    } break;
#ifdef __DOS16__
    case w2:
    {
      fork(P_WIND | P_KEYB|P_MAIL, 0, mbwin2, m.sysopcall);
    } break;
    case uwin:
    {
      fork(P_WIND | P_KEYB|P_MAIL, 0, userwin, "Users");
    } break;
    case twin:
    {
      fork(P_WIND | P_MAIL, 0, taskwin, befbuf);
    } break;
#ifdef _AUTOTRCWIN
    case trwin:
    {
      if (*befbuf) fork(P_WIND | P_MAIL, 0, trcwin, befbuf);
      else putf("Syntax: TRWIN [-iords] <task-id>\n");
    } break;
#endif
#endif //__DOS16__
    case mkb:
    {
      char mainboard[30];
      char newboard[20];
      char *slash;
      befbuf = nexttoken(befbuf, mainboard, 29);
      befbuf = nexttoken(befbuf, newboard, 19);
      slash = strchr(mainboard + 1, '/');
      if (slash && (! *newboard))
      {
        *slash = 0;
        strcpy(newboard, slash + 1);
      }
      if (! *newboard && *mainboard == '/')
      {
        strcpy(newboard, mainboard + 1);
        mainboard[1] = 0;
      }
      if (*mainboard && *newboard)
      {
        switch (mkboard(mainboard, newboard, 0))
        {
          case 0: putf(ms(m_boardcreated)); break;
          case 1: putf(ms(m_mainboardnotfound)); break;
          case 2: putf(ms(m_toomanyboards)); break;
          case 3: putf(ms(m_boardnameexist)); break;
          case 4: putf(ms(m_invalidboardname)); break;
        }
      }
      else
        putf("Syntax: MKBOARD <mainboard> <subboard>\n");
    } break;
    case rmb:
    {
      if (*befbuf)
      {
        subst1(befbuf, ' ', '/');
        if (*befbuf == '/' && befbuf[1] == '/') befbuf++;
        switch (rmboard(befbuf))
        {
          case 0: putf(ms(m_boardremoved)); break;
          case 1: putf(ms(m_boardnotfound)); break;
          case 2: putf(ms(m_boardnotempty)); break;
        }
      }
      else
        putf("Syntax: RMBOARD <mainboard> <subboard>\n");
    } break;
    case mvb:
    {
      char oldboard[20];
      char subboard[20];
      char neuboard[20];
      befbuf = nexttoken(befbuf, oldboard, 19);
      befbuf = nexttoken(befbuf, subboard, 19);
      befbuf = nexttoken(befbuf, neuboard, 19);
      if (*oldboard && *subboard && *neuboard)
      {
        switch (mvboard(oldboard, subboard, neuboard))
        {
          case 0: putf(ms(m_boardmoved)); break;
          case 1: putf(ms(m_newboardnotfound)); break;
          case 2: putf(ms(m_toomanyboards)); break;
          case 4: putf(ms(m_oldboardnotfound)); break;
        }
      }
      else
        putf("Syntax: MVBOARD <oldboard> <subboard> <newboard>\n");
    } break;
    case shutdown_:
    {
      scanoptions(befbuf);
#ifdef __DOS16__
      if (b->optplus & o_r) atexit((void(*)()) MK_FP(0xffff, 0x0000));
#endif
      runterfahren = 1;
      sprintf(shutdown_reason, "shutdown by %s", b->logincall);
      stopreason = shutdown_reason;
    } break;
    case cfgflex_:
    {
      if (*befbuf && file_isreg("cfgflex.bcm"))
      {
        putf(ms(m_flexstarted));
        fork(P_BACK | P_MAIL, 0, cfgflex, befbuf);
      }
      else
        putf("Syntax: CFGFLEX <flexcall> (cfgflex.bcm must exist)\n");
    } break;
    case import:
    {
      sysimport(befbuf);
    } break;
    case export_:
    {
      if (*befbuf)
      {
        if ((t->input != io_file || t->output == io_dummy)
            && t->output != io_file)
        {
          char fname[51];
          scanoptions(befbuf);
          befbuf = nexttoken(befbuf, fname, 50);
          if (b->optplus & o_a) // neue Option -b fuer binaer
          {
            if (b->optplus & o_b) b->outputfile = s_fopen(fname, "sab");
            else b->outputfile = s_fopen(fname, "sat");
          }
          else
          {
            if (b->optplus & o_b) b->outputfile = s_fopen(fname, "swb");
            else b->outputfile = s_fopen(fname, "swt");
          }
          if (b->outputfile)
          {
            s_fsetopt(b->outputfile, 1);
            b->oldinput = t->input;
            b->oldoutput = t->output;
            t->input = io_dummy;
            t->output = io_file;
            b->continous = 1;
            if (b->optplus & o_u) b->sysop = 0;
            if (*befbuf) mailbef(befbuf, 0);
            b->sysop = 1;
          }
          else
            putf(ms(m_filenotopen), fname);
        }
      }
      else
        putf("Syntax: EXPORT <filename> <box-command>\n");
    } break;
    case beacon:
    {
      if (*befbuf)
      {
        FILE *f = s_fopen(BEACONNAME, "srt");
        unsigned int i = 0;
        char s[LINELEN+1];
        if (f)
        {
          while (fgets(s, LINELEN, f))
          {
            if (*s)
            {
              s[strlen(s) - 1] = 0;
              putbeacon_tnc(s, befbuf);
              i++;
            }
          }
          s_fclose(f);
        }
        putf(ms(m_beaconframes), i);
      }
      else
      {
        fork(P_BACK | P_MAIL, 0, sendmailbake, "Beacon");
        putf(ms(m_beaconstarted));
      }
    } break;
    case pwgen:
    {
      FILE *f;
      if (*befbuf && (f = s_fopen(befbuf, "swt")) != 0)
      {
        unsigned int i;
        int upw;
        upw = ! stricmp(befbuf, "userpw.bcm"); // file fuer setpw
        for (i = 0; i < 1620; i++)
        {
          char c = 0;
          while (! isalnum(c)) c = random_max('z');
          fputc(c, f);
          //pw-file fuer setpw erzeugen (81 Zeilen mit je 20 Zeichen)
          if (upw && (i % 20) == 19) fputc(LF, f);
        }
        trace(report, "pwgen", "%s created", befbuf);
        s_fclose(f);
      }
      else //ohne Parameter immer userpw.bcm erzeugen
      if (! *befbuf && (f = s_fopen("userpw.bcm", "swt")) != 0)
      {
        unsigned int i;
        for (i = 0; i < 1620; i++)
        {
          char c = 0;
          while (! isalnum(c)) c = random_max('z');
          fputc(c, f);
          //pw-file fuer setpw erzeugen (81 Zeilen mit je 20 Zeichen)
          if ((i % 20) == 19) fputc(LF, f);
        }
        trace(report, "pwgen", "userpw.bcm created");
        s_fclose(f);
      }
    } break;
    case scmdlist: // DH3MB
    {
      unsigned int i = 0;
      while (beftab[i]) putf("(%02d) %s\n", ++i, beftab[i]);
    } break;
#ifdef FEATURE_MDPW
    case md2sum:
    {
      if (! *befbuf)
      {
        putf("Syntax: MD2SUM <filename>\n");
        break;
      }
      if (! file_isreg(befbuf))
        putf(ms(m_filenotfound), befbuf);
      else
      {
        MD2 md2;
        md2.readfile(befbuf, 0L);
        md2.gethexdigest(b->line);
        putf("%s  %s\n", b->line, befbuf);
      }
    } break;
    case md5sum:
    {
      if (! *befbuf)
      {
        putf("Syntax: MD5SUM <filename>\n");
        break;
      }
      if (! file_isreg(befbuf))
        putf(ms(m_filenotfound), befbuf);
      else
      {
        MD5 md5;
        md5.readfile(befbuf, 0L);
        md5.gethexdigest(b->line);
        putf("%s  %s\n", b->line, befbuf);
      }
    } break;
#endif
#if defined FEATURE_SERIAL || defined _TELEPHONE
    case ttyinit:
    {
      if (eingelogt("getty", 0, 0))
        putf(ms(m_ttyactive));
      else
        init_tty();
    } break;
#endif
#ifdef _TELEPHONE // JJ
    case ttycmd:
    {
      if (*befbuf)
      {
        if (m.ttydevice > 1)
          putf_tty("%s\r", befbuf);
        else
          putf(ms(m_nomodem));
      }
      else
        putf("Syntax: TTYCMD <command>\n");
    } break;
    case ttydial:
    {
      strupr(befbuf);
      char *nummer;
      char call[8];
      nummer = nexttoken(befbuf, call, 8);
      if (*befbuf && mbcallok(call))
      {
        if (m.ttydevice
            && (get_ufwd(call)[0] || isforwardpartner(call) >= 0))
        {
          putf(ms(m_startphonefwd), call, nummer);
          sprintf(befbuf, "%s TTY %s", call, nummer);
          fork(P_BACK | P_MAIL, 0, fwdsend, befbuf);
        }
        else
          putf(ms(m_nottyactive));
      }
      else
        putf("Syntax: TTYDIAL <call> <number>\n");
    } break;
    case ttyhangup:
    {
      tty_hangup();
      putf(ms(m_hangupmodem));
    } break;
    case ttystatus:
    {
      tty_statustext();
      putv(LF);
    } break;
    case ttywin_:
    {
      fork(P_WIND | P_MAIL, 0, tty_win, befbuf);
    } break;
    case ttycounterreset:
    {
      tty_counterreset();
      putv(LF);
    } break;
#endif
#ifdef _FILEFWD
    case fwdimport:
    {
      if (*befbuf) fwd_import(befbuf);
    } break;
    case fwdexport:
    {
      if (*befbuf) fwd_export(befbuf);
    } break;
#endif

    case ymbtest:
    {
#ifdef _USERCOMP
      if (u->comp == 1)
      {
/*
    char output[256] = { 0 };
    char output2[256] = { 0 };
    int i, il = 0;
*/
        putf("//COMP 1\n\n");
        putflush();

/*
    il = comp_sp_stat_huff(befbuf, strlen(befbuf), output);
//    printf("il: %d strlen: %d\n",il,strlen(befbuf));
//    printf("befbuf:\n-%s-\nOut:\n-%s-\n",befbuf,output);
    //putflush();
    for (i = 1; i < il ; i++)
      bputv(output[i]);

    putv(LF);
    putflush();
    output[0] = '\0';
    strcpy(befbuf, "dies ist noch ein laengerer text 2");
    il = comp_sp_stat_huff(befbuf, strlen(befbuf), output);
    for (i = 1; i < il ; i++)
      bputv(output[i]);

    putv(LF);
    putflush();
    output[0] = '\0';
    strcpy(befbuf, "dies ist ein noch laengerer text 3");
    il = comp_sp_stat_huff(befbuf, strlen(befbuf), output);
    for (i = 1; i < il ; i++)
      bputv(output[i]);


    putv(LF);
    putflush();
    putf("\n");
    il = decomp_sp_stat_huff(output, strlen(output), output2);
    printf("il: %d strlen: %d\n",il,strlen(output));
    printf("Out2:\n-%s-\n",output2);
*/

/*
#include "ahuf.h"
   // TOP-Huffman
class AHUF;
   AHUF *ahuf;
   ahuf = new AHUF();

    il = ahuf->Komprimieren(true, befbuf, output, strlen(befbuf) );
    printf("il: %d strlen: %d\n",il,strlen(befbuf));
    printf("befbuf:\n-%s-\nOut:\n-%s-\n",befbuf,output);
    putflush();
    putf("%s",output);
    putflush();
    putf("\n");
*/
      }
#endif
    } break;
  }
  return OK;
Beispiel #22
0
/* control interface reports status changes with "interrupt" transfers */
static void acm_ctrl_irq(struct urb *urb)
{
	struct acm *acm = urb->context;
	struct usb_cdc_notification *dr = urb->transfer_buffer;
	unsigned char *data;
	int newctrl;
	int retval;
	int status = urb->status;

	switch (status) {
	case 0:
		/* success */
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/* this urb is terminated, clean up */
		dbg("%s - urb shutting down with status: %d", __FUNCTION__, status);
		return;
	default:
		dbg("%s - nonzero urb status received: %d", __FUNCTION__, status);
		goto exit;
	}

	if (!ACM_READY(acm))
		goto exit;

	data = (unsigned char *)(dr + 1);
	switch (dr->bNotificationType) {

		case USB_CDC_NOTIFY_NETWORK_CONNECTION:

			dbg("%s network", dr->wValue ? "connected to" : "disconnected from");
			break;

		case USB_CDC_NOTIFY_SERIAL_STATE:

			newctrl = le16_to_cpu(get_unaligned((__le16 *) data));

			if (acm->tty && !acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
				dbg("calling hangup");
				tty_hangup(acm->tty);
			}

			acm->ctrlin = newctrl;

			dbg("input control lines: dcd%c dsr%c break%c ring%c framing%c parity%c overrun%c",
				acm->ctrlin & ACM_CTRL_DCD ? '+' : '-',	acm->ctrlin & ACM_CTRL_DSR ? '+' : '-',
				acm->ctrlin & ACM_CTRL_BRK ? '+' : '-',	acm->ctrlin & ACM_CTRL_RI  ? '+' : '-',
				acm->ctrlin & ACM_CTRL_FRAMING ? '+' : '-',	acm->ctrlin & ACM_CTRL_PARITY ? '+' : '-',
				acm->ctrlin & ACM_CTRL_OVERRUN ? '+' : '-');

			break;

		default:
			dbg("unknown notification %d received: index %d len %d data0 %d data1 %d",
				dr->bNotificationType, dr->wIndex,
				dr->wLength, data[0], data[1]);
			break;
	}
exit:
	usb_mark_last_busy(acm->dev);
	retval = usb_submit_urb (urb, GFP_ATOMIC);
	if (retval)
		err ("%s - usb_submit_urb failed with result %d",
		     __FUNCTION__, retval);
}
Beispiel #23
0
static void	usa26_instat_callback(struct urb *urb)
{
	unsigned char 				*data = urb->transfer_buffer;
	struct keyspan_usa26_portStatusMessage	*msg;
	struct usb_serial			*serial;
	struct usb_serial_port			*port;
	struct keyspan_port_private	 	*p_priv;
	struct tty_struct			*tty;
	int old_dcd_state, err;
	int status = urb->status;

	serial =  urb->context;

	if (status) {
		dbg("%s - nonzero status: %x", __func__, status);
		return;
	}
	if (urb->actual_length != 9) {
		dbg("%s - %d byte report??", __func__, urb->actual_length);
		goto exit;
	}

	msg = (struct keyspan_usa26_portStatusMessage *)data;

#if 0
	dbg("%s - port status: port %d cts %d dcd %d dsr %d ri %d toff %d txoff %d rxen %d cr %d",
	    __func__, msg->port, msg->hskia_cts, msg->gpia_dcd, msg->dsr, msg->ri, msg->_txOff,
	    msg->_txXoff, msg->rxEnabled, msg->controlResponse);
#endif

	/* Now do something useful with the data */


	/* Check port number from message and retrieve private data */
	if (msg->port >= serial->num_ports) {
		dbg("%s - Unexpected port number %d", __func__, msg->port);
		goto exit;
	}
	port = serial->port[msg->port];
	p_priv = usb_get_serial_port_data(port);

	/* Update handshaking pin state information */
	old_dcd_state = p_priv->dcd_state;
	p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);
	p_priv->dsr_state = ((msg->dsr) ? 1 : 0);
	p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
	p_priv->ri_state = ((msg->ri) ? 1 : 0);

	if (old_dcd_state != p_priv->dcd_state) {
		tty = tty_port_tty_get(&port->port);
		if (tty && !C_CLOCAL(tty))
			tty_hangup(tty);
		tty_kref_put(tty);
	}

	/* Resubmit urb so we continue receiving */
	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err != 0)
		dbg("%s - resubmit read urb failed. (%d)", __func__, err);
exit: ;
}