Пример #1
0
/*
 * Cleanup - unregister the appropriate file from /proc
 */
void ip860_intr_cleanup (void)
{
	int irq;

	debugk ("Cleanup IP860 Interrupt Support\n");

	/* make sure all interrupts are disabled */

	/* VME Interrupts first */
	for (irq=0; irq < NR_VME_INTERRUPTS; ++irq) {
		if (vme_intr_hdlr[irq].handler) {
			debugk ("Cleanup VME Interrupt handler vector 0x%02x\n",
				irq);
			free_ip860_irq (irq);
		}
	}

	/* the Onboard Interrupts */
	for ( ; irq < NR_VME_INTERRUPTS+NR_ONBOARD_INTERRUPTS; ++irq) {
		int index = irq - NR_VME_INTERRUPTS;
		if (onbd_intr_hdlr[index].int_hand.handler) {
			debugk ("Cleanup Onboard Interrupt handler vector 0x%02x\n",
				irq);
			free_ip860_irq (irq);
		}
	}

	debugk ("Cleanup completed\n");
}
Пример #2
0
/***********************************************************************
F* Function:     static ssize_t wd_write(struct file *filp, const char *buffer,
                                   size_t length, loff_t *offset) P*A*Z*
 *
P* Parameters:   struct file *file
P*                - Passed by the kernel, pointer to the file structure
P*                  for the device file
P*               char *buf
P*                - Pointer to buffer in userspace
P*               size_t count
P*                - Number of bytes to write
P*               loff_t *ppos
P*                - Offset for the write - ignored.
P*
P* Returnvalue:  int
P*                 - >0 number of bytes actually written, i.e. 4
P*                   <0 Errorcondition, which can be
P*                    -EINVAL  When trying to write more or less than 4
P*                             bytes, i.e. sizeof(unsigned)
P*                    -EFAULT  A user-provided pointer is invalid
 *
Z* Intention:    Set the rest counter to the value provided by the user
Z*               process interpreted as a number of seconds.
 *
D* Design:       Haider / [email protected]
C* Coding:       Haider / [email protected]
V* Verification: [email protected] / [email protected]
 ***********************************************************************/
static ssize_t wd_write(struct file *filp, const char *buffer,
				size_t length, loff_t *offset)
{
	int error;
	unsigned int new_count;

	debugk("ENTER %s (%p, %p, %d, %p)\n",
		__FUNCTION__, filp, buffer, length,  offset);

	if (length != sizeof(new_count)) {
		debugk("%s: invalid length (%d instead of %d)\n",
			__FUNCTION__, length, sizeof(new_count));

		return -EINVAL;
	}

	/* copy count value into kernel space */
	if ((error = get_user(new_count, (int *) buffer)) != 0) {
		debugk("%s: get_user failed: rc=%d\n",
			__FUNCTION__, error);

		return error;
	}

	/*
	 * The external interface is in seconds, but internal all calculations
	 * is done in jiffies.
	 */
	timer_count = HZ * new_count;

	return sizeof(new_count);
}
Пример #3
0
/***********************************************************************
F* Function:     static ssize_t wdt_mpc8xx_write (struct file *filp, const char *buffer,
				                  size_t length, loff_t *offset) P*A*Z*
 *
P* Parameters:   struct file *file
P*                - Passed by the kernel, pointer to the file structure
P*                  for the device file
P*               char *buf
P*                - Pointer to buffer in userspace
P*               size_t count
P*                - Number of bytes to write
P*               loff_t *ppos
P*                - Offset for the write - ignored.
P*
P* Returnvalue:  int
P*                 - >0 number of bytes actually written, i.e. 4
P*                   <0 Errorcondition, which can be
P*                    -EINVAL  When trying to write more or less than 4
P*                             bytes, i.e. sizeof(unsigned)
P*                    -EFAULT  A user-provided pointer is invalid
 *
Z* Intention:    Set the rest counter to the value provided by the user
Z*               process interpreted as a number of seconds.
 *
D* Design:       Haider / [email protected]
C* Coding:       Haider / [email protected]
V* Verification: [email protected] / [email protected]
 ***********************************************************************/
