Example #1
0
void EnableCtrInterrupt(void) {

	unsigned int val;

	printk(KERN_DEBUG PFX "Enabling PPS interrupt on IRQ%d Vector %d\n",
	       CTR_IRQ_LEVEL, CTR_IRQ_VECTOR);

	/* Setup the IRQ level and vector */
	val = (unsigned long)((CTR_IRQ_LEVEL << 8) | (CTR_IRQ_VECTOR & 0xff));
	iowrite32be(val, &mmap->Setup);

	if (vme_bus_error_check(1))
		printk(KERN_ERR PFX "Bus error writing Setup\n");

	/* Will interrupt once per second */
	iowrite32be(CtrDrvrInterruptMaskPPS, &mmap->InterruptEnable);

	if (vme_bus_error_check(1))
		printk(KERN_ERR PFX "Bus error writing InterruptEnable\n");

	val = ioread32be(&mmap->InterruptEnable);

	if (vme_bus_error_check(1))
		printk(KERN_ERR PFX "Bus error reading InterruptEnable\n");

	if (val != CtrDrvrInterruptMaskPPS)
		printk(KERN_DEBUG PFX "Failed to enable PPS interrupt %08x\n",
			val);
}
Example #2
0
void DisableCtrModule(void)
{
	int val = ioread32be(&mmap->Command);

	printk(KERN_DEBUG PFX "Disabling CTR module\n");

	if (vme_bus_error_check(1))
		printk(KERN_ERR PFX "Bus error reading Command\n");

	val &= ~CtrDrvrCommandENABLE;
	val |= CtrDrvrCommandDISABLE;

	iowrite32be(val, &mmap->Command);

	if (vme_bus_error_check(1))
		printk(KERN_ERR PFX "Bus error writing Command\n");
}
Example #3
0
void DisableCtrInterrupt(void)
{
	printk(KERN_DEBUG PFX "Disabling PPS interrupt\n");
	iowrite32be(0, &mmap->InterruptEnable);

	if (vme_bus_error_check(1))
		printk(KERN_ERR PFX "Bus error writing InterruptEnable\n");
}
Example #4
0
/**
 * \brief Get the number of post-trigger samples
 *
 * \return the number of requested samples on success or -1 on a VME bus error.
 *
 * Get the number of post-trigger samples requested.
 */
int vd80_get_postsamples(void)
{
	int val = swapbe32(regs[VD80_TCR2/4]);

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error reading POSTSAMPLES\n");
		return -1;
	}

	return val;
}
Example #5
0
void ResetCtr(void)
{
	printk(KERN_DEBUG PFX "Resetting CTR module\n");
	iowrite32be(CtrDrvrCommandRESET, &mmap->Command);

	if (vme_bus_error_check(1))
		printk(KERN_ERR PFX "Bus error Writing Command\n");

	/* Wait at least 10 ms after a "reset", for the module to recover */
	msleep(20);
}
Example #6
0
/**
 * \brief Generate an internal trigger
 *
 * \return 0 on success else 1 on a VME bus error.
 */
int vd80_cmd_trig(void)
{
	regs[VD80_GCR1/4] |= swapbe32(VD80_COMMAND_TRIG);

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error triggering sampling\n");
		return 1;
	}

	return 0;
}
Example #7
0
/**
 * \brief Record only a single sample
 *
 * \return 0 on success else 1 on a VME bus error.
 */
int vd80_cmd_single(void)
{
	regs[VD80_GCR1/4] |= swapbe32(VD80_COMMAND_SINGLE);

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error setting SINGLE\n");
		return 1;
	}

	return 0;
}
Example #8
0
/**
 * \brief Stop sampling
 *
 * \return 0 on success else 1 on a VME bus error.
 */
int vd80_cmd_stop(void)
{
	regs[VD80_GCR1/4] |= swapbe32(VD80_COMMAND_STOP);

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error stopping sampling\n");
		return 1;
	}

	return 0;
}
Example #9
0
/**
 * \brief Start subsampling
 *
 * \return 0 on success else 1 on a VME bus error.
 */
