示例#1
0
void
omap_clock_enable(DEV_OMAP* dev, clk_enable_t clk_cfg)
{
	int enable_rc = 0;
	int functional_rc = 0;

	/* Our idle state can be changed by the ISR so we must use a spinlock */
	InterruptLock(&dev->idle_spinlock);

	/* Only enable clocks if they aren't enabled already */
	if (dev->idle == 0) {
		goto done;
	}

	if (dev->clkctrl_base) {
		/* Enable the clock */
		out32(dev->clkctrl_base, OMAP_CLKCTRL_MODMODE_ENABLE);

		/* Wait for the module mode to have been written */
		enable_rc = poll_for_condition(dev->clkctrl_base, OMAP_CLKCTRL_MODMODE_MASK, OMAP_CLKCTRL_MODMODE_ENABLE);

		/* Wait for the module idle status to report "fully functional" */
		functional_rc = poll_for_condition(dev->clkctrl_base, OMAP_CLKCTRL_IDLEST_MASK, OMAP_CLKCTRL_IDLEST_FUNCTIONAL);
        
		/* Re-configure clock if specified otherwise simply skip it */
		if (clk_cfg != clk_enable_skip) {

			/* Set the idle mode to smart idle with wake up */
			set_port(dev->port[OMAP_UART_SYSC], OMAP_UART_SYSC_IDLEMODE_MASK, clk_cfg);	
        }

		/* Enable the CTS wakeup */
		write_omap(dev->port[OMAP_UART_WER], OMAP_UART_WER_CTS_ENABLE);

		/* Indicate clocks are enabled */
		dev->idle = 0;
	}

done:
#ifdef WINBT
	/* clear CTS debounce timer and OHW_PAGED flag */
	if (dev->tty.un.s.spare_tmr > 0) {
		dev->tty.un.s.spare_tmr = 0;
		if (dev->tty.flags & OHW_PAGED)
			atomic_clr (&dev->tty.flags, OHW_PAGED);
	}
#endif
	omap_uart_ctx_restore(dev);
	InterruptUnlock(&dev->idle_spinlock);

	/* Don't slog while interrupts are disabled - otherwise slogf() will re-enable interrupts */
	if (enable_rc) {
		slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "%s: Failed to set module mode to 'enabled'", __FUNCTION__);
	}

	if (functional_rc) {
		slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "%s: Module failed to report 'fully functional'", __FUNCTION__);
	}
}
void setVolume(int level)
{
    int volume;
    snd_mixer_t *mixer_handle;

    if (snd_mixer_open (&mixer_handle, card, device) < 0) {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to open mixer\n");
        return;
    }

    snd_mixer_group_read(mixer_handle, &group);

    volume = (float)(group.max - group.min) * ( level / 100.0) + group.min;

    if (group.channels & SND_MIXER_CHN_MASK_FRONT_LEFT)
        group.volume.names.front_left = volume;
    if (group.channels & SND_MIXER_CHN_MASK_REAR_LEFT)
        group.volume.names.rear_left = volume;
    if (group.channels & SND_MIXER_CHN_MASK_FRONT_CENTER)
        group.volume.names.front_center = volume;
    if (group.channels & SND_MIXER_CHN_MASK_FRONT_RIGHT)
        group.volume.names.front_right = volume;
    if (group.channels & SND_MIXER_CHN_MASK_REAR_RIGHT)
        group.volume.names.rear_right = volume;
    if (group.channels & SND_MIXER_CHN_MASK_WOOFER)
        group.volume.names.woofer = volume;
    snd_mixer_group_write(mixer_handle, &group);

    snd_mixer_close (mixer_handle);
}
示例#3
0
文件: dumper.c 项目: vocho/openqnx
void slog_tid( procfs_status *status, const char *path )
{
	switch (status->why) {
	case _DEBUG_WHY_SIGNALLED:
	case _DEBUG_WHY_FAULTED:
		slogf( _SLOG_SETCODE( _SLOGC_DUMPER, 0 ), _SLOG_INFO,
			"run fault pid %d tid %d signal %d code %d ip %#llx %s", 
				(int)status->pid, (int)status->tid, (int)status->info.si_signo, (int)status->info.si_code, (uint64_t)status->ip, path ?:"" );
		break;
	default:
		slogf( _SLOG_SETCODE( _SLOGC_DUMPER, 0 ), _SLOG_INFO,
			"run fault pid %d tid %d why %d what %d ip %#llx %s", 
				(int)status->pid, (int)status->tid, (int)status->why, (int)status->what, (uint64_t)status->ip, path ?:"" );
		break;
	}
}
示例#4
0
static void 
termination_hndlr(int sig_num)
{
        char * pMsgTxt = "Hit with signal: %d, shutting down\n";
        if(verbosity)
            fprintf(stderr, pMsgTxt, sig_num);
	slogf(_SLOG_SETCODE(_SLOGC_INPUT, 0), _SLOG_ERROR, pMsgTxt, sig_num);
   
        input_shutdown();
}
示例#5
0
int
omap_clock_toggle_init(DEV_OMAP* dev)
{
	if (OMAP_UART1_PHYSBASE == dev->physbase) {
		dev->clkctrl_phys = CM_L4PER_UART1_CLKCTRL;
	} else if (OMAP_UART2_PHYSBASE == dev->physbase) {
		dev->clkctrl_phys = CM_L4PER_UART2_CLKCTRL;
	} else if (OMAP_UART3_PHYSBASE == dev->physbase) {
		dev->clkctrl_phys = CM_L4PER_UART3_CLKCTRL;
	} else if (OMAP_UART4_PHYSBASE == dev->physbase) {
		dev->clkctrl_phys = CM_L4PER_UART4_CLKCTRL;
	} else if (OMAP5_UART5_PHYSBASE == dev->physbase) {
                dev->clkctrl_phys = CM_L4PER_UART5_CLKCTRL;
        } else if (OMAP5_UART6_PHYSBASE == dev->physbase) {
                dev->clkctrl_phys = CM_L4PER_UART6_CLKCTRL;
        } else {
		dev->clkctrl_phys = 0;
		dev->clkctrl_base = 0;
		slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "%s: Unrecognized physical address, clock toggling not enabled", __FUNCTION__);
		return -1;
	}

	if (dev->clkctrl_phys) {
		dev->clkctrl_base = mmap_device_io(4, dev->clkctrl_phys);
		if (dev->clkctrl_base == (uintptr_t)MAP_FAILED) {
			slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "%s: mmap_device_io clkctrl_base: %s", __FUNCTION__, strerror(errno));
			return -1;
		}
	}

	/* Indicate clocks are disabled by default */
	dev->idle = 1;
	
	/* oband notification set to off */
	dev->signal_oband_notification = 0;

	/* initialize UART context */
	omap_uart_ctx_init(dev);

	return 0;
}
示例#6
0
/* Comment    : Must be called before any other devi_usb... function                */
void devi_usb_init()
{
   LIST_INIT(&modList);
   pGlbConnection = NULL;
   
   if(EOK != pthread_mutex_init(&mod_mutex, NULL))
     {
     char * pMsgTxt = "Error: USB stack initialization error. Driver is terminating\n";
     fprintf(stderr, pMsgTxt);
     slogf(_SLOG_SETCODE(_SLOGC_INPUT, 0), _SLOG_ERROR, pMsgTxt);
     exit(-1);
     }
}
示例#7
0
void
omap_clock_disable(DEV_OMAP* dev)
{
	int rc = 0;

	/* Our idle state can be changed by the ISR so we must use a spinlock */
	InterruptLock(&dev->idle_spinlock);

	/* Only disable clocks if needed */
	if (dev->idle == 1) {
		goto done;
	}
	
	if (dev->clkctrl_base) {

		/* Indicate clocks are disabled */
		dev->idle = 1;

		/* Save UART context */
		omap_uart_ctx_save(dev);

		/* Set the idle mode to smart idle with wake up */
		write_omap(dev->port[OMAP_UART_SYSC], 	OMAP_UART_SYSC_IDLEMODE_SMARTWAKEUP |
												OMAP_UART_SYSC_ENAWAKEUP_ENABLE |
												OMAP_UART_SYSC_AUTOIDLE_ENABLE);

		/* Enable the wakeup event */
		set_port(dev->port[OMAP_UART_SCR], OMAP_SCR_WAKEUPEN, OMAP_SCR_WAKEUPEN);

		/* Disable the clock */
		out32(dev->clkctrl_base, OMAP_CLKCTRL_MODMODE_DISABLE);

		/* Wait for the module mode to have been written */
		rc = poll_for_condition(dev->clkctrl_base, OMAP_CLKCTRL_MODMODE_MASK, OMAP_CLKCTRL_MODMODE_DISABLE);

	}

done:
	InterruptUnlock(&dev->idle_spinlock);

	/* Don't slog while interrupts are disabled - otherwise slogf() will re-enable interrupts */
	if (rc) {
		slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "%s: Failed to set module mode to 'disabled'", __FUNCTION__);
	}
}
示例#8
0
/*              devices ( see devi_register_hid_client)                             */
int devi_usb_server_connect(char * serv_path_name)
{
   int rc = EOK;
   usbd_funcs_t		  funcs = { _USBDI_NFUNCS, insertion, removal, NULL };
   usbd_device_ident_t	  interest = { USBD_CONNECT_WILDCARD, USBD_CONNECT_WILDCARD, USBD_CONNECT_WILDCARD, USBD_CONNECT_WILDCARD, USBD_CONNECT_WILDCARD };
   usbd_connect_parm_t	  parm = { NULL, USB_VERSION, USBD_VERSION, 0, 0, NULL, 0, &interest, &funcs, USBD_CONNECT_WAIT };
   
  
   parm.path = serv_path_name;
   
   if(EOK != ( rc = usbd_connect( &parm, &pGlbConnection ) ) )
     {
     char * pMsgTxt = "Error: cannot connect to USB server (error code = %d).\nDriver is terminating\n";
     fprintf(stderr, pMsgTxt, rc);
     slogf(_SLOG_SETCODE(_SLOGC_INPUT, 0), _SLOG_ERROR, pMsgTxt, rc);
     exit(-2);
     }

   return EOK;
}
示例#9
0
static int 
remove_ocb(devi_attr_t *attr, RESMGR_OCB_T *ocb)
{
	struct _ocb_list *op;
	
	for (op = attr->ocb_list; op; op = op->next) {
                if (op->ocb == ocb)
                        break;
        }

        if (op == NULL) {
                char * pMsgTxt = "Error: nable to remove ocb from list, not found\n";
                fprintf(stderr, pMsgTxt);
                slogf(_SLOG_SETCODE(_SLOGC_INPUT, 0), _SLOG_ERROR, pMsgTxt);
                return (-1);
        }
        
        /* If removing first one */

        if (op->prev == NULL)  {

                if (op->next) {
                        attr->ocb_list = op->next;
                        op->next->prev = NULL;
                }
                else {
                        attr->ocb_list = NULL;
                }
        }
        else {
                if (op->next) {
                        op->prev->next = op->next;
                        op->next->prev = op->prev;
                }
                else 
                        op->prev->next = NULL;
        }
        return (0);
}
示例#10
0
int 
begin(int argc, char *argv[])
{
        int                   	i, j;
	uint32_t		ph_flags = 0;
        thread_pool_attr_t	tp_attr;
	static void 		*tpp;
        dispatch_t              *dpp;

        dpp = dispatch_create();
        if (dpp == NULL) {
               char * pMsgTxt = "Error: cannot create dispatch interface\n";
               fprintf(stderr, pMsgTxt);
               slogf(_SLOG_SETCODE(_SLOGC_INPUT, 0), _SLOG_ERROR, pMsgTxt);
                return (EXIT_FAILURE);
        }
        devi_set_dispatch_handle(dpp);
        /* set up the module table */
        if (modules != NULL) {

                for (i = 0; i < MODULE_TABLE_SIZE && ModuleTable[i] != NULL; 
		     i++)
                        ;
                /* add extra modules to end of ModuleTable */
                
                for (j = 0; j < (MODULE_TABLE_SIZE - i) && modules[j] != NULL; 
		     j++, i++) 
                        ModuleTable[i] = modules[j];
        }
        
        if(ThreadCtl(_NTO_TCTL_IO, 0) == -1) {
                errno_print("ThreadCtl");
                return (EXIT_FAILURE);
        }
        // Call global callback if it was specified        
        if(commonCallbacks.pre_init && commonCallbacks.pre_init())
		return (EXIT_FAILURE);
        if (options(argc, argv, &ph_flags, &OptFlags) < 0)
		return (EXIT_FAILURE);
        // Call global callback if it was specified        
        if(commonCallbacks.post_init && commonCallbacks.post_init())
		return (EXIT_FAILURE);
        sig_install(signal_table, termination_hndlr);

	if (procmgr_daemon(0, PROCMGR_DAEMON_NODEVNULL | 
			   PROCMGR_DAEMON_NOCLOSE) < 0) {
		errno_print("procmgr_daemon");
		return (EXIT_FAILURE);
	}


        if (!(OptFlags & OPT_NO_PHOTON))  {
                if (start_photon_interface(ph_flags) < 0) {
                        errno_print("unable to start photon interface");
                        return (EXIT_FAILURE);
                }
        }

	memset(&tp_attr, 0, sizeof(tp_attr));
        tp_attr.handle = devi_get_dispatch_handle();
        tp_attr.context_alloc = dispatch_context_alloc;
        tp_attr.block_func = dispatch_block;
        tp_attr.handler_func = dispatch_handler;
        tp_attr.context_free = dispatch_context_free;
    /* We'd rather not to use thread pool for device driver - it could 
       cause desynchronizing and data losing                       */
	tp_attr.lo_water  = 1;   /* min amount threads waiting blocked */
	tp_attr.hi_water  = 1;   /* max amount threads waiting blocked */
	tp_attr.increment = 1;  
	tp_attr.maximum   = 1;    

	tpp = thread_pool_create(&tp_attr, POOL_FLAG_USE_SELF);
	if (tpp == NULL) {
                errno_print("thread_pool_create");
                return (EXIT_FAILURE);
        }

	thread_pool_start(tpp);

        return (EOK);
}
示例#11
0
/*
 * Return -1
 *     This prp can never match the criteria
 * Return 0
 *     This prp does not currently match the criteria
 * Return WNOHANG 
 *     An error with wap, reply was done (i.e. a thread unblocked)
 * Return non-zero W????? 
 *     This prp matched and a reply was done (i.e. a thread unblocked)
 */
