Esempio n. 1
0
/**
*
* \brief int open(const char *pathname, int flags);
* opens the CAN device for following operations
* \param pathname device pathname, usual /dev/can?
* \param flags is one of \c O_RDONLY, \c O_WRONLY or \c O_RDWR which request
*       opening  the  file  read-only,  write-only  or read/write,
*       respectively.
*
*
* The open call is used to "open" the device.
* Doing a first initialization according the to values in the /proc/sys/Can
* file system.
* Additional an ISR function is assigned to the IRQ.
*
* The CLK OUT pin is configured for creating the same frequency
* like the chips input frequency fclk (XTAL). 
*
* If Vendor Option \a VendOpt is set to 's' the driver performs
* an hardware reset befor initializing the chip.
*
* \returns
* open return the new file descriptor,
* or -1 if an error occurred (in which case, errno is set appropriately).
*
* \par ERRORS
* the following errors can occur
* \arg \c ENXIO  the file is a device special file
* and no corresponding device exists.
* \arg \c EINVAL illegal \b minor device number
* \arg \c EINVAL wrong IO-model format in /proc/sys/Can/IOmodel
* \arg \c EBUSY  IRQ for hardware is not available
* \arg \c EBUSY  I/O region for hardware is not available

*/
int can_open( __LDDK_OPEN_PARAM )
{
int retval = 0;

    DBGin("can_open");
    {

	int lasterr;	

	unsigned int minor = iminor(inode);

	if( minor > MAX_CHANNELS )
	{
	    printk(KERN_ERR "CAN: Illegal minor number %d\n", minor);
	    DBGout();
	    return -EINVAL;
	}

    /* check if device is already open, should be used only by one process */
	if(Can_isopen[minor] == 1) {
	    DBGout();
	    return -ENXIO;
	} 

	if( Base[minor] == 0x00) {
	    /* No device available */
	    printk(KERN_ERR "CAN[%d]: no device available\n", minor);
	    DBGout();
	    return -ENXIO;
	}

	/* the following does all the board specific things
	   also memory remapping if necessary */
	if( (lasterr = CAN_VendorInit(minor)) < 0 ){
	    DBGout();
	    return lasterr;
	}

	/* Access macros based in can_base[] should work now */
	/* CAN_ShowStat(minor); */

/* controller_available(curr + 0x400, 4); */
	Can_WaitInit(minor);	/* initialize wait queue for select() */
	Can_FifoInit(minor);
#if CAN_USE_FILTER
	Can_FilterInit(minor);
#endif

	if( CAN_ChipReset(minor) < 0 ) {
	    DBGout();
	    return -EINVAL;
	}
	CAN_StartChip(minor);
#if DEBUG
	CAN_ShowStat(minor);
#endif
	++Can_isopen[minor]; /* flag device in use */
    }

    DBGout();
    return retval;
}
Esempio n. 2
0
int can_select( __LDDK_SELECT_PARAM )
#endif
{

unsigned int minor = __LDDK_MINOR;
msg_fifo_t *RxFifo = &Rx_Buf[minor];
    DBGin("can_select");
	    DBGprint(DBG_DATA,("minor = %d", minor));
#if 0
	    DBGprint(DBG_DATA,("file = %p", file));
	    ;
	    DBGprint(DBG_DATA,("s(CanWait[]) = %2d", sizeof(CanWait[0])));
	    ;
	    /* DBGprint(DBG_DATA,("s(CanWait)   = %2d", sizeof(CanWait))); */
	    ;
	    DBGprint(DBG_DATA,("&CanWait[] = %p", &CanWait[0]));
	    DBGprint(DBG_DATA,("CanWait[minor].task_list.n = %p", CanWait[minor].task_list.next));
	    DBGprint(DBG_DATA,("CanWait[minor].task_list.p = %p", CanWait[minor].task_list.prev));
	    DBGprint(DBG_DATA,("&CanWait[minor]->task_list.p = %p", (&CanWait[minor])->task_list.prev));

	    DBGprint(DBG_DATA,("wait = %p", wait));
	    if(wait) {
	    DBGprint(DBG_DATA,("wait->error = %d", wait->error));
	    DBGprint(DBG_DATA,("wait->table = %p", wait->table));
	    } else {
	    DBGprint(DBG_DATA,("can not dereference wait components"));
	    }
#endif
#ifdef DEBUG
    CAN_ShowStat(minor);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
    DBGprint(DBG_BRANCH,("POLL: fifo empty,poll waiting...\n"));

    /* every event queue that could wake up the process
     * and change the status of the poll operation
     * can be added to the poll_table structure by
     * calling the function poll_wait:  
     */
                /*     _select para, wait queue, _select para */
/* X */		poll_wait(file, &CanWait[minor] , wait);

    DBGprint(DBG_BRANCH,("POLL: wait returned \n"));
    if( RxFifo->head != RxFifo->tail ) {
	/* fifo has some telegrams */
	/* Return a bit mask
	 * describing operations that could be immediately performed
	 * without blocking.
	 */
	DBGout();
	/*
	 * POLLIN This bit must be set
	 *        if the device can be read without blocking. 
	 * POLLRDNORM This bit must be set
	 * if "normal'' data is available for reading.
	 * A readable device returns (POLLIN | POLLRDNORM)
	 *
	 *
	 *
	 */
	return POLLIN | POLLRDNORM;
    }
    DBGout();return 0;

#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,3)
    DBGprint(DBG_BRANCH,("POLL: fifo empty,poll waiting...\n"));
    poll_wait(file, &CanWait[minor] , wait);
    DBGprint(DBG_BRANCH,("POLL: wait returned \n"));
    if( RxFifo->head != RxFifo->tail ) {
	/* fifo has some telegrams */
	DBGout();
	return POLLIN | POLLRDNORM;
    }
    DBGout();return 0;

#else
    switch (sel_type) {
	case SEL_IN:
	    DBGprint(DBG_BRANCH,("sel_in \n"));
	    if( RxFifo->head == RxFifo->tail ) {
		DBGprint(DBG_BRANCH,("fifo empty \n"));
		select_wait(&CanWait[minor],wait);
		DBGout();return 0;
	    }
	    break;
	case SEL_OUT:
	    DBGprint(DBG_BRANCH,("sel_out \n"));
	    /* ready for write ? */
	    select_wait(&CanWait[minor],wait);
	    DBGout();return 0;
    }
    DBGout();return 1;
#endif

        
    DBGout();
    return 0;
}