static ssize_t wdt_mpc8xx_write (struct file *filp, const char *buffer,
				 size_t length, loff_t *offset)
{
	int error;
	unsigned int new_count;

	debugk ("ENTER %s (%p, %p, %d, %p)\n",
		__FUNCTION__, filp, buffer, length,  offset);

	if (length != sizeof(new_count)) {
		debugk ("%s: invalid length (%d instead of %d)\n",
			__FUNCTION__, length, sizeof(new_count));

		return -EINVAL;
	}

	/* copy count value into kernel space */
	if ((error = get_user (new_count, (int *) buffer)) != 0) {
		debugk ("%s: get_user failed: rc=%d\n",
			__FUNCTION__, error);

		return (error);
	}

	timer_count = HZ * new_count;

	return (sizeof(new_count));
}
Пример #4
0
void 
soc_internal_init_hash_state(pcid_info_t *pcid_info)
{
    int         t, s, b;
    uint32      rval, banks;
    soc_block_t blk;
    uint8       at;

    /* Assign everything to ESM to begin with */
    for (b = 0; b < _SOC_ISM_MAX_BANKS; b++) {
        _soc_ism_bank_avail[pcid_info->unit][b] = SOC_ISM_MEM_ESM_L2;
    }
    for (t = 0; t < _SOC_ISM_MAX_TABLES; t++) {
        soc_internal_extended_read_reg(pcid_info, blk, at,
            soc_reg_addr_get(pcid_info->unit, _ism_table_bank_cfg_reg[t],
                             REG_PORT_ANY, 0, &blk, &at), &rval);
        debugk(DK_VERBOSE, "Table: %d = %x\n", t, rval);
        for (s = 0; s < _SOC_ISM_MAX_STAGES; s++) {
            banks = soc_reg_field_get(pcid_info->unit, _ism_table_bank_cfg_reg[t],
                                     rval, _ism_table_bank_cfg_fld[s]);
            for (b = 0; b < _SOC_ISM_BANKS_PER_STAGE; b++) { 
                if (banks & (1 << b)) {
                    debugk(DK_VERBOSE, "Bank[%d] = mem[%d]\n", (s * _SOC_ISM_BANKS_PER_STAGE) + b, t+1);
                    _soc_ism_bank_avail[pcid_info->unit][(s * _SOC_ISM_BANKS_PER_STAGE) + b] = t+1;
                }
            } 
        }
    }
} 
Пример #5
0
int 
soc_internal_generic_hash_lookup(pcid_info_t *pcid_info, soc_mem_t mem, int banks, 
                                 void *entry, uint32 *result)
{
    int rc;
    uint32 index;
    schan_genresp_v2_t *genresp = (schan_genresp_v2_t *) result;
    uint32 opres;

    debugk(DK_VERBOSE, "Mem: %d\n", mem);
    rc = soc_internal_generic_hash(pcid_info, mem, entry, banks, TABLE_LOOKUP_CMD_MSG,
                                   &index, &opres);
    
    genresp->err_info = 0;
    if (rc) {
        genresp->type = SCHAN_GEN_RESP_TYPE_ERROR;
        genresp->index = -1;
    } else if (opres == SCHAN_GEN_RESP_TYPE_NOT_FOUND) {
        genresp->type = opres;
        genresp->index = -1;
        debugk(DK_VERBOSE, "Not found\n");
    } else {
        genresp->type = opres;
        genresp->index = index;
        debugk(DK_VERBOSE, "Found Index: %d\n", index);
    }
    return SOC_E_NONE;
}
Пример #6
0
uint32 pci_config_getw(pci_dev_t *dev, uint32 addr)
{
    UINT32 inWord = 0;
    STATUS requestStatus;

    assert(! (addr & 3));

    debugk(DK_PCI, "PCI(%d,%d,%d) configR(0x%x)=",
	   dev->busNo, dev->devNo, dev->funcNo, addr);

    requestStatus = pciConfigInLong(dev->busNo,
				    dev->devNo,
				    dev->funcNo,
				    addr,
				    (UINT32*) &inWord);

    if (requestStatus != OK) {
	printk("ERROR: PCI configuration read bus=%d dev=%d func=%d "
               "(0x%x=0x%x) -READ ERROR(%d)\n",
	       dev->busNo, dev->devNo, dev->funcNo, addr, inWord, 
               requestStatus);
	return -1;
    } else {
	debugk(DK_PCI, "0x%x\n", inWord);
	return inWord;
    }
}
Пример #7
0
/***********************************************************************
F* Function:     static int wd_release(struct inode *inode,
F*                                              struct file *filp) P*A*Z*
 *
P* Parameters:   struct inode *inode
P*                - Inode of the device file being closed
P*               struct file *file
P*                - Passed by the kernel, but not used
P*
P* Returnvalue:  int
P*                - 0 is always returned
 *
Z* Intention:    This function is called by the kernel when a device file
Z*               of the driver is closed with close(2).
 *
D* Design:       Haider / [email protected]
C* Coding:       Haider / [email protected]
V* Verification: [email protected] / [email protected]
 ***********************************************************************/
static int wd_release(struct inode *inode, struct file *filp)
{
	debugk("ENTER %s (%p, %p)\n", __FUNCTION__, inode, filp);

	device_open--;			/* decrement usage counter */
	debugk("%s: /dev/watchdog closed\n", __FUNCTION__);

	return 0;
}
Пример #8
0
/***********************************************************************
F* Function:     static int wdt_mpc8xx_release (struct inode *inode,
F*                                              struct file *filp) P*A*Z*
 *
P* Parameters:   struct inode *inode
P*                - Inode of the device file being closed
P*               struct file *file
P*                - Passed by the kernel, but not used
P*
P* Returnvalue:  int
P*                - 0 is always returned
 *
Z* Intention:    This function is called by the kernel when a device file
Z*               of the driver is closed with close(2).
 *
D* Design:       Haider / [email protected]
C* Coding:       Haider / [email protected]
V* Verification: [email protected] / [email protected]
 ***********************************************************************/
static int wdt_mpc8xx_release (struct inode *inode, struct file *filp)
{
	debugk ("ENTER %s (%p, %p)\n", __FUNCTION__, inode, filp);

	device_open--;			/* decrement usage counter */
	MOD_DEC_USE_COUNT;
	debugk ("%s: WDT is closed\n", __FUNCTION__);

	return 0;
}
Пример #9
0
/***********************************************************************
F* Function:     static int wd_open(struct inode *inode,
F*                                           struct file *filp) P*A*Z*
 *
P* Parameters:   struct inode *inode
P*                - Inode of the device file being opened
P*               struct file *file
P*                - Passed by the kernel, but not used
P*
P* Returnvalue:  int - 0 success
P*                    <0 Errorcondition, which can be
P*                     -ENXIO  Watchdog is not enabled
 *
Z* Intention:    This function is called by the kernel when a device file
Z*               for the driver is opened by open(2).
 *
D* Design:       Haider / [email protected]
C* Coding:       Haider / [email protected]
V* Verification: [email protected] / [email protected]
 ***********************************************************************/