int procmgr_wait_check(PROCESS *prp, PROCESS *parent, struct wait_entry *wap, int match) {
	struct _msg_info		info;

	/*
	 * Check if this prp matched the requested group
	 */
	switch(wap->idtype) {
	case P_ALL:
		break;

	case P_PID:
		if(prp->pid != wap->id) {
			return -1;
		}
		break;

	case P_PGID:
		if(prp->pgrp != wap->id) {
			return -1;
		}
		break;

	default:
		MsgError(wap->rcvid, EINVAL);
		return WNOHANG;
	}

	if(match) {
		/*
		 * Check for match, if parent is ignoring SIGCHLD, are we the last child?
		 */
		match &= wap->options;
		if(wap->idtype == P_ALL && (prp->sibling || parent->child != prp) &&
				sigismember(&parent->sig_ignore, SIGCHLD)) {
			match &= ~WEXITED;
		}
		/*
		 * Have we already responded with exit code?
		 */
		if(!(prp->flags & _NTO_PF_WAITINFO)) {
			match &= ~WEXITED;
		}
	} else {
		/*
		 * Check if the requested prp currently matches any options
		 */
		if((wap->options & WTRAPPED) && (prp->flags & (_NTO_PF_DEBUG_STOPPED | _NTO_PF_PTRACED)) ==
				(_NTO_PF_DEBUG_STOPPED | _NTO_PF_PTRACED)) {
			match = WTRAPPED;
		} else if((wap->options & WEXITED) && (prp->flags & _NTO_PF_WAITINFO)) {
			match = WEXITED;
		} else if((wap->options & WCONTINUED) && (prp->flags & _NTO_PF_CONTINUED)) {
			match = WCONTINUED;
		} else if((wap->options & WUNTRACED) && (prp->flags & _NTO_PF_STOPPED) &&
				prp->siginfo.si_signo != 0) {
			match = WUNTRACED;
		}
	}

	/*
	 * If no options matched, check if it could ever match options
	 */
	if(match == 0) {
		int				options = wap->options;
        
		if(prp->flags & (_NTO_PF_ZOMBIE | _NTO_PF_TERMING)) {
			options &= ~(WUNTRACED|WTRAPPED|WCONTINUED);
		}
		if((prp->flags & (_NTO_PF_ZOMBIE | _NTO_PF_WAITINFO)) == _NTO_PF_ZOMBIE) {
			options &= ~WEXITED;
		}
		if((prp->flags & _NTO_PF_NOZOMBIE) || sigismember(&parent->sig_ignore, SIGCHLD)) {
			options &= ~WEXITED;
		}
		if(prp->flags & _NTO_PF_WAITDONE) {
			options &= ~WEXITED;
		}
		if(!(prp->flags & _NTO_PF_PTRACED)) {
			options &= ~WTRAPPED;
		}
		if((options & (WEXITED|WUNTRACED|WTRAPPED|WCONTINUED)) == 0) {
			return -1;
		}
		return 0;
	}

	/*
	 * Unblock the waiting thread...
	 */
	
	if(MsgInfo(wap->rcvid, &info) != -1) {
		siginfo_t	siginfo;

		// unbind and unblock if rcvid is still around
		if((!parent->wap) || ((parent->wap == wap) && (parent->wap->next == NULL))) {
			(void)_resmgr_unbind(&info);
		}
		siginfo = prp->siginfo;
		if(siginfo.si_signo != SIGCHLD) {
			if(prp->flags & _NTO_PF_COREDUMP) {
				siginfo.si_code = CLD_DUMPED;
			} else {
				siginfo.si_code = CLD_KILLED;
			}
			siginfo.si_status = siginfo.si_signo;
			siginfo.si_pid = prp->pid;
			siginfo.si_signo = SIGCHLD;
		}
		if(info.flags & _NTO_MI_ENDIAN_DIFF) {
			ENDIAN_SWAP32(&siginfo.si_signo);
			ENDIAN_SWAP32(&siginfo.si_code);
			ENDIAN_SWAP32(&siginfo.si_errno);
			ENDIAN_SWAP32(&siginfo.si_pid);
			ENDIAN_SWAP32(&siginfo.si_status);
			ENDIAN_SWAP32(&siginfo.si_utime);
			ENDIAN_SWAP32(&siginfo.si_stime);
		}
		MsgReply(wap->rcvid, 0, &siginfo, sizeof siginfo);
	} else {
		KerextSlogf( _SLOG_SETCODE( _SLOGC_PROC, 0 ), _SLOG_INFO, "proc_wait_check: MsgInfo() failed, errno=%d", errno);
	}

	/*
	 * Clean up prp status if requested so it is not reported again
	 */
	if(wap->options & WNOWAIT) {
		return WNOWAIT;
	}
	switch(match) {
	case WEXITED:
		if(prp->flags & _NTO_PF_WAITINFO) {
			parent->kids_running_time += prp->running_time + prp->kids_running_time;
			parent->kids_system_time += prp->system_time + prp->kids_system_time;
			prp->flags &= ~_NTO_PF_WAITINFO;
			prp->flags |= _NTO_PF_WAITDONE;
		}
		if(prp->flags & _NTO_PF_ZOMBIE) {
			MsgSendPulse(PROCMGR_COID, prp->terming_priority, PROC_CODE_TERM, prp->pid);
		} else {
			match = WNOWAIT;
		}
		break;
	case WUNTRACED: // also WSTOPPED
		prp->siginfo.si_signo = 0;
		break;
	case WTRAPPED:
		break;
	case WCONTINUED:
		prp->flags &= ~_NTO_PF_CONTINUED;
		break;
	default:
		break;
	}
	return match;
}
示例#12
0
int
tto(TTYDEV *ttydev, int action, int arg1) {
	TTYBUF 			*bup = &ttydev->obuf;
	DEV_OMAP		*dev = (DEV_OMAP *)ttydev;
	const uintptr_t	*port = dev->port;
	unsigned char 	c;
	
#ifdef PWR_MAN

	if (dev->idle) {

		/* Check the client lists for notify conditions */
		return(tto_checkclients(&dev->tty));
	}
#endif

	switch(action) {
	case TTO_STTY:
//            if (dev->driver_pmd.cur_mode == PM_MODE_ACTIVE)
			ser_stty(dev);
		return (0);

	case TTO_CTRL:

		if(arg1 & _SERCTL_BRK_CHG)
			set_port(port[OMAP_UART_LCR], OMAP_LCR_BREAK, arg1 &_SERCTL_BRK ? OMAP_LCR_BREAK : 0);

		if(arg1 & _SERCTL_DTR_CHG)
			set_port(port[OMAP_UART_MCR], OMAP_MCR_DTR, arg1 & _SERCTL_DTR ? OMAP_MCR_DTR : 0);

		if(arg1 & _SERCTL_RTS_CHG)
		{
			if (dev->auto_rts_enable)
			{
				/* For auto-rts enable/disable RX & LS interrupts to assert/clear 
				 * input flow control (the FIFO will automatically handle the RTS line) 
				*/
				if (arg1 & _SERCTL_RTS)
					write_omap(port[OMAP_UART_IER], read_omap(port[OMAP_UART_IER] ) | OMAP_IER_RHR | OMAP_IER_LS );
				else
					write_omap(port[OMAP_UART_IER], read_omap(port[OMAP_UART_IER] ) & ~(OMAP_IER_RHR | OMAP_IER_LS ) );
			}
			else
				set_port(port[OMAP_UART_MCR], OMAP_MCR_RTS, arg1 & _SERCTL_RTS ? OMAP_MCR_RTS : 0);
		}

#ifdef WINBT
        if (arg1 & _CTL_TIMED_CHG) {

            slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "%s: Turning clocks OFF due to CTS glitch\n", __FUNCTION__);
            dev->signal_oband_notification = 0;
            omap_clock_disable(dev);
        }
#endif
		return (0);

	case TTO_LINESTATUS:
		return (((read_omap(port[OMAP_UART_MSR]) << 8) | read_omap(port[OMAP_UART_MCR])) & 0xf003);

	case TTO_DATA:
	case TTO_EVENT:
		break;

	default:
		return (0);
	}


	while (bup->cnt > 0 && (!(read_omap(port[OMAP_UART_SSR]) & OMAP_SSR_TXFULL)) )
	{
		/*
    		* If the OSW_PAGED_OVERRIDE flag is set then allow
   		* transmit of character even if output is suspended via
    		* the OSW_PAGED flag. This flag implies that the next
    		* character in the obuf is a software flow control
    		* charater (STOP/START).
    		* Note: tx_inject sets it up so that the contol
    		*       character is at the start (tail) of the buffer.
    		*
		*/
	

		if (dev->tty.flags & (OHW_PAGED | OSW_PAGED) && !(dev->tty.xflags & OSW_PAGED_OVERRIDE))
			break;

		/* Get character from obuf and do any output processing */
		dev_lock(&dev->tty);
		c = tto_getchar(&dev->tty);
		dev_unlock(&dev->tty);
	    	
		/* Print the character */
		dev->tty.un.s.tx_tmr = 3;       /* Timeout 3 */
		write_omap(port[OMAP_UART_THR], c);

		/* Clear the OSW_PAGED_OVERRIDE flag as we only want
      		* one character to be transmitted in this case.
     		*/
    		if (dev->tty.xflags & OSW_PAGED_OVERRIDE){
           		atomic_clr(&dev->tty.xflags, OSW_PAGED_OVERRIDE);
			break;
 		}	
 	}

	/* If there is still data in the obuf and we are not in a flow 
	 * controlled state then turn TX interrupts back on to notify us
	 * when the hardware is ready for more characters.
	 */
	if (bup->cnt > 0 && !(dev->tty.flags & (OHW_PAGED|OSW_PAGED)) )
	 { 
		// enable all interrupts
		set_port(dev->port[OMAP_UART_IER], OMAP_IER_THR, OMAP_IER_THR);
	 }
	 

	/* Check the client lists for notify conditions */
	return(tto_checkclients(&dev->tty));
}
示例#13
0
/* Return     : None                                                                */
void insertion( struct usbd_connection *pConnection, usbd_device_instance_t *pInstance )
{
   int rc;
   struct usbd_device * pDevice;
   pModule_data_t pModule, * ppModule;
   
   if(verbosity)
     printf("Try to inser device\n");
   if( EOK != (rc = usbd_attach( pConnection, pInstance, sizeof(module_data_t **), &pDevice ) ))
     {
     char * pMsgTxt = "Error: cannot attach USB device #%i (error code is %i)\n";
     fprintf(stderr, pMsgTxt, (int)(pInstance -> devno), rc);
     slogf(_SLOG_SETCODE(_SLOGC_INPUT, 0), _SLOG_ERROR, pMsgTxt, (int)(pInstance -> devno), rc);
     return;
     }
   ppModule = (pModule_data_t *)usbd_device_extra(pDevice);
	
	
   // Try to find if somebody cares about keyboard reports
   for(pModule = LIST_FIRST_ITEM(&modList); NULL != pModule; pModule = LIST_NEXT_ITEM(pModule, lst_conn))
        {
	// Check device number if specified
        if( (USBD_CONNECT_WILDCARD != pModule -> nDev) && (pModule -> nDev != pInstance -> devno))
	     continue;

        if( (USBD_CONNECT_WILDCARD != pModule -> nVendor) && (pModule -> nVendor != pInstance -> ident.vendor))
             continue; // Wrong vendor - ignore
	   
        if((USBD_CONNECT_WILDCARD != pModule -> nClass) && (pModule -> nClass != pInstance -> ident.dclass))
             continue;
   
        if((USBD_CONNECT_WILDCARD != pModule -> nSubClass) && (pModule -> nSubClass != pInstance -> ident.subclass))
             continue;

	pModule -> pInstance = pInstance;
	pModule -> pDevice   = pDevice;
        if( EOK == parse_descriptors( pModule) )
	   {
	   if( pModule -> ep_int_buf = usbd_alloc( pModule -> ep_int_size ) )
	      {
	      if( pModule -> urb = usbd_alloc_urb( NULL ) )
		 {
		 // Initialize request block
		 usbd_setup_interrupt( pModule -> urb,  
				      URB_DIR_IN, 
				      pModule -> ep_int_buf, 
				      pModule->ep_int_size );
		 // Initialize Interrupt callback function
		 if( EOK == usbd_io( pModule -> urb, 
				   pModule -> ep_int, 
				   usb_dev_int, 
				   pModule, USBD_TIME_INFINITY ) ) 
		      {
		      pModule -> flags |= USB_DEVICE_ON |  USB_DEVICE_PRESENT;
		      *ppModule = pModule;
                      if(verbosity)
                         printf("Attach device\n");
		      return;
		      }
		 else
		      {
                      if(verbosity)
                         printf("Cannot attach device\n");
		      }
		 }
               usbd_free( pModule -> ep_int_buf );
	       }
	   usbd_detach( pDevice );
	   }
         }
}
// Initialize audio and report back a few parameters of the channel
int setupAudio( )
{
    int error;
    snd_pcm_channel_info_t pi;
    snd_pcm_channel_params_t pp;
    snd_pcm_channel_setup_t ps;

    //if ((error = snd_pcm_open_name (&playback_handle, "pcmPreferred", SND_PCM_OPEN_PLAYBACK)) < 0) {
    if ((error = snd_pcm_open_name (&playback_handle, "tones", SND_PCM_OPEN_PLAYBACK)) < 0) {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to open preferred audio driver\n");
        return -error;
    }

    sample_handle = snd_pcm_file_descriptor( playback_handle, SND_PCM_CHANNEL_PLAYBACK );

    if ((error = snd_pcm_plugin_set_disable (playback_handle, PLUGIN_DISABLE_MMAP)) < 0) {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to disable mmap\n");
        snd_pcm_close(playback_handle);
        return -error;
    }

    if ((error = snd_pcm_plugin_set_enable (playback_handle, PLUGIN_ROUTING)) < 0)
    {
        slogf ( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "snd_pcm_plugin_set_enable failed: %s\n", snd_strerror (error));
        snd_pcm_close(playback_handle);
        return -error;
    }

    // Find what sample rate and format to use
    memset( &pi, 0, sizeof(pi) );
    pi.channel = SND_PCM_CHANNEL_PLAYBACK;
    if ((error = snd_pcm_channel_info (playback_handle, &pi)) < 0) {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to get plugin info\n");
        snd_pcm_close(playback_handle);
        return -error;
    }

    // Initialize the playback channel
    memset(&pp, 0, sizeof(pp) );
    pp.mode = SND_PCM_MODE_BLOCK;
    pp.channel = SND_PCM_CHANNEL_PLAYBACK;
    pp.start_mode = SND_PCM_START_FULL;
    pp.stop_mode = SND_PCM_STOP_STOP;
    pp.buf.block.frag_size = pi.max_fragment_size;
    pp.buf.block.frags_max = 3;
    pp.buf.block.frags_min = 1;
    pp.format.interleave = 1;
    pp.format.format =  SND_PCM_SFMT_S16_LE;
    pp.format.rate = 48000;
    pp.format.voices = 2;

    memset( &ps, 0, sizeof( ps ) );
    memset( &group, 0, sizeof( group ) );
    ps.channel = SND_PCM_CHANNEL_PLAYBACK;
    ps.mixer_gid = &group.gid;
    //strcpy(pp.sw_mixer_subchn_name, "Wave playback channel");
    strcpy(pp.sw_mixer_subchn_name, "voice_ringtone");

    if ((error = snd_pcm_plugin_params( playback_handle, &pp)) < 0)
    {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to set plugin params\n");
        snd_pcm_close(playback_handle);
        return -error;
    }

    if ((error = snd_pcm_plugin_prepare (playback_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to set prepare plugin\n");
        snd_pcm_close(playback_handle);
        return -error;
    }

    if ((error = snd_pcm_plugin_setup (playback_handle, &ps)) < 0) {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to setup plugin\n");
        snd_pcm_close(playback_handle);
        return -error;
    }

    card = ps.mixer_card;
    device = ps.mixer_device;

    if( audioman_handle ) {
        if ((error = snd_pcm_set_audioman_handle (playback_handle, audioman_handle)) < 0) {
            slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to set audioman handle \n");
            snd_pcm_close(playback_handle);
            return -error;
        }
    }

    sample_frequency = ps.format.rate;
    frag_samples = ps.buf.block.frag_size / 4;
    frame_size = ps.buf.block.frag_size;
    format = pp.format.format;
/*
    // Only support 16-bit samples for now
    frag_buffer = malloc( ps.buf.block.frag_size * 2 );
    if( frag_buffer == NULL ) {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to alloc frag buffer\n");
        snd_pcm_close(playback_handle);
        return ENOMEM;
    }
*/
	fprintf (stderr,"Playback Format %s card = %d\n", snd_pcm_get_format_name (ps.format.format),card);
	fprintf (stderr,"Playback preferred frame_size %d \n", pi.max_fragment_size);
	fprintf (stderr,"Playback frame_size %d \n", ps.buf.block.frag_size);
	fprintf (stderr,"Playback frame_samples %d \n", frag_samples);
	fprintf (stderr,"Playback Rate %d \n", ps.format.rate);

	if (group.gid.name[0] == 0)
	{
		fprintf (stderr,"Playback Mixer Pcm Group [%s] Not Set \n", group.gid.name);
        return -1;
	}
	fprintf (stderr, "Playback Mixer Pcm Group [%s]\n", group.gid.name);

    return EOK;
}
static void *processTones(void *dummy)
{
    bool done;
    int error;
    int length;
    int index;
    Tone *tone, *nextTone;
    snd_pcm_channel_status_t status;


    //pthread_setname_np(pthread_self(), "tonegen");

    // Main loop. Wait for audio driver to need more data
    while( live ) {
        pthread_mutex_lock( &toneMutex );
        if( tone_count == 0 ) {
            // Wait for a tone command to come in
            snd_pcm_playback_flush( playback_handle );
            snd_pcm_plugin_prepare( playback_handle, SND_PCM_CHANNEL_PLAYBACK );

            pthread_cond_wait( &condvar_newtone, &toneMutex );
        }
        if( tone_count == 0 ) {
            pthread_mutex_unlock( &toneMutex );
            continue;
        }
        pthread_mutex_unlock( &toneMutex );

        // Send tone data
        FD_ZERO( &write_handles );
        FD_SET( sample_handle, &write_handles );
        error = select(sample_handle + 1, NULL, &write_handles, NULL, NULL);

        if( error < 0 ) {
            // Select failed.
            slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "processTones select failed %d (%d)\n", error, errno);
            pthread_mutex_unlock( &toneMutex );
            live = DEAD;
            break;
        }

        length = 0;

        // This should always be true
        if( FD_ISSET( sample_handle, &write_handles ) ) {
        	int active_count = 0;
        	for(tone = tones; tone != NULL; tone = tone->next) {
                done = tone->killed || (tonepos > tone->end);
    			//fprintf (stderr,"processTone::writeTone (before active check) tone %ld tone->end %ld active %d done %d tonepos %ld \n", tone, tone->end, tone->active, done, tonepos);
                if( !done ) {
                    // Write the tone
                    error = writeTone(tone, (tone != tones));
                    //error = tone->generator(tone->position, length, sample_frequency, frag_buffer, &tone->data, terminating);
                    if( error != EOK ) {
                        done = true;
                    }
                    active_count++;
                }

                tone->active &= !done;
    			//fprintf (stderr,"processTone::writeTone tone %ld tone->end %ld active %d tonepos %ld \n", tone, tone->end, tone->active, tonepos);
        	}

        	for(index = 0; index < frag_samples; index++) {
        		record_buffer[index*2  ] = stage_buffer[index] / stage_samples[index];
        		record_buffer[index*2+1] = stage_buffer[index] / stage_samples[index];
        	}

        	pthread_mutex_lock(&fillMutex);

        	if (render_buffer != NULL) {
        		memcpy(render_buffer, record_buffer, frame_size);
        	}

        	pthread_mutex_unlock(&fillMutex);

			tonepos += frag_samples;

			if (active_count > 0) {
				fprintf (stderr,"processTone tonepos %ld \n", tonepos);

				error = snd_pcm_plugin_write (playback_handle, record_buffer, frame_size);
				if( error != frame_size ) {
				   memset (&status, 0, sizeof (status));
					status.channel = SND_PCM_CHANNEL_PLAYBACK;
					if ((error = snd_pcm_plugin_status (playback_handle, &status)) < 0)
					{
						slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "retrieving audio interface status failed (%s)\n", snd_strerror (error));
					} else if (status.status == SND_PCM_STATUS_READY ||
							   status.status == SND_PCM_STATUS_UNDERRUN ||
							   status.status == SND_PCM_STATUS_CHANGE)
					{
						if ((error = snd_pcm_plugin_prepare (playback_handle, SND_PCM_CHANNEL_PLAYBACK)) < 0) {
							slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "cannot prepare audio interface for use (%s)\n", snd_strerror (error));
						}
					} else {
						slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "non-underrun write failure (%s)\n", snd_strerror (error));
					}
					// Retry now that we're prepared
					error = snd_pcm_plugin_write (playback_handle, record_buffer, frame_size);
				}
				if( error != frame_size ) {
					slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "write to audio interface failed (%s) %d\n", snd_strerror (error), error);
				}
			}

        } else {
            slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unknown file handle activated" );
        }

		pthread_mutex_lock( &toneMutex );


		//fprintf (stderr,"processTone::delete tones %lx count %d \n", tones, tone_count);

        int delete_count;
        do {
        	delete_count = 0;
			for(tone = tones; tone != NULL; tone = tone->next) {
				done = tone->killed || (tonepos > tone->end);
				if( done || !tone->active ) {
					// Remove the tone from the list
					if (tone->prev != NULL) {
						tone->prev->next = tone->next;
					} else {
						tones = tone->next;
					}
					if (tone->next != NULL) {
						tone->next->prev = tone->prev;
					}

					tone_count--;

					free(tone);

					delete_count++;

					fprintf (stderr,"processTone::delete tone %lx tones %lx count %d \n", tone, tones, tone_count);

					break;
				}
			}
        } while (delete_count > 0);

		pthread_mutex_unlock( &toneMutex );

        if (tone_count == 0) {
        	memset(record_buffer, 0, frame_size);
        }
    }

    return NULL;
}
int initToneGenerator(void)
{
    _int32 staticMemSize, scratchMemSize;
    int policy;
    struct sched_param param;
    int error;
    pthread_attr_t attr;

    if( live == RUNNING) {
        return 0;
    } else if( live == DEAD ) {
        return -EINVAL;
    }


   if( (error = pthread_mutex_init (&fillMutex, NULL) ) != 0 ) {
		return error;
	}

    tone_count = 0;
    if( (error = pthread_mutex_init( &toneMutex, NULL ) ) != 0 ) {
        return error;
    }

    if( (error = pthread_cond_init( &condvar_newtone, NULL ) ) != 0 ) {
        pthread_mutex_destroy( &toneMutex );
        return error;
    }

    audio_manager_get_handle( AUDIO_TYPE_VOICE_TONES, getpid(), true, &audioman_handle );

    if( (error = setupAudio( )) != 0 ) {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to initialize audio %s\n", snd_strerror(error));
        pthread_mutex_destroy( &toneMutex );
        pthread_cond_destroy( &condvar_newtone );
        if( audioman_handle ) {
            audio_manager_free_handle( audioman_handle );
        }
        return error;
    }

	// Re-usable buffer for generation
	stage_buffer = malloc (frame_size);
	memset(stage_buffer, 0, frame_size);
	stage_samples = malloc (frame_size);
	memset(stage_samples, 0, frame_size);
	record_buffer = malloc (frame_size);
	memset(record_buffer, 0, frame_size);
	render_buffer = malloc (frame_size);
	memset(render_buffer, 0, frame_size);

    // Default tonegen volume is 75% to achieve a 16dB loss ( SW mixer uses 10%=6dB. )
    setVolume(85);

    live = RUNNING;

    pthread_attr_init (&attr);
    pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE);
    pthread_attr_setinheritsched (&attr, PTHREAD_EXPLICIT_SCHED);
    pthread_getschedparam (pthread_self (), &policy, &param);
    param.sched_priority=12;
    pthread_attr_setschedparam (&attr, &param);
    pthread_attr_setschedpolicy (&attr, SCHED_RR);

    if( (error = pthread_create( &toneGeneratorThread, &attr, processTones, NULL ) ) != 0 ) {
        slogf( _SLOG_SETCODE(_SLOGC_AUDIO, 0), _SLOG_CRITICAL, "Unable to create tone thread %s\n", strerror(error));
        snd_pcm_close (playback_handle);
        //free( frag_buffer );
        pthread_mutex_destroy( &toneMutex );
        pthread_cond_destroy( &condvar_newtone );

        live = STOPPED;
        if( audioman_handle ) {
            audio_manager_free_handle( audioman_handle );
        }
        pthread_attr_destroy(&attr);
        return error;
    }

    pthread_attr_destroy(&attr);

    return 0;
}
示例#17
0
/*******************************************************************************
**
**	gckCOMMAND_Stall
**
**	The calling thread will be suspended until the command queue has been
**  completed.
**
**	INPUT:
**
**		gckCOMMAND Command
**			Pointer to an gckCOMMAND object.
**
**	OUTPUT:
**
**		Nothing.
*/
gceSTATUS
gckCOMMAND_Stall(
    IN gckCOMMAND Command
    )
{
    gckOS os;
    gckHARDWARE hardware;
    gckEVENT event;
    gceSTATUS status;
	gctSIGNAL signal = gcvNULL;

	gcmkHEADER_ARG("Command=0x%x", Command);

    /* Verify the arguments. */
    gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);