int vd80_cmd_substart(void)
{
	regs[VD80_GCR1/4] |= swapbe32(VD80_COMMAND_SUBSTART);

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error starting sub sampling\n");
		return 1;
	}

	return 0;
}
Example #10
0
/**
 * \brief Clear the pre-trigger counter
 *
 * \return 0 on success else 1 on a VME bus error.
 */
int vd80_cmd_clear(void)
{
	regs[VD80_GCR1/4] |= swapbe32(VD80_COMMAND_CLEAR);

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error setting CLEAR\n");
		return 1;
	}

	return 0;
}
Example #11
0
/**
 * \brief Set the readout starting sample
 * \param readstart READSTART value to set
 *
 * \return 0 on success else 1 on a VME bus error.
 *
 * \note READSTART counts in steps of 32 samples. Therefore the number of
 * samples is READSTART * 32.
 */
int vd80_set_readstart(unsigned int readstart)
{
	regs[VD80_MCR1/4] = swapbe32((readstart << VD80_READSTART_SHIFT) &
				     VD80_READSTART_MASK);

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error setting READSTART\n");
		return 1;
	}

	return 0;
}
Example #12
0
/**
 * \brief Set the number of post-trigger samples
 * \param num Number of post-trigger samples to store
 *
 * \return 0 on success or -1 on a VME bus error.
 *
 * Set the number of samples recorded between the trigger and sampling end.
 */
int vd80_set_postsamples(unsigned int num)
{

	regs[VD80_TCR2/4] = swapbe32(num & 0x7ffff);

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error setting POSTSAMPLES\n");
		return -1;
	}

	return 0;
}
Example #13
0
/**
 * \brief Set the number of samples that must be read
 * \param readlen READLEN value to set
 *
 * \return 0 on success else 1 on a VME bus error.
 *
 * \note READLEN counts in steps of 32 samples. Therefore the number of samples
 * is (READLEN + 1) * 32 and the minimum number of samples is 32
 */
int vd80_set_readlen(unsigned int readlen)
{
	regs[VD80_MCR2/4] = swapbe32((readlen << VD80_READLEN_SHIFT) &
				     VD80_READLEN_MASK);

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error setting READLEN\n");
		return 1;
	}

	return 0;
}
Example #14
0
/**
 * \brief Get the number of post-trigger samples
 *
 * \return the number of post-trigger samples or -1 on a VME bus error.
 *
 * Get the number of samples recorded between the trigger and the sampling
 * end.
 */
int vd80_get_post_length(void)
{
	int reg = swapbe32(regs[VD80_TSR/4]);
	int val = (reg & VD80_ACTPOSTSAMPLES_MASK) >>
		VD80_ACTPOSTSAMPLES_SHIFT;

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error reading ACTPOSTSAMPLES\n");
		return -1;
	}

	return val;
}
Example #15
0
/**
 * \brief Get the total shot length
 *
 * \return the total number of samples or -1 on a VME bus error.
 *
 * Get the total number of samples taken during a shot
 * (pre-samples + post-samples).
 */
int vd80_get_shot_length(void)
{
	int reg = swapbe32(regs[VD80_SSR/4]);
	int val = (reg & VD80_SHOTLEN_MASK) >>
		VD80_SHOTLEN_SHIFT;

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error reading SHOTLEN\n");
		return -1;
	}

	return val;
}
Example #16
0
/**
 * \brief Enable readout of the sample buffer
 * \param channel Channel to read samples from (1 to 16)
 *
 * \return 0 on success else 1 on a VME bus error.
 */
int vd80_cmd_read(unsigned int channel)
{
	regs[VD80_GCR1/4] |= swapbe32((VD80_COMMAND_READ |
				       ((channel << VD80_OPERANT_SHIFT) &
					VD80_OPERANT_MASK)));

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error setting READ for channel %d\n", channel);
		return 1;
	}

	return 0;
}
Example #17
0
/**
 * \brief Set little or big endian samples recording
 * \param bigend When set, samples are stored in big endian ordering, else in
 *               little endian
 *
 * \return 0 on success else 1 on a VME bus error.
 */