static int wd_open(struct inode *inode, struct file *filp)
{
	debugk("ENTER %s (%p, %p)\n", __FUNCTION__, inode, filp);

	if (!enabled) {			/* user interface disabled */
		return -ENXIO;
	}
	device_open++;			/* increment usage counter */
	opened = 1;
	debugk("%s: /dev/watchdog opened\n", __FUNCTION__);
	return 0;
}
Пример #10
0
/***********************************************************************
F* Function:     static int wdt_mpc8xx_open (struct inode *inode,
F*                                           struct file *filp) P*A*Z*
 *
P* Parameters:   struct inode *inode
P*                - Inode of the device file being opened
P*               struct file *file
P*                - Passed by the kernel, but not used
P*
P* Returnvalue:  int - 0 success
P*                    <0 Errorcondition, which can be
P*                     -ENXIO  Watchdog is not enabled
 *
Z* Intention:    This function is called by the kernel when a device file
Z*               for the driver is opened by open(2).
 *
D* Design:       Haider / [email protected]
C* Coding:       Haider / [email protected]
V* Verification: [email protected] / [email protected]
 ***********************************************************************/
static int wdt_mpc8xx_open (struct inode *inode, struct file *filp)
{
	debugk ("ENTER %s (%p, %p)\n", __FUNCTION__, inode, filp);

	if (!enabled) {			/* user interface disabled */
		return -ENXIO;
	}
	device_open++;			/* increment usage counter */
	MOD_INC_USE_COUNT;
	debugk ("%s: WDT is open\n", __FUNCTION__);
	return 0;
}
Пример #11
0
int 
soc_internal_generic_hash_delete(pcid_info_t *pcid_info, soc_mem_t mem, int banks, 
                                 void *entry, uint32 *result)
{
    int         rc, blk;             
    soc_block_t sblk;
    uint8       at;
    uint32      index, opres, tmp[SOC_MAX_MEM_WORDS];
    int         unit = pcid_info->unit; 
    schan_genresp_v2_t *genresp = (schan_genresp_v2_t *) result;

    debugk(DK_VERBOSE, "Mem: %d\n", mem);
    rc = soc_internal_generic_hash(pcid_info, mem, entry, banks, TABLE_DELETE_CMD_MSG,
                                   &index, &opres);
    
    genresp->err_info = 0;
    if (rc) {
        genresp->type = SCHAN_GEN_RESP_TYPE_ERROR;
        genresp->index = -1;
    } else if (opres == SCHAN_GEN_RESP_TYPE_NOT_FOUND) {
        genresp->type = opres;
        genresp->index = -1;
        debugk(DK_VERBOSE, "Not found\n");
    } else {
        genresp->type = opres;
        genresp->index = index;
        blk = SOC_MEM_BLOCK_ANY(unit, mem);
        sblk = SOC_BLOCK2SCH(unit, blk);
        soc_internal_extended_read_mem(pcid_info, sblk, at,
                                        soc_mem_addr_get(unit, mem, 0,
                                        blk, index, &at), (uint32 *)entry);
        if (soc_mem_field_valid(unit, mem, VALIDf)) {
            soc_mem_field32_set(unit, mem, tmp, VALIDf, 0);
        } else {
            soc_mem_field32_set(unit, mem, tmp, VALID_0f, 0);
            if (soc_mem_field_valid(unit, mem, VALID_1f)) {
                soc_mem_field32_set(unit, mem, tmp, VALID_1f, 0);
            }
            if (soc_mem_field_valid(unit, mem, VALID_2f)) {
                soc_mem_field32_set(unit, mem, tmp, VALID_2f, 0);
            }
            if (soc_mem_field_valid(unit, mem, VALID_3f)) {
                soc_mem_field32_set(unit, mem, tmp, VALID_3f, 0);
            }
        }  
        soc_internal_extended_write_mem(pcid_info, sblk, at,
                                        soc_mem_addr_get(unit, mem, 0,
                                        blk, index, &at), (uint32 *)tmp);
        debugk(DK_VERBOSE, "Deleted Index: %d\n", index);
    }
    return SOC_E_NONE;
}
Пример #12
0
/***********************************************************************
F* Function:	 void wdt_mpc8xx_reset (void) P*A*Z*
 *
P* Parameters:	 none
P*
P* Returnvalue:	 none
 *
Z* Intention:	 Reset the hardware watchdog.
Z*		 This function is callable from other kernel functions,
Z*		 too.
 *
D* Design:	 [email protected]
C* Coding:	 [email protected]
V* Verification: [email protected] / [email protected]
 ***********************************************************************/