#if gcdNULL_DRIVER == 2
	/* Do nothing with infinite hardware. */
	gcmkFOOTER_NO();
	return gcvSTATUS_OK;
#endif

    /* Extract the gckOS object pointer. */
    os = Command->os;
    gcmkVERIFY_OBJECT(os, gcvOBJ_OS);

    /* Extract the gckHARDWARE object pointer. */
    hardware = Command->kernel->hardware;
    gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);

    /* Extract the gckEVENT object pointer. */
    event = Command->kernel->event;
    gcmkVERIFY_OBJECT(event, gcvOBJ_EVENT);

    /* Allocate the signal. */
	gcmkONERROR(
		gckOS_CreateSignal(os, gcvTRUE, &signal));

    /* Append the EVENT command to trigger the signal. */
    gcmkONERROR(gckEVENT_Signal(event,
                                signal,
                                gcvKERNEL_PIXEL,
								gcvFALSE));

    /* Submit the event queue. */
	gcmkONERROR(gckEVENT_Submit(event, gcvTRUE, gcvFALSE));

#if gcdDUMP_COMMAND
    gcmkPRINT("@[kernel.stall]");
#endif

    if (status == gcvSTATUS_CHIP_NOT_READY)
    {
        /* Error. */
        goto OnError;
    }

	do
	{
		/* Wait for the signal. */
		status = gckOS_WaitSignal(os, signal, gcvINFINITE);

		if (status == gcvSTATUS_TIMEOUT)
		{
#if gcdDEBUG
			gctUINT32 idle;

			/* IDLE */
			gckOS_ReadRegister(Command->os, 0x0004, &idle);
                
			gcmkTRACE(gcvLEVEL_ERROR,
					  "%s(%d): idle=%08x",
					  __FUNCTION__, __LINE__, idle);
        	    	gckOS_Log(_GFX_LOG_WARNING_, "%s : %d : idle register = 0x%08x \n", 
                            __FUNCTION__, __LINE__, idle);                
#endif 

#if MRVL_PRINT_CMD_BUFFER
            {
    			gctUINT i;
                gctUINT32 idle;
    			gctUINT32 intAck;
    			gctUINT32 prevAddr = 0;
    			gctUINT32 currAddr;
    			gctBOOL changeDetected;

    			changeDetected = gcvFALSE;

                /* IDLE */
			    gckOS_ReadRegister(Command->os, 0x0004, &idle);
                
				/* INT ACK */
				gckOS_ReadRegister(Command->os, 0x0010, &intAck);

				/* DMA POS */
				for (i = 0; i < 300; i += 1)
				{
					gckOS_ReadRegister(Command->os, 0x0664, &currAddr);

					if ((i > 0) && (prevAddr != currAddr))
					{
						changeDetected = gcvTRUE;
					}

					prevAddr = currAddr;
				}

				gcmTRACE(0,
					"\n%s(%d):\n"
					"  idle = 0x%08X\n"
					"  int  = 0x%08X\n"
					"  dma  = 0x%08X (change=%d)\n",
					__FUNCTION__, __LINE__,
					idle,
					intAck,
					currAddr,
					changeDetected
					);
                
				_PrintCmdBuffer(Command, currAddr);
				_PrintLinkChain();
            }
#endif


#if MRVL_LOW_POWER_MODE_DEBUG
            	{
                	int i = 0;
                
                	printk(">>>>>>>>>>>>galDevice->kernel->kernelMSG\n");
                	printk("galDevice->kernel->msgLen=%d\n",Command->kernel->msgLen);
                
                	for(i=0;i<Command->kernel->msgLen;i+=1024)
                	{
                    		Command->kernel->kernelMSG[i+1023] = '\0';
            	    		printk("%s\n",(char*)Command->kernel->kernelMSG + i);
                	}
            	}
#endif
#ifdef __QNXNTO__
            gctUINT32 reg_cmdbuf_fetch;
            gctUINT32 reg_intr;

            gcmkVERIFY_OK(
                    gckOS_ReadRegister(Command->kernel->hardware->os, 0x0664, &reg_cmdbuf_fetch));

            if (idle == 0x7FFFFFFE)
            {
                /*
                 * GPU is idle so there should not be pending interrupts.
                 * Just double check.
                 *
                 * Note that reading interrupt register clears it.
                 * That's why we don't read it in all cases.
                 */
                gcmkVERIFY_OK(
                        gckOS_ReadRegister(Command->kernel->hardware->os, 0x10, &reg_intr));

                slogf(
                    _SLOG_SETCODE(1, 0),
                    _SLOG_CRITICAL,
                    "GALcore: Stall timeout (idle = 0x%X, command buffer fetch = 0x%X, interrupt = 0x%X)",
                    idle, reg_cmdbuf_fetch, reg_intr);
            }
            else
            {
                slogf(
                    _SLOG_SETCODE(1, 0),
                    _SLOG_CRITICAL,
                    "GALcore: Stall timeout (idle = 0x%X, command buffer fetch = 0x%X)",
                    idle, reg_cmdbuf_fetch);
            }
#endif
			gcmkVERIFY_OK(
				gckOS_MemoryBarrier(os, gcvNULL));
		}

	}
	while (gcmIS_ERROR(status));

	/* Delete the signal. */
	gcmkVERIFY_OK(gckOS_DestroySignal(os, signal));

    /* Success. */
    gcmkFOOTER_NO();
    return gcvSTATUS_OK;