int vd80_cmd_setbig(int bigend)
{
	if (bigend)
		regs[VD80_GCR2/4] |= swapbe32(VD80_BIGEND);
	else
		regs[VD80_GCR2/4] &= swapbe32(~VD80_BIGEND);	

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error setting samples endianess\n");
		return 1;
	}

	return 0;
}
Example #18
0
/**
 * \brief Enable/Disable generation of the test waveform
 * \param debug When set, enable generation of the test waveform, else disable
 *
 * \return 0 on success else 1 on a VME bus error.
 *
 * The test waveform consists in a digital ramp.
 */
int vd80_cmd_setdebug(int debug)
{
	if (debug)
		regs[VD80_GCR2/4] |= swapbe32(VD80_DBCNTSEL);
	else
		regs[VD80_GCR2/4] &= swapbe32(~VD80_DBCNTSEL);	

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error setting debug counter select\n");
		return 1;
	}

	return 0;
}
Example #19
0
int main(int argc, char **argv)
{
	struct pdparam_master param;
	struct vme_mapping *desc;
	unsigned int *vme_buf;
	int i;
	unsigned int val;
	unsigned int saved;

	memset(&param, 0, sizeof(struct pdparam_master));

	if ((vme_buf = (unsigned int *)find_controller(MODULE_VME_ADDR,
						       MODULE_VME_SIZE,
						       MODULE_AM, 0, 4,
						       &param)) == 0) {
		printf("Failed to find_controller: %s\n", strerror(errno));
		exit(1);
	}

	printf("find_controller mmap'ed at %p\n\n", vme_buf);

	desc = (struct vme_mapping *)param.sgmin;

	/* Now test read access */
	for (i = 1; i <= 5; i++) {
		val = swapbe32(vme_buf[i]);

		printf("%x:  0x%08x\n", MODULE_VME_ADDR + i*4, val);
	}

	/* Check for a bus error */
	if (vme_bus_error_check(desc))
		printf("Bus error occured\n");

	/* Test a write access */
	printf("\n");
	saved = swapbe32(vme_buf[1]);
	printf("Read 0x%08x at 0x%08x\n", saved, MODULE_VME_ADDR + 4);

	/* Check for a bus error */
	if (vme_bus_error_check(desc))
		printf("Bus error occured\n");

	printf("\n");

	printf("Writing 0x55aa55aa at address %x\n", MODULE_VME_ADDR + 4);
	vme_buf[1] = swapbe32(0x55aa55aa);
	fsync(desc->fd);

	/* Check for a bus error */
	if (vme_bus_error_check(desc))
		printf("Bus error occured\n");

	val = swapbe32(vme_buf[1]);

	/* Check for a bus error */
	if (vme_bus_error_check(desc))
		printf("Bus error occured\n");

	printf("Read back 0x%08x at address %x\n", val, MODULE_VME_ADDR + 4);
/*
	vme_buf[1] = swapbe32(saved);

	if (vme_bus_error_check(desc))
		printf("Bus error occured\n");
*/
	printf("\n");

	if (return_controller(desc))
		printf("Failed to return_controler: %s\n", strerror(errno));


	return 0;
}
Example #20
0
/**
 * \brief Map and initialize the VD80 for operation
 *
 * \return 0 on success else 1 on failure.
 *
 * This functions performs the necessary initializations to prepare the
 * board for sampling:
 *
 * \li map the operational registers into the user address space
 * \li clear any interrupts
 * \li disable interrupts
 * \li configure the sampling clock source to use the internal clock divided
 *     by 2 which yields a 100kHz sampling clock
 * \li configure the trigger source to use the internal trigger
 * \li set the number of post samples to 0
 * \li setup the pretrigger control to clear the pretrigger counter on a
 *     \a START command, to clear the \a PRESAMPLES counter on reading the
 *      pretrigger status register and to unse the sample clock for the
 *      pretrigger counter
 * \li enable generation of the test waveform
 *
 * \note Those settings are \b testing settings and must be adapted for
 *       operational use.
 *
 */