void wdt_mpc8xx_reset (void)
{
	volatile immap_t *imap = (immap_t *) IMAP_ADDR;
#if defined(CONFIG_LWMON)
	/*
	 * The LWMON board uses a MAX706TESA Watchdog
	 * with the trigger pin connected to port PA.7
	 *
	 * The port has already been set up in the firmware,
	 * so we just have to toggle it.
	 */
	imap->im_ioport.iop_padat ^= 0x0100;
	/*
	 * Do NOT add a call to "debugk()" here;
	 * it would be called TOO often.
	 */
#else
	/*
	 * All other boards use the MPC8xx Internal Watchdog
	 */
	imap->im_siu_conf.sc_swsr = 0x556C;
	imap->im_siu_conf.sc_swsr = 0xAA39;
	debugk ("%s: WDT serviced\n", __FUNCTION__);
#endif /* CONFIG_LWMON */
}
Пример #13
0
Файл: dma.c Проект: ariavie/bcm
uint32
pcid_dcb_fetch(pcid_info_t *pcid_info, uint32 addr, dcb_t *dcb)
{
    int     size, i;
    uint32  *temp;

    debugk(DK_DMA, "Reading descriptor at 0x%08x\n", addr);

    size = SOC_DCB_SIZE(pcid_info->unit);
    soc_internal_bytes_fetch(pcid_info, addr, (uint8 *)dcb, size);

    /* Convert to chip(same as host for sim mode) endian-ness */
    temp = (uint32 *)dcb;
    for (i=0; i < (size/sizeof(uint32)); i++) {
        *(temp + i) = soc_internal_endian_swap(pcid_info, *(temp + i), 
                                               MF_ES_DMA_OTHER);
    }

#ifdef BROADCOM_DEBUG
    if (debugk_check(DK_DMA)) {
	SOC_DCB_DUMP(pcid_info->unit, dcb, "PCID Fetch", 0);
    }
#endif /* BROADCOM_DEBUG */

    return addr + size;
}
Пример #14
0
int replayfs_fs_init(void) {
	int err;

	perftimer_init();

	debugk("Sizeof pgoff_t is %u, loff_t %u\n", sizeof(pgoff_t),
			sizeof(loff_t));

	if (PAGE_SIZE != sizeof(struct replayfs_dir_page)) {
		printk("REPLAYFS ERROR: PAGE_SIZE == %lu, replayfs_dir_page size == %d\n",
				PAGE_SIZE, sizeof(struct replayfs_dir_page));
		return 1;
	}

	/* Init memory management */
	if (replayfs_init_allocators()) {
		return 1;
	}

	/* All is going well so far, setup our super block */
	err = register_filesystem(&replayfs_type);
	if (err) {
		replayfs_destroy_allocators();
		return 1;
	}

	return 0;
}
Пример #15
0
/***********************************************************************
F* Function:     void cleanup_module (void) P*A*Z*
 *
P* Parameters:   none
P*
P* Returnvalue:  none
 *
Z* Intention:    Cleanup and shutdown the driver to allow unloading
Z*               of the module.
 *
D* Design:       Haider / [email protected]
C* Coding:       Haider / [email protected]
V* Verification: [email protected] / [email protected]
 ***********************************************************************/
void cleanup_module (void)
{
	debugk ("%s: cleanup WDT8xx\n", __FUNCTION__);

	del_timer (&wd_timer);
	free_mon_list();

	misc_deregister (&wdt_miscdev);
}
Пример #16
0
static int replayfs_create(struct inode *dir, struct dentry *dentry, int mode,
		struct nameidata *nd) {
	struct inode *inode;

	int err;

	inode = replayfs_new_inode(dir->i_sb, mode);
	err = PTR_ERR(inode);

	debugk("%s %d: Creating a new inode, parent has mode %o\n", __func__,
			__LINE__, dir->i_mode);

	if (!IS_ERR(inode)) {
		replayfs_log_t log;
		replayfs_log_inode_t log_inode;

		inode->i_op = &replayfs_file_iops;
		inode->i_mapping->a_ops = &replayfs_aops;
		inode->i_fop = &replayfs_fops;

		replayfs_begin_log_operation(&log);

		replayfs_log_add_inode(&log, &log_inode, dentry->d_parent->d_inode);

		mark_inode_dirty(inode);

		err = replayfs_dir_add_nondir(dentry, inode, &log, &log_inode);

		replayfs_log_inode_done(&log, &log_inode,
					dentry->d_parent->d_inode->i_size);

		/* Save the metadata modification to the new inode */
		replayfs_log_add_inode(&log, &log_inode, inode);

		replayfs_inode_modified_metadata(inode, &log, &log_inode);

		replayfs_log_inode_done(&log, &log_inode, inode->i_size);
		replayfs_end_log_operation(&log);
	}

	debugk("%s %d: Done creating a new inode\n", __func__, __LINE__);

	return err;
}
Пример #17
0
/***********************************************************************
F* Function:     void wd_cleanup(void) P*A*Z*
 *
P* Parameters:   none
P*
P* Returnvalue:  none
 *
Z* Intention:    Cleanup and shutdown the driver to allow unloading
Z*               of the module.
 *
D* Design:       Haider / [email protected]
C* Coding:       Haider / [email protected]
V* Verification: [email protected] / [email protected]
 ***********************************************************************/
