Ejemplo n.º 1
0
/******************************************************************************
 *
 *  usb_cpia_cleanup
 *
 *****************************************************************************/
void cpia2_usb_cleanup(void)
{
	schedule_timeout(2 * HZ);
	usb_deregister(&cpia2_driver);
}
Ejemplo n.º 2
0
/*
 * receive a message from an RxRPC socket
 * - we need to be careful about two or more threads calling recvmsg
 *   simultaneously
 */
int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,
		  struct msghdr *msg, size_t len, int flags)
{
	struct rxrpc_skb_priv *sp;
	struct rxrpc_call *call = NULL, *continue_call = NULL;
	struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
	struct sk_buff *skb;
	long timeo;
	int copy, ret, ullen, offset, copied = 0;
	u32 abort_code;

	DEFINE_WAIT(wait);

	_enter(",,,%zu,%d", len, flags);

	if (flags & (MSG_OOB | MSG_TRUNC))
		return -EOPNOTSUPP;

	ullen = msg->msg_flags & MSG_CMSG_COMPAT ? 4 : sizeof(unsigned long);

	timeo = sock_rcvtimeo(&rx->sk, flags & MSG_DONTWAIT);
	msg->msg_flags |= MSG_MORE;

	lock_sock(&rx->sk);

	for (;;) {
		/* return immediately if a client socket has no outstanding
		 * calls */
		if (RB_EMPTY_ROOT(&rx->calls)) {
			if (copied)
				goto out;
			if (rx->sk.sk_state != RXRPC_SERVER_LISTENING) {
				release_sock(&rx->sk);
				if (continue_call)
					rxrpc_put_call(continue_call);
				return -ENODATA;
			}
		}

		/* get the next message on the Rx queue */
		skb = skb_peek(&rx->sk.sk_receive_queue);
		if (!skb) {
			/* nothing remains on the queue */
			if (copied &&
			    (msg->msg_flags & MSG_PEEK || timeo == 0))
				goto out;

			/* wait for a message to turn up */
			release_sock(&rx->sk);
			prepare_to_wait_exclusive(rx->sk), &wait,
						  TASK_INTERRUPTIBLE);
			ret = sock_error(&rx->sk);
			if (ret)
				goto wait_error;

			if (skb_queue_empty(&rx->sk.sk_receive_queue)) {
				if (signal_pending(current))
					goto wait_interrupted;
				timeo = schedule_timeout(timeo);
			}
			finish_wait(sk_sleep(rx->sk), &wait);
			lock_sock(&rx->sk);
			continue;
		}

	peek_next_packet:
		sp = rxrpc_skb(skb);
		call = sp->call;
		ASSERT(call != NULL);

		_debug("next pkt %s", rxrpc_pkts[sp->hdr.type]);

		/* make sure we wait for the state to be updated in this call */
		spin_lock_bh(&call->lock);
		spin_unlock_bh(&call->lock);

		if (test_bit(RXRPC_CALL_RELEASED, &call->flags)) {
			_debug("packet from released call");
			if (skb_dequeue(&rx->sk.sk_receive_queue) != skb)
				BUG();
			rxrpc_free_skb(skb);
			continue;
		}

		/* determine whether to continue last data receive */
		if (continue_call) {
			_debug("maybe cont");
			if (call != continue_call ||
			    skb->mark != RXRPC_SKB_MARK_DATA) {
				release_sock(&rx->sk);
				rxrpc_put_call(continue_call);
				_leave(" = %d [noncont]", copied);
				return copied;
			}
		}

		rxrpc_get_call(call);

		/* copy the peer address and timestamp */
		if (!continue_call) {
			if (msg->msg_name && msg->msg_namelen > 0)
				memcpy(&msg->msg_name, &call->conn->trans->peer->srx,
				       sizeof(call->conn->trans->peer->srx));
			sock_recv_timestamp(msg, &rx->sk, skb);
		}

		/* receive the message */
		if (skb->mark != RXRPC_SKB_MARK_DATA)
			goto receive_non_data_message;

		_debug("recvmsg DATA #%u { %d, %d }",
		       ntohl(sp->hdr.seq), skb->len, sp->offset);

		if (!continue_call) {
			/* only set the control data once per recvmsg() */
			ret = put_cmsg(msg, SOL_RXRPC, RXRPC_USER_CALL_ID,
				       ullen, &call->user_call_ID);
			if (ret < 0)
				goto copy_error;
			ASSERT(test_bit(RXRPC_CALL_HAS_USERID, &call->flags));
		}

		ASSERTCMP(ntohl(sp->hdr.seq), >=, call->rx_data_recv);
		ASSERTCMP(ntohl(sp->hdr.seq), <=, call->rx_data_recv + 1);
		call->rx_data_recv = ntohl(sp->hdr.seq);

		ASSERTCMP(ntohl(sp->hdr.seq), >, call->rx_data_eaten);

		offset = sp->offset;
		copy = skb->len - offset;
		if (copy > len - copied)
			copy = len - copied;

		if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
			ret = skb_copy_datagram_iovec(skb, offset,
						      msg->msg_iov, copy);
		} else {
			ret = skb_copy_and_csum_datagram_iovec(skb, offset,
							       msg->msg_iov);
			if (ret == -EINVAL)
				goto csum_copy_error;
		}

		if (ret < 0)
			goto copy_error;

		/* handle piecemeal consumption of data packets */
		_debug("copied %d+%d", copy, copied);

		offset += copy;
		copied += copy;

		if (!(flags & MSG_PEEK))
			sp->offset = offset;

		if (sp->offset < skb->len) {
			_debug("buffer full");
			ASSERTCMP(copied, ==, len);
			break;
		}

		/* we transferred the whole data packet */
		if (sp->hdr.flags & RXRPC_LAST_PACKET) {
			_debug("last");
			if (call->conn->out_clientflag) {
				 /* last byte of reply received */
				ret = copied;
				goto terminal_message;
			}

			/* last bit of request received */
			if (!(flags & MSG_PEEK)) {
				_debug("eat packet");
				if (skb_dequeue(&rx->sk.sk_receive_queue) !=
				    skb)
					BUG();
				rxrpc_free_skb(skb);
			}
			msg->msg_flags &= ~MSG_MORE;
			break;
		}

		/* move on to the next data message */
		_debug("next");
		if (!continue_call)
			continue_call = sp->call;
		else
			rxrpc_put_call(call);
		call = NULL;

		if (flags & MSG_PEEK) {
			_debug("peek next");
			skb = skb->next;
			if (skb == (struct sk_buff *) &rx->sk.sk_receive_queue)
				break;
			goto peek_next_packet;
		}

		_debug("eat packet");
		if (skb_dequeue(&rx->sk.sk_receive_queue) != skb)
			BUG();
		rxrpc_free_skb(skb);
	}