OnError:
    /* Free the signal. */
    if (signal != gcvNULL)
    {
    	gcmkVERIFY_OK(gckOS_DestroySignal(os, signal));
    }

    /* Return the status. */
    gcmkFOOTER();
    return status;
}
示例#18
0
void
ser_stty(DEV_OMAP *dev) {
	unsigned char	lcr = 0;
	unsigned char	efr = 0;
	const uintptr_t *port = dev->port;
	unsigned		brd = 0;
	int     		multiple;
	int			i;

#ifdef PWR_MAN
	if (dev->idle) {
		slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "%s: Called while idle, ignoring\n", __FUNCTION__);
		return;
	}
#endif

	/* determine data bits */
	switch (dev->tty.c_cflag & CSIZE) {
		case CS8: ++lcr;
		case CS7: ++lcr;
		case CS6: ++lcr;
	}

	/* determine stop bits */
	if (dev->tty.c_cflag & CSTOPB)
		lcr |= OMAP_LCR_STB2;
	/* determine parity bits */
	if (dev->tty.c_cflag & PARENB)
		lcr |= OMAP_LCR_PEN;
	if ((dev->tty.c_cflag & PARODD) == 0)
		lcr |= OMAP_LCR_EPS;

	if (dev->tty.c_cflag & OHFLOW)
		efr = OMAP_EFR_AUTO_CTS;
	if (dev->tty.c_cflag & IHFLOW && dev->auto_rts_enable)
		efr |= OMAP_EFR_AUTO_RTS;

	/* Apply EFR value if changed */
	if (dev->efr != efr)
	{
		/* Switch to Config mode B to access the Enhanced Feature Register (EFR) */
		write_omap(port[OMAP_UART_LCR],0xbf);
		/* turn off S/W flow control, Config AUTO hw flow control, enable writes to MCR[7:5], FCR[5:4], and IER[7:4] */
		set_port(port[OMAP_UART_EFR], efr, efr);
		/* Switch back to operational mode */
		write_omap(port[OMAP_UART_LCR],0);
		/* Restore LCR config values */
		write_omap(port[OMAP_UART_LCR], lcr);
		dev->lcr = lcr;
		dev->efr = efr;
	}

	if (dev->tty.baud != dev->baud)
	{
		/* Get acces to Divisor Latch registers  */
		write_omap(port[OMAP_UART_LCR], OMAP_LCR_DLAB);

#ifdef OMAP5910
		/*
		 * Oscillator frequency is fixed at 12MHz. This normally wouldn't allow a 
		 * 115200 baud rate, since divisor = Fin / (16 * baud), which, for 115200, = 6.5,
		 * which is out of tolerance. There is a special register with a bit which, when
		 * set, automatically enables a 6.5 divisor value in hardware, and the DLH / DLL
		 * registers can just be programmed with a 1.
		 */

		if (dev->tty.baud == 115200)
		{
			brd = 1;
			write_omap(port[OMAP_UART_DLL], brd);
			write_omap(port[OMAP_UART_DLH], (brd >> 8) & 0xff);
			write_omap(port[OMAP_UART_OSC_12M_SEL], 0x01);
		}
示例#19
0
int
resmgr_create_device(event_bus_line_t *line)
{
        devi_attr_t				*attr;
        resmgr_attr_t				res_attr;
	static resmgr_connect_funcs_t		connect_funcs;
	static resmgr_io_funcs_t		io_funcs;
        static int				once = 0;
        int					i;
	char					name[48];
        char					path[_POSIX_PATH_MAX];
	int					id;
        dev_t					d;

	if ((attr = malloc(sizeof(devi_attr_t))) == NULL) {
                errno_print("malloc");
                return (-1);
        }

	if (!once) {
                iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
                                 _RESMGR_IO_NFUNCS, &io_funcs);
                connect_funcs.open = devi_open;
                io_funcs.devctl = devi_devctl;
                io_funcs.read = devi_read;
                io_funcs.close_ocb = devi_close;
                io_funcs.unblock = devi_unblock;
                io_funcs.notify = devi_notify;
                once = 1;
        }

        iofunc_attr_init(&attr->attr, 0666 | S_IFCHR, NULL, NULL);
	attr->flags = line->type;
        attr->ocb_list = NULL;
        line->attr = attr;

	switch (attr->flags) {

        case DEVI_CLASS_KBD:
                strcpy(name, "keyboard");
                break;
                
        case DEVI_CLASS_REL:
                strcpy(name, "mouse");
                break;
                
        case DEVI_CLASS_ABS:
                strcpy(name, "touch");
                break;
        }

        attr->line = line;

        memset(&res_attr, 0, sizeof(res_attr));
        res_attr.msg_max_size = 2048;
        res_attr.nparts_max = 3;

        for (i = 0; i < 10; i++) {

                sprintf(path, DEVICE_NAME, name, i);
                if (access(path, F_OK) != 0)
                        break;
        }
        if (i == 10) {

                char * pMsgTxt = "Error: unable to create device %s\n";
                fprintf(stderr, pMsgTxt, path);
                slogf(_SLOG_SETCODE(_SLOGC_INPUT, 0), _SLOG_ERROR, pMsgTxt, path);
                free(attr);
                return (-1);
        }

        id = resmgr_attach(devi_get_dispatch_handle(), &res_attr, path, 
                           _FTYPE_ANY, 0, &connect_funcs, 
                           &io_funcs, (void *) &attr->attr);

        if (id < 0) {
                char * pMsgTxt = "Error: could not attach resource manager\n";
                fprintf(stderr, pMsgTxt);
                slogf(_SLOG_SETCODE(_SLOGC_INPUT, 0), _SLOG_ERROR, pMsgTxt);
                free(attr);
                return (-1);
        }

        attr->attr.rdev = rsrcdbmgr_devno_attach(name, -1, 0);
        resmgr_devino(id, &d, &attr->attr.inode);

        return (0);
}
示例#20
0
DEV_OMAP *
create_device(TTYINIT_OMAP *dip, unsigned unit, unsigned maxim_xcvr_kick) {
	DEV_OMAP 			*dev;
	unsigned			i;
	uintptr_t			port;
	unsigned char		msr;
	unsigned char		tlr = 0, tcr = 0;
#ifdef PWR_MAN
    clk_enable_t        clk_cfg = clk_enable_none;
#endif

	// Get a device entry and the input/output buffers for it.
	if ((dev = malloc(sizeof(*dev))) == NULL)
	{
		slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "io-char: Allocation of device entry failed (%d)", errno);
		return (dev);
	}	
	memset(dev, 0, sizeof(*dev));

	// Get buffers.
	dev->tty.ibuf.head = dev->tty.ibuf.tail = dev->tty.ibuf.buff = malloc(dev->tty.ibuf.size = dip->tty.isize);
	if (dev->tty.ibuf.buff == NULL)
	{
		slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "io-char: Allocation of input buffer failed (%d)", errno);
		free(dev);
		return (NULL);
	}
						   
	dev->tty.obuf.head = dev->tty.obuf.tail = dev->tty.obuf.buff = malloc(dev->tty.obuf.size = dip->tty.osize);
	if (dev->tty.obuf.buff == NULL)
	{
		slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "io-char: Allocation of output buffer failed (%d)", errno);
		free(dev->tty.ibuf.buff);
		free(dev);
		return (NULL);
	}

	dev->tty.cbuf.head = dev->tty.cbuf.tail = dev->tty.cbuf.buff = malloc(dev->tty.cbuf.size = dip->tty.csize);
	if (dev->tty.cbuf.buff == NULL)
	{
		slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "io-char: Allocation of canonical buffer failed (%d)", errno);
		free(dev->tty.ibuf.buff);
		free(dev->tty.obuf.buff);
		free(dev);
		return (NULL);
	}

	if (dip->tty.highwater)
		dev->tty.highwater = dip->tty.highwater;
	else
		dev->tty.highwater = dev->tty.ibuf.size - (FIFO_SIZE * 2);

	strcpy(dev->tty.name, dip->tty.name);

	dev->tty.baud = dip->tty.baud;
	dev->tty.fifo = dip->tty.fifo;
	dev->tty.verbose = dip->tty.verbose;

	port = mmap_device_io(OMAP_UART_SIZE, dip->tty.port);
	for (i = 0; i < OMAP_UART_SIZE; i += 4)
		dev->port[i] = port + i;

	dev->intr = dip->tty.intr;
	dev->clk = dip->tty.clk;
	dev->div = dip->tty.div;

	dev->tty.flags = EDIT_INSERT | LOSES_TX_INTR;
	dev->tty.c_cflag = dip->tty.c_cflag;
	dev->tty.c_iflag = dip->tty.c_iflag;
	dev->tty.c_lflag = dip->tty.c_lflag;
	dev->tty.c_oflag = dip->tty.c_oflag;
	dev->tty.lflags = dip->tty.lflags;
	if (dip->tty.logging_path[0] != NULL)
		dev->tty.logging_path = strdup(dip->tty.logging_path);