void wd_cleanup(void)
{
	debugk("%s: cleanup WD\n", __FUNCTION__);

	misc_deregister(&wd_miscdev);
	BUG_ON(wd_hw_functions.wd_delete == NULL);
	wd_hw_functions.wd_delete();
	del_timer(&wd_timer);
	free_mon_list();
}
Пример #18
0
int 
soc_internal_generic_hash_insert(pcid_info_t *pcid_info, soc_mem_t mem, int32 banks, 
                                 void *entry, uint32 *result)
{   
    int rc,     blk;             
    soc_block_t sblk;
    uint8       at;
    uint32      index, opres;
    int         unit = pcid_info->unit; 
    schan_genresp_v2_t *genresp = (schan_genresp_v2_t *) result;

    debugk(DK_VERBOSE, "Mem: %d\n", mem);
    rc = soc_internal_generic_hash(pcid_info, mem, entry, banks, TABLE_INSERT_CMD_MSG,
                                   &index, &opres);
    
    genresp->err_info = 0;
    if (rc) {
        genresp->type = SCHAN_GEN_RESP_TYPE_ERROR;
        genresp->index = -1;
    } else {
        genresp->type = opres;
        if (opres == SCHAN_GEN_RESP_TYPE_FULL) {
            genresp->index = -1;
            debugk(DK_VERBOSE, "Full\n");
        } else {
            blk = SOC_MEM_BLOCK_ANY(unit, mem);
            sblk = SOC_BLOCK2SCH(unit, blk);
            genresp->index = index;
            soc_internal_extended_write_mem(pcid_info, sblk, at,
                                            soc_mem_addr_get(unit, mem, 0,
                                            blk, index, &at), (uint32 *)entry);
            if (opres == SCHAN_GEN_RESP_TYPE_REPLACED) {
                debugk(DK_VERBOSE, "Replace ");
            } else {
                debugk(DK_VERBOSE, "Insert ");
            }
            debugk(DK_VERBOSE, "Index: %d\n", index);
        }
    }
    return SOC_E_NONE;
}
Пример #19
0
/***********************************************************************
F* Function:     static ssize_t wdt_mpc8xx_read (struct file *filp, char *buffer,
				size_t length, loff_t *offset) P*A*Z*
 *
P* Parameters:   struct file *file
P*                - Passed by the kernel, pointer to the file structure
P*                  for the device file
P*               char *buf
P*                - Pointer to buffer in userspace
P*               size_t count
P*                - Number of bytes to read
P*               loff_t *ppos
P*                - Offset for the read - ignored.
P*
P* Returnvalue:  int
P*                 - >0 number of bytes read, i.e. 4
P*                   <0 Errorcondition, which can be
P*                    -EINVAL  When trying to read fewer bytes than the
P*                             rest counter occupies, i.e. sizeof(unsigned)
P*                    -EFAULT  A user-provided pointer is invalid
 *
Z* Intention:    Read the rest counter from the device.
 *
D* Design:       Haider / [email protected]
C* Coding:       Haider / [email protected]
V* Verification: [email protected] / [email protected]
 ***********************************************************************/
static ssize_t wdt_mpc8xx_read (struct file *filp, char *buffer,
				size_t length,   loff_t *offset)
{
	unsigned int rest_count = timer_count / HZ;
	int rc;

	debugk ("ENTER %s (%p, %p, %d, %p)\n",
		__FUNCTION__, filp, buffer, length,  offset);

	if (length < sizeof(rest_count)) {
		debugk ("wdt_mpc8xx_release/kernel: invalid argument\n");

		return -EINVAL;
	}
	/* copy value into userspace */
	if ((rc=put_user (rest_count, (int *) buffer)))
		return(rc);

	debugk ("%s: rest_count=%i\n", __FUNCTION__, rest_count);

	return (sizeof(rest_count));	/* read always exactly 4 bytes */
}
Пример #20
0
/***********************************************************************
F* Function:     void wd_handler(unsigned long ptr) P*A*Z*
 *
P* Parameters:   unsigned long ptr
P*                - Parameter passed in from the timer invocation, ignored
P*
P* Returnvalue:  none
 *
Z* Intention:    This is the core functionality of the watchdog.  It is
Z*               called from the timer wd_timer and handles the necessary
Z*               processing, including resetting the hardware watchdog.
Z*               When chains are registered, they override the
Z*               default behaviour and are processed in process_mon_chains().
 *
D* Design:       Haider / [email protected]
C* Coding:       Haider / [email protected]
V* Verification: [email protected] / [email protected]
 ***********************************************************************/
void wd_handler(unsigned long ptr)
{
	debugk("%s: timer_count=%ld jiffies\n", __FUNCTION__, timer_count);

	if ((timer_count == 0) && enabled) {
		printk("WD: Reseting system...\n");
		BUG_ON(wd_hw_functions.wd_machine_restart == NULL);
		wd_hw_functions.wd_machine_restart();
	} else if ((timer_count > 0) || (!enabled)) {

		/* execute WD service sequence */
		BUG_ON(wd_hw_functions.wd_kick == NULL);
		wd_hw_functions.wd_kick();

		wd_timer.expires = jiffies + timer_period;
		add_timer(&wd_timer);	/* ...re-activate timer */

		/*
		 * process the monitor list
		 */
		process_mon_chains();

		/*
		 * don't timeout if disabled
		 */
		if (!enabled)
			return;

		/* don't timeout if interface was never opened */
		if (!opened)
			return;
		/*
		 * don't timeout if new interface is used or if device
		 * is not opened
		 */
		if (((timeout_open_only && (!device_open)) || mon_chains))
			return;

		/* decrement variable for timer-control */
		if (timer_count > timer_period)
			timer_count -= timer_period;
		else
			timer_count = 0;

		if (timer_count == 0)
			printk("WD: watchdog about to expire\n");
	}

	return;
}
Пример #21
0
/***********************************************************************
F* Function:     static void free_mon_list(void) P*A*Z*
 *
P* Parameters:   none
P*
P* Returnvalue:  none
 *
Z* Intention:    This function frees the entire kmalloc'ed list of
Z*               monitored chains in case the module is unloaded.
 *
D* Design:       [email protected]
C* Coding:       [email protected]
V* Verification: [email protected]
 ***********************************************************************/