int vd80_init(void)
{
	int rc = 1;

	/* Open a mapping for the VD80 operational registers */
	memset(&regs_desc, 0, sizeof(struct vme_mapping));

	regs_desc.window_num = 0;
	regs_desc.am = VD80_OPER_AM;
	regs_desc.read_prefetch_enabled = 0;
	regs_desc.data_width = VD80_OPER_DW;
	regs_desc.sizeu = 0;
	regs_desc.sizel = VD80_OPER_SIZE;
	regs_desc.vme_addru = 0;
	regs_desc.vme_addrl = VD80_OPER_BASE;

	if ((regs = vme_map(&regs_desc, 1)) == NULL) {
		printf("Failed to map VD80 operational registers: %s\n",
		       strerror(errno));
		printf("  addr: %x size: %x am: %x dw: %d\n", VD80_OPER_BASE,
		       VD80_OPER_SIZE, VD80_OPER_AM, VD80_OPER_DW);
		return 1;
	}

	/* Clear interrupts */
	regs[VD80_GCR1/4] |= swapbe32(VD80_INTCLR | VD80_IOERRCLR);

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error initializing GCR1\n");
		goto out;
	}

	/*
	 * Disable interrupts, set little endian mode and disable debug
	 * counter (Clear all bits).
	 */
	regs[VD80_GCR2/4] = 0;

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error initializing GCR2\n");
		goto out;
	}

	/*
	 * Set sampling clock:
	 *    - Internal clock
	 *    - No VXI clock output
	 *    - Divide mode
	 *    - Rising edge
	 *    - No 50 ohm termination
	 *    - Clkdiv = 2 (I want a 100kHz clock from the 200 kHz internal
	 *                  clock - which yields a 10 us sampling period)
	 */
	regs[VD80_CCR/4] = swapbe32(1 << VD80_CLKDIV_SHIFT);

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error initializing CCR\n");
		goto out;
	}

	/*
	 * Set trigger:
	 *    - Internal trigger
	 *    - No VXI trigger output
	 *    - No trigger output
	 *    - Rising edge
	 *    - No 50 ohm termination
	 *    - No trigger synchronization
	 */
	regs[VD80_TCR1/4] = 0;

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error initializing TCR1\n");
		goto out;
	}

	/* Set number of post samples to 0 */
	
	if (vd80_set_postsamples(0))
		goto out;

	/*
	 * Setup the Pretrigger Control Register:
	 *    - Clear pretrigger counter on START
	 *    - Clear PRESAMPLES on Pretrigger Status Register read
	 *    - Clock the pretrigger counter on the sample clock
	 */
	regs[VD80_PTCR/4] |= swapbe32(VD80_PSCNTCLRONSTART |
				      VD80_PSREGCLRONREAD |
				      VD80_PSCNTCLKONSMPL);
	

	if (vme_bus_error_check(&regs_desc)) {
		printf("Bus error initializing PTCR\n");
		goto out;
	}

	/* Enable generation of debug waveform */
	if ((rc = vd80_cmd_setdebug(1)))
		goto out;

	return 0;