Ejemplo n.º 3
0
static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
			 unsigned char __user *buf, size_t nr)
{
	unsigned char __user *b = buf;
	DECLARE_WAITQUEUE(wait, current);
	int c;
	int minimum, time;
	ssize_t retval = 0;
	ssize_t size;
	long timeout;
	unsigned long flags;
	int packet;
	struct tty_buffer *head;
	int count;

do_it_again:

	if (WARN_ON(!tty->read_buf))
		return -EAGAIN;

	c = job_control(tty, file);
	if (c < 0)
		return c;

	minimum = time = 0;
	timeout = MAX_SCHEDULE_TIMEOUT;
	if (!tty->icanon) {
		time = (HZ / 10) * TIME_CHAR(tty);
		minimum = MIN_CHAR(tty);
		if (minimum) {
			if (time)
				tty->minimum_to_wake = 1;
			else if (!waitqueue_active(&tty->read_wait) ||
				 (tty->minimum_to_wake > minimum))
				tty->minimum_to_wake = minimum;
		} else {
			timeout = 0;
			if (time) {
				timeout = time;
				time = 0;
			}
			tty->minimum_to_wake = minimum = 1;
		}
	}

	if (file->f_flags & O_NONBLOCK) {
		if (!mutex_trylock(&tty->atomic_read_lock))
			return -EAGAIN;
	} else {
		if (mutex_lock_interruptible(&tty->atomic_read_lock))
			return -ERESTARTSYS;
	}
	packet = tty->packet;

	add_wait_queue(&tty->read_wait, &wait);
	while (nr) {
		
		if (packet && tty->link->ctrl_status) {
			unsigned char cs;
			if (b != buf)
				break;
			spin_lock_irqsave(&tty->link->ctrl_lock, flags);
			cs = tty->link->ctrl_status;
			tty->link->ctrl_status = 0;
			spin_unlock_irqrestore(&tty->link->ctrl_lock, flags);
			if (tty_put_user(tty, cs, b++)) {
				retval = -EFAULT;
				b--;
				break;
			}
			nr--;
			break;
		}
		set_current_state(TASK_INTERRUPTIBLE);

		if (((minimum - (b - buf)) < tty->minimum_to_wake) &&
		    ((minimum - (b - buf)) >= 1))
			tty->minimum_to_wake = (minimum - (b - buf));

		if (!input_available_p(tty, 0)) {
			if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
				retval = -EIO;
				break;
			}
			if (tty_hung_up_p(file))
				break;
			if (!timeout)
				break;
			if (file->f_flags & O_NONBLOCK) {
				retval = -EAGAIN;
				break;
			}
			if (signal_pending(current)) {
				retval = -ERESTARTSYS;
				break;
			}
			
			n_tty_set_room(tty);
			timeout = schedule_timeout(timeout);
			BUG_ON(!tty->read_buf);
			continue;
		}
		__set_current_state(TASK_RUNNING);

		
		if (packet && b == buf) {
			if (tty_put_user(tty, TIOCPKT_DATA, b++)) {
				retval = -EFAULT;
				b--;
				break;
			}
			nr--;
		}

		if (tty->icanon && !L_EXTPROC(tty)) {
			
			while (nr && tty->read_cnt) {
				int eol;

				eol = test_and_clear_bit(tty->read_tail,
						tty->read_flags);
				c = tty->read_buf[tty->read_tail];
				spin_lock_irqsave(&tty->read_lock, flags);
				tty->read_tail = ((tty->read_tail+1) &
						  (N_TTY_BUF_SIZE-1));
				tty->read_cnt--;
				if (eol) {
					if (--tty->canon_data < 0)
						tty->canon_data = 0;
				}
				spin_unlock_irqrestore(&tty->read_lock, flags);

				if (!eol || (c != __DISABLED_CHAR)) {
					if (tty_put_user(tty, c, b++)) {
						retval = -EFAULT;
						b--;
						break;
					}
					nr--;
				}
				if (eol) {
					tty_audit_push(tty);
					break;
				}
			}
			if (retval)
				break;
		} else {
			int uncopied;
			uncopied = copy_from_read_buf(tty, &b, &nr);
			uncopied += copy_from_read_buf(tty, &b, &nr);
			if (uncopied) {
				retval = -EFAULT;
				break;
			}
		}

		if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) {
			n_tty_set_room(tty);
			check_unthrottle(tty);
		}

		if (b - buf >= minimum)
			break;
		if (time)
			timeout = time;
	}
	mutex_unlock(&tty->atomic_read_lock);
	remove_wait_queue(&tty->read_wait, &wait);

	if (!waitqueue_active(&tty->read_wait))
		tty->minimum_to_wake = minimum;

	__set_current_state(TASK_RUNNING);
	size = b - buf;
	if (size) {
		retval = size;
		if (nr)
			clear_bit(TTY_PUSH, &tty->flags);
	} else if (test_and_clear_bit(TTY_PUSH, &tty->flags))
		goto do_it_again;

	n_tty_set_room(tty);
	
	if(tty->update_room_in_ldisc){
		spin_lock_irqsave(&tty->buf.lock, flags);
		head = tty->buf.head;
		if (head) {
		count = head->commit - head->read;
			if ((count || tty->buf.head != tty->buf.tail) && tty->receive_room && !work_busy(&tty->buf.work)){
				schedule_work(&tty->buf.work);
			}
		}
		spin_unlock_irqrestore(&tty->buf.lock, flags);
	}
	
	return retval;
}
Ejemplo n.º 4
0
static void do_catch_up(struct spk_synth *synth)
{
	int synth_full_val = 0;
	static u_char ch;
	static u_char last = '\0';
	unsigned long flags;
	unsigned long jiff_max;
	unsigned long timeout = msecs_to_jiffies(4000);
	DEFINE_WAIT(wait);
	struct var_t *jiffy_delta;
	struct var_t *delay_time;
	int jiffy_delta_val;
	int delay_time_val;

	jiffy_delta = spk_get_var(JIFFY);
	delay_time = spk_get_var(DELAY);
	spin_lock_irqsave(&speakup_info.spinlock, flags);
	jiffy_delta_val = jiffy_delta->u.n.value;
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);
	jiff_max = jiffies + jiffy_delta_val;

	while (!kthread_should_stop()) {
		/* if no ctl-a in 4, send data anyway */
		spin_lock_irqsave(&flush_lock, flags);
		while (is_flushing && timeout) {
			prepare_to_wait(&flush, &wait, TASK_INTERRUPTIBLE);
			spin_unlock_irqrestore(&flush_lock, flags);
			timeout = schedule_timeout(timeout);
			spin_lock_irqsave(&flush_lock, flags);
		}
		finish_wait(&flush, &wait);
		is_flushing = 0;
		spin_unlock_irqrestore(&flush_lock, flags);

		spin_lock_irqsave(&speakup_info.spinlock, flags);
		if (speakup_info.flushing) {
			speakup_info.flushing = 0;
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			synth->flush(synth);
			continue;
		}
		if (synth_buffer_empty()) {
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			break;
		}
		ch = synth_buffer_peek();
		set_current_state(TASK_INTERRUPTIBLE);
		delay_time_val = delay_time->u.n.value;
		synth_full_val = synth_full();
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		if (ch == '\n')
			ch = 0x0D;
		if (synth_full_val || !spk_serial_out(ch)) {
			schedule_timeout(msecs_to_jiffies(delay_time_val));
			continue;
		}
		set_current_state(TASK_RUNNING);
		spin_lock_irqsave(&speakup_info.spinlock, flags);
		synth_buffer_getc();
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		if (ch == '[')
			in_escape = 1;
		else if (ch == ']')
			in_escape = 0;
		else if (ch <= SPACE) {
			if (!in_escape && strchr(",.!?;:", last))
				spk_serial_out(PROCSPEECH);
			if (time_after_eq(jiffies, jiff_max)) {
				if (!in_escape)
					spk_serial_out(PROCSPEECH);
				spin_lock_irqsave(&speakup_info.spinlock,
						flags);
				jiffy_delta_val = jiffy_delta->u.n.value;
				delay_time_val = delay_time->u.n.value;
				spin_unlock_irqrestore(&speakup_info.spinlock,
						flags);
				schedule_timeout(msecs_to_jiffies
						 (delay_time_val));
				jiff_max = jiffies + jiffy_delta_val;
			}
		}
		last = ch;
	}
	if (!in_escape)
		spk_serial_out(PROCSPEECH);
}
Ejemplo n.º 5
0
static int
lnet_acceptor(void *arg)
{
	struct socket *newsock;
	int rc;
	__u32 magic;
	__u32 peer_ip;
	int peer_port;
	int secure = (int)((long_ptr_t)arg);

	LASSERT(lnet_acceptor_state.pta_sock == NULL);

	cfs_block_allsigs();

	rc = lnet_sock_listen(&lnet_acceptor_state.pta_sock, 0, accept_port,
			      accept_backlog);
	if (rc != 0) {
		if (rc == -EADDRINUSE)
			LCONSOLE_ERROR_MSG(0x122, "Can't start acceptor on port %d: port already in use\n",
					   accept_port);
		else
			LCONSOLE_ERROR_MSG(0x123, "Can't start acceptor on port %d: unexpected error %d\n",
					   accept_port, rc);

		lnet_acceptor_state.pta_sock = NULL;
	} else {
		LCONSOLE(0, "Accept %s, port %d\n", accept_type, accept_port);
	}

	/* set init status and unblock parent */
	lnet_acceptor_state.pta_shutdown = rc;
	complete(&lnet_acceptor_state.pta_signal);

	if (rc != 0)
		return rc;

	while (!lnet_acceptor_state.pta_shutdown) {

		rc = lnet_sock_accept(&newsock, lnet_acceptor_state.pta_sock);
		if (rc != 0) {
			if (rc != -EAGAIN) {
				CWARN("Accept error %d: pausing...\n", rc);
				set_current_state(TASK_UNINTERRUPTIBLE);
				schedule_timeout(cfs_time_seconds(1));
			}
			continue;
		}

		/* maybe the LNet acceptor thread has been waken */
		if (lnet_acceptor_state.pta_shutdown) {
			sock_release(newsock);
			break;
		}

		rc = lnet_sock_getaddr(newsock, 1, &peer_ip, &peer_port);
		if (rc != 0) {
			CERROR("Can't determine new connection's address\n");
			goto failed;
		}

		if (secure && peer_port > LNET_ACCEPTOR_MAX_RESERVED_PORT) {
			CERROR("Refusing connection from %pI4h: insecure port %d\n",
			       &peer_ip, peer_port);
			goto failed;
		}

		rc = lnet_sock_read(newsock, &magic, sizeof(magic),
				    accept_timeout);
		if (rc != 0) {
			CERROR("Error %d reading connection request from %pI4h\n",
				rc, &peer_ip);
			goto failed;
		}

		rc = lnet_accept(newsock, magic);
		if (rc != 0)
			goto failed;

		continue;

failed:
		sock_release(newsock);
	}

	sock_release(lnet_acceptor_state.pta_sock);
	lnet_acceptor_state.pta_sock = NULL;

	CDEBUG(D_NET, "Acceptor stopping\n");

	/* unblock lnet_acceptor_stop() */
	complete(&lnet_acceptor_state.pta_signal);
	return 0;
}
Ejemplo n.º 6
0
static int init_port(void)
{
	int i, nlow, nhigh;
	
	/* Reserve io region. */
#if defined(LIRC_ALLOW_MMAPPED_IO)
	/* Future MMAP-Developers: Attention!
	   For memory mapped I/O you *might* need to use ioremap() first,
	   for the NSLU2 it's done in boot code. */
	if(((iommap != 0)
	    && (request_mem_region(iommap, 8<<ioshift,
				   LIRC_DRIVER_NAME) == NULL))
	   || ((iommap == 0)
	       && (request_region(io, 8, LIRC_DRIVER_NAME) == NULL)))
#else
	if(request_region(io, 8, LIRC_DRIVER_NAME)==NULL)
#endif
	{
		printk(KERN_ERR  LIRC_DRIVER_NAME  
		       ": port %04x already in use\n", io);
		printk(KERN_WARNING LIRC_DRIVER_NAME  
		       ": use 'setserial /dev/ttySX uart none'\n");
		printk(KERN_WARNING LIRC_DRIVER_NAME  
		       ": or compile the serial port driver as module and\n");
		printk(KERN_WARNING LIRC_DRIVER_NAME  
		       ": make sure this module is loaded first\n");
		return(-EBUSY);
	}
	
	hardware_init_port();

	/* Initialize pulse/space widths */
	init_timing_params(duty_cycle, freq);

	/* If pin is high, then this must be an active low receiver. */
	if(sense==-1)
	{
		/* wait 1/2 sec for the power supply */
		
		set_current_state(TASK_INTERRUPTIBLE);
		schedule_timeout(HZ/2);
		
		/* probe 9 times every 0.04s, collect "votes" for
		   active high/low */
		nlow = 0;
		nhigh = 0;
		for(i = 0; i < 9; i ++)
		{
			if (sinp(UART_MSR) & hardware[type].signal_pin)
			{
				nlow++;
			}
			else
			{
				nhigh++;
			}
			schedule_timeout(HZ/25);
		}
		sense = (nlow >= nhigh ? 1 : 0);
		printk(KERN_INFO  LIRC_DRIVER_NAME  ": auto-detected active "
		       "%s receiver\n",sense ? "low":"high");
	}
	else
	{
		printk(KERN_INFO  LIRC_DRIVER_NAME  ": Manually using active "
		       "%s receiver\n",sense ? "low":"high");
	};
	
	return 0;
}
Ejemplo n.º 7
0
static int cifs_oplock_thread(void * dummyarg)
{
    struct oplock_q_entry * oplock_item;
    struct cifsTconInfo *pTcon;
    struct inode * inode;
    __u16  netfid;
    int rc;

    daemonize("cifsoplockd");
    allow_signal(SIGTERM);

    oplockThread = current;
    do {
        set_current_state(TASK_INTERRUPTIBLE);

        schedule_timeout(1*HZ);
        spin_lock(&GlobalMid_Lock);
        if(list_empty(&GlobalOplock_Q)) {
            spin_unlock(&GlobalMid_Lock);
            set_current_state(TASK_INTERRUPTIBLE);
            schedule_timeout(39*HZ);
        } else {
            oplock_item = list_entry(GlobalOplock_Q.next,
                                     struct oplock_q_entry, qhead);
            if(oplock_item) {
                cFYI(1,("found oplock item to write out"));
                pTcon = oplock_item->tcon;
                inode = oplock_item->pinode;
                netfid = oplock_item->netfid;
                spin_unlock(&GlobalMid_Lock);
                DeleteOplockQEntry(oplock_item);
                /* can not grab inode sem here since it would
                deadlock when oplock received on delete
                since vfs_unlink holds the i_sem across
                the call */
                /* down(&inode->i_sem);*/
                if (S_ISREG(inode->i_mode)) {
                    rc = filemap_fdatawrite(inode->i_mapping);
                    if(CIFS_I(inode)->clientCanCacheRead == 0) {
                        filemap_fdatawait(inode->i_mapping);
                        invalidate_remote_inode(inode);
                    }
                } else
                    rc = 0;
                /* up(&inode->i_sem);*/
                if (rc)
                    CIFS_I(inode)->write_behind_rc = rc;
                cFYI(1,("Oplock flush inode %p rc %d",inode,rc));

                /* releasing a stale oplock after recent reconnection
                of smb session using a now incorrect file
                handle is not a data integrity issue but do
                not bother sending an oplock release if session
                to server still is disconnected since oplock
                already released by the server in that case */
                if(pTcon->tidStatus != CifsNeedReconnect) {
                    rc = CIFSSMBLock(0, pTcon, netfid,
                                     0 /* len */ , 0 /* offset */, 0,
                                     0, LOCKING_ANDX_OPLOCK_RELEASE,
                                     0 /* wait flag */);
                    cFYI(1,("Oplock release rc = %d ",rc));
                }
            } else
                spin_unlock(&GlobalMid_Lock);
        }
    } while(!signal_pending(current));
    complete_and_exit (&cifs_oplock_exited, 0);
    oplockThread = NULL;
}
Ejemplo n.º 8
0
void
one_core_wq_wait( OneCore      *core,
                  OneWaitQueue *queue,
                  int          *timeout_ms )
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
     DEFINE_WAIT(wait);

     int timeout = 0;

     if (timeout_ms)
          timeout = *timeout_ms * HZ / 1000;


     D_MAGIC_ASSERT( core, OneCore );
     D_MAGIC_ASSERT( queue, OneWaitQueue );

     prepare_to_wait( &queue->queue, &wait, TASK_INTERRUPTIBLE );

     one_core_unlock( core );

     if (timeout_ms) {
          timeout = schedule_timeout(timeout);
          if (timeout) {
               timeout = timeout * 1000 / HZ;

               *timeout_ms = timeout ? timeout : 1;
          }
          else
               *timeout_ms = 0;
     }
     else
          schedule();

     one_core_lock( core );

     finish_wait( &queue->queue, &wait );