static void free_mon_list(void)
{
	struct list_head *ptr, *n;
	monitored_chain_t *entry;

	debugk("%s: WDT8xx freeing monitor list\n", __FUNCTION__);

	spin_lock(&mon_lock);

	for (ptr=mon_list.next, n=ptr->next; ptr!=&mon_list; ptr=n) {
		entry=list_entry(ptr, monitored_chain_t, list);
		kfree(entry);
	}

	spin_unlock(&mon_lock);
}
Пример #22
0
int pci_config_putw(pci_dev_t *dev, uint32 addr, uint32 data)
{
    STATUS requestStatus;

    debugk(DK_PCI,
	   "PCI(%d,%d,%d) configW(0x%x)=0x%x\n",
	   dev->busNo, dev->devNo, dev->funcNo, addr, data);

    assert(! (addr & 3));

    requestStatus = pciConfigOutLong(dev->busNo,
				     dev->devNo,
				     dev->funcNo,
				     (int) addr,
				     (UINT32) data);
    return requestStatus;
}
Пример #23
0
/***********************************************************************
F* Function:     int wdt_mpc8xx_unregister_mon_chain(unsigned int chainid) P*A*Z*
 *
P* Parameters:   unsigned int chainid
P*                - The id of the chain to unregister
P*
P* Returnvalue:  int
P*                - 0 The chain was unregistered successfully
P*                  -EINVAL  The chainid is unknown
 *
Z* Intention:    When the watchdog functionality is no longer needed,
Z*               chains can be unregistered through this call.
Z*               The function is called through the ioctl() mechanism
Z*               or directly from other kernel proper, as it is exported.
 *
D* Design:       [email protected]
C* Coding:       [email protected]
V* Verification: [email protected]
 ***********************************************************************/
int wdt_mpc8xx_unregister_mon_chain(unsigned int chainid)
{
	monitored_chain_t *entry;

	if ((entry=find_mon_chain_by_chainid(chainid))==NULL)
		return(-EINVAL);

	debugk("%s: WDT8xx unregistering monitor for id %d\n", __FUNCTION__, entry->chainid);

	spin_lock(&mon_lock);

	list_del(&entry->list);
	kfree(entry);

	spin_unlock(&mon_lock);

	return(0);
}
Пример #24
0
/***********************************************************************
F* Function:     int wd_reset_mon_chain(int chainid) P*A*Z*
 *
P* Parameters:   int chainid
P*                - The id of the chain to reset
P*
P* Returnvalue:  int
P*                - 0 The chain was reset suiccessfully
P*                 <0 Errorcondition, which can be
P*                  -EINVAL The supplied id is unknown.
 *
Z* Intention:    This function resets a chain to its initial state.
Z*               The function is called through the ioctl() mechanism
Z*               to reset or trigger a chain or directly from other
Z*               kernel proper, as it is exported.
 *
D* Design:       [email protected]
C* Coding:       [email protected]
V* Verification: [email protected]
 ***********************************************************************/
int wd_reset_mon_chain(int chainid)
{
	monitored_chain_t *entry;
	int result = 0;

	debugk("%s: WD monitor reset for id %d\n", __FUNCTION__, chainid);

	spin_lock(&mon_lock);

	if ((entry = find_mon_chain_by_chainid(chainid)) == NULL) {
		result = -EINVAL;
		goto out;
	}
	entry->escalation = 0;
	entry->expires = jiffies + HZ * entry->timer_count[0];
	list_del(&entry->list);
	insert_mon_chain(entry);
out:
	spin_unlock(&mon_lock);

	return result;
}
Пример #25
0
/***************************************************************************
 *
 * Initialize the module
 */
static int __init ip860_intr_init (void)
{
	vme_mem_t *p;

	printk (KERN_INFO
		"IP860 Extended Interrupt Support version "
		IP860_INTR_VERSION
		"\n"
	);

	if ((p = vme_mem_dev(VME_MEM_BCSR)) == NULL)
		return (-ENODEV);

	bcsr  = (ip860_bcsr_t *)(p->addr);

	if ((p = vme_mem_dev(VME_MEM_IPMOD)) == NULL)
		return (-ENODEV);

	ip_mod = (vu_short *)(p->addr);

	debugk ("IP860 Interrupt Support installed\n");

	return 0;
}
Пример #26
0
/*
 * main: Sets up the socket and handles client requests with a child 
 * process per socket.                                       
 */