#ifdef PWR_MAN
	dev->physbase = dip->tty.port;
	
	if (omap_clock_toggle_init(dev) != EOK)
	{
		slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "io-char: Fail to initialize clocks for PM!");
		free(dev->tty.ibuf.buff);
		free(dev->tty.obuf.buff);
		free(dev);
		return (NULL);
	}
#ifdef WINBT
    clk_cfg = clk_enable_smart_wkup;
    
	if (omap_force_rts_init(dev) != EOK)
	{
		slogf(_SLOG_SETCODE(_SLOGC_CHAR, 0), _SLOG_ERROR, "io-char: Fail to initialize force_rts for PM!");
		free(dev->tty.ibuf.buff);
		free(dev->tty.obuf.buff);
		free(dev);
		return (NULL);
	}
#endif

	omap_clock_enable(dev, clk_cfg);

#ifdef WINBT	
	bt_ctrl_init();
#endif	
#endif

	/* Set auto_rts mode */
	dev->auto_rts_enable = dip->auto_rts_enable;
	
	// Do not enable MSR interrupt                                                                                                        
	dev->no_msr_int  = dip->no_msr_int;   

	// Initialize termios cc codes to an ANSI terminal.
	ttc(TTC_INIT_CC, &dev->tty, 0);

	// Initialize the device's name.
	// Assume that the basename is set in device name.  This will attach
	// to the path assigned by the unit number/minor number combination
	unit = SET_NAME_NUMBER(unit) | NUMBER_DEV_FROM_USER;
	ttc(TTC_INIT_TTYNAME, &dev->tty, unit);

	// see if we have a maxim rs-232 transceiver that needs to be
	// kicked after it goes to sleep
	dev->kick_maxim = maxim_xcvr_kick;

	// Only setup IRQ handler for non-pcmcia devices.
	// Pcmcia devices will have this done later when card is inserted.
	if (dip->tty.port != 0 && dip->tty.intr != _NTO_INTR_SPARE) {
#ifdef OMAP5910
		/*
		 * Don't change default mode set in the very distant past. Even though
		 * MODE_SELECT should be DISABLE before changing DLH, DLL.
		 */
                // enable the UART
                write_omap(dev->port[OMAP_UART_MDR1], OMAP_MDR1_MODE_16X);
#else
		/*
		 * TRM states: Before initializing or modifying clock parameter controls
		 * (DLH, DLL), MODE_SELECT must be set to 0x7 (DISABLE). Failure to observe
		 * this rule can result in unpredictable module behavior.
		 */
		write_omap(dev->port[OMAP_UART_MDR1], OMAP_MDR1_MODE_DISABLE);
#endif
		/* Work around for silicon errata i202 states: */
		/* Need a delay = 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS) */
		nanospin_ns(200);
		/* Clear FIFOs */
		set_port(dev->port[OMAP_UART_FCR], OMAP_FCR_RXCLR | OMAP_FCR_TXCLR, OMAP_FCR_RXCLR | OMAP_FCR_TXCLR);
		/* Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and TX_FIFO_E bit is 1 */
		i = 5;
		while ((read_omap(dev->port[OMAP_UART_LSR]) & (OMAP_UART_LSR_THRE | OMAP_UART_LSR_DR)) != OMAP_UART_LSR_THRE)
		{
		   nanospin_ns(200);
		   if (--i == 0)
		   {
		      break;  /* No need to do anything drastic if FIFO is still not empty */
		   }
		}
		// enable access to divisor registers
		write_omap(dev->port[OMAP_UART_LCR], OMAP_LCR_DLAB);
		write_omap(dev->port[OMAP_UART_DLL], 0);
		write_omap(dev->port[OMAP_UART_DLH], 0);

		/* Switch to config mode B to get access to EFR Register */
		write_omap(dev->port[OMAP_UART_LCR], 0xBF);
		/* Enable access to TLR register */
		set_port(dev->port[OMAP_UART_EFR], OMAP_EFR_ENHANCED, OMAP_EFR_ENHANCED);
		/* Switch to operational mode to get acces to MCR register */
		write_omap(dev->port[OMAP_UART_LCR], 0x00);
		/* set MCR bit 6 to enable access to TCR and TLR registers */
	    set_port(dev->port[OMAP_UART_MCR], OMAP_MCR_TCRTLR, OMAP_MCR_TCRTLR);
		write_omap(dev->port[OMAP_UART_FCR], OMAP_FCR_ENABLE|OMAP_FCR_RXCLR|OMAP_FCR_TXCLR);

		tcr = 0x0e; 	/* set auto-rts assert at 56 bytes, restore at 0 bytes */
    	if (dev->tty.fifo) 
		{
        	/* Set RX fifo trigger level */
	        switch (dev->tty.fifo >> 4) {
    	        case FIFO_TRIG_8:
				default:   
					tlr = 0x20; 
					break;
        	    case FIFO_TRIG_16:  tlr = 0x40; break;
	            case FIFO_TRIG_32:  tlr = 0x80; break;
    	        case FIFO_TRIG_56:  tlr = 0xe0; break;
        	    case FIFO_TRIG_60:  
					tlr = 0xf0; 
					tcr = 0x0f; /* Ensure auto-rts trigger is not less the RX trigger */
					break;
	        }

    	    /* Set TX fifo trigger level */
        	switch (dev->tty.fifo & 0x0f) {
	            case FIFO_TRIG_8:   
				default:
					tlr |= 0x02;
					break;
    	        case FIFO_TRIG_16:  tlr |= 0x04; break;
        	    case FIFO_TRIG_32:  tlr |= 0x08; break;
            	case FIFO_TRIG_56:  tlr |= 0x0e; break;
	            case FIFO_TRIG_60:  tlr |= 0x0f; break;
    	    }
	    }

	    write_omap(dev->port[OMAP_UART_TCR], tcr);
	    write_omap(dev->port[OMAP_UART_TLR], tlr);
#ifdef PWR_MAN
	    write_omap(dev->port[OMAP_UART_SCR], OMAP_SCR_WAKEUPEN);
#else
		write_omap(dev->port[OMAP_UART_SCR], 0x00);
#endif
		/* Switch back to Config mode B to gain access to EFR again */
		write_omap(dev->port[OMAP_UART_LCR], 0xBF);
		/* remove access to TLR register */
		set_port(dev->port[OMAP_UART_EFR], OMAP_EFR_ENHANCED, 0);
		/* Switch to operational mode to get acces to MCR register */
		write_omap(dev->port[OMAP_UART_LCR], 0x00);
		/* clr MCR bit 6 to remove access to TCR and TLR registers */
	    set_port(dev->port[OMAP_UART_MCR], OMAP_MCR_TCRTLR, 0);

		ser_stty(dev);
		ser_attach_intr(dev);
	}