out:
	if (vme_unmap(&regs_desc, 1))
		printf("Failed to unmap operational registers: %s\n",
		       strerror(errno));

	return rc;
}
Example #21
0
File: ctc.c Project: dcobas/cvorj
int install_device(struct vmeio_device *dev, unsigned i)
{
	unsigned int serial;

	memset(dev, 0, sizeof(*dev));

	dev->lun = lun[i];
	dev->debug = DEBUG;

	/* configure mmapped I/O */
	if (base_address1_num && map(&dev->maps[0], base_address1[i],
						data_width1, am1, size1)) {
		printk(KERN_ERR PFX "could not map lun:%d, first space\n",
							dev->lun);
		goto out_map1;
	}
	/* check device absence */
	serial = ioread32be(dev->maps[0].kernel_va);
	if (vme_bus_error_check(1)) {
		printk(KERN_ERR PFX "module %d not found at address 0x%08lx\n",
				dev->lun, base_address1[i]);
		dev->lun = -1;
		goto out_map2;
	}

	if (base_address2_num && map(&dev->maps[1], base_address2[i],
						data_width2, am2, size2)) {
		printk(KERN_ERR PFX "could not map lun:%d, second space\n",
							dev->lun);
		goto out_map2;
	}

	/* configure interrupt handling */
	dev->vector  = vector[i];
	dev->level  = level;
	dev->isrc = isrc;
	dev->timeout = msecs_to_jiffies(TIMEOUT);
	dev->icnt = 0;
	init_waitqueue_head(&dev->queue);

	if (dev->level && dev->vector &&
		register_isr(dev, dev->vector, dev->level) < 0) {
			printk(KERN_ERR PFX "could not register isr "
				"for vector %d, level %d\n",
				dev->vector, dev->level);
			goto out_isr;
	}
	/* This will be eventually removed */
	register_int_source(dev, dev->maps[0].kernel_va, dev->isrc);

	printk(KERN_INFO PFX "lun %2ld installed, base address 0x%08lx, serial 0x%x\n",
				lun[i], base_address1[i], serial);
	return 0;

out_isr:
	vme_release_mapping(&dev->maps[1], 1);
out_map2:
	vme_release_mapping(&dev->maps[0], 1);
out_map1:
	printk(KERN_ERR PFX "lun %2ld not installed\n", lun[i]);
	return -ENODEV;

}
Example #22
0
/**
 * \brief Probe and configure the VD80
 *
 * \return 0 on success else 1 on failure.
 *
 * This function probes and configures the VD80 using the CR/CSR address space.
 *
 * It performs the following operations:
 *
 * \li map the VME CR/CSR address space of the board
 * \li check we're talking to a VD80 board by checking the module ID
 * \li configure the function 0 Address Decode Compare register (\a ADER0) to
 *     map the operational registers on an A24/D32 address space at base
 *     address 0x600000. Used for operational registers access.
 * \li configure the function 1 Address Decode Compare register (\a ADER1) to
 *     map the operational registers on an A24-BLT/D32 address space at base
 *     address 0x600000. Used for DMA reading of the samples memory using
 *     VME block transfer.
 *
 * \note The VME CR/CSR address space is unmapped on function return.
 */
int vd80_map(void)
{
	int rc = 1;
	struct vme_mapping crcsr_desc;
	unsigned int *crcsr;
	int i;
	unsigned int val;
	char cr_sig[2];
	char board_id[5];
	char rev_id[5];
	unsigned int desc_offset;
	char board_desc[512];

	/*
	 * Open a mapping into the VD80 CR/CSR (0x2f) address space for
	 * configuring the board.
	 */
	memset(&crcsr_desc, 0, sizeof(struct vme_mapping));

	crcsr_desc.window_num = 0;
	crcsr_desc.am = VD80_SETUP_AM;
	crcsr_desc.read_prefetch_enabled = 0;
	crcsr_desc.data_width = VD80_SETUP_DW;
	crcsr_desc.sizeu = 0;
	crcsr_desc.sizel = VD80_SETUP_SIZE;
	crcsr_desc.vme_addru = 0;
	crcsr_desc.vme_addrl = VD80_SETUP_BASE;

	if ((crcsr = vme_map(&crcsr_desc, 1)) == NULL) {
		printf("Failed to map CR/CSR: %s\n", strerror(errno));
		return 1;
	}

	/* First check we're accessing a configuration ROM */
	cr_sig[0] = swapbe32(crcsr[VD80_CR_SIG1/4]) & 0xff;

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error reading CR signature byte 0 at %08x\n",
		       VD80_SETUP_BASE + VD80_CR_SIG1);
		goto out;
	}

	cr_sig[1] = swapbe32(crcsr[VD80_CR_SIG2/4]) & 0xff;

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error reading CR signature byte 1 at %08x\n",
		       VD80_SETUP_BASE + VD80_CR_SIG2);
		goto out;
	}

	if ((cr_sig[0] != 'C') && (cr_sig[1] != 'R')) {
		printf("Not a Configuration ROM at 0x%x (%08x %08x)\n",
		       VD80_SETUP_BASE, swapbe32(crcsr[VD80_CR_SIG1/4]),
		       swapbe32(crcsr[VD80_CR_SIG2/4]));
		goto out;
	}

	/* Try to read module ID - offset 0x30 */
	for (i = 0; i < VD80_CR_BOARD_ID_LEN; i++) {
		val = swapbe32(crcsr[VD80_CR_BOARD_ID/4 + i]);
		board_id[i] = (char)(val & 0xff);
	}
	board_id[4] = '\0';

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error reading board ID\n");
		goto out;
	}

	for (i = 0; i < VD80_CR_REV_ID_LEN; i++) {
		val = swapbe32(crcsr[VD80_CR_REV_ID/4 + i]);
		rev_id[i] = (char)(val & 0xff);
	}
	rev_id[4] = '\0';

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error reading revision ID\n");
		goto out;
	}

	if (strncmp(board_id, "VD80", 4)) {
		printf("No VD80 board found at base address 0x%x\n",
		       VD80_SETUP_BASE);
		goto out;
	}

	printf("Found board ID %s - revision ID: %s\n", board_id, rev_id);

	/* Read board string */
	desc_offset = 0;

	for (i = 0; i < VD80_CR_DESC_PTR_LEN; i++) {
		desc_offset <<= 8;
		desc_offset |= swapbe32(crcsr[VD80_CR_DESC_PTR/4 + i]) & 0xff;
	}

	desc_offset &= ~3;

	if (desc_offset != 0) {
		for (i = 0; i < VD80_UCR_BOARD_DESC_LEN; i++) {
			val = swapbe32(crcsr[0x1040/4 + i]);
			board_desc[i] = (char)(val & 0xff);

			if (board_desc[i] == '\0')
				break;
		}
		board_desc[320] = '\0';
	}

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error reading board description\n");
		goto out;
	}

	printf("Board name: %s\n", board_desc);
	printf("\n");

	/* Configure ADER0 for A24 USER DATA access (AM=0x39 BA=0x600000) */
	crcsr[VD80_CSR_ADER0/4] = swapbe32((VD80_OPER_BASE >> 24) & 0xff);
	crcsr[VD80_CSR_ADER0/4 + 1] = swapbe32((VD80_OPER_BASE >> 16) & 0xff);
	crcsr[VD80_CSR_ADER0/4 + 2] = swapbe32((VD80_OPER_BASE >> 8) & 0xff);
	crcsr[VD80_CSR_ADER0/4 + 3] = swapbe32(VD80_OPER_AM * 4);

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error setting ADER0\n");
		goto out;
	}

	/* Configure ADER1 for A24 USER block transfer (AM=0x3b BA=0x600000) */
	crcsr[VD80_CSR_ADER1/4] = swapbe32((VD80_OPER_BASE >> 24) & 0xff);
	crcsr[VD80_CSR_ADER1/4 + 1] = swapbe32((VD80_OPER_BASE >> 16) & 0xff);
	crcsr[VD80_CSR_ADER1/4 + 2] = swapbe32((VD80_OPER_BASE >> 8) & 0xff);
	crcsr[VD80_CSR_ADER1/4 + 3] = swapbe32(VD80_DMA_AM * 4);

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error setting ADER1\n");
		goto out;
	}

	/*
	 * Clear address counter enable for function 1 to use it for block
	 * transfer of the sample memory.
	 */
	val = swapbe32(crcsr[VD80_CSR_FUNC_ACEN/4]) | 0x02;
	crcsr[VD80_CSR_FUNC_ACEN/4] = swapbe32(0);

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error setting ACEN\n");
		goto out;
	}

	/* Enable the module */
	crcsr[VD80_CSR_BITSET/4] = swapbe32(VD80_CSR_ENABLE_MODULE);

	if (vme_bus_error_check(&crcsr_desc)) {
		printf("Bus error enabling module\n");
		goto out;
	}

	rc = 0;

out:
	if (vme_unmap(&crcsr_desc, 1))
		printf("Failed to unmap CR/CSR space: %s\n",
		       strerror(errno));

	return rc;
}