#else
     wait_queue_t wait;
     int          timeout = 0;

     if (timeout_ms)
          timeout = *timeout_ms * HZ / 1000;


     D_MAGIC_ASSERT( core, OneCore );
     D_MAGIC_ASSERT( queue, OneWaitQueue );

     init_waitqueue_entry(&wait, current);

     current->state = TASK_INTERRUPTIBLE;

     write_lock( &queue->queue.lock);
     __add_wait_queue( &queue->queue, &wait);
     write_unlock( &queue->queue.lock );

     one_core_unlock( core );

     if (timeout_ms) {
          timeout = schedule_timeout(timeout);
          if (timeout) {
               timeout = timeout * 1000 / HZ;

               *timeout_ms = timeout ? timeout : 1;
          }
          else
               *timeout_ms = 0;
     }
     else
          schedule();

     one_core_lock( core );

     write_lock( &queue->queue.lock );
     __remove_wait_queue( &queue->queue, &wait );
     write_unlock( &queue->queue.lock );
#endif
}
static void do_catch_up(struct spk_synth *synth)
{
	u_char ch;
	static u_char last;
	unsigned long flags;
	unsigned long jiff_max;
	struct var_t *jiffy_delta;
	struct var_t *delay_time;
	int jiffy_delta_val;
	int delay_time_val;

	jiffy_delta = spk_get_var(JIFFY);
	delay_time = spk_get_var(DELAY);
	spk_lock(flags);
	jiffy_delta_val = jiffy_delta->u.n.value;
	spk_unlock(flags);
	jiff_max = jiffies + jiffy_delta_val;

	while (!kthread_should_stop()) {
		spk_lock(flags);
		if (speakup_info.flushing) {
			speakup_info.flushing = 0;
			spk_unlock(flags);
			synth->flush(synth);
			continue;
		}
		if (synth_buffer_empty()) {
			spk_unlock(flags);
			break;
		}
		ch = synth_buffer_peek();
		set_current_state(TASK_INTERRUPTIBLE);
		delay_time_val = delay_time->u.n.value;
		spk_unlock(flags);
		if (ch == '\n')
			ch = 0x0D;
		if (dt_sendchar(ch)) {
			schedule_timeout(msecs_to_jiffies(delay_time_val));
			continue;
		}
		set_current_state(TASK_RUNNING);
		spk_lock(flags);
		synth_buffer_getc();
		spk_unlock(flags);
		if (ch == '[')
			in_escape = 1;
		else if (ch == ']')
			in_escape = 0;
		else if (ch <= SPACE) {
			if (!in_escape && strchr(",.!?;:", last))
				dt_sendchar(PROCSPEECH);
			if (jiffies >= jiff_max) {
				if (!in_escape)
					dt_sendchar(PROCSPEECH);
				spk_lock(flags);
				jiffy_delta_val = jiffy_delta->u.n.value;
				delay_time_val = delay_time->u.n.value;
				spk_unlock(flags);
				schedule_timeout(msecs_to_jiffies
						 (delay_time_val));
				jiff_max = jiffies + jiffy_delta_val;
			}
		}
		last = ch;
		ch = 0;
	}
	if (!in_escape)
		dt_sendchar(PROCSPEECH);
}
Ejemplo n.º 10
0
static ssize_t
scdrv_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos)
{
    int status;
    int len;
    unsigned long flags;
    struct subch_data_s *sd = (struct subch_data_s *) file->private_data;

    /* try to get control of the read buffer */
    if (down_trylock(&sd->sd_rbs)) {
        /* somebody else has it now;
         * if we're non-blocking, then exit...
         */
        if (file->f_flags & O_NONBLOCK) {
            return -EAGAIN;
        }
        /* ...or if we want to block, then do so here */
        if (down_interruptible(&sd->sd_rbs)) {
            /* something went wrong with wait */
            return -ERESTARTSYS;
        }
    }

    /* anything to read? */
    len = CHUNKSIZE;
    spin_lock_irqsave(&sd->sd_rlock, flags);
    status = read_status_check(sd, &len);

    /* if not, and we're blocking I/O, loop */
    while (status < 0) {
        DECLARE_WAITQUEUE(wait, current);

        if (file->f_flags & O_NONBLOCK) {
            spin_unlock_irqrestore(&sd->sd_rlock, flags);
            up(&sd->sd_rbs);
            return -EAGAIN;
        }

        len = CHUNKSIZE;
        set_current_state(TASK_INTERRUPTIBLE);
        add_wait_queue(&sd->sd_rq, &wait);
        spin_unlock_irqrestore(&sd->sd_rlock, flags);

        schedule_timeout(SCDRV_TIMEOUT);

        remove_wait_queue(&sd->sd_rq, &wait);
        if (signal_pending(current)) {
            /* wait was interrupted */
            up(&sd->sd_rbs);
            return -ERESTARTSYS;
        }

        spin_lock_irqsave(&sd->sd_rlock, flags);
        status = read_status_check(sd, &len);
    }
    spin_unlock_irqrestore(&sd->sd_rlock, flags);

    if (len > 0) {
        /* we read something in the last read_status_check(); copy
         * it out to user space
         */
        if (count < len) {
            pr_debug("%s: only accepting %d of %d bytes\n",
                     __func__, (int) count, len);
        }
        len = min((int) count, len);
        if (copy_to_user(buf, sd->sd_rb, len))
            len = -EFAULT;
    }

    /* release the read buffer and wake anyone who might be
     * waiting for it
     */
    up(&sd->sd_rbs);

    /* return the number of characters read in */
    return len;
}
Ejemplo n.º 11
0
static ssize_t
scdrv_write(struct file *file, const char __user *buf,
            size_t count, loff_t *f_pos)
{
    unsigned long flags;
    int status;
    struct subch_data_s *sd = (struct subch_data_s *) file->private_data;

    /* try to get control of the write buffer */
    if (down_trylock(&sd->sd_wbs)) {
        /* somebody else has it now;
         * if we're non-blocking, then exit...
         */
        if (file->f_flags & O_NONBLOCK) {
            return -EAGAIN;
        }
        /* ...or if we want to block, then do so here */
        if (down_interruptible(&sd->sd_wbs)) {
            /* something went wrong with wait */
            return -ERESTARTSYS;
        }
    }

    count = min((int) count, CHUNKSIZE);
    if (copy_from_user(sd->sd_wb, buf, count)) {
        up(&sd->sd_wbs);
        return -EFAULT;
    }

    /* try to send the buffer */
    spin_lock_irqsave(&sd->sd_wlock, flags);
    status = write_status_check(sd, count);

    /* if we failed, and we want to block, then loop */
    while (status <= 0) {
        DECLARE_WAITQUEUE(wait, current);

        if (file->f_flags & O_NONBLOCK) {
            spin_unlock(&sd->sd_wlock);
            up(&sd->sd_wbs);
            return -EAGAIN;
        }

        set_current_state(TASK_INTERRUPTIBLE);
        add_wait_queue(&sd->sd_wq, &wait);
        spin_unlock_irqrestore(&sd->sd_wlock, flags);

        schedule_timeout(SCDRV_TIMEOUT);

        remove_wait_queue(&sd->sd_wq, &wait);
        if (signal_pending(current)) {
            /* wait was interrupted */
            up(&sd->sd_wbs);
            return -ERESTARTSYS;
        }

        spin_lock_irqsave(&sd->sd_wlock, flags);
        status = write_status_check(sd, count);
    }
    spin_unlock_irqrestore(&sd->sd_wlock, flags);

    /* release the write buffer and wake anyone who's waiting for it */
    up(&sd->sd_wbs);

    /* return the number of characters accepted (should be the complete
     * "chunk" as requested)
     */
    if ((status >= 0) && (status < count)) {
        pr_debug("Didn't accept the full chunk; %d of %d\n",
                 status, (int) count);
    }
    return status;
}
static void do_catch_up(struct spk_synth *synth)
{
	u_char ch;
	int timeout;
	unsigned long flags;
	unsigned long jiff_max;
	struct var_t *jiffy_delta;
	struct var_t *delay_time;
	struct var_t *full_time;
	int delay_time_val;
	int full_time_val;
	int jiffy_delta_val;

	jiffy_delta = get_var(JIFFY);
	delay_time = get_var(DELAY);
	full_time = get_var(FULL);
spk_lock(flags);
	jiffy_delta_val = jiffy_delta->u.n.value;
	spk_unlock(flags);

	jiff_max = jiffies + jiffy_delta_val;
	while (!kthread_should_stop()) {
		spk_lock(flags);
		if (speakup_info.flushing) {
			speakup_info.flushing = 0;
			spk_unlock(flags);
			synth->flush(synth);
			continue;
		}
		if (synth_buffer_empty()) {
			spk_unlock(flags);
			break;
		}
		set_current_state(TASK_INTERRUPTIBLE);
		full_time_val = full_time->u.n.value;
		spk_unlock(flags);
		if (synth_full()) {
			schedule_timeout(msecs_to_jiffies(full_time_val));
			continue;
		}
		set_current_state(TASK_RUNNING);
		timeout = 1000;
		while (synth_writable())
			if (--timeout <= 0)
				break;
		if (timeout <= 0) {
			oops();
			break;
		}
		spk_lock(flags);
		ch = synth_buffer_getc();
		spk_unlock(flags);
		if (ch == '\n')
			ch = PROCSPEECH;
		outb_p(ch, synth_port);
		SWAIT;
		if ((jiffies >= jiff_max) && (ch == SPACE)) {
			timeout = 1000;
			while (synth_writable())
				if (--timeout <= 0)
					break;
			if (timeout <= 0) {
				oops();
				break;
			}
			outb_p(PROCSPEECH, synth_port);
			spk_lock(flags);
			jiffy_delta_val = jiffy_delta->u.n.value;
			delay_time_val = delay_time->u.n.value;
			spk_unlock(flags);
			schedule_timeout(msecs_to_jiffies(delay_time_val));
			jiff_max = jiffies+jiffy_delta_val;
		}
	}
	timeout = 1000;
	while (synth_writable())
		if (--timeout <= 0)
			break;
	if (timeout <= 0)
		oops();
	else
		outb_p(PROCSPEECH, synth_port);
}
Ejemplo n.º 13
0
static void do_catch_up(struct spk_synth *synth)
{
	u_char ch;
	unsigned long flags;
	unsigned long jiff_max;
	int timeout;
	int delay_time_val;
	int jiffy_delta_val;
	int full_time_val;
	struct var_t *delay_time;
	struct var_t *full_time;
	struct var_t *jiffy_delta;

	jiffy_delta = spk_get_var(JIFFY);
	delay_time = spk_get_var(DELAY);
	full_time = spk_get_var(FULL);

	spin_lock_irqsave(&speakup_info.spinlock, flags);
	jiffy_delta_val = jiffy_delta->u.n.value;
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);

	jiff_max = jiffies + jiffy_delta_val;
	while (!kthread_should_stop()) {
		spin_lock_irqsave(&speakup_info.spinlock, flags);
		if (speakup_info.flushing) {
			speakup_info.flushing = 0;
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			synth->flush(synth);
			continue;
		}
		if (synth_buffer_empty()) {
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			break;
		}
		set_current_state(TASK_INTERRUPTIBLE);
		full_time_val = full_time->u.n.value;
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		if (synth_full()) {
			schedule_timeout(msecs_to_jiffies(full_time_val));
			continue;
		}
		set_current_state(TASK_RUNNING);
		timeout = SPK_XMITR_TIMEOUT;
		while (synth_writable()) {
			if (!--timeout)
				break;
			udelay(1);
		}
		spin_lock_irqsave(&speakup_info.spinlock, flags);
		ch = synth_buffer_getc();
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		if (ch == '\n')
			ch = PROCSPEECH;
		outb_p(ch, speakup_info.port_tts);
		if (time_after_eq(jiffies, jiff_max) && ch == SPACE) {
			timeout = SPK_XMITR_TIMEOUT;
			while (synth_writable()) {
				if (!--timeout)
					break;
				udelay(1);
			}
			outb_p(PROCSPEECH, speakup_info.port_tts);
			spin_lock_irqsave(&speakup_info.spinlock, flags);
			jiffy_delta_val = jiffy_delta->u.n.value;
			delay_time_val = delay_time->u.n.value;
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			schedule_timeout(msecs_to_jiffies(delay_time_val));
			jiff_max = jiffies+jiffy_delta_val;
		}
	}
	timeout = SPK_XMITR_TIMEOUT;
	while (synth_writable()) {
		if (!--timeout)
			break;
		udelay(1);
	}
	outb_p(PROCSPEECH, speakup_info.port_tts);
}
Ejemplo n.º 14
0
static void ad1889_update_ptr(ad1889_dev_t *dev, int wake)
{
	ad1889_state_t *state;
	struct dmabuf *dmabuf;
	unsigned long hwptr;
	int diff;

	/* check ADC first */
	state = &dev->adc_state;
	dmabuf = &state->dmabuf;
	if (dmabuf->enable & ADC_RUNNING) {
		hwptr = ad1889_get_dma_addr(state);
		diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;

		dmabuf->hwptr = hwptr;
		dmabuf->total_bytes += diff;
		dmabuf->count += diff;
		if (dmabuf->count > dmabuf->dmasize)
			dmabuf->count = dmabuf->dmasize;

		if (dmabuf->mapped) {
			if (wake & dmabuf->count >= dmabuf->fragsize)
				wake_up(&dmabuf->wait);
		} else {
			if (wake & dmabuf->count > 0)
				wake_up(&dmabuf->wait);
		}
	}

	/* check DAC */
	state = &dev->wav_state;
	dmabuf = &state->dmabuf;
	if (dmabuf->enable & DAC_RUNNING) {
XXX

}
#endif

/************************* /dev/dsp interfaces ************************* */

static ssize_t ad1889_read(struct file *file, char __user *buffer, size_t count,
	loff_t *ppos)
{
	return 0;
}

static ssize_t ad1889_write(struct file *file, const char __user *buffer, size_t count,
	loff_t *ppos)
{
	ad1889_dev_t *dev = (ad1889_dev_t *)file->private_data;
	ad1889_state_t *state = &dev->state[AD_WAV_STATE];
	volatile struct dmabuf *dmabuf = &state->dmabuf;
	ssize_t ret = 0;
	DECLARE_WAITQUEUE(wait, current);

	down(&state->sem);
#if 0
	if (dmabuf->mapped) {
		ret = -ENXIO;
		goto err1;
	}
#endif
	if (!access_ok(VERIFY_READ, buffer, count)) {
		ret = -EFAULT;
		goto err1;
	}

	add_wait_queue(&state->dmabuf.wait, &wait);

	/* start filling dma buffer.... */
	while (count > 0) {
		long rem;
		long cnt = count;
		unsigned long flags;

		for (;;) {
			long used_bytes;
			long timeout;	/* max time for DMA in jiffies */

			/* buffer is full if wr catches up to rd */
			spin_lock_irqsave(&state->card->lock, flags);
			used_bytes = dmabuf->wr_ptr - dmabuf->rd_ptr;
			timeout = (dmabuf->dma_len * HZ) / dmabuf->rate;
			spin_unlock_irqrestore(&state->card->lock, flags);

			/* adjust for buffer wrap around */
			used_bytes = (used_bytes + DMA_SIZE) & (DMA_SIZE - 1);

			/* If at least one page unused */
			if (used_bytes < (DMA_SIZE - 0x1000))
				break;

			/* dma buffer full */

			if (file->f_flags & O_NONBLOCK) {
				ret = -EAGAIN;
				goto err2;
			}

			set_current_state(TASK_INTERRUPTIBLE);
			schedule_timeout(timeout + 1);
			if (signal_pending(current)) {
				ret = -ERESTARTSYS;
				goto err2;
			}
		}

		/* watch out for wrapping around static buffer */
		spin_lock_irqsave(&state->card->lock, flags);
		rem = DMA_SIZE - dmabuf->wr_ptr;
		if (cnt > rem)
			cnt = rem;

		rem = dmabuf->wr_ptr;

		/* update dma pointers */
		dmabuf->wr_ptr += cnt;
		dmabuf->wr_ptr &= DMA_SIZE - 1;	/* wrap ptr if necessary */
		spin_unlock_irqrestore(&state->card->lock, flags);

		/* transfer unwrapped chunk */
		if (copy_from_user(dmabuf->rawbuf + rem, buffer, cnt)) {
			ret = -EFAULT;
			goto err2;
		}

		DBG("Writing 0x%lx bytes to +0x%lx\n", cnt, rem);

		/* update counters */
		count -= cnt;
		buffer += cnt;
		ret += cnt;

		/* we have something to play - go play it! */
		ad1889_trigger_playback(dev);
	}

err2:
	remove_wait_queue(&state->dmabuf.wait, &wait);
err1:
	up(&state->sem);
	return ret;
}
Ejemplo n.º 15
0
static int
zpios_thread_main(void *data)
{
	thread_data_t *thr = (thread_data_t *)data;
	run_args_t *run_args = thr->run_args;
	zpios_time_t t;
	dmu_obj_t obj;
	__u64 offset;
	__u32 chunk_size;
	zpios_region_t *region;
	char *buf;
	unsigned int random_int;
	int chunk_noise = run_args->chunk_noise;
	int chunk_noise_tmp = 0;
	int thread_delay = run_args->thread_delay;
	int thread_delay_tmp = 0;
	int i, rc = 0;

	if (chunk_noise) {
		get_random_bytes(&random_int, sizeof (unsigned int));
		chunk_noise_tmp = (random_int % (chunk_noise * 2))-chunk_noise;
	}

	/*
	 * It's OK to vmem_alloc() this memory because it will be copied
	 * in to the slab and pointers to the slab copy will be setup in
	 * the bio when the IO is submitted.  This of course is not ideal
	 * since we want a zero-copy IO path if possible.  It would be nice
	 * to have direct access to those slab entries.
	 */
	chunk_size = run_args->chunk_size + chunk_noise_tmp;
	buf = (char *)vmem_alloc(chunk_size, KM_SLEEP);
	ASSERT(buf);

	/* Trivial data verification pattern for now. */
	if (run_args->flags & DMU_VERIFY)
		memset(buf, 'z', chunk_size);

	/* Write phase */
	mutex_enter(&thr->lock);
	thr->stats.wr_time.start = zpios_timespec_now();
	mutex_exit(&thr->lock);

	while (zpios_get_work_item(run_args, &obj, &offset,
	    &chunk_size, &region, DMU_WRITE)) {
		if (thread_delay) {
			get_random_bytes(&random_int, sizeof (unsigned int));
			thread_delay_tmp = random_int % thread_delay;
			set_current_state(TASK_UNINTERRUPTIBLE);
			schedule_timeout(thread_delay_tmp); /* In jiffies */
		}

		t.start = zpios_timespec_now();
		rc = zpios_dmu_write(run_args, obj.os, obj.obj,
		    offset, chunk_size, buf);
		t.stop  = zpios_timespec_now();
		t.delta = zpios_timespec_sub(t.stop, t.start);

		if (rc) {
			zpios_print(run_args->file, "IO error while doing "
			    "dmu_write(): %d\n", rc);
			break;
		}

		mutex_enter(&thr->lock);
		thr->stats.wr_data += chunk_size;
		thr->stats.wr_chunks++;
		thr->stats.wr_time.delta = zpios_timespec_add(
		    thr->stats.wr_time.delta, t.delta);
		mutex_exit(&thr->lock);

		mutex_enter(&region->lock);
		region->stats.wr_data += chunk_size;
		region->stats.wr_chunks++;
		region->stats.wr_time.delta = zpios_timespec_add(
		    region->stats.wr_time.delta, t.delta);

		/* First time region was accessed */
		if (region->init_offset == offset)
			region->stats.wr_time.start = t.start;

		mutex_exit(&region->lock);
	}

	mutex_enter(&run_args->lock_ctl);
	run_args->threads_done++;
	mutex_exit(&run_args->lock_ctl);

	mutex_enter(&thr->lock);
	thr->rc = rc;
	thr->stats.wr_time.stop = zpios_timespec_now();
	mutex_exit(&thr->lock);
	wake_up(&run_args->waitq);

	set_current_state(TASK_UNINTERRUPTIBLE);
	schedule();

	/* Check if we should exit */
	mutex_enter(&thr->lock);
	rc = thr->rc;
	mutex_exit(&thr->lock);
	if (rc)
		goto out;

	/* Read phase */
	mutex_enter(&thr->lock);
	thr->stats.rd_time.start = zpios_timespec_now();
	mutex_exit(&thr->lock);

	while (zpios_get_work_item(run_args, &obj, &offset,
	    &chunk_size, &region, DMU_READ)) {
		if (thread_delay) {
			get_random_bytes(&random_int, sizeof (unsigned int));
			thread_delay_tmp = random_int % thread_delay;
			set_current_state(TASK_UNINTERRUPTIBLE);
			schedule_timeout(thread_delay_tmp); /* In jiffies */
		}

		if (run_args->flags & DMU_VERIFY)
			memset(buf, 0, chunk_size);

		t.start = zpios_timespec_now();
		rc = zpios_dmu_read(run_args, obj.os, obj.obj,
		    offset, chunk_size, buf);
		t.stop  = zpios_timespec_now();
		t.delta = zpios_timespec_sub(t.stop, t.start);

		if (rc) {
			zpios_print(run_args->file, "IO error while doing "
			    "dmu_read(): %d\n", rc);
			break;
		}

		/* Trivial data verification, expensive! */
		if (run_args->flags & DMU_VERIFY) {
			for (i = 0; i < chunk_size; i++) {
				if (buf[i] != 'z') {
					zpios_print(run_args->file,
					    "IO verify error: %d/%d/%d\n",
					    (int)obj.obj, (int)offset,
					    (int)chunk_size);
					break;
				}
			}
		}

		mutex_enter(&thr->lock);
		thr->stats.rd_data += chunk_size;
		thr->stats.rd_chunks++;
		thr->stats.rd_time.delta = zpios_timespec_add(
		    thr->stats.rd_time.delta, t.delta);
		mutex_exit(&thr->lock);

		mutex_enter(&region->lock);
		region->stats.rd_data += chunk_size;
		region->stats.rd_chunks++;
		region->stats.rd_time.delta = zpios_timespec_add(
		    region->stats.rd_time.delta, t.delta);

		/* First time region was accessed */
		if (region->init_offset == offset)
			region->stats.rd_time.start = t.start;

		mutex_exit(&region->lock);
	}

	mutex_enter(&run_args->lock_ctl);
	run_args->threads_done++;
	mutex_exit(&run_args->lock_ctl);

	mutex_enter(&thr->lock);
	thr->rc = rc;
	thr->stats.rd_time.stop = zpios_timespec_now();
	mutex_exit(&thr->lock);
	wake_up(&run_args->waitq);

out:
	vmem_free(buf, chunk_size);
	do_exit(0);

	return (rc); /* Unreachable, due to do_exit() */
}
Ejemplo n.º 16
0
int vmw_fallback_wait(struct vmw_private *dev_priv,
		      bool lazy,
		      bool fifo_idle,
		      uint32_t sequence,
		      bool interruptible,
		      unsigned long timeout)
{
	struct vmw_fifo_state *fifo_state = &dev_priv->fifo;

	uint32_t count = 0;
	uint32_t signal_seq;
	int ret;
	unsigned long end_jiffies = jiffies + timeout;
	bool (*wait_condition)(struct vmw_private *, uint32_t);
	DEFINE_WAIT(__wait);

	wait_condition = (fifo_idle) ? &vmw_fifo_idle :
		&vmw_fence_signaled;

	/**
	 * Block command submission while waiting for idle.
	 */

	if (fifo_idle)
		down_read(&fifo_state->rwsem);
	signal_seq = atomic_read_unchecked(&dev_priv->fence_seq);
	ret = 0;

	for (;;) {
		prepare_to_wait(&dev_priv->fence_queue, &__wait,
				(interruptible) ?
				TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
		if (wait_condition(dev_priv, sequence))
			break;
		if (time_after_eq(jiffies, end_jiffies)) {
			DRM_ERROR("SVGA device lockup.\n");
			break;
		}
		if (lazy)
			schedule_timeout(1);
		else if ((++count & 0x0F) == 0) {
			/**
			 * FIXME: Use schedule_hr_timeout here for
			 * newer kernels and lower CPU utilization.
			 */

			__set_current_state(TASK_RUNNING);
			schedule();
			__set_current_state((interruptible) ?
					    TASK_INTERRUPTIBLE :
					    TASK_UNINTERRUPTIBLE);
		}
		if (interruptible && signal_pending(current)) {
			ret = -ERESTARTSYS;
			break;
		}
	}
	finish_wait(&dev_priv->fence_queue, &__wait);
	if (ret == 0 && fifo_idle) {
		__le32 __iomem *fifo_mem = dev_priv->mmio_virt;
		iowrite32(signal_seq, fifo_mem + SVGA_FIFO_FENCE);
	}
	wake_up_all(&dev_priv->fence_queue);
	if (fifo_idle)
		up_read(&fifo_state->rwsem);

	return ret;
}
Ejemplo n.º 17
0
static void bluecard_write_wakeup(bluecard_info_t *info)
{
	if (!info) {
		BT_ERR("Unknown device");
		return;
	}

	if (!test_bit(XMIT_SENDING_READY, &(info->tx_state)))
		return;

	if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
		set_bit(XMIT_WAKEUP, &(info->tx_state));
		return;
	}

	do {
		register unsigned int iobase = info->p_dev->resource[0]->start;
		register unsigned int offset;
		register unsigned char command;
		register unsigned long ready_bit;
		register struct sk_buff *skb;
		register int len;

		clear_bit(XMIT_WAKEUP, &(info->tx_state));

		if (!pcmcia_dev_present(info->p_dev))
			return;

		if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) {
			if (!test_bit(XMIT_BUF_TWO_READY, &(info->tx_state)))
				break;
			offset = 0x10;
			command = REG_COMMAND_TX_BUF_TWO;
			ready_bit = XMIT_BUF_TWO_READY;
		} else {
			if (!test_bit(XMIT_BUF_ONE_READY, &(info->tx_state)))
				break;
			offset = 0x00;
			command = REG_COMMAND_TX_BUF_ONE;
			ready_bit = XMIT_BUF_ONE_READY;
		}

		if (!(skb = skb_dequeue(&(info->txq))))
			break;

		if (bt_cb(skb)->pkt_type & 0x80) {
			/* Disable RTS */
			info->ctrl_reg |= REG_CONTROL_RTS;
			outb(info->ctrl_reg, iobase + REG_CONTROL);
		}

		/* Activate LED */
		bluecard_enable_activity_led(info);

		/* Send frame */
		len = bluecard_write(iobase, offset, skb->data, skb->len);

		/* Tell the FPGA to send the data */
		outb_p(command, iobase + REG_COMMAND);

		/* Mark the buffer as dirty */
		clear_bit(ready_bit, &(info->tx_state));

		if (bt_cb(skb)->pkt_type & 0x80) {
			DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
			DEFINE_WAIT(wait);

			unsigned char baud_reg;

			switch (bt_cb(skb)->pkt_type) {
			case PKT_BAUD_RATE_460800:
				baud_reg = REG_CONTROL_BAUD_RATE_460800;
				break;
			case PKT_BAUD_RATE_230400:
				baud_reg = REG_CONTROL_BAUD_RATE_230400;
				break;
			case PKT_BAUD_RATE_115200:
				baud_reg = REG_CONTROL_BAUD_RATE_115200;
				break;
			case PKT_BAUD_RATE_57600:
				/* Fall through... */
			default:
				baud_reg = REG_CONTROL_BAUD_RATE_57600;
				break;
			}

			/* Wait until the command reaches the baseband */
			prepare_to_wait(&wq, &wait, TASK_INTERRUPTIBLE);
			schedule_timeout(HZ/10);
			finish_wait(&wq, &wait);

			/* Set baud on baseband */
			info->ctrl_reg &= ~0x03;
			info->ctrl_reg |= baud_reg;
			outb(info->ctrl_reg, iobase + REG_CONTROL);

			/* Enable RTS */
			info->ctrl_reg &= ~REG_CONTROL_RTS;
			outb(info->ctrl_reg, iobase + REG_CONTROL);

			/* Wait before the next HCI packet can be send */
			prepare_to_wait(&wq, &wait, TASK_INTERRUPTIBLE);
			schedule_timeout(HZ);
			finish_wait(&wq, &wait);
		}

		if (len == skb->len) {
			kfree_skb(skb);
		} else {
			skb_pull(skb, len);
			skb_queue_head(&(info->txq), skb);
		}

		info->hdev->stat.byte_tx += len;

		/* Change buffer */
		change_bit(XMIT_BUFFER_NUMBER, &(info->tx_state));

	} while (test_bit(XMIT_WAKEUP, &(info->tx_state)));

	clear_bit(XMIT_SENDING, &(info->tx_state));
}
Ejemplo n.º 18
0
static int sdio_irq_thread(void *_host)
{
    struct mmc_host *host = _host;
    struct sched_param param = { .sched_priority = 1 };
    unsigned long period, idle_period;
    int ret;

    sched_setscheduler(current, SCHED_FIFO, &param);

    idle_period = msecs_to_jiffies(10);
    period = (host->caps & MMC_CAP_SDIO_IRQ) ?
             MAX_SCHEDULE_TIMEOUT : idle_period;

    pr_debug("%s: IRQ thread started (poll period = %lu jiffies)\n",
             mmc_hostname(host), period);

    do {
        ret = __mmc_claim_host(host, &host->sdio_irq_thread_abort);
        if (ret)
            break;
        ret = process_sdio_pending_irqs(host);
        host->sdio_irq_pending = false;
        mmc_release_host(host);

        if (ret < 0) {
            set_current_state(TASK_INTERRUPTIBLE);
            if (!kthread_should_stop())
                schedule_timeout(HZ);
            set_current_state(TASK_RUNNING);
        }

        if (!(host->caps & MMC_CAP_SDIO_IRQ)) {
            if (ret > 0)
                period /= 2;
            else {
                period++;
                if (period > idle_period)
                    period = idle_period;
            }
        }

        set_current_state(TASK_INTERRUPTIBLE);
        if (host->caps & MMC_CAP_SDIO_IRQ) {
            mmc_host_clk_hold(host);
            host->ops->enable_sdio_irq(host, 1);
            mmc_host_clk_release(host);
        }
        if (!kthread_should_stop())
            schedule_timeout(period);
        set_current_state(TASK_RUNNING);
    } while (!kthread_should_stop());

    if (host->caps & MMC_CAP_SDIO_IRQ) {
        mmc_host_clk_hold(host);
        host->ops->enable_sdio_irq(host, 0);
        mmc_host_clk_release(host);
    }

    pr_debug("%s: IRQ thread exiting with code %d\n",
             mmc_hostname(host), ret);

    return ret;
}