void
dmac_listener(void *v_void)
{
    verinet_t *v = (verinet_t *)v_void;
    int sockfd, newsockfd, one = 1;
    socklen_t clilen;
    struct sockaddr_in cli_addr, serv_addr;

    /* Initialize socket ... */

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
	perror("server: can't open stream socket");
	exit(1);
    }

    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
		   (char *) &one, sizeof (one)) < 0) {
	perror("setsockopt");
    }

    /*
     * Setup server address...
     */
    memset((void *) &serv_addr,0x0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(0);	/* Pick any port */

    /*
     * Bind our local address
     */
    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
	perror("dmac: unable to bind address");
	sal_thread_exit(0);
    }

    v->dmaPort = getsockport(sockfd);	/* Get port that was picked */

    /* listen for inbound connections ... */
    listen(sockfd, 5);
  
    /* Notify dmac_init that socket is listening */
    sal_sem_give(v->dmacListening);

    printk("DMA Controller listening on port[%d]\n", v->dmaPort);

    while (!v->dmacWorkerExit) { 
	clilen = sizeof(cli_addr);

	newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
	if (newsockfd < 0 && errno == EINTR) {
	    continue;
	}

	if (newsockfd < 0) {
	    perror("server: accept error");
	} else {
	    v->dmacFd = newsockfd;
	    v->dmacHandler = sal_thread_create("DMA-controller",
						SAL_THREAD_STKSZ, 100,
						dmac_handler, v);

	    if (SAL_THREAD_ERROR == v->dmacHandler) {
		printk("Thread creation error!\n");
	    } else {
		debugk(DK_VERINET, "DMAC request thread dispatched.\n");
	    }
	}
    }
    debugk(DK_VERINET, "DMA listener shutdown.\n");
    sal_thread_exit(0);
}
Пример #27
0
/*
 * Main thread of control. This worker thread will service requests
 * on a socket, read or writing to memory based on the command
 * dispatched from the main execution thread.
 */ 
void
dmac_handler(void *v_void)
{
    verinet_t *v = (verinet_t *)v_void;
    volatile int finished = 0;
    volatile uint32 dmaAddr, dmaData;
    rpc_cmd_t cmd;
    int sockfd = v->dmacFd;
    uint8 *byte_ptr;
    uint32 i;

    while (!finished){    
	debugk(DK_VERINET, "dmac_handler: wait...\n");

	if (wait_command(sockfd, &cmd) < 0) {
	    break;	/* Error message already printed */
	}

	debugk(DK_VERINET, "dmac_handler: request opcode 0x%x\n",
	       cmd.opcode);

	switch(cmd.opcode){
	case RPC_DMAC_READ_REQ:
	    /* Read DMA memory ... */
	    dmaAddr = cmd.args[0];
	    /* Read data from shared memory at Addr */
	    dmaData = _dma_getw(dmaAddr);
	    debugk(DK_VERINET, "**DMA_RD: 0x%x = 0x%x\n", dmaAddr, dmaData);
	    /* Send back a response */
	    make_rpc_getmem_resp(&cmd, dmaData);
	    write_command(sockfd, &cmd);
	    break;
      
	case RPC_DMAC_WRITE_REQ:
	    /* Write DMA memory ... */
	    dmaAddr = cmd.args[0]; /* Address */
	    dmaData = cmd.args[1]; /* Data */
	    /* Write the data to shared memory */
	    _dma_putw(dmaAddr, dmaData);
	    debugk(DK_VERINET, "**DMA_WR: 0x%x = 0x%x\n", dmaAddr, dmaData);
	    /* Send back a response */
	    make_rpc_setmem_resp(&cmd,dmaData);
	    write_command(sockfd, &cmd);
	    break;

	case RPC_DMAC_READ_BYTES_REQ:
	    /* Read DMA memory as a string.  Would be nice to use memcpy */
	    dmaAddr = cmd.args[0];
            byte_ptr = (uint8 *)&cmd.args[1];
	    debugk(DK_VERINET, "**DMA_RD_B: 0x%x, %d bytes\n",
                   dmaAddr, cmd.argcount);
            for (i = 0; i < cmd.argcount; i++) {
                byte_ptr[i] = _dma_getb(dmaAddr++);
            }
	    /* Send back a response */
            cmd.status = RPC_OK;
            cmd.opcode = RPC_DMAC_READ_BYTES_RESP;
	    write_command(sockfd, &cmd);
	    break;

	case RPC_DMAC_WRITE_BYTES_REQ:
	    /* Write DMA memory as a string.  Would be nice to use memcpy */
	    dmaAddr = cmd.args[0]; /* Address */
	    byte_ptr = (uint8 *)&cmd.args[1]; /* Data */
	    /* Write the data to shared memory */
	    debugk(DK_VERINET, "**DMA_WR_B: 0x%x, %d bytes\n",
                   dmaAddr, cmd.argcount);
            for (i = 0; i < cmd.argcount; i++) {
                _dma_putb(dmaAddr++, byte_ptr[i]);
            }
	    /* Send back a response */
            cmd.status = RPC_OK;
            cmd.opcode = RPC_DMAC_WRITE_BYTES_RESP;
	    write_command(sockfd, &cmd);
	    break;

	case RPC_DISCONNECT:
	    finished = 1;
	    v->dmacWorkerExit++;
	    printk("dma thread received disconnect\n");
	    exit(0);
	    break;
      
	default:
	    /* Unknown opcode */
	    break;
	}
    }
    printk("DMA controller shutdown.\n");
    close(sockfd);
    sal_thread_exit(0);
}
Пример #28
0
/***********************************************************************
F* Function:     static int register_mon_chain(wdt_mpc8xx_param_t *param,
F*                                             int userproc) P*A*Z*
 *
P* Parameters:   wdt_mpc8xx_param_t *param
P*                - The parameters for the chain to be registered.
P*                  Unused stages should be cleared with 0's.
P*               int userproc
P*                - Flag whether we are called from user or kernel space
P*
P* Returnvalue:  int
P*                - 0  success
P*                  -EINVAL  invalid parameters
P*                  -ENOMEM  out of memory
 *
Z* Intention:    This is the main interface to register a watchdog chain
Z*               either from userspace throught ioctl() or from kernel
Z*               space through the wrapper function
Z*               wdt_mpc8x_register_mon_chain().
Z*               Re-registering an existing chain is explicitely ok, as
Z*               a restarted process has to go through this.  This
Z*               effectively resets the corresponding chain.
Z*               For a detailed description of the parameters, see the
Z*               wdt_mpc8xx(4) manpage.
 *
D* Design:       [email protected]
C* Coding:       [email protected]
V* Verification: [email protected]
 ***********************************************************************/