示例#21
0
int kdecl
ker_msg_error(THREAD *act, struct kerargs_msg_error *kap) {
	CONNECT				*cop;
	THREAD				*thp;

	if((cop = lookup_rcvid((KERARGS *)(void *)kap, kap->rcvid, &thp)) == NULL) {
		return ENOERROR;
	}

	// Make sure thread is replied blocked on a channel owned by this process.
	if(thp->state != STATE_REPLY && thp->state != STATE_NET_REPLY) {
		return ESRCH;
	}

	// Verify that the message has been fully received, and that the receiving
	// thread has completed any specialret() processing that needs to be done.
	if ( thp->internal_flags & _NTO_ITF_SPECRET_PENDING ) {
		return ESRCH;
	}

	if(thp->blocked_on != cop) {
		CONNECT *cop1 = cop;
		cop = thp->blocked_on;
		if((cop->flags & COF_VCONNECT) == 0 || cop->un.lcl.cop != cop1) {
			return ESRCH;
		}
	}

	if(thp->internal_flags & _NTO_ITF_UNBLOCK_QUEUED) {
		remove_unblock(thp, cop, kap->rcvid);
	}

	lock_kernel();

	if(thp->args.ms.server != 0) {
		thp->args.ms.server->client = 0;
		thp->args.ms.server = 0;
	}

	thp->flags &= ~(_NTO_TF_BUFF_MSG | _NTO_TF_UNBLOCK_REQ);
	if(kap->err == ERESTART) {
		CRASHCHECK(TYPE_MASK(thp->type) != TYPE_THREAD);
		SETKIP(thp, KIP(thp) - KER_ENTRY_SIZE);
	} else {
		if ( _TRACE_GETSYSCALL(thp->syscall) == __KER_CHANNEL_DESTROY ) {
			/* you may think we're crazy... but... ok, we ARE, but it's for the best, really.
			 *
			 * The only way we could be doing a MsgError on a thread that is really calling ChannelDestroy is
			 * if we were handling the destruction of channel which has off-node connections, and net_send2
			 * had to deal with the qnet manager.  It's now doing a MsgError to let us know the status of
			 * that message.  Unfortunately, the status field will overwrite the syscall type field of the
			 * thread, which will mean that he will restart his kernel call with the wrong kernel call number!
			 *
			 * Aiieeeeee!
			 */
			if ( kap->err != EOK ) {
				KerextSlogf( _SLOG_SETCODE( _SLOGC_QNET, 0 ), _SLOG_INFO, "Qnet ChannelDestroy failed %d", kap->err);
			}
		} else {
			kererr(thp, kap->err);
		}
	}
	_TRACE_COMM_EMIT_ERROR(thp, cop, thp->tid+1);

	LINKPRIL_REM(thp);
	if(--cop->links == 0) {
		connect_detach(cop, thp->priority);
	}
	ready(thp);

	act->restart = NULL;
	return EOK;
}