static int sdio_card_irq_get(struct mmc_card *card)
{
    struct mmc_host *host = card->host;

    WARN_ON(!host->claimed);

    if (!host->sdio_irqs++) {
        atomic_set(&host->sdio_irq_thread_abort, 0);
        host->sdio_irq_thread =
            kthread_run(sdio_irq_thread, host, "ksdioirqd/%s",
                        mmc_hostname(host));
        if (IS_ERR(host->sdio_irq_thread)) {
            int err = PTR_ERR(host->sdio_irq_thread);
            host->sdio_irqs--;
            return err;
        }
        if (host->caps & MMC_CAP_SDIO_IRQ) {
            mmc_host_clk_hold(host);
            host->ops->enable_sdio_irq(host, 1);
            mmc_host_clk_release(host);
        }
    }

    return 0;
}

static int sdio_card_irq_put(struct mmc_card *card)
{
    struct mmc_host *host = card->host;

    WARN_ON(!host->claimed);
    BUG_ON(host->sdio_irqs < 1);

    if (host->sdio_irqs == 1) {
        if (host->caps & MMC_CAP_SDIO_IRQ) {
            mmc_host_clk_hold(host);
            host->ops->enable_sdio_irq(host, 0);
            mmc_host_clk_release(host);
        }
    }

    if (!--host->sdio_irqs) {
        atomic_set(&host->sdio_irq_thread_abort, 1);
        kthread_stop(host->sdio_irq_thread);
    }

    return 0;
}