static int register_mon_chain(wdt_mpc8xx_param_t *param, int userproc)
{
	monitored_chain_t *entry;
	int result=0, i;

	/* Before kmallocing storage we first check the parameters */
	for (i=0; (i<3)&&(param->timer_count[i]); i++)
		if ((param->action[i]<WDT_MPC8XX_ACTION_SIGNAL)||
		    (param->action[i]>WDT_MPC8XX_ACTION_RESET))
			return(-EINVAL);

	debugk("%s: registering WDT8xx monitor\n", __FUNCTION__);

	spin_lock(&mon_lock);

	if ((entry=find_mon_chain_by_chainid(param->chainid))==NULL) {
		/* New chain-id so allocate list entry */
		entry=(monitored_chain_t *)kmalloc(sizeof(monitored_chain_t), GFP_KERNEL);
		if (entry==NULL) {
			result=-ENOMEM;
			goto out;
		}

		/* Copy request data to internal format */
		if (userproc)
			entry->pid=current->pid;
		else
			entry->pid=0;
		entry->chainid=param->chainid;
		entry->signal=param->signal;
		for (i=0; i<2 ; i++) {
			if (entry->action[i]!=0) {
				entry->timer_count[i]=param->timer_count[i];
				entry->action[i]=param->action[i];
			} else {
				/* Fill with stop entries */
				entry->timer_count[i]=2;
				entry->action[i]=WDT_MPC8XX_ACTION_RESET;
			}
		}
					
		/* This is a final stop entry */
		entry->timer_count[3]=2;
		entry->action[3]=WDT_MPC8XX_ACTION_RESET;

		/* Initialize internal data */
		entry->escalation=0;
		entry->expires=jiffies + HZ * entry->timer_count[0];
		insert_mon_chain(entry);
		mon_chains++;
	} else {
		/* Re-registering of active monitor */
		entry->pid=current->pid;
		entry->escalation=0;
		entry->expires=jiffies + HZ * entry->timer_count[0];
		entry->escalation=0;
		list_del(&entry->list);
		insert_mon_chain(entry);
	}

 out:
	spin_unlock(&mon_lock);

	return(result);
}
Пример #29
0
/***********************************************************************
F* Function:     void wdt_mpc8xx_handler (unsigned long ptr) P*A*Z*
 *
P* Parameters:   unsigned long ptr
P*                - Parameter passed in from the timer invocation, ignored
P*
P* Returnvalue:  none
 *
Z* Intention:    This is the core functionality of the watchdog.  It is
Z*               called from the timer wd_timer and handles the necessary
Z*               processing, including resetting the hardware watchdog.
Z*               When chains are registered, they override the
Z*               default behaviour and are processed in process_mon_chains().
 *
D* Design:       Haider / [email protected]
C* Coding:       Haider / [email protected]
V* Verification: [email protected] / [email protected]
 ***********************************************************************/
void wdt_mpc8xx_handler (unsigned long ptr)
{

#ifndef CONFIG_LWMON	/* This produces too much output on the LWMON */
	debugk ("%s: timer_count=%d jiffies\n", __FUNCTION__, timer_count);
#endif

	/*
	 * Signal arch/ppc/kernel/time.c that this driver has taken
	 * over the responsibility to trigger the watchdog
	 */
	wdt_mpc8xx_is_ready = 1;

	if ((timer_count == 0) && enabled) {	/* try "graceful" shutdown */
		printk ("WDT_8xx: Reset system...\n");
#ifdef CONFIG_8xx
		m8xx_restart (NULL);
#else
		machine_restart (NULL);
#endif
	}

	if ((timer_count > 0) || (!enabled)) {

		/* execute WDT service sequence */
		wdt_mpc8xx_reset ();

		wd_timer.expires = jiffies + timer_period;
		add_timer (&wd_timer);	/* ...re-activate timer */

		/*
		 * process the monitor list
		 */
		process_mon_chains();

		/*
		 * don't timeout if disabled
		 */
		if (!enabled)
			return;

		/*
		 * don't timeout if new interface is used or if device
		 * is not opened
		 */
		if ((timeout_open_only && (!device_open)) || mon_chains)
			return;

		/* decrement variable for timer-control */
		if (timer_count > timer_period)
			timer_count -= timer_period;
		else
			timer_count = 0;

		if (timer_count == 0) {
			printk ("WDT_8xx: watchdog about to expire\n");
		}
	}

	return;
}
Пример #30
0
/***********************************************************************
F* Function:     int init_module (void) P*A*Z*
 *
P* Parameters:   none
P*
P* Returnvalue:  int
P*                - see wdt_mpc8xx_init()
 *
Z* Intention:    This is a wrapper function for the module initialization
Z*               simply calling wdt_mpc8xx_init().
 *
D* Design:       Haider / [email protected]
C* Coding:       Haider / [email protected]
V* Verification: [email protected] / [email protected]
 ***********************************************************************/
int init_module (void)
{
	debugk ("%s: initialize WDT8xx\n", __FUNCTION__);

	return wdt_mpc8xx_init ();
}