コード例 #1
0
ファイル: adapter.c プロジェクト: prime5711/blackbox
static void xsa_complete_request(int uptodate)
{
	XSysAce_Unlock(&SysAce);
	spin_lock_irq(&xsysace_lock);
	xsysace_end_request(xsysace_req, uptodate);
	xsysace_req = 0;
	spin_unlock_irq(&xsysace_lock);
	schedule_work(&xsysace_read_write_work);
}
コード例 #2
0
ファイル: xsysace_selftest.c プロジェクト: aalonso/mb-ml507
/**
*
* A self-test that simply proves communication to the ACE controller from the
* device driver by obtaining an MPU lock, verifying it, then releasing it.
*
* @param InstancePtr is a pointer to the XSysAce instance to be worked on.
*
* @return
*
* XST_SUCCESS if self-test passes, or XST_FAILURE if an error occurs.
*
* @note
*
* None.
*
******************************************************************************/
int XSysAce_SelfTest(XSysAce * InstancePtr)
{
	int Result;

	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/*
	 * Grab a lock (expect immediate success)
	 */
	Result = XSysAce_Lock(InstancePtr, TRUE);
	if (Result != XST_SUCCESS) {
		return Result;
	}

	/*
	 * Verify the lock was retrieved
	 */
	if (!XSysAce_mIsMpuLocked(InstancePtr->BaseAddress)) {
		return XST_FAILURE;
	}

	/*
	 * Release the lock
	 */
	XSysAce_Unlock(InstancePtr);

	/*
	 * Verify the lock was released
	 */
	if (XSysAce_mIsMpuLocked(InstancePtr->BaseAddress)) {
		return XST_FAILURE;
	}

	/*
	 * If there are currently any errors on the device, fail self-test
	 */
	if (XSysAce_mGetErrorReg(InstancePtr->BaseAddress) != 0) {
		return XST_FAILURE;
	}

	return XST_SUCCESS;
}
コード例 #3
0
ファイル: adapter.c プロジェクト: prime5711/blackbox
static int xsysace_probe(struct device *dev)
{
	XSysAce_Config xsysace_cfg;
	struct platform_device *pdev = to_platform_device(dev);
	struct resource *irq_res, *regs_res;
	unsigned long remap_size;
	XStatus stat;
	long size;
	XSysAce_CFParameters ident;
	int retval;

	if (!dev)
		return -EINVAL;

	/* Find irq number, map the control registers in */
	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!regs_res || !irq_res) {
		printk(KERN_ERR "%s #%d: IO resource(s) not found\n",
		       DRIVER_NAME, pdev->id);
		retval = -EFAULT;
		goto failed1;
	}
	xsa_irq = irq_res->start;
	xsa_phys_addr = regs_res->start;
	remap_size = regs_res->end - regs_res->start + 1;
	if (!request_mem_region(regs_res->start, remap_size, DRIVER_NAME)) {
		printk(KERN_ERR
		       "%s #%d: Couldn't lock memory region at 0x%08lX\n",
		       DRIVER_NAME, pdev->id, regs_res->start);
		retval = -EBUSY;
		goto failed1;
	}

	/* Fill in cfg data and add them to the list */
	xsa_remap_size = remap_size;
	xsysace_cfg.DeviceId = pdev->id;
	xsysace_cfg.BaseAddress = (u32) ioremap(regs_res->start, remap_size);
	if (xsysace_cfg.BaseAddress == 0) {
		printk(KERN_ERR
		       "%s #%d: Couldn't ioremap memory at 0x%08lX\n",
		       DRIVER_NAME, pdev->id, regs_res->start);
		retval = -EFAULT;
		goto failed2;
	}

	/* Tell the Xilinx code to bring this SystemACE interface up. */
	down(&cfg_sem);
	if (XSysAce_CfgInitialize
	    (&SysAce, &xsysace_cfg, xsysace_cfg.BaseAddress) != XST_SUCCESS) {
		up(&cfg_sem);
		printk(KERN_ERR
		       "%s #%d: Could not initialize device.\n",
		       DRIVER_NAME, pdev->id);
		retval = -ENODEV;
		goto failed3;
	}
	up(&cfg_sem);

	retval = request_irq(xsa_irq, xsysace_interrupt, 0, DEVICE_NAME, NULL);
	if (retval) {
		printk(KERN_ERR
		       "%s #%d: Couldn't allocate interrupt %d.\n",
		       DRIVER_NAME, pdev->id, xsa_irq);
		goto failed3;
	}

	XSysAce_SetEventHandler(&SysAce, EventHandler, (void *)NULL);
	XSysAce_EnableInterrupt(&SysAce);

	/* Time to identify the drive. */
	while (XSysAce_Lock(&SysAce, 0) == XST_DEVICE_BUSY) ;
	while ((stat =
		XSysAce_IdentifyCF(&SysAce, &ident)) == XST_DEVICE_BUSY) ;
	XSysAce_Unlock(&SysAce);
	if (stat != XST_SUCCESS) {
		printk(KERN_ERR "%s: Could not send identify command.\n",
		       DEVICE_NAME);
		retval = -ENODEV;
		goto failed4;
	}

	/* Fill in what we learned. */
	heads = ident.NumHeads;
	sectors = ident.NumSectorsPerTrack;
	cylinders = ident.NumCylinders;
	size = (long)cylinders *(long)heads *(long)sectors;

	xsysace_queue = blk_init_queue(xsysace_do_request, &xsysace_lock);
	if (!xsysace_queue) {
		retval = -ENODEV;
		goto failed4;
	}

	if (register_blkdev(xsa_major, MAJOR_NAME)) {
		retval = -EBUSY;
		goto failed5;
	}

	xsa_gendisk = alloc_disk(16);
	if (!xsa_gendisk) {
		retval = -ENODEV;
		goto failed6;
	}

	strcpy(xsa_gendisk->disk_name, MAJOR_NAME);
	xsa_gendisk->fops = &xsysace_fops;
	xsa_gendisk->major = xsa_major;
	xsa_gendisk->first_minor = 0;
	xsa_gendisk->minors = 16;
	xsa_gendisk->queue = xsysace_queue;

	set_capacity(xsa_gendisk, size);

	printk(KERN_INFO
	       "%s at 0x%08X mapped to 0x%08X, irq=%d, %ldKB\n",
	       DEVICE_NAME, xsa_phys_addr, SysAce.BaseAddress, xsa_irq,
	       size / 2);

	/* Hook our reset function into system's restart code. */
	if (old_restart == NULL) {
		old_restart = ppc_md.restart;
		ppc_md.restart = xsysace_restart;
	}

	if (proc_init())
		printk(KERN_WARNING "%s: could not register /proc interface.\n",
		       DEVICE_NAME);

	add_disk(xsa_gendisk);

	return 0;		/* success */

      failed6:
	unregister_blkdev(xsa_major, MAJOR_NAME);

      failed5:
	blk_cleanup_queue(xsysace_queue);

      failed4:
	XSysAce_DisableInterrupt(&SysAce);
	free_irq(xsa_irq, NULL);

      failed3:
	iounmap((void *)(xsysace_cfg.BaseAddress));

      failed2:
	release_mem_region(regs_res->start, remap_size);

      failed1:
	return retval;
}