static void sdio_single_irq_set(struct mmc_card *card)
{
    struct sdio_func *func;
    int i;

    card->sdio_single_irq = NULL;
    if ((card->host->caps & MMC_CAP_SDIO_IRQ) &&
            card->host->sdio_irqs == 1)
        for (i = 0; i < card->sdio_funcs; i++) {
            func = card->sdio_func[i];
            if (func && func->irq_handler) {
                card->sdio_single_irq = func;
                break;
            }
        }
}

int sdio_claim_irq(struct sdio_func *func, sdio_irq_handler_t *handler)
{
    int ret;
    unsigned char reg;

    BUG_ON(!func);
    BUG_ON(!func->card);

    pr_debug("SDIO: Enabling IRQ for %s...\n", sdio_func_id(func));

    if (func->irq_handler) {
        pr_debug("SDIO: IRQ for %s already in use.\n", sdio_func_id(func));
        return -EBUSY;
    }

    ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, &reg);
    if (ret)
        return ret;

    reg |= 1 << func->num;

    reg |= 1;

    ret = mmc_io_rw_direct(func->card, 1, 0, SDIO_CCCR_IENx, reg, NULL);
    if (ret)
        return ret;

    func->irq_handler = handler;
    ret = sdio_card_irq_get(func->card);
    if (ret)
        func->irq_handler = NULL;
    sdio_single_irq_set(func->card);

    return ret;
}
static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter)
{
	u32 val = 0;
	int retval;

	DBG(1,"");

	isac_init(&adapter->isac); // FIXME is this okay now

	retval = -EBUSY;
	if (!request_region(adapter->io, 32, "fcpcipnp"))
		goto err;

	switch (adapter->type) {
	case AVM_FRITZ_PCIV2:
		retval = request_irq(adapter->irq, fcpci2_irq, SA_SHIRQ, 
				     "fcpcipnp", adapter);
		break;
	case AVM_FRITZ_PCI:
		retval = request_irq(adapter->irq, fcpci_irq, SA_SHIRQ,
				     "fcpcipnp", adapter);
		break;
	case AVM_FRITZ_PNP:
		retval = request_irq(adapter->irq, fcpci_irq, 0,
				     "fcpcipnp", adapter);
		break;
	}
	if (retval)
		goto err_region;

	switch (adapter->type) {
	case AVM_FRITZ_PCIV2:
	case AVM_FRITZ_PCI:
		val = inl(adapter->io);
		break;
	case AVM_FRITZ_PNP:
		val = inb(adapter->io);
		val |= inb(adapter->io + 1) << 8;
		break;
	}

	DBG(1, "stat %#x Class %X Rev %d",
	    val, val & 0xff, (val>>8) & 0xff);

	spin_lock_init(&adapter->hw_lock);
	adapter->isac.priv = adapter;
	switch (adapter->type) {
	case AVM_FRITZ_PCIV2:
		adapter->isac.read_isac       = &fcpci2_read_isac;;
		adapter->isac.write_isac      = &fcpci2_write_isac;
		adapter->isac.read_isac_fifo  = &fcpci2_read_isac_fifo;
		adapter->isac.write_isac_fifo = &fcpci2_write_isac_fifo;

		adapter->read_hdlc_status     = &fcpci2_read_hdlc_status;
		adapter->write_ctrl           = &fcpci2_write_ctrl;
		break;
	case AVM_FRITZ_PCI:
		adapter->isac.read_isac       = &fcpci_read_isac;;
		adapter->isac.write_isac      = &fcpci_write_isac;
		adapter->isac.read_isac_fifo  = &fcpci_read_isac_fifo;
		adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo;

		adapter->read_hdlc_status     = &fcpci_read_hdlc_status;
		adapter->write_ctrl           = &fcpci_write_ctrl;
		break;
	case AVM_FRITZ_PNP:
		adapter->isac.read_isac       = &fcpci_read_isac;;
		adapter->isac.write_isac      = &fcpci_write_isac;
		adapter->isac.read_isac_fifo  = &fcpci_read_isac_fifo;
		adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo;

		adapter->read_hdlc_status     = &fcpnp_read_hdlc_status;
		adapter->write_ctrl           = &fcpnp_write_ctrl;
		break;
	}

	// Reset
	outb(0, adapter->io + AVM_STATUS0);
	set_current_state(TASK_UNINTERRUPTIBLE);
	schedule_timeout(50 * HZ / 1000); // 50 msec
	outb(AVM_STATUS0_RESET, adapter->io + AVM_STATUS0);
	set_current_state(TASK_UNINTERRUPTIBLE);
	schedule_timeout(50 * HZ / 1000); // 50 msec
	outb(0, adapter->io + AVM_STATUS0);
	set_current_state(TASK_UNINTERRUPTIBLE);
	schedule_timeout(10 * HZ / 1000); // 10 msec

	switch (adapter->type) {
	case AVM_FRITZ_PCIV2:
		fcpci2_init(adapter);
		isacsx_setup(&adapter->isac);
		break;
	case AVM_FRITZ_PCI:
	case AVM_FRITZ_PNP:
		fcpci_init(adapter);
		isac_setup(&adapter->isac);
		break;
	}
	val = adapter->read_hdlc_status(adapter, 0);
	DBG(0x20, "HDLC A STA %x", val);
	val = adapter->read_hdlc_status(adapter, 1);
	DBG(0x20, "HDLC B STA %x", val);

	adapter->bcs[0].mode = -1;
	adapter->bcs[1].mode = -1;
	modehdlc(&adapter->bcs[0], L1_MODE_NULL);
	modehdlc(&adapter->bcs[1], L1_MODE_NULL);

	return 0;

 err_region:
	release_region(adapter->io, 32);
 err:
	return retval;
}
Ejemplo n.º 20
0
/* Delay */
static void delay_cycx(int sec)
{
	set_current_state(TASK_INTERRUPTIBLE);
	schedule_timeout(sec*HZ);
}
inline void cpm_uart_wait_until_send(struct uart_cpm_port *pinfo)
{
	set_current_state(TASK_UNINTERRUPTIBLE);
	schedule_timeout(pinfo->wait_closing);
}
Ejemplo n.º 22
0
int do_select(int n, fd_set_bits *fds, long *timeout)
{
	struct poll_wqueues table;
	poll_table *wait;
	int retval, i;
	long __timeout = *timeout;

 	spin_lock(&current->files->file_lock);
	retval = max_select_fd(n, fds);
	spin_unlock(&current->files->file_lock);

	if (retval < 0)
		return retval;
	n = retval;

	poll_initwait(&table);
	wait = &table.pt;
	if (!__timeout)
		wait = NULL;
	retval = 0;
	for (;;) {
		unsigned long *rinp, *routp, *rexp, *inp, *outp, *exp;

		set_current_state(TASK_INTERRUPTIBLE);

		inp = fds->in; outp = fds->out; exp = fds->ex;
		rinp = fds->res_in; routp = fds->res_out; rexp = fds->res_ex;

		for (i = 0; i < n; ++rinp, ++routp, ++rexp) {
			unsigned long in, out, ex, all_bits, bit = 1, mask, j;
			unsigned long res_in = 0, res_out = 0, res_ex = 0;
			struct file_operations *f_op = NULL;
			struct file *file = NULL;

			in = *inp++; out = *outp++; ex = *exp++;
			all_bits = in | out | ex;
			if (all_bits == 0) {
				i += __NFDBITS;
				continue;
			}

			for (j = 0; j < __NFDBITS; ++j, ++i, bit <<= 1) {
				if (i >= n)
					break;
				if (!(bit & all_bits))
					continue;
				file = fget(i);
				if (file) {
					f_op = file->f_op;
					mask = DEFAULT_POLLMASK;
					if (f_op && f_op->poll)
						mask = (*f_op->poll)(file, retval ? NULL : wait);
					fput(file);
					if ((mask & POLLIN_SET) && (in & bit)) {
						res_in |= bit;
						retval++;
					}
					if ((mask & POLLOUT_SET) && (out & bit)) {
						res_out |= bit;
						retval++;
					}
					if ((mask & POLLEX_SET) && (ex & bit)) {
						res_ex |= bit;
						retval++;
					}
				}
			}
			if (res_in)
				*rinp = res_in;
			if (res_out)
				*routp = res_out;
			if (res_ex)
				*rexp = res_ex;
		}
		wait = NULL;
		if (retval || !__timeout || signal_pending(current))
			break;
		if(table.error) {
			retval = table.error;
			break;
		}
		__timeout = schedule_timeout(__timeout);
	}
	__set_current_state(TASK_RUNNING);

	poll_freewait(&table);

	/*
	 * Up-to-date the caller timeout.
	 */
	*timeout = __timeout;
	return retval;
}
Ejemplo n.º 23
0
static void do_catch_up(struct spk_synth *synth)
{
	u_char ch;
	static u_char last = '\0';
	unsigned long flags;
	unsigned long jiff_max;
	struct var_t *jiffy_delta;
	struct var_t *delay_time;
	int jiffy_delta_val = 0;
	int delay_time_val = 0;

	jiffy_delta = spk_get_var(JIFFY);
	delay_time = spk_get_var(DELAY);

	spin_lock_irqsave(&speakup_info.spinlock, flags);
	jiffy_delta_val = jiffy_delta->u.n.value;
	spin_unlock_irqrestore(&speakup_info.spinlock, flags);
	jiff_max = jiffies + jiffy_delta_val;

	while (!kthread_should_stop()) {
		spin_lock_irqsave(&speakup_info.spinlock, flags);
		if (speakup_info.flushing) {
			speakup_info.flushing = 0;
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			synth->flush(synth);
			continue;
		}
		synth_buffer_skip_nonlatin1();
		if (synth_buffer_empty()) {
			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
			break;
		}
		ch = synth_buffer_peek();
		set_current_state(TASK_INTERRUPTIBLE);
		delay_time_val = delay_time->u.n.value;
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		if (ch == '\n')
			ch = 0x0D;
		if (synth_full() || !synth->io_ops->synth_out(synth, ch)) {
			schedule_timeout(msecs_to_jiffies(delay_time_val));
			continue;
		}
		set_current_state(TASK_RUNNING);
		spin_lock_irqsave(&speakup_info.spinlock, flags);
		synth_buffer_getc();
		spin_unlock_irqrestore(&speakup_info.spinlock, flags);
		if (ch == '[') {
			in_escape = 1;
		} else if (ch == ']') {
			in_escape = 0;
		} else if (ch <= SPACE) {
			if (!in_escape && strchr(",.!?;:", last))
				synth->io_ops->synth_out(synth, PROCSPEECH);
			if (time_after_eq(jiffies, jiff_max)) {
				if (!in_escape)
					synth->io_ops->synth_out(synth, PROCSPEECH);
				spin_lock_irqsave(&speakup_info.spinlock,
						  flags);
				jiffy_delta_val = jiffy_delta->u.n.value;
				delay_time_val = delay_time->u.n.value;
				spin_unlock_irqrestore(&speakup_info.spinlock,
						       flags);
				schedule_timeout(msecs_to_jiffies
						 (delay_time_val));
				jiff_max = jiffies + jiffy_delta_val;
			}
		}
		last = ch;
	}
	if (!in_escape)
		synth->io_ops->synth_out(synth, PROCSPEECH);
}
Ejemplo n.º 24
0
static ssize_t
write_rio(struct file *file, const char __user *buffer,
	  size_t count, loff_t * ppos)
{
	DEFINE_WAIT(wait);
	struct rio_usb_data *rio = &rio_instance;

	unsigned long copy_size;
	unsigned long bytes_written = 0;
	unsigned int partial;

	int result = 0;
	int maxretry;
	int errn = 0;
	int intr;

	intr = mutex_lock_interruptible(&(rio->lock));
	if (intr)
		return -EINTR;
        /* Sanity check to make sure rio is connected, powered, etc */
        if (rio->present == 0 || rio->rio_dev == NULL) {
		mutex_unlock(&(rio->lock));
		return -ENODEV;
	}



	do {
		unsigned long thistime;
		char *obuf = rio->obuf;

		thistime = copy_size =
		    (count >= OBUF_SIZE) ? OBUF_SIZE : count;
		if (copy_from_user(rio->obuf, buffer, copy_size)) {
			errn = -EFAULT;
			goto error;
		}
		maxretry = 5;
		while (thistime) {
			if (!rio->rio_dev) {
				errn = -ENODEV;
				goto error;
			}
			if (signal_pending(current)) {
				mutex_unlock(&(rio->lock));
				return bytes_written ? bytes_written : -EINTR;
			}

			result = usb_bulk_msg(rio->rio_dev,
					 usb_sndbulkpipe(rio->rio_dev, 2),
					 obuf, thistime, &partial, 5000);

			dbg("write stats: result:%d thistime:%lu partial:%u",
			     result, thistime, partial);

			if (result == -ETIMEDOUT) {	/* NAK - so hold for a while */
				if (!maxretry--) {
					errn = -ETIME;
					goto error;
				}
				prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
				schedule_timeout(NAK_TIMEOUT);
				finish_wait(&rio->wait_q, &wait);
				continue;
			} else if (!result && partial) {
				obuf += partial;
				thistime -= partial;
			} else
				break;
		};
		if (result) {
			err("Write Whoops - %x", result);
			errn = -EIO;
			goto error;
		}
		bytes_written += copy_size;
		count -= copy_size;
		buffer += copy_size;
	} while (count > 0);

	mutex_unlock(&(rio->lock));

	return bytes_written ? bytes_written : -EIO;

error:
	mutex_unlock(&(rio->lock));
	return errn;
}
Ejemplo n.º 25
0
/*
 * iterate through the VL servers in a cell until one of them admits knowing
 * about the volume in question
 */
static int afs_vlocation_access_vl_by_id(struct afs_vlocation *vl,
					 struct key *key,
					 afs_volid_t volid,
					 afs_voltype_t voltype,
					 struct afs_cache_vlocation *vldb)
{
	struct afs_cell *cell = vl->cell;
	struct in_addr addr;
	int count, ret;

	_enter("%s,%x,%d,", cell->name, volid, voltype);

	down_write(&vl->cell->vl_sem);
	ret = -ENOMEDIUM;
	for (count = cell->vl_naddrs; count > 0; count--) {
		addr = cell->vl_addrs[cell->vl_curr_svix];

		_debug("CellServ[%hu]: %08x", cell->vl_curr_svix, addr.s_addr);

		/* attempt to access the VL server */
		ret = afs_vl_get_entry_by_id(&addr, key, volid, voltype, vldb,
					     &afs_sync_call);
		switch (ret) {
		case 0:
			goto out;
		case -ENOMEM:
		case -ENONET:
		case -ENETUNREACH:
		case -EHOSTUNREACH:
		case -ECONNREFUSED:
			if (ret == -ENOMEM || ret == -ENONET)
				goto out;
			goto rotate;
		case -EBUSY:
			vl->upd_busy_cnt++;
			if (vl->upd_busy_cnt <= 3) {
				if (vl->upd_busy_cnt > 1) {
					/* second+ BUSY - sleep a little bit */
					set_current_state(TASK_UNINTERRUPTIBLE);
					schedule_timeout(1);
					__set_current_state(TASK_RUNNING);
				}
				continue;
			}
			break;
		case -ENOMEDIUM:
			vl->upd_rej_cnt++;
			goto rotate;
		default:
			ret = -EIO;
			goto rotate;
		}

		/* rotate the server records upon lookup failure */
	rotate:
		cell->vl_curr_svix++;
		cell->vl_curr_svix %= cell->vl_naddrs;
		vl->upd_busy_cnt = 0;
	}

out:
	if (ret < 0 && vl->upd_rej_cnt > 0) {
		printk(KERN_NOTICE "kAFS:"
		       " Active volume no longer valid '%s'\n",
		       vl->vldb.name);
		vl->valid = 0;
		ret = -ENOMEDIUM;
	}

	up_write(&vl->cell->vl_sem);
	_leave(" = %d", ret);
	return ret;
}
Ejemplo n.º 26
0
static ssize_t
read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
{
	DEFINE_WAIT(wait);
	struct rio_usb_data *rio = &rio_instance;
	ssize_t read_count;
	unsigned int partial;
	int this_read;
	int result;
	int maxretry = 10;
	char *ibuf;
	int intr;

	intr = mutex_lock_interruptible(&(rio->lock));
	if (intr)
		return -EINTR;
	/* Sanity check to make sure rio is connected, powered, etc */
        if (rio->present == 0 || rio->rio_dev == NULL) {
		mutex_unlock(&(rio->lock));
		return -ENODEV;
	}

	ibuf = rio->ibuf;

	read_count = 0;


	while (count > 0) {
		if (signal_pending(current)) {
			mutex_unlock(&(rio->lock));
			return read_count ? read_count : -EINTR;
		}
		if (!rio->rio_dev) {
			mutex_unlock(&(rio->lock));
			return -ENODEV;
		}
		this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;

		result = usb_bulk_msg(rio->rio_dev,
				      usb_rcvbulkpipe(rio->rio_dev, 1),
				      ibuf, this_read, &partial,
				      8000);

		dbg("read stats: result:%d this_read:%u partial:%u",
		       result, this_read, partial);

		if (partial) {
			count = this_read = partial;
		} else if (result == -ETIMEDOUT || result == 15) {	/* FIXME: 15 ??? */
			if (!maxretry--) {
				mutex_unlock(&(rio->lock));
				err("read_rio: maxretry timeout");
				return -ETIME;
			}
			prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE);
			schedule_timeout(NAK_TIMEOUT);
			finish_wait(&rio->wait_q, &wait);
			continue;
		} else if (result != -EREMOTEIO) {
			mutex_unlock(&(rio->lock));
			err("Read Whoops - result:%u partial:%u this_read:%u",
			     result, partial, this_read);
			return -EIO;
		} else {
			mutex_unlock(&(rio->lock));
			return (0);
		}

		if (this_read) {
			if (copy_to_user(buffer, ibuf, this_read)) {
				mutex_unlock(&(rio->lock));
				return -EFAULT;
			}
			count -= this_read;
			read_count += this_read;
			buffer += this_read;
		}
	}
	mutex_unlock(&(rio->lock));
	return read_count;
}
Ejemplo n.º 27
0
/* Main loop of the progression thread: keep eating from the buffer
 * and push to the serial port, waiting as needed
 *
 * For devices that have a "full" notification mecanism, the driver can
 * adapt the loop the way they prefer.
 */
void spk_do_catch_up(struct spk_synth *synth)
{
	u_char ch;
	unsigned long flags;
	unsigned long jiff_max;
	struct var_t *delay_time;
	struct var_t *full_time;
	struct var_t *jiffy_delta;
	int jiffy_delta_val;
	int delay_time_val;
	int full_time_val;

	jiffy_delta = spk_get_var(JIFFY);
	full_time = spk_get_var(FULL);
	delay_time = spk_get_var(DELAY);

	spk_lock(flags);
	jiffy_delta_val = jiffy_delta->u.n.value;
	spk_unlock(flags);

	jiff_max = jiffies + jiffy_delta_val;
	while (!kthread_should_stop()) {
		spk_lock(flags);
		if (speakup_info.flushing) {
			speakup_info.flushing = 0;
			spk_unlock(flags);
			synth->flush(synth);
			continue;
		}
		if (synth_buffer_empty()) {
			spk_unlock(flags);
			break;
		}
		ch = synth_buffer_peek();
		set_current_state(TASK_INTERRUPTIBLE);
		full_time_val = full_time->u.n.value;
		spk_unlock(flags);
		if (ch == '\n')
			ch = synth->procspeech;
		if (!spk_serial_out(ch)) {
			schedule_timeout(msecs_to_jiffies(full_time_val));
			continue;
		}
		if ((jiffies >= jiff_max) && (ch == SPACE)) {
			spk_lock(flags);
			jiffy_delta_val = jiffy_delta->u.n.value;
			delay_time_val = delay_time->u.n.value;
			full_time_val = full_time->u.n.value;
			spk_unlock(flags);
			if (spk_serial_out(synth->procspeech))
				schedule_timeout(
					msecs_to_jiffies(delay_time_val));
			else
				schedule_timeout(
					msecs_to_jiffies(full_time_val));
			jiff_max = jiffies + jiffy_delta_val;
		}
		set_current_state(TASK_RUNNING);
		spk_lock(flags);
		synth_buffer_getc();
		spk_unlock(flags);
	}
	spk_serial_out(synth->procspeech);
}
Ejemplo n.º 28
0
static void ide_config(dev_link_t *link)
{
    client_handle_t handle = link->handle;
    ide_info_t *info = link->priv;
    tuple_t tuple;
    struct {
	u_short		buf[128];
	cisparse_t	parse;
	config_info_t	conf;
	cistpl_cftable_entry_t dflt;
    } *stk = NULL;
    cistpl_cftable_entry_t *cfg;
    int i, pass, last_ret = 0, last_fn = 0, hd, is_kme = 0;
    unsigned long io_base, ctl_base;

    DEBUG(0, "ide_config(0x%p)\n", link);

    stk = kmalloc(sizeof(*stk), GFP_KERNEL);
    if (!stk) goto err_mem;
    memset(stk, 0, sizeof(*stk));
    cfg = &stk->parse.cftable_entry;

    tuple.TupleData = (cisdata_t *)&stk->buf;
    tuple.TupleOffset = 0;
    tuple.TupleDataMax = 255;
    tuple.Attributes = 0;
    tuple.DesiredTuple = CISTPL_CONFIG;
    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &stk->parse));
    link->conf.ConfigBase = stk->parse.config.base;
    link->conf.Present = stk->parse.config.rmask[0];

    tuple.DesiredTuple = CISTPL_MANFID;
    if (!pcmcia_get_first_tuple(handle, &tuple) &&
	!pcmcia_get_tuple_data(handle, &tuple) &&
	!pcmcia_parse_tuple(handle, &tuple, &stk->parse))
	is_kme = ((stk->parse.manfid.manf == MANFID_KME) &&
		  ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) ||
		   (stk->parse.manfid.card == PRODID_KME_KXLC005_B)));

    /* Configure card */
    link->state |= DEV_CONFIG;

    /* Not sure if this is right... look up the current Vcc */
    CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &stk->conf));
    link->conf.Vcc = stk->conf.Vcc;

    pass = io_base = ctl_base = 0;
    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
    tuple.Attributes = 0;
    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
    while (1) {
    	if (pcmcia_get_tuple_data(handle, &tuple) != 0) goto next_entry;
	if (pcmcia_parse_tuple(handle, &tuple, &stk->parse) != 0) goto next_entry;

	/* Check for matching Vcc, unless we're desperate */
	if (!pass) {
	    if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
		if (stk->conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
		    goto next_entry;
	    } else if (stk->dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
		if (stk->conf.Vcc != stk->dflt.vcc.param[CISTPL_POWER_VNOM] / 10000)
		    goto next_entry;
	    }
	}

	if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
	    link->conf.Vpp1 = link->conf.Vpp2 =
		cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
	else if (stk->dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
	    link->conf.Vpp1 = link->conf.Vpp2 =
		stk->dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;

	if ((cfg->io.nwin > 0) || (stk->dflt.io.nwin > 0)) {
	    cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &stk->dflt.io;
	    link->conf.ConfigIndex = cfg->index;
	    link->io.BasePort1 = io->win[0].base;
	    link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
	    if (!(io->flags & CISTPL_IO_16BIT))
		link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
	    if (io->nwin == 2) {
		link->io.NumPorts1 = 8;
		link->io.BasePort2 = io->win[1].base;
		link->io.NumPorts2 = (is_kme) ? 2 : 1;
		if (pcmcia_request_io(link->handle, &link->io) != 0)
			goto next_entry;
		io_base = link->io.BasePort1;
		ctl_base = link->io.BasePort2;
	    } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
		link->io.NumPorts1 = io->win[0].len;
		link->io.NumPorts2 = 0;
		if (pcmcia_request_io(link->handle, &link->io) != 0)
			goto next_entry;
		io_base = link->io.BasePort1;
		ctl_base = link->io.BasePort1 + 0x0e;
	    } else goto next_entry;
	    /* If we've got this far, we're done */
	    break;
	}

    next_entry:
	if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
	    memcpy(&stk->dflt, cfg, sizeof(stk->dflt));
	if (pass) {
	    CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
	} else if (pcmcia_get_next_tuple(handle, &tuple) != 0) {
	    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
	    memset(&stk->dflt, 0, sizeof(stk->dflt));
	    pass++;
	}
    }

    CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq));
    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));

    /* disable drive interrupts during IDE probe */
    outb(0x02, ctl_base);

    /* special setup for KXLC005 card */
    if (is_kme)
	outb(0x81, ctl_base+1);

    /* retry registration in case device is still spinning up */
    for (hd = -1, i = 0; i < 10; i++) {
	hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ);
	if (hd >= 0) break;
	if (link->io.NumPorts1 == 0x20) {
	    outb(0x02, ctl_base + 0x10);
	    hd = idecs_register(io_base + 0x10, ctl_base + 0x10,
				link->irq.AssignedIRQ);
	    if (hd >= 0) {
		io_base += 0x10;
		ctl_base += 0x10;
		break;
	    }
	}
	__set_current_state(TASK_UNINTERRUPTIBLE);
	schedule_timeout(HZ/10);
    }

    if (hd < 0) {
	printk(KERN_NOTICE "ide-cs: ide_register() at 0x%3lx & 0x%3lx"
	       ", irq %u failed\n", io_base, ctl_base,
	       link->irq.AssignedIRQ);
	goto failed;
    }

    info->ndev = 1;
    sprintf(info->node.dev_name, "hd%c", 'a' + (hd * 2));
    info->node.major = ide_major[hd];
    info->node.minor = 0;
    info->hd = hd;
    link->dev = &info->node;
    printk(KERN_INFO "ide-cs: %s: Vcc = %d.%d, Vpp = %d.%d\n",
	   info->node.dev_name, link->conf.Vcc / 10, link->conf.Vcc % 10,
	   link->conf.Vpp1 / 10, link->conf.Vpp1 % 10);

    link->state &= ~DEV_CONFIG_PENDING;
    kfree(stk);
    return;

err_mem:
    printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
    goto failed;

cs_failed:
    cs_error(link->handle, last_fn, last_ret);
failed:
    kfree(stk);
    ide_release(link);
    link->state &= ~DEV_CONFIG_PENDING;
} /* ide_config */
Ejemplo n.º 29
0
int netlink_unicast(struct sock *ssk, struct sk_buff *skb, u32 pid, int nonblock)
{
	struct sock *sk;
	int len = skb->len;
	int protocol = ssk->protocol;
	long timeo;
        DECLARE_WAITQUEUE(wait, current);

	timeo = sock_sndtimeo(ssk, nonblock);

retry:
	sk = netlink_lookup(protocol, pid);
	if (sk == NULL)
		goto no_dst;

	/* Don't bother queuing skb if kernel socket has no input function */
	if (sk->protinfo.af_netlink->pid == 0 &&
	    !sk->protinfo.af_netlink->data_ready)
		goto no_dst;

#ifdef NL_EMULATE_DEV
	if (sk->protinfo.af_netlink->handler) {
		skb_orphan(skb);
		len = sk->protinfo.af_netlink->handler(protocol, skb);
		sock_put(sk);
		return len;
	}
#endif

	if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf ||
	    test_bit(0, &sk->protinfo.af_netlink->state)) {
		if (!timeo) {
			if (ssk->protinfo.af_netlink->pid == 0)
				netlink_overrun(sk);
			sock_put(sk);
			kfree_skb(skb);
			return -EAGAIN;
		}

		__set_current_state(TASK_INTERRUPTIBLE);
		add_wait_queue(&sk->protinfo.af_netlink->wait, &wait);

		if ((atomic_read(&sk->rmem_alloc) > sk->rcvbuf ||
		    test_bit(0, &sk->protinfo.af_netlink->state)) &&
		    !sk->dead)
			timeo = schedule_timeout(timeo);

		__set_current_state(TASK_RUNNING);
		remove_wait_queue(&sk->protinfo.af_netlink->wait, &wait);
		sock_put(sk);

		if (signal_pending(current)) {
			kfree_skb(skb);
			return sock_intr_errno(timeo);
		}
		goto retry;
	}

	skb_orphan(skb);
	skb_set_owner_r(skb, sk);
	skb_queue_tail(&sk->receive_queue, skb);
	sk->data_ready(sk, len);
	sock_put(sk);
	return len;

no_dst:
	kfree_skb(skb);
	return -ECONNREFUSED;
}
Ejemplo n.º 30
0
/** 
 * @param interface 
 * @param id 
 * 
 * @returns 0 if all is OK
 *
 * @brief Load the driver
 *
 * This function detects the device and allocate the buffers for the device
 * and the video interface.
 */
static int usb_linect_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
	int err;

	int vendor_id;
	int product_id;
	int webcam_model;
	int tmpi, try, found;

	struct usb_linect *dev = NULL;
	struct usb_device *udev = interface_to_usbdev(interface);


	// Get USB VendorID and ProductID
	vendor_id = le16_to_cpu(udev->descriptor.idVendor);
	product_id = le16_to_cpu(udev->descriptor.idProduct);

	// Check if we can handle this device
	LNT_DEBUG("Probe function called with VendorID=%04X, ProductID=%04X and InterfaceNumber=%d\n",
			vendor_id, product_id, interface->cur_altsetting->desc.bInterfaceNumber);

	if (interface->cur_altsetting->desc.bInterfaceNumber > 0)
		return -ENODEV;

	// Detect device
	if (vendor_id == USB_MS_VENDOR_ID) {
		switch (product_id) {

			case USB_K1414_PRODUCT_ID:
				LNT_INFO("MS Kinect Model 1414 found.\n");
				webcam_model = KNT_K1414;
				break;
			case USB_K1414_MOTOR_PRODUCT_ID:
				// Motor
				LNT_DEBUG("Kinect Motor found.\n");
				tmpi = -1;
				found = 0; try = 10;
				while(1) {
					mutex_lock(&modlock_tmpmotor);
					if (tmp_motor_dev == NULL) {
						tmp_motor_dev = udev;
						tmp_motor_index = kindex++;
						LNT_DEBUG("Got number %d current %d.\n", tmp_motor_index, kindex);
						tmpi = tmp_motor_index;
						found = 1;
						mutex_unlock(&modlock_tmpmotor);
						break;
					}
					mutex_unlock(&modlock_tmpmotor);
					schedule_timeout(50);
					try--;
					if (try == 0) break;
				}
				
				if (!found) { LNT_INFO("Kinect unplugged. Please connect the Kinect power source.\n"); return -ENODEV;}
				
				dev = kzalloc(sizeof(struct usb_linect), GFP_KERNEL);

				if (dev == NULL) {
					LNT_ERROR("Out of memory !\n");
					return -ENOMEM;
				}
				dev->type = KNT_TYPE_MOTOR;
				dev->index = tmpi;
				dev->motor_udev = udev;
				
				// Proc
				linect_proc_create(dev);
				
				mutex_lock(&modlock_tmpmotor);
				nmotors++;
				mutex_unlock(&modlock_tmpmotor);
				
				LNT_DEBUG("Kinect Motor ready.\n");
				
				usb_set_intfdata(interface, dev);
				return 0;
				break;
			default:
				LNT_ERROR("usb_linect_probe failed ! Kinect product 0x%04X is not supported.\n",
						le16_to_cpu(udev->descriptor.idProduct));
				return -ENODEV;
		}
	}
	else
		return -ENODEV;

	// Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device
	dev = kzalloc(sizeof(struct usb_linect), GFP_KERNEL);
	
	
	if (dev == NULL) {
		LNT_ERROR("Out of memory !\n");
		return -ENOMEM;
	}
	
	dev->cam = kzalloc(sizeof(struct linect_cam), GFP_KERNEL);
	
	if (dev->cam == NULL) {
		LNT_ERROR("Out of memory !\n");
		return -ENOMEM;
	}

	// Init mutexes, spinlock, etc.
	sema_init(&dev->cam->mutex_rgb, 1);
	sema_init(&dev->cam->mutex_depth, 1);
	mutex_init(&dev->mutex_motor);
	mutex_init(&dev->cam->mutex_cam);
	mutex_init(&dev->cam->modlock_rgb);
	mutex_init(&dev->cam->modlock_depth);
	spin_lock_init(&dev->cam->spinlock_rgb);
	spin_lock_init(&dev->cam->spinlock_depth);
	init_waitqueue_head(&dev->cam->wait_rgb_frame);
	init_waitqueue_head(&dev->cam->wait_depth_frame);

	// Save pointers
	dev->cam->webcam_model = webcam_model;
	dev->cam->udev = udev;
	dev->cam->interface = interface;

	// Read the product release 
	dev->cam->release = le16_to_cpu(udev->descriptor.bcdDevice);
	LNT_INFO("Release: %04x\n", dev->cam->release);

	// Constructor
	dev->cam->nbuffers = 2;
	dev->cam->len_per_image = PAGE_ALIGN((640 * 480 * 4));
	
	dev->cam->nbuffers_depth = 2;
	dev->cam->len_per_image_depth = PAGE_ALIGN((640 * 480 * 4));
	
	// Get Motor
	while(1) {
		mutex_lock(&modlock_tmpmotor);
		if (tmp_motor_dev != NULL) {
			dev->motor_udev = tmp_motor_dev;
			LNT_DEBUG("Got Kinect motor ref to dev!\n");
			tmp_motor_dev = NULL;
			dev->index = tmp_motor_index;
			tmp_motor_index = -1;
			mutex_unlock(&modlock_tmpmotor);
			break;
		}
		mutex_unlock(&modlock_tmpmotor);
	}
	
	// Params
	dev->freemotor = freemotor ? 1 : 0;
	dev->freeled = freeled ? 1 : 0;
	dev->cam->startupinit = startupinit ? 1 : 0;
	
	dev->type = KNT_TYPE_CAM;
	
	// Led
	if (!dev->freeled)
		linect_motor_set_led(dev, LED_GREEN);
	
	// Reset motor
	if (!dev->freemotor)
		linect_motor_set_tilt_degs(dev, 0);

	// TODO: Remove V4L2 deps and replace by some other video output mechanism...
	// V4L2 !!
/*
	// Initialize the video device
	dev->cam->vdev = video_device_alloc();
	dev->cam->depth_vdev = video_device_alloc();

	if (!dev->cam->vdev) {
		kfree(dev);
		return -ENOMEM;
	}
	
	if (!dev->cam->depth_vdev) {
		kfree(dev);
		return -ENOMEM;
	}*/

	// Initialize the camera
	linect_cam_init(dev);
	
/*	// Register the video device
	err = v4l_linect_register_rgb_video_device(dev);

	if (err) {
		kfree(dev);
		return err;
	}
	
	err = v4l_linect_register_depth_video_device(dev);

	if (err) {
		kfree(dev);
		return err;
	}*/

	// Save our data pointer in this interface device
	usb_set_intfdata(interface, dev);

	// Default settings video device
	usb_linect_default_settings(dev);

	return 0;
}