Пример #1
0
static int wb_resume(struct platform_device *devptr)
{
	int retval;
	int sd_status;
	/* cy_as_hal_print_message(KERN_ERR"%s called\n", __func__); */
	/* cyasdevice_leave_standby(); */
	/* down(&cy_as_device_controller->wq_sema); */
	cy_as_hal_enable_power(cy_as_device_controller->hal_tag, 1);
	cy_as_hal_enable_NANDCLK(1);
	gpio_set_value(WB_CLK_EN, 1);
	msleep(10);
	/* cy_as_hal_sleep(10); */
	/* up(&cy_as_device_controller->wq_sema); */
	enable_irq(WB_CYAS_IRQ_INT);
	msleep(5);
	sd_status = cy_as_hal_detect_SD();
	if (sd_status) {
		down(&cy_as_device_controller->wq_sema);
		cy_as_device_controller->cy_work->f_isrunning = 1;
		up(&cy_as_device_controller->wq_sema);
		retval = cyasdevice_wakeup_thread(1);

		if (retval ==  0) {
			msleep(10);
			cyasblkdev_stop_sdcard();
			retval = cyasblkdev_start_sdcard();
			/* retval = cy_as_misc_storage_changed(
					cy_as_device_controller->dev_handle, 0, 0); */
			if (retval != CY_AS_ERROR_SUCCESS) {
				#ifndef WESTBRIDGE_NDEBUG
				cy_as_hal_print_message(KERN_ERR
					"%s : fail in cy_as_misc_storage_changed (%d)\n",
					__func__, retval);
				#endif
			}
		}
		down(&cy_as_device_controller->wq_sema);
		cy_as_device_controller->cy_work->f_isrunning = 0;
		up(&cy_as_device_controller->wq_sema);
	}
	if (sd_status || cy_as_device_controller->cy_work->f_status) {
		cy_as_device_controller->cy_work->f_reload = 2;
		queue_delayed_work(cy_as_device_controller->cy_wq,
			&cy_as_device_controller->cy_work->work, 0);
	}
	enable_irq(WB_SDCD_IRQ_INT);
	return 0;
}
Пример #2
0
static int __devinit wb_probe(struct platform_device *devptr)
{
	if (sd_detection_cmd_dev == NULL) {
		sd_detection_cmd_dev =
			device_create(sec_class, NULL, 0,
					NULL, "sdcard");
		if (IS_ERR(sd_detection_cmd_dev))
			pr_err("Fail to create sysfs dev\n");

		if (device_create_file(sd_detection_cmd_dev,
					&dev_attr_status) < 0)
			pr_err("Fail to create sysfs file\n");
	}
	cy_as_hal_print_message("%s called\n", __func__);
	return 0;
}
Пример #3
0
/* start block device */
static int __init cyasblkdev_blk_init(void)
{
	int res = -ENOMEM;

	DBGPRN_FUNC_NAME;

	/* get the cyasdev handle for future use*/
	cyas_dev_handle = cyasdevice_getdevhandle();

	if  (cyasblkdev_blk_initialize() == 0)
		return 0;

	#ifndef WESTBRIDGE_NDEBUG
	cy_as_hal_print_message("cyasblkdev init error:%d\n", res);
	#endif
	return res;
}
Пример #4
0
/*
 * Prepare a -BLK_DEV  request.  Essentially, this means passing the
 * preparation off to the media driver.  The media driver will
 * create request to CyAsDev.
 */
static int cyasblkdev_prep_request(
    struct request_queue *q, struct request *req)
{
    DBGPRN_FUNC_NAME;

    /* we only like normal block requests.*/
    if (req->cmd_type != REQ_TYPE_FS && !(req->cmd_flags & REQ_DISCARD)) {
#ifndef WESTBRIDGE_NDEBUG
        cy_as_hal_print_message("%s:%x bad request received\n",
                                __func__, current->pid);
#endif

        blk_dump_rq_flags(req, "cyasblkdev bad request");
        return BLKPREP_KILL;
    }

    req->cmd_flags |= REQ_DONTPREP;

    return BLKPREP_OK;
}
Пример #5
0
static void cyasdevice_deinit(cyasdevice *cy_as_dev)
{
    cy_as_hal_print_message("<1>_cy_as_device deinitialize called\n");
    if (!cy_as_dev) {
        cy_as_hal_print_message("<1>_cy_as_device_deinit:  "
                                "device handle %x is invalid\n", (uint32_t)cy_as_dev);
        return;
    }

    /* stop west_brige */
    if (cy_as_dev->dev_handle) {
        cy_as_hal_print_message("<1>_cy_as_device: "
                                "cy_as_misc_destroy_device called\n");
        if (cy_as_misc_destroy_device(cy_as_dev->dev_handle) !=
                CY_AS_ERROR_SUCCESS) {
            cy_as_hal_print_message(
                "<1>_cy_as_device: destroying failed\n");
        }
    }

    if (cy_as_dev->hal_tag) {

#ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
        if (stop_o_m_a_p_kernel(dev_handle_name,
                                cy_as_dev->hal_tag) != 0)
            cy_as_hal_print_message("<1>_cy_as_device: stopping "
                                    "OMAP kernel HAL failed\n");

#endif
    }
    cy_as_hal_print_message("<1>_cy_as_device:HAL layer stopped\n");

    kfree(cy_as_dev);
    cy_as_device_controller = NULL;
    cy_as_hal_print_message("<1>_cy_as_device: deinitialized\n");
}
Пример #6
0
static struct cyasblkdev_blk_data *cyasblkdev_blk_alloc(void)
{
	struct cyasblkdev_blk_data *bd;
	int ret = 0;
	cy_as_return_status_t stat = -1;
	int bus_num = 0;
	int total_media_count = 0;
	int devidx = 0;
	DBGPRN_FUNC_NAME;

	total_media_count = 0;
	devidx = find_first_zero_bit(dev_use, CYASBLKDEV_NUM_MINORS);
	if (devidx >= CYASBLKDEV_NUM_MINORS)
		return ERR_PTR(-ENOSPC);

	__set_bit(devidx, dev_use);
	__set_bit(devidx + 1, dev_use);

	bd = kzalloc(sizeof(struct cyasblkdev_blk_data), GFP_KERNEL);
	if (bd) {
		gl_bd = bd;

		spin_lock_init(&bd->lock);
		bd->usage = 1;

		/* setup the block_dev_ops pointer*/
		bd->blkops = &cyasblkdev_bdops;

		/* Get the device handle */
		bd->dev_handle = cyasdevice_getdevhandle();
		if (0 == bd->dev_handle) {
			#ifndef WESTBRIDGE_NDEBUG
			cy_as_hal_print_message(
				"%s: get device failed\n", __func__);
			#endif
			ret = ENODEV;
			goto out;
		}

		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("%s west bridge device handle:%x\n",
			__func__, (uint32_t)bd->dev_handle);
		#endif

		/* start the storage api and get a handle to the
		 * device we are interested in. */

		/* Error code to use if the conditions are not satisfied. */
		ret = ENOMEDIUM;

		stat = cy_as_misc_release_resource(bd->dev_handle, cy_as_bus_0);
		if ((stat != CY_AS_ERROR_SUCCESS) &&
		(stat != CY_AS_ERROR_RESOURCE_NOT_OWNED)) {
			#ifndef WESTBRIDGE_NDEBUG
			cy_as_hal_print_message("%s: cannot release "
				"resource bus 0 - reason code %d\n",
				__func__, stat);
			#endif
		}

		stat = cy_as_misc_release_resource(bd->dev_handle, cy_as_bus_1);
		if ((stat != CY_AS_ERROR_SUCCESS) &&
		(stat != CY_AS_ERROR_RESOURCE_NOT_OWNED)) {
			#ifndef WESTBRIDGE_NDEBUG
			cy_as_hal_print_message("%s: cannot release "
				"resource bus 0 - reason code %d\n",
				__func__, stat);
			#endif
		}

		/* start storage stack*/
		stat = cy_as_storage_start(bd->dev_handle, 0, 0x101);
		if (stat != CY_AS_ERROR_SUCCESS) {
			#ifndef WESTBRIDGE_NDEBUG
			cy_as_hal_print_message("%s: cannot start storage "
				"stack - reason code %d\n", __func__, stat);
			#endif
			goto out;
		}

		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("%s: storage started:%d ok\n",
			__func__, stat);
		#endif

		stat = cy_as_storage_register_callback(bd->dev_handle,
			cyasblkdev_storage_callback);
		if (stat != CY_AS_ERROR_SUCCESS) {
			#ifndef WESTBRIDGE_NDEBUG
			cy_as_hal_print_message("%s: cannot register callback "
				"- reason code %d\n", __func__, stat);
			#endif
			goto out;
		}

		for (bus_num = 0; bus_num < 2; bus_num++) {
			stat = cy_as_storage_query_bus(bd->dev_handle,
				bus_num, &bd->media_count[bus_num],  0, 0);
			if (stat == CY_AS_ERROR_SUCCESS) {
				total_media_count = total_media_count +
					bd->media_count[bus_num];
			} else {
				#ifndef WESTBRIDGE_NDEBUG
				cy_as_hal_print_message("%s: cannot query %d, "
					"reason code: %d\n",
					__func__, bus_num, stat);
				#endif
				goto out;
			}
		}

		if (total_media_count == 0) {
			#ifndef WESTBRIDGE_NDEBUG
			cy_as_hal_print_message(
				"%s: no storage media was found\n", __func__);
			#endif
			goto out;
		} else if (total_media_count >= 1) {
			if (bd->user_disk_0 == NULL) {

				bd->user_disk_0 =
					alloc_disk(8);
				if (bd->user_disk_0 == NULL) {
					kfree(bd);
					bd = ERR_PTR(-ENOMEM);
					return bd;
				}
			}
			#ifndef WESTBRIDGE_NDEBUG
			else {
				cy_as_hal_print_message("%s: no available "
					"gen_disk for disk 0, "
					"physically inconsistent\n", __func__);
			}
			#endif
		}

		if (total_media_count == 2) {
			if (bd->user_disk_1 == NULL) {
				bd->user_disk_1 =
					alloc_disk(8);
				if (bd->user_disk_1 == NULL) {
					kfree(bd);
					bd = ERR_PTR(-ENOMEM);
					return bd;
				}
			}
			#ifndef WESTBRIDGE_NDEBUG
			else {
				cy_as_hal_print_message("%s: no available "
					"gen_disk for media, "
					"physically inconsistent\n", __func__);
			}
			#endif
		}
		#ifndef WESTBRIDGE_NDEBUG
		else if (total_media_count > 2) {
			cy_as_hal_print_message("%s: count corrupted = 0x%d\n",
				__func__, total_media_count);
		}
		#endif

		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("%s: %d device(s) found\n",
			__func__, total_media_count);
		#endif

		for (bus_num = 0; bus_num <= 1; bus_num++) {
			/*claim storage for cpu */
			stat = cy_as_storage_claim(bd->dev_handle,
				bus_num, 0, 0, 0);
			if (stat != CY_AS_ERROR_SUCCESS) {
				cy_as_hal_print_message("%s: cannot claim "
					"%d bus - reason code %d\n",
					__func__, bus_num, stat);
				goto out;
			}

			dev_data.bus = bus_num;
			dev_data.device = 0;

			stat = cy_as_storage_query_device(bd->dev_handle,
				&dev_data, 0, 0);
			if (stat == CY_AS_ERROR_SUCCESS) {
				cyasblkdev_add_disks(bus_num, bd,
					total_media_count, devidx);
			} else if (stat == CY_AS_ERROR_NO_SUCH_DEVICE) {
				#ifndef WESTBRIDGE_NDEBUG
				cy_as_hal_print_message(
					"%s: no device on bus %d\n",
					__func__, bus_num);
				#endif
			} else {
				#ifndef WESTBRIDGE_NDEBUG
				cy_as_hal_print_message(
					"%s: cannot query %d device "
					"- reason code %d\n",
					__func__, bus_num, stat);
				#endif
				goto out;
			}
		} /* end for (bus_num = 0; bus_num <= 1; bus_num++)*/

		return bd;
	}
out:
	#ifndef WESTBRIDGE_NDEBUG
	cy_as_hal_print_message(
		"%s: bd failed to initialize\n", __func__);
	#endif

	kfree(bd);
	bd = ERR_PTR(-ret);
	return bd;
}
Пример #7
0
/* west bridge device driver main init */
static int cyasdevice_initialize(void)
{
    cyasdevice *cy_as_dev = 0;
    int		 ret	= 0;
    int		 retval = 0;
    cy_as_device_config config;
    cy_as_hal_sleep_channel channel;
    cy_as_get_firmware_version_data ver_data = {0};
    const char *str = "";
    int spin_lim;
    const struct firmware *fw_entry;

    cy_as_device_init_done = 0;

    cy_as_misc_set_log_level(8);

    cy_as_hal_print_message("<1>_cy_as_device initialize called\n");

    if (cy_as_device_controller != 0) {
        cy_as_hal_print_message("<1>_cy_as_device: the device "
                                "has already been initilaized. ignoring\n");
        return -EBUSY;
    }

    /* cy_as_dev = CyAsHalAlloc (sizeof(cyasdevice), SLAB_KERNEL); */
    cy_as_dev = cy_as_hal_alloc(sizeof(cyasdevice));
    if (cy_as_dev == NULL) {
        cy_as_hal_print_message("<1>_cy_as_device: "
                                "memory allocation failed\n");
        return -ENOMEM;
    }
    memset(cy_as_dev, 0, sizeof(cyasdevice));


    /* Init the HAL & CyAsDeviceHandle */

#ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
    /* start OMAP HAL init instsnce */

    if (!start_o_m_a_p_kernel(dev_handle_name,
                              &(cy_as_dev->hal_tag), cy_false)) {

        cy_as_hal_print_message(
            "<1>_cy_as_device: start OMAP34xx HAL failed\n");
        goto done;
    }
#endif

    /* Now create the device */
    if (cy_as_misc_create_device(&(cy_as_dev->dev_handle),
                                 cy_as_dev->hal_tag) != CY_AS_ERROR_SUCCESS) {

        cy_as_hal_print_message(
            "<1>_cy_as_device: create device failed\n");
        goto done;
    }

    memset(&config, 0, sizeof(config));
    config.dmaintr = cy_true;

    ret = cy_as_misc_configure_device(cy_as_dev->dev_handle, &config);
    if (ret != CY_AS_ERROR_SUCCESS) {

        cy_as_hal_print_message(
            "<1>_cy_as_device: configure device "
            "failed. reason code: %d\n", ret);
        goto done;
    }

    ret = cy_as_misc_register_callback(cy_as_dev->dev_handle,
                                       cy_misc_callback);
    if (ret != CY_AS_ERROR_SUCCESS) {
        cy_as_hal_print_message("<1>_cy_as_device: "
                                "cy_as_misc_register_callback failed. "
                                "reason code: %d\n", ret);
        goto done;
    }

    ret = platform_driver_register(&west_bridge_driver);
    if (unlikely(ret < 0))
        return ret;
    westbridge_pd = platform_device_register_simple(
                        "west_bridge_dev", -1, NULL, 0);

    if (IS_ERR(westbridge_pd)) {
        platform_driver_unregister(&west_bridge_driver);
        return PTR_ERR(westbridge_pd);
    }
    /* Load the firmware */
    ret = request_firmware(&fw_entry,
                           "west bridge fw", &westbridge_pd->dev);
    if (ret) {
        cy_as_hal_print_message("cy_as_device: "
                                "request_firmware failed return val = %d\n", ret);
    } else {
        cy_as_hal_print_message("cy_as_device: "
                                "got the firmware %d size=0x%x\n", ret, fw_entry->size);

        ret = cy_as_misc_download_firmware(
                  cy_as_dev->dev_handle,
                  fw_entry->data,
                  fw_entry->size ,
                  0, 0);
    }

    if (ret != CY_AS_ERROR_SUCCESS) {
        cy_as_hal_print_message("<1>_cy_as_device: cannot download "
                                "firmware. reason code: %d\n", ret);
        goto done;
    }

    /* spin until the device init is completed */
    /* 50 -MAX wait time for the FW load & init
     * to complete is 5sec*/
    spin_lim = 50;

    cy_as_hal_create_sleep_channel(&channel);
    while (!cy_as_device_init_done) {

        cy_as_hal_sleep_on(&channel, 100);

        if (spin_lim-- <= 0) {
            cy_as_hal_print_message(
                "<1>\n_e_r_r_o_r!: "
                "wait for FW init has timed out !!!");
            break;
        }
    }
    cy_as_hal_destroy_sleep_channel(&channel);

    if (spin_lim > 0)
        cy_as_hal_print_message(
            "cy_as_device: astoria firmware is loaded\n");

    ret = cy_as_misc_get_firmware_version(cy_as_dev->dev_handle,
                                          &ver_data, 0, 0);
    if (ret != CY_AS_ERROR_SUCCESS) {
        cy_as_hal_print_message("<1>_cy_as_device: cannot get firmware "
                                "version. reason code: %d\n", ret);
        goto done;
    }

    if ((ver_data.media_type & 0x01) && (ver_data.media_type & 0x06))
        str = "nand and SD/MMC.";
    else if ((ver_data.media_type & 0x01) && (ver_data.media_type & 0x08))
        str = "nand and CEATA.";
    else if (ver_data.media_type & 0x01)
        str = "nand.";
    else if (ver_data.media_type & 0x08)
        str = "CEATA.";
    else
        str = "SD/MMC.";

    cy_as_hal_print_message("<1> cy_as_device:_firmware version: %s "
                            "major=%d minor=%d build=%d,\n_media types supported:%s\n",
                            ((ver_data.is_debug_mode) ? "debug" : "release"),
                            ver_data.major, ver_data.minor, ver_data.build, str);

    spin_lock_init(&cy_as_dev->common_lock);

    /* done now */
    cy_as_device_controller = cy_as_dev;

    return 0;

done:
    if (cy_as_dev)
        cyasdevice_deinit(cy_as_dev);

    return -EINVAL;
}
Пример #8
0
static int __devexit wb_remove(struct platform_device *devptr)
{
    cy_as_hal_print_message("%s called\n", __func__);
    return 0;
}
Пример #9
0
/* west bridge device driver main init */
static int cyasdevice_initialize(void)
{
	cyasdevice *cy_as_dev = 0;
	int		 ret	= 0;
	int		 retval = 0;
	cy_as_device_config config;
	cy_as_hal_sleep_channel channel;
	cy_as_get_firmware_version_data ver_data = {0};
	const char *str = "";
	int spin_lim;
	const struct firmware *fw_entry;

	cy_as_device_init_done = 0;

	cy_as_misc_set_log_level(8);

	cy_as_hal_print_message("<1>_cy_as_device initialize called\n");

	if (cy_as_device_controller != 0) {
		cy_as_hal_print_message("<1>_cy_as_device: the device "
			"has already been initilaized. ignoring\n");
		return -EBUSY;
	}

	/* cy_as_dev = CyAsHalAlloc (sizeof(cyasdevice), SLAB_KERNEL); */
	cy_as_dev = cy_as_hal_alloc(sizeof(cyasdevice));
	if (cy_as_dev == NULL) {
		cy_as_hal_print_message("<1>_cy_as_device: "
			"memory allocation failed\n");
		return -ENOMEM;
	}
	memset(cy_as_dev, 0, sizeof(cyasdevice));


	/* Init the HAL & CyAsDeviceHandle */

 #ifdef CONFIG_MACH_OMAP3_WESTBRIDGE_AST_PNAND_HAL
 /* start OMAP HAL init instsnce */

	if (!start_o_m_a_p_kernel(dev_handle_name,
		&(cy_as_dev->hal_tag), cy_false)) {

		cy_as_hal_print_message(
			"<1>_cy_as_device: start OMAP34xx HAL failed\n");
		goto done;
	}
 #endif

#ifdef CONFIG_MACH_C110_WESTBRIDGE_AST_PNAND_HAL
 /* start C110 HAL init instsnce */
	if (!cy_as_hal_c110_pnand_start(dev_handle_name,
		&(cy_as_dev->hal_tag), cy_false)) {
		cy_as_hal_print_message("<1>_cy_as_device: start C110 HAL failed\n") ;
		goto done;
	}
#endif
	/* Now create the device */
	if (cy_as_misc_create_device(&(cy_as_dev->dev_handle),
		cy_as_dev->hal_tag) != CY_AS_ERROR_SUCCESS) {

		cy_as_hal_print_message(
			"<1>_cy_as_device: create device failed\n");
		goto done;
	}

	memset(&config, 0, sizeof(config));
	config.dmaintr = cy_true;

	ret = cy_as_misc_configure_device(cy_as_dev->dev_handle, &config);
	if (ret != CY_AS_ERROR_SUCCESS) {

		cy_as_hal_print_message(
			"<1>_cy_as_device: configure device "
			"failed. reason code: %d\n", ret);
		goto done;
	}

	ret = cy_as_misc_register_callback(cy_as_dev->dev_handle,
		cy_misc_callback);
	if (ret != CY_AS_ERROR_SUCCESS) {
		cy_as_hal_print_message("<1>_cy_as_device: "
			"cy_as_misc_register_callback failed. "
			"reason code: %d\n", ret);
		goto done;
	}

	ret = platform_driver_register(&west_bridge_driver);
	if (unlikely(ret < 0))
		return ret;
	westbridge_pd = platform_device_register_simple(
		"west_bridge_dev", -1, NULL, 0);

	if (IS_ERR(westbridge_pd)) {
		cy_as_hal_print_message("[%s] error in register the platform\
			driver for west bridge\n", __FUNCTION__);
		platform_driver_unregister(&west_bridge_driver);
		return PTR_ERR(westbridge_pd);
	} else {
uint32_t cy_as_hal_gpmc_init(cy_as_omap_dev_kernel *dev_p)
{
	u32 tmp32;
	int err;
	struct gpmc_timings	timings;
	unsigned int cs_mem_base;
	unsigned int cs_vma_base;
	
	/*
	 * get GPMC i/o registers base(already been i/o mapped
	 * in kernel, no need for separate i/o remap)
	 */
	cy_as_hal_print_message(KERN_INFO "%s: mapping phys_to_virt\n", __func__);
					
	gpmc_base = (u32)ioremap_nocache(OMAP34XX_GPMC_BASE, SZ_16K);
	cy_as_hal_print_message(KERN_INFO "kernel has gpmc_base=%x , val@ the base=%x",
		gpmc_base, __raw_readl(gpmc_base)
	);
	
	cy_as_hal_print_message(KERN_INFO "%s: calling gpmc_cs_request\n", __func__);
	/*
	 * request GPMC CS for ASTORIA request
	 */
	if (gpmc_cs_request(AST_GPMC_CS, SZ_16M, (void *)&cs_mem_base) < 0) {
		cy_as_hal_print_message(KERN_ERR "error failed to request"
					"ncs4 for ASTORIA\n");
			return -1;
	} else {
		cy_as_hal_print_message(KERN_INFO "got phy_addr:%x for "
				"GPMC CS%d GPMC_CFGREG7[CS4]\n",
				 cs_mem_base, AST_GPMC_CS);
	}
	
	cy_as_hal_print_message(KERN_INFO "%s: calling request_mem_region\n", __func__);
	/*
	 * request VM region for 4K addr space for chip select 4 phy address
	 * technically we don't need it for NAND devices, but do it anyway
	 * so that data read/write bus cycle can be triggered by reading
	 * or writing this mem region
	 */
	if (!request_mem_region(cs_mem_base, SZ_16K, "AST_OMAP_HAL")) {
		err = -EBUSY;
		cy_as_hal_print_message(KERN_ERR "error MEM region "
					"request for phy_addr:%x failed\n",
					cs_mem_base);
			goto out_free_cs;
	}
	
	cy_as_hal_print_message(KERN_INFO "%s: calling ioremap_nocache\n", __func__);
	
	/* REMAP mem region associated with our CS */
	cs_vma_base = (u32)ioremap_nocache(cs_mem_base, SZ_16K);
	if (!cs_vma_base) {
		err = -ENOMEM;
		cy_as_hal_print_message(KERN_ERR "error- ioremap()"
					"for phy_addr:%x failed", cs_mem_base);

		goto out_release_mem_region;
	}
	cy_as_hal_print_message(KERN_INFO "ioremap(%x) returned vma=%x\n",
							cs_mem_base, cs_vma_base);

	dev_p->m_phy_addr_base = (void *) cs_mem_base;
	dev_p->m_vma_addr_base = (void *) cs_vma_base;

	memset(&timings, 0, sizeof(timings));

	/* cs timing */
	timings.cs_on = WB_GPMC_CS_t_on;
	timings.cs_wr_off = WB_GPMC_BUSCYC_t;
	timings.cs_rd_off = WB_GPMC_BUSCYC_t;

	/* adv timing */
	timings.adv_on = WB_GPMC_ADV_t_on;
	timings.adv_rd_off = WB_GPMC_ADV_t_off;
	timings.adv_wr_off = WB_GPMC_ADV_t_off;

	/* oe timing */
	timings.oe_on = WB_GPMC_OE_t_on;
	timings.oe_off = WB_GPMC_OE_t_off;
	timings.access = WB_GPMC_RD_t_a_c_c;
	timings.rd_cycle = WB_GPMC_BUSCYC_t;

	/* we timing */
	timings.we_on = WB_GPMC_WE_t_on;
	timings.we_off = WB_GPMC_WE_t_off;
	timings.wr_access = WB_GPMC_WR_t_a_c_c;
	timings.wr_cycle = WB_GPMC_BUSCYC_t;

	timings.page_burst_access = WB_GPMC_BUSCYC_t;
	timings.wr_data_mux_bus = WB_GPMC_BUSCYC_t;
	gpmc_cs_set_timings(AST_GPMC_CS, &timings);

	/*
	 * by default configure GPMC into 8 bit mode
	 * (to match astoria default mode)
	 */
	gpmc_cs_write_reg(AST_GPMC_CS, GPMC_CS_CONFIG1,
					(GPMC_CONFIG1_DEVICETYPE(0) |
					 GPMC_CONFIG1_DEVICESIZE_16
					| 0x10 //twhs
					));

	/*
	 * No method currently exists to write this register through GPMC APIs
	 * need to change WAIT2 polarity
	 */
	tmp32 = IORD32(GPMC_VMA(GPMC_CONFIG_REG));
	tmp32 = tmp32 | NAND_FORCE_POSTED_WRITE_B | 0x40;
	IOWR32(GPMC_VMA(GPMC_CONFIG_REG), tmp32);

	tmp32 = IORD32(GPMC_VMA(GPMC_CONFIG_REG));
	cy_as_hal_print_message("GPMC_CONFIG_REG=0x%x\n", tmp32);

	cy_as_hal_print_omap_regs("GPMC_CONFIG", 1,
			GPMC_VMA(GPMC_CFG_REG(1, AST_GPMC_CS)), 7);

	return 0;

out_release_mem_region:
	release_mem_region(cs_mem_base, SZ_16K);

out_free_cs:
	gpmc_cs_free(AST_GPMC_CS);

	return err;
}
Пример #11
0
/*west bridge storage async api on_completed callback */
static void cyasblkdev_issuecallback(
	/* Handle to the device completing the storage operation */
	cy_as_device_handle handle,
	/* The media type completing the operation */
	cy_as_media_type type,
	/* The device completing the operation */
	uint32_t device,
	/* The unit completing the operation */
	uint32_t unit,
	/* The block number of the completed operation */
	uint32_t block_number,
	/* The type of operation */
	cy_as_oper_type op,
	/* The error status */
	cy_as_return_status_t status
	)
{
	int retry_cnt = 0;
	DBGPRN_FUNC_NAME;

	if (status != CY_AS_ERROR_SUCCESS) {
		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message(
		  "%s: async r/w: op:%d failed with error %d at address %d\n",
			__func__, op, status, block_number);
		#endif
	}

	#ifndef WESTBRIDGE_NDEBUG
	cy_as_hal_print_message(
		"%s calling blk_end_request from issue_callback "
		"req=0x%x, status=0x%x, nr_sectors=0x%x\n",
		__func__, (unsigned int) gl_bd->queue.req, status,
		(unsigned int) blk_rq_sectors(gl_bd->queue.req));
	#endif

	/* note: blk_end_request w/o __ prefix should
	 * not require spinlocks on the queue*/
	while (blk_end_request(gl_bd->queue.req,
	status, blk_rq_sectors(gl_bd->queue.req)*512)) {
		retry_cnt++;
	}

	#ifndef WESTBRIDGE_NDEBUG
	cy_as_hal_print_message(
		"%s blkdev_callback: ended rq on %d sectors, "
		"with err:%d, n:%d times\n", __func__,
		(int)blk_rq_sectors(gl_bd->queue.req), status,
		retry_cnt
	);
	#endif

	spin_lock_irq(&gl_bd->lock);

	/*elevate next request, if there is one*/
	if (!blk_queue_plugged(gl_bd->queue.queue)) {
		/* queue is not plugged */
		gl_bd->queue.req = blk_fetch_request(gl_bd->queue.queue);
		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("%s blkdev_callback: "
		"blk_fetch_request():%p\n",
			__func__, gl_bd->queue.req);
		#endif
	}

	if (gl_bd->queue.req) {
		spin_unlock_irq(&gl_bd->lock);

		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("%s blkdev_callback: about to "
		"call issue_fn:%p\n", __func__, gl_bd->queue.req);
		#endif

		gl_bd->queue.issue_fn(&gl_bd->queue, gl_bd->queue.req);
	} else {
		spin_unlock_irq(&gl_bd->lock);
	}
}
Пример #12
0
static ssize_t store_cyas_diagnostics(struct device *dev,
		struct device_attribute *attr,
		const char *buf, size_t count)
{
	int	ret;
	int	mode = 0;
	int i = 0, len;

	sscanf(buf, "%s", cyas_diagnostics);

	len = strnlen(buf, PAGE_SIZE);

	while (i < len) {
		if (buf[i] < 0x30 || buf[i] > 0x39)
			break;

		mode += (buf[i]&0x0F);

		i++;

		if (i == len)
			break;
		else if (buf[i] == 0xa)
			break;
		else
			mode *= 10;
	}

	cy_as_hal_print_message("[%s] mode=%d\n", __func__, mode);

	switch (mode) {
	case 1:
		ret = cy_as_diagnostics(CY_AS_DIAG_GET_VERSION, cyas_diagnostics);
		break;
	case 2:
		ret = cy_as_diagnostics(CY_AS_DIAG_DISABLE_MSM_SDIO, cyas_diagnostics);
		break;
	case 3:
		ret = cy_as_diagnostics(CY_AS_DIAG_ENABLE_MSM_SDIO, cyas_diagnostics);
		break;
	case 4:
		ret = cy_as_diagnostics(CY_AS_DIAG_LEAVE_STANDBY, cyas_diagnostics);
		break;
	case 5:
		ret = cy_as_diagnostics(CY_AS_DIAG_ENTER_STANDBY, cyas_diagnostics);
		break;
	case 6:
		ret = cy_as_diagnostics(CY_AS_DIAG_CREATE_BLKDEV, cyas_diagnostics);
		break;
	case 7:
		ret = cy_as_diagnostics(CY_AS_DIAG_DESTROY_BLKDEV, cyas_diagnostics);
		break;
	case 11:
		ret = cy_as_diagnostics(CY_AS_DIAG_SD_MOUNT, cyas_diagnostics);
		break;
	case 12:
		ret = cy_as_diagnostics(CY_AS_DIAG_SD_READ, cyas_diagnostics);
		break;
	case 13:
		ret = cy_as_diagnostics(CY_AS_DIAG_SD_WRITE, cyas_diagnostics);
		break;
	case 14:
		ret = cy_as_diagnostics(CY_AS_DIAG_SD_UNMOUNT, cyas_diagnostics);
		break;
	case 21:
		ret = cy_as_diagnostics(CY_AS_DIAG_CONNECT_UMS, cyas_diagnostics);
		break;
	case 22:
		ret = cy_as_diagnostics(CY_AS_DIAG_DISCONNECT_UMS, cyas_diagnostics);
		break;
	case 31:
		ret = cy_as_diagnostics(CY_AS_DIAG_CONNECT_MTP, cyas_diagnostics);
		break;
	case 32:
		ret = cy_as_diagnostics(CY_AS_DIAG_DISCONNECT_MTP, cyas_diagnostics);
		break;
	case 40:
		ret = cy_as_diagnostics(CY_AS_DIAG_TEST_RESET_LOW, cyas_diagnostics);
		break;
	case 41:
		ret = cy_as_diagnostics(CY_AS_DIAG_TEST_RESET_HIGH, cyas_diagnostics);
		break;
	default:
		ret = 1;
		break;
	}

	if (ret)
		return 0;

	return len;
}
Пример #13
0
static void cy_wq_function(struct work_struct *work)
{
	int	status;
	int	is_inserted;
	int ret;
	int retry_count;

	down(&cy_as_device_controller->thread_sleep_sem);

	down(&cy_as_device_controller->wq_sema);
	cy_as_device_controller->cy_work->f_isrunning = 1;
	up(&cy_as_device_controller->wq_sema);

	status = cy_as_device_controller->cy_work->f_status;
	g_SD_flag = is_inserted = cy_as_hal_detect_SD();

	if (cy_as_device_controller->cy_work->f_reload == 1) {
		cy_as_device_controller->cy_work->f_reload = 0;
		cy_as_hal_enable_power(cy_as_device_controller->hal_tag, 1);
	}

	#ifdef __USE_CYAS_AUTO_SUSPEND__
	cyasdevice_disable_thread();
	#endif

	if (!is_inserted) {	/* removed SD card. */

		cy_as_hal_print_message(KERN_ERR
			"[cyasdevice.c] %s: SD card is removed.\n", __func__) ;
		if (status) {
			cy_as_hal_print_message(KERN_ERR
			"[cyasdevice.c] %s: cyasblkdev_blk_exit\n", __func__) ;
			down(&cy_as_device_controller->wq_sema);
			cyasdevice_leave_standby();
			cy_as_device_controller->cy_work->f_status = 0x0;
			up(&cy_as_device_controller->wq_sema);

			cyasblkdev_blk_exit();
			retry_count = 0;
			while (!cy_as_device_init_done) {
				if (++retry_count == 5) {
					cyasdevice_reload_firmware(0);
					break;
				}
				msleep(10);
			}

		}
		down(&cy_as_device_controller->wq_sema);
		cyasdevice_enter_standby();
		up(&cy_as_device_controller->wq_sema);
		msleep(10);
	} else {		/* insterted SD card.  */

		cy_as_hal_print_message(KERN_ERR"[cyasdevice.c] %s:\
					leave standby\n", __func__) ;
		down(&cy_as_device_controller->wq_sema);
		cyasdevice_leave_standby();
		up(&cy_as_device_controller->wq_sema);

		retry_count = 0;
		while (!cy_as_device_init_done) {
			if (++retry_count == 5) {
				cyasdevice_reload_firmware(0);
				break;
			}
			msleep(10);
		}

		cy_as_hal_print_message(KERN_ERR
		"++++++++++++  [cyasdevice.c] %s: SD card is inserted.\n",
		__func__) ;
		if (cy_as_device_controller->cy_work->f_reload == 2) {
			cy_as_device_controller->cy_work->f_reload = 0;

			ret = cyasblkdev_check_sdcard();
			if (ret == 1) {
				cy_as_hal_print_message(
				"[cyasdevice.c] %s: cyasblkdev_blk_exit\n",
				__func__) ;
				cyasblkdev_blk_exit();
				status =
				cy_as_device_controller->cy_work->f_status = 0x0;
			} else if (ret < 0) {
				cyasblkdev_blk_exit();
				cy_as_hal_print_message(
				"[cyasdevice.c] %s: reload firmware\n", __func__) ;
				status = cy_as_device_controller->cy_work->f_status = 0x0;
			} else {
				#ifdef __USE_CYAS_AUTO_SUSPEND__
				cyasdevice_enable_thread();
				#endif
			}
		}
		if (status == 0) {
			cy_as_hal_print_message(KERN_ERR
			"[cyasdevice.c] %s: cyasblkdev_blk_init\n", __func__) ;
			cy_as_device_controller->cy_work->f_status = 0x1;

			retry_count = 2;

			while (retry_count--) {
				ret = cyasblkdev_blk_init(0, 0);

				if (ret) {
					cyasblkdev_blk_exit();
					msleep(10);
					cyasdevice_reload_firmware(-1);
					msleep(10);
				} else
					break;
			}

			if (ret) {
				down(&cy_as_device_controller->wq_sema);
				cyasdevice_enter_standby();
				up(&cy_as_device_controller->wq_sema);
				msleep(10);

				cy_as_device_controller->cy_work->f_isrunning = 0;
				up(&cy_as_device_controller->thread_sleep_sem);
				return;
			}
		}

		#ifdef __USE_CYAS_AUTO_SUSPEND__
		/* cyasdevice_enable_thread(); */
		#endif
	}
	cy_as_device_controller->cy_work->f_isrunning = 0;

	up(&cy_as_device_controller->thread_sleep_sem);

	return;
}
Пример #14
0
/* queue worker thread */
static int cyasblkdev_queue_thread(void *d)
{
    DECLARE_WAITQUEUE(wait, current);
    struct cyasblkdev_queue *bq = d;
    struct request_queue *q = bq->queue;
    u32 qth_pid;

    DBGPRN_FUNC_NAME;

    /*
     * set iothread to ensure that we aren't put to sleep by
     * the process freezing.  we handle suspension ourselves.
     */
    daemonize("cyasblkdev_queue_thread");

    /* signal to queue_init() so it could contnue */
    complete(&bq->thread_complete);

    down(&bq->thread_sem);
    add_wait_queue(&bq->thread_wq, &wait);

    qth_pid = current->pid;

#ifndef WESTBRIDGE_NDEBUG
    cy_as_hal_print_message(
        "%s:%x started, bq:%p, q:%p\n", __func__, qth_pid, bq, q);
#endif

    do {
        struct request *req = NULL;

        /* the thread wants to be woken up by signals as well */
        set_current_state(TASK_INTERRUPTIBLE);

        spin_lock_irq(q->queue_lock);

#ifndef WESTBRIDGE_NDEBUG
        cy_as_hal_print_message(
            "%s: for bq->queue is null\n", __func__);
#endif

        if (!bq->req) {
            /* chk if queue is plugged */
            if (!blk_queue_plugged(q)) {
                bq->req = req = blk_fetch_request(q);
#ifndef WESTBRIDGE_NDEBUG
                cy_as_hal_print_message(
                    "%s: blk_fetch_request:%x\n",
                    __func__, (uint32_t)req);
#endif
            } else {
#ifndef WESTBRIDGE_NDEBUG
                cy_as_hal_print_message(
                    "%s: queue plugged, "
                    "skip blk_fetch()\n", __func__);
#endif
            }
        }
        spin_unlock_irq(q->queue_lock);

#ifndef WESTBRIDGE_NDEBUG
        cy_as_hal_print_message(
            "%s: checking if request queue is null\n", __func__);
#endif

        if (!req) {
            if (bq->flags & CYASBLKDEV_QUEUE_EXIT) {
#ifndef WESTBRIDGE_NDEBUG
                cy_as_hal_print_message(
                    "%s:got QUEUE_EXIT flag\n", __func__);
#endif

                break;
            }

#ifndef WESTBRIDGE_NDEBUG
            cy_as_hal_print_message(
                "%s: request queue is null, goto sleep, "
                "thread_sem->count=%d\n",
                __func__, bq->thread_sem.count);
            if (spin_is_locked(q->queue_lock)) {
                cy_as_hal_print_message("%s: queue_lock "
                                        "is locked, need to release\n", __func__);
                spin_unlock(q->queue_lock);

                if (spin_is_locked(q->queue_lock))
                    cy_as_hal_print_message(
                        "%s: unlock did not work\n",
                        __func__);
            } else {
                cy_as_hal_print_message(
                    "%s: checked lock, is not locked\n",
                    __func__);
            }
#endif

            up(&bq->thread_sem);

            /* yields to the next rdytorun proc,
             * then goes back to sleep*/
            schedule();
            down(&bq->thread_sem);

#ifndef WESTBRIDGE_NDEBUG
            cy_as_hal_print_message(
                "%s: wake_up,continue\n",
                __func__);
#endif
            continue;
        }

        /* new req received, issue it to the driver  */
        set_current_state(TASK_RUNNING);

#ifndef WESTBRIDGE_NDEBUG
        cy_as_hal_print_message(
            "%s: issued a RQ:%x\n",
            __func__, (uint32_t)req);
#endif

        bq->issue_fn(bq, req);

#ifndef WESTBRIDGE_NDEBUG
        cy_as_hal_print_message(
            "%s: bq->issue_fn() returned\n",
            __func__);
#endif

    } while (1);

    set_current_state(TASK_RUNNING);
    remove_wait_queue(&bq->thread_wq, &wait);
    up(&bq->thread_sem);

    complete_and_exit(&bq->thread_complete, 0);

#ifndef WESTBRIDGE_NDEBUG
    cy_as_hal_print_message("%s: is finished\n", __func__);
#endif

    return 0;
}
int cy_as_diagnostics(cy_as_diag_cmd_type mode, char *result)
{
	uint32_t retVal = 0;
	
#ifdef __CYAS_SYSFS_FOR_DIAGNOSTICS__
	cy_as_device_handle cyas_hd = cyasdevice_getdevhandle();

	switch( mode )
	{
		case CY_AS_DIAG_GET_VERSION:
			{
				cy_as_get_firmware_version_data ver_data = {0};
				const char *str = "" ;

				cyasdevice_leave_standby();

				retVal = cy_as_misc_get_firmware_version(cyas_hd, &ver_data, 0, 0) ;
				if (retVal != CY_AS_ERROR_SUCCESS) {
					cy_as_hal_print_message("cy_as_diagnostics: cannot get firmware version. reason code: %d\n", retVal) ;
					sprintf( result, "fail - %d", retVal );
					return retVal;
				}

				if ((ver_data.media_type & 0x01) && (ver_data.media_type & 0x06))
					str = "nand and SD/MMC." ;
				else if ((ver_data.media_type & 0x01) && (ver_data.media_type & 0x08))
					str = "nand and CEATA." ;
				else if (ver_data.media_type & 0x01)
					str = "nand." ;
				else if (ver_data.media_type & 0x08)
					str = "CEATA." ;
				else
					str = "SD/MMC." ;

				cyasdevice_enter_standby();
				
				cy_as_hal_print_message("<1> cy_as_device:_firmware version: %s "
										"major=%d minor=%d build=%d,\n_media types supported:%s\n",
										((ver_data.is_debug_mode) ? "debug" : "release"),
										ver_data.major, ver_data.minor, ver_data.build, str) ;
				
				sprintf( result, "%d.%d.%d", ver_data.major, ver_data.minor, ver_data.build );
			}
			break;
			
		case CY_AS_DIAG_DISABLE_MSM_SDIO:
			break;
			
		case CY_AS_DIAG_ENABLE_MSM_SDIO:
			break;

		case CY_AS_DIAG_ENTER_STANDBY:
			cyasdevice_enter_standby();
			break;
			
		case CY_AS_DIAG_LEAVE_STANDBY:
			cyasdevice_leave_standby();
			break;
			
		case CY_AS_DIAG_CREATE_BLKDEV:
			retVal = cyasblkdev_blk_init(0, 0);
			break;
			
		case CY_AS_DIAG_DESTROY_BLKDEV:
			cyasblkdev_blk_exit();
			break;

		case CY_AS_DIAG_SD_MOUNT:
			{
				int	i;
		        uint32_t count = 0 ;
		        int bus = 1 ;
				cy_as_storage_query_device_data dev_data ;
				cy_as_storage_query_unit_data unit_data = {0} ;
		
				cyasdevice_leave_standby();

				actdata = (uint8_t *)cy_as_hal_alloc(CYASSTORAGE_MAX_XFER_SIZE);
				expdata = (uint8_t *)cy_as_hal_alloc(CYASSTORAGE_MAX_XFER_SIZE);
		        cy_as_hal_mem_set(actdata, 0, CYASSTORAGE_MAX_XFER_SIZE);
		        cy_as_hal_mem_set(expdata, 0, CYASSTORAGE_MAX_XFER_SIZE);

		        retVal = cy_as_storage_device_control(cyas_hd, bus, 0, cy_true, cy_false, cy_as_storage_detect_SDAT_3, 0, 0) ;
		        if (retVal != CY_AS_ERROR_SUCCESS)
		        {
		                cy_as_hal_print_message(KERN_ERR"ERROR: Cannot set Device control - Reason code %d\n", retVal) ;
		                return retVal;
		        }

		        // Start the storage API and get a handle to the device we are interested in.
		        retVal = cy_as_storage_start(cyas_hd,0,0) ;
		        if (retVal != CY_AS_ERROR_SUCCESS)
		        {
		                cy_as_hal_print_message(KERN_ERR"ERROR: Cannot start storage stack - Reason code %d\n", retVal) ;
		                return retVal;
		        }

		        retVal = cy_as_storage_query_media(cyas_hd, cy_as_media_sd_flash, &count, 0, 0) ;
		        if (retVal != CY_AS_ERROR_SUCCESS)
		        {
		                cy_as_hal_print_message(KERN_ERR"ERROR: Cannot query SD device count - Reason code %d\n", retVal) ;
		                return retVal;
		        }
				if (!count)
		        {
		                cy_as_hal_print_message(KERN_ERR"ERROR: SD storage media was not found\n") ;
		                return retVal;
		        }
		        else
		        {
		                cy_as_hal_print_message(KERN_ERR"SUCCESS: %d SD device(s) found. SD_CLK, SD_CMD, and SD_D0 connected\n", count) ;


		                dev_data.bus = 1 ;
		                dev_data.device = 0 ;

		                retVal = cy_as_storage_query_device(cyas_hd, &dev_data, 0, 0 );
		                if(retVal != CY_AS_ERROR_SUCCESS)
		                {
		                        cy_as_hal_print_message(KERN_ERR"ERROR: Cannot query SD device count - Reason code %d\n", retVal) ;
		                        return retVal;
		                }
		                else
		                {
			 				#if 1 //skkm
							retVal = cy_as_storage_change_sd_frequency(cyas_hd, bus, 0x11, 24, 0, 0);
							if(retVal != CY_AS_ERROR_SUCCESS) {
								cy_as_hal_print_message("%s: Cannot control cy_as_storage_change_sd_frequency - reason [%d]\n", __func__, retVal) ;
							}
							#endif
							cy_as_hal_print_message(KERN_ERR"Checking for SD_WP Connectivity:\n");
							
							if(dev_data.desc_p.writeable)
							{
								cy_as_hal_print_message(KERN_ERR" SD media is not write protected \n") ;
							}
							else
							{
								cy_as_hal_print_message(KERN_ERR" SD media is write protected %d\n", retVal) ;
							}
							
							unit_data.device = 0 ;
							unit_data.unit   = 0 ;
							unit_data.bus    = bus;
							retVal = cy_as_storage_query_unit(cyas_hd,&unit_data, 0, 0) ;
							if (retVal != CY_AS_ERROR_SUCCESS) {
								#ifndef WESTBRIDGE_NDEBUG
								cy_as_hal_print_message(KERN_INFO"%s: cannot query %d device unit - reason code %d\n",
																	__func__, unit_data.bus, retVal) ;
								#endif
								return retVal;
							}

		                }
		        }
				
				cy_as_hal_set_ep_dma_mode(4, false);  
				cy_as_hal_set_ep_dma_mode(8, false); 

				start_unit = unit_data.desc_p.unit_size - MAX_DRQ_LOOPS_IN_ISR*2;
				
				for ( i = 0 ; i < CYASSTORAGE_MAX_XFER_SIZE ; i++ )
				{
					expdata[i] = i;
				}
			}
		break;
		
		case CY_AS_DIAG_SD_READ:
			{
				int i;
				int bus = 1 ;
				struct timespec mStartTime, mEndTime;
				long second,nano;
				long mDelta;


	    		mStartTime = CURRENT_TIME;
			    retVal = cy_as_storage_read(cyas_hd, bus, 0, 0, start_unit, actdata, MAX_DRQ_LOOPS_IN_ISR) ;
			    if (retVal != CY_AS_ERROR_SUCCESS)
			    {
			    	cy_as_hal_print_message(KERN_ERR "ERROR: cannot read from block device - code %d\n", retVal) ;
			    	break;
			    }

	    		mEndTime = CURRENT_TIME;
	        	second = mEndTime.tv_sec - mStartTime.tv_sec;
	        	nano = mEndTime.tv_nsec - mStartTime.tv_nsec;

				mDelta = (second*1000000) + nano/1000;
				
				cy_as_hal_print_message("<1>%s: reading speed = %d KByte/s\n", __func__, (int)((CYASSTORAGE_MAX_XFER_SIZE*1000)/mDelta) ) ;

			    if ( memcmp(expdata, actdata, 2048) != 0 )
			    {
				   int errCnt = 0 ;
		           cy_as_hal_print_message(KERN_ERR "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n") ;
					for ( i = 0 ; i < 2048 ; i++ )
					{
						if ( expdata[i] != actdata[i] )
						{
							cy_as_hal_print_message(KERN_ERR "EXP[%d]: 0x%02x\n",i, expdata[i]);
							cy_as_hal_print_message(KERN_ERR "ACT[%d]: 0x%02x\n",i, actdata[i]);
							errCnt++ ;
							if ( errCnt > 10 )
							{
								break;
							}
						}
					}
		           cy_as_hal_print_message(KERN_ERR "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n") ;
					retVal = CY_AS_ERROR_INVALID_RESPONSE;
					break;
			    }
				else
				{
					 cy_as_hal_print_message(KERN_ERR "success : storage test\n") ;
				}

			}
			break;
			
		case CY_AS_DIAG_SD_WRITE:
			{
				int	i;
				int bus = 1 ;
				struct timespec mStartTime, mEndTime;
				long second,nano;
				long mDelta;
				
				for ( i = 0 ; i < CYASSTORAGE_MAX_XFER_SIZE ; i++ )
				{
					expdata[i] = i;
				}

	    		mStartTime = CURRENT_TIME;
				
				retVal = cy_as_storage_write(cyas_hd, bus, 0, 0, start_unit, expdata, MAX_DRQ_LOOPS_IN_ISR) ;
		        if (retVal != CY_AS_ERROR_SUCCESS)
		        {
	                cy_as_hal_print_message(KERN_ERR "ERROR: cannot write to block device - code %d\n", retVal) ;
	                break;
		        }
				
	    		mEndTime = CURRENT_TIME;
	        	second = mEndTime.tv_sec - mStartTime.tv_sec;
	        	nano = mEndTime.tv_nsec - mStartTime.tv_nsec;

				mDelta = (second*1000000) + nano/1000;
				
				cy_as_hal_print_message("<1>%s: writing speed = %d KByte/s\n", __func__, (int)((CYASSTORAGE_MAX_XFER_SIZE*1000)/mDelta) ) ;
			}
			break;
			
		case CY_AS_DIAG_SD_UNMOUNT:
			cy_as_hal_set_ep_dma_mode(4, true);  
			cy_as_hal_set_ep_dma_mode(8, true); 

	        // Start the storage API and get a handle to the device we are interested in.
	        retVal = cy_as_storage_stop(cyas_hd,0,0) ;
	        if (retVal != CY_AS_ERROR_SUCCESS)
	        {
	                cy_as_hal_print_message(KERN_ERR"ERROR: Cannot stop storage stack - Reason code %d\n", retVal) ;
	                return retVal;
	        }

			cy_as_hal_free(actdata);
			cy_as_hal_free(expdata);
			
			cyasdevice_enter_standby();
			break;
#if 0
		case CY_AS_DIAG_CONNECT_UMS:
			cyasdevice_leave_standby();
			//cyasblkdev_blk_exit();

			cyasdevice_reload_firmware(0);
		
			//CyAsHalSelUSBSwitch(1);	
			retVal = CyAsAPIUsbInit();
			if (retVal)
			{
				cy_as_hal_print_message("%s: USB test failed.\n", __func__) ;
				return 0;	
			}
			else
			{
				msleep(1000);
				cy_as_hal_print_message("%s: USB connected.\n", __func__) ;
			}
			
			cy_as_hal_print_message("%s: UMS MODE init done\n", __func__) ;
		break;

	    case CY_AS_DIAG_DISCONNECT_UMS:

			CyAsAPIUsbExit();
			//CyAsHalSelUSBSwitch(0);	
			cy_as_hal_print_message("%s: UMS mode - close done\n", __func__) ;

			cyasdevice_reload_firmware(1);
			//cyasblkdev_blk_init(0, 0);
			cyasdevice_enter_standby();
			cy_as_hal_print_message("%s: reload F/W - close done\n", __func__) ;
		break;
		
	    case CY_AS_DIAG_CONNECT_MTP:
			cyasdevice_leave_standby();
			//CyAsHalSelUSBSwitch(1);	
			cyasblkdev_blk_init(0, 0);
			retVal = cy_as_gadget_init(1);
			if (retVal)
			{
				cy_as_hal_print_message("%s: cy_as_gadget_init failed.\n", __func__) ;
			}
			else
			{
				cy_as_hal_print_message("%s: cy_as_gadget_init success\n", __func__) ;
			}
			cy_as_hal_print_message("%s: Start cy_as_gadget driver -  init done\n", __func__) ;
		break;

	    case CY_AS_DIAG_DISCONNECT_MTP:
			cyasblkdev_blk_exit();
			cy_as_gadget_cleanup();
			//CyAsHalSelUSBSwitch(0);
			cyasdevice_enter_standby();
			cy_as_hal_print_message("%s: cy_as_gadget driver - close done\n", __func__) ;
		break;
#endif
		case CY_AS_DIAG_TEST_RESET_LOW:
			//cy_as_hal_set_reset_pin(0);
			cy_as_hal_print_message("%s: cy_as_hal_set_reset_pin - set LOW\n", __func__) ;
		break;

		case CY_AS_DIAG_TEST_RESET_HIGH:
			//cy_as_hal_set_reset_pin(1);
			cy_as_hal_print_message("%s: cy_as_hal_set_reset_pin - set HIGH\n", __func__) ;
		break;
		
		default:
			cy_as_hal_print_message("%s: unkown mode \n", __func__) ;
		break;

	}
#endif 
	return retVal;
}
/*
 * initialize OMAP pads/pins to user defined functions
 */
static void cy_as_hal_init_user_pads(user_pad_cfg_t *pad_cfg_tab)
{
	/*
	 * browse through the table an dinitiaze the pins
	 */
	u32 in_level = 0;
	u16 tmp16, mux_val;

	while (pad_cfg_tab->name != NULL) {

		if (gpio_request(pad_cfg_tab->pin_num, NULL) == 0) {

			pad_cfg_tab->valid = 1;
			mux_val = omap_cfg_reg_L(pad_cfg_tab->mux_func);

			/*
			 * always set drv level before changing out direction
			 */
			__gpio_set_value(pad_cfg_tab->pin_num,
							pad_cfg_tab->drv);

			/*
			 * "0" - OUT, "1", input omap_set_gpio_direction
			 * (pad_cfg_tab->pin_num, pad_cfg_tab->dir);
			 */
			if (pad_cfg_tab->dir)
				gpio_direction_input(pad_cfg_tab->pin_num);
			else
				gpio_direction_output(pad_cfg_tab->pin_num,
							pad_cfg_tab->drv);

			/*  sample the pin  */
			in_level = __gpio_get_value(pad_cfg_tab->pin_num);

			cy_as_hal_print_message(KERN_INFO "configured %s to "
					"OMAP pad_%d, DIR=%d "
					"DOUT=%d, DIN=%d\n",
					pad_cfg_tab->name,
					pad_cfg_tab->pin_num,
					pad_cfg_tab->dir,
					pad_cfg_tab->drv,
					in_level
			);
		} else {
			/*
			 * get the pad_mux value to check on the pin_function
			 */
			cy_as_hal_print_message(KERN_INFO "couldn't cfg pin %d"
					"for signal %s, its already taken\n",
					pad_cfg_tab->pin_num,
					pad_cfg_tab->name);
		}

		tmp16 = *(u16 *)PADCFG_VMA
			(omap_mux_pin_cfg[pad_cfg_tab->mux_func].offset);

		cy_as_hal_print_message(KERN_INFO "GPIO_%d(PAD_CFG=%x,OE=%d"
			"DOUT=%d, DIN=%d IRQEN=%d)\n\n",
			pad_cfg_tab->pin_num, tmp16,
			OMAP_GPIO_BIT(pad_cfg_tab->pin_num, GPIO_OE),
			OMAP_GPIO_BIT(pad_cfg_tab->pin_num, GPIO_DATA_OUT),
			OMAP_GPIO_BIT(pad_cfg_tab->pin_num, GPIO_DATA_IN),
			OMAP_GPIO_BIT(pad_cfg_tab->pin_num, GPIO_IRQENABLE1)
			);

		/*
		 * next pad_cfg deriptor
		 */
		pad_cfg_tab++;
	}

	cy_as_hal_print_message(KERN_INFO"pads configured\n");
}
Пример #17
0
uint32_t cyasblkdev_get_vfat_offset(int bus_num, int unit_no)
{
	/*
	 * for sd media, vfat partition boot record is not always
	 * located at sector it greatly depends on the system and
	 * software that was used to format the sd however, linux
	 * fs layer always expects it at sector 0, this function
	 * finds the offset and then uses it in all media r/w
	 * operations
	 */
	int sect_no, stat;
	uint8_t *sect_buf;
	bool br_found = false;

	DBGPRN_FUNC_NAME;

	sect_buf = kmalloc(1024, GFP_KERNEL);

	/* since HAL layer always uses sg lists instead of the
	 * buffer (for hw dmas) we need to initialize the sg list
	 * for local buffer*/
	sg_init_one(gl_bd->sg, sect_buf, 512);

	/*
	* Check MPR partition table 1st, then try to scan through
	* 1st 384 sectors until BR signature(intel JMP istruction
	* code and ,0x55AA) is found
	*/
	#ifndef WESTBRIDGE_NDEBUG
	  cy_as_hal_print_message(
		"%s scanning media for vfat partition...\n", __func__);
	#endif

	for (sect_no = 0; sect_no < SECTORS_TO_SCAN; sect_no++) {
		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("%s before cyasstorageread "
			"gl_bd->sg addr=0x%x\n", __func__,
			(unsigned int) gl_bd->sg);
		#endif

		stat = cy_as_storage_read(
			/* Handle to the device of interest */
			gl_bd->dev_handle,
			/* The bus to access */
			bus_num,
			/* The device to access */
			0,
			/* The unit to access */
			unit_no,
			/* absolute sector number */
			sect_no,
			/* sg structure */
			gl_bd->sg,
			/* The number of blocks to be read */
			1
		);

		/* try only sectors with boot signature */
		if ((sect_buf[510] == 0x55) && (sect_buf[511] == 0xaa)) {
			/* vfat boot record may also be located at
			 * sector 0, check it first  */
			if (sect_buf[0] == 0xEB) {
				#ifndef WESTBRIDGE_NDEBUG
				cy_as_hal_print_message(
					"%s vfat partition found "
					"at sector:%d\n",
					__func__, sect_no);
				#endif

				br_found = true;
				   break;
			}
		}

		if (stat != 0) {
			#ifndef WESTBRIDGE_NDEBUG
			cy_as_hal_print_message("%s sector scan error\n",
				__func__);
			#endif
			break;
		}
	}

	kfree(sect_buf);

	if (br_found) {
		return sect_no;
	} else {
		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message(
			"%s vfat partition is not found, using 0 offset\n",
			__func__);
		#endif
		return 0;
	}
}
Пример #18
0
static void cyasblkdev_blk_put(
			struct cyasblkdev_blk_data *bd
			)
{
	DBGPRN_FUNC_NAME;

	down(&open_lock);

	if (bd) {
		bd->usage--;
		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message(
			" cyasblkdev_blk_put , bd->usage= %d\n", bd->usage);
		#endif
	} else  {
		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message(
			"cyasblkdev: blk_put(bd) on bd = NULL!: usage = %d\n",
			bd->usage);
		#endif
		up(&open_lock);
		return;
	}

	if (bd->usage == 0) {
		put_disk(bd->user_disk_0);
		put_disk(bd->user_disk_1);
		put_disk(bd->system_disk);
		cyasblkdev_cleanup_queue(&bd->queue);

		if (CY_AS_ERROR_SUCCESS !=
			cy_as_storage_release(bd->dev_handle, 0, 0, 0, 0)) {
			#ifndef WESTBRIDGE_NDEBUG
			cy_as_hal_print_message(
				"cyasblkdev: cannot release bus 0\n");
			#endif
		}

		if (CY_AS_ERROR_SUCCESS !=
			cy_as_storage_release(bd->dev_handle, 1, 0, 0, 0)) {
			#ifndef WESTBRIDGE_NDEBUG
			cy_as_hal_print_message(
				"cyasblkdev: cannot release bus 1\n");
			#endif
		}

		if (CY_AS_ERROR_SUCCESS !=
			cy_as_storage_stop(bd->dev_handle, 0, 0)) {
			#ifndef WESTBRIDGE_NDEBUG
			cy_as_hal_print_message(
				"cyasblkdev: cannot stop storage stack\n");
			#endif
		}

	#ifdef __CY_ASTORIA_SCM_KERNEL_HAL__
		/* If the SCM Kernel HAL is being used, disable the use
		 * of scatter/gather lists at the end of block driver usage.
		 */
		cy_as_hal_disable_scatter_list(cyasdevice_gethaltag());
	#endif

		/*ptr to global struct cyasblkdev_blk_data */
		gl_bd = NULL;
		kfree(bd);
	}

	#ifndef WESTBRIDGE_NDEBUG
	cy_as_hal_print_message(
		"cyasblkdev (blk_put): usage = %d\n",
		bd->usage);
	#endif
	up(&open_lock);
}
void cy_as_hal_pll_lock_loss_handler(cy_as_hal_device_tag tag)
{
	cy_as_hal_print_message("error: astoria PLL lock is lost\n") ;
	cy_as_hal_print_message("please check the input voltage levels");
	cy_as_hal_print_message("and clock, and restart the system\n") ;
}
Пример #20
0
/* issue astoria blkdev request (issue_fn) */
static int cyasblkdev_blk_issue_rq(
					struct cyasblkdev_queue *bq,
					struct request *req
					)
{
	struct cyasblkdev_blk_data *bd = bq->data;
	int index = 0;
	int ret = CY_AS_ERROR_SUCCESS;
	uint32_t req_sector = 0;
	uint32_t req_nr_sectors = 0;
	int bus_num = 0;
	int lcl_unit_no = 0;

	DBGPRN_FUNC_NAME;

	/*
	 * will construct a scatterlist for the given request;
	 * the return value is the number of actually used
	 * entries in the resulting list. Then, this scatterlist
	 * can be used for the actual DMA prep operation.
	 */
	spin_lock_irq(&bd->lock);
	index = blk_rq_map_sg(bq->queue, req, bd->sg);

	if (req->rq_disk == bd->user_disk_0) {
		bus_num = bd->user_disk_0_bus_num;
		req_sector = blk_rq_pos(req) + gl_bd->user_disk_0_first_sector;
		req_nr_sectors = blk_rq_sectors(req);
		lcl_unit_no = gl_bd->user_disk_0_unit_no;

		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("%s: request made to disk 0 "
			"for sector=%d, num_sectors=%d, unit_no=%d\n",
			__func__, req_sector, (int) blk_rq_sectors(req),
			lcl_unit_no);
		#endif
	} else if (req->rq_disk == bd->user_disk_1) {
		bus_num = bd->user_disk_1_bus_num;
		req_sector = blk_rq_pos(req) + gl_bd->user_disk_1_first_sector;
		/*SECT_NUM_TRANSLATE(blk_rq_sectors(req));*/
		req_nr_sectors = blk_rq_sectors(req);
		lcl_unit_no = gl_bd->user_disk_1_unit_no;

		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("%s: request made to disk 1 for "
			"sector=%d, num_sectors=%d, unit_no=%d\n", __func__,
			req_sector, (int) blk_rq_sectors(req), lcl_unit_no);
		#endif
	} else if (req->rq_disk == bd->system_disk) {
		bus_num = bd->system_disk_bus_num;
		req_sector = blk_rq_pos(req) + gl_bd->system_disk_first_sector;
		req_nr_sectors = blk_rq_sectors(req);
		lcl_unit_no = gl_bd->system_disk_unit_no;

		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("%s: request made to system disk "
			"for sector=%d, num_sectors=%d, unit_no=%d\n", __func__,
			req_sector, (int) blk_rq_sectors(req), lcl_unit_no);
		#endif
	}
	#ifndef WESTBRIDGE_NDEBUG
	else {
		cy_as_hal_print_message(
			"%s: invalid disk used for request\n", __func__);
	}
	#endif

	spin_unlock_irq(&bd->lock);

	if (rq_data_dir(req) == READ) {
		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("%s: calling readasync() "
			"req_sector=0x%x, req_nr_sectors=0x%x, bd->sg:%x\n\n",
			__func__, req_sector, req_nr_sectors, (uint32_t)bd->sg);
		#endif

		ret = cy_as_storage_read_async(bd->dev_handle, bus_num, 0,
			lcl_unit_no, req_sector, bd->sg, req_nr_sectors,
			(cy_as_storage_callback)cyasblkdev_issuecallback);

		if (ret != CY_AS_ERROR_SUCCESS) {
			#ifndef WESTBRIDGE_NDEBUG
			cy_as_hal_print_message("%s:readasync() error %d at "
				"address %ld, unit no %d\n", __func__, ret,
				blk_rq_pos(req), lcl_unit_no);
			cy_as_hal_print_message("%s:ending i/o request "
				"on reg:%x\n", __func__, (uint32_t)req);
			#endif

			while (blk_end_request(req,
				(ret == CY_AS_ERROR_SUCCESS),
				req_nr_sectors*512))
				;

			bq->req = NULL;
		}
	} else {
		ret = cy_as_storage_write_async(bd->dev_handle, bus_num, 0,
			lcl_unit_no, req_sector, bd->sg, req_nr_sectors,
			(cy_as_storage_callback)cyasblkdev_issuecallback);

		if (ret != CY_AS_ERROR_SUCCESS) {
			#ifndef WESTBRIDGE_NDEBUG
			cy_as_hal_print_message("%s: write failed with "
			"error %d at address %ld, unit no %d\n",
			__func__, ret, blk_rq_pos(req), lcl_unit_no);
			#endif

			/*end IO op on this request(does both
			 * end_that_request_... _first & _last) */
			while (blk_end_request(req,
				(ret == CY_AS_ERROR_SUCCESS),
				req_nr_sectors*512))
				;

			bq->req = NULL;
		}
	}

	return ret;
}
/*
 * init OMAP h/w resources
 */
int cy_as_hal_omap_cram_start(const char *pgm,
				cy_as_hal_device_tag *tag, cy_bool debug)
{
	cy_as_omap_dev_kernel *dev_p ;
	int i;
	u16 data16[4];
	uint32_t err = 0;
	/* No debug mode support through argument as of now */
	(void)debug;

	have_irq = false;

	/*
	 * Initialize the HAL level endpoint DMA data.
	 */
	for (i = 0 ; i < sizeof(end_points)/sizeof(end_points[0]) ; i++) {
		end_points[i].data_p = 0 ;
		end_points[i].pending = cy_false ;
		end_points[i].size = 0 ;	/* No debug mode support through argument as of now */
	(void)debug;
		
		end_points[i].type = cy_as_hal_none ;
		end_points[i].sg_list_enabled = cy_false;

		/*
		 * by default the DMA transfers to/from the E_ps don't
		 * use sg_list that implies that the upper devices like
		 * blockdevice have to enable it for the E_ps in their
		 * initialization code
		 */
	}

	/* allocate memory for OMAP HAL*/
	dev_p = (cy_as_omap_dev_kernel *)cy_as_hal_alloc(
						sizeof(cy_as_omap_dev_kernel)) ;
	if (dev_p == 0) {
		cy_as_hal_print_message("out of memory allocating OMAP"
					"device structure\n") ;
		return 0 ;
	}

	dev_p->m_sig = CY_AS_OMAP_CRAM_HAL_SIG;

	/* initialize OMAP hardware and StartOMAPKernelall gpio pins */
	err = cy_as_hal_processor_hw_init(dev_p);
	if(err)
		goto bus_acc_error;

	/*
	 * Now perform a hard reset of the device to have
	 * the new settings take effect
	 */
	__gpio_set_value(AST_WAKEUP, 1);

	/*
	 * do Astoria  h/w reset
	 */
	DBGPRN(KERN_INFO"-_-_pulse -> westbridge RST pin\n");

	/*
	 * NEGATIVE PULSE on RST pin
	 */
	__gpio_set_value(AST_RESET, 0);
	mdelay(1);
	__gpio_set_value(AST_RESET, 1);
	mdelay(50);


   /*
	*  NOTE: if you want to capture bus activity on the LA,
	*  don't use printks in between the activities you want to capture.
	*  prinks may take milliseconds, and the data of interest
	*  will fall outside the LA capture window/buffer
	*/
	cy_as_hal_dump_reg((cy_as_hal_device_tag)dev_p);

	data16[0] = cy_as_hal_read_register((cy_as_hal_device_tag)dev_p, CY_AS_MEM_CM_WB_CFG_ID);

	if ( (data16[0]&0xA100 != 0xA100) ||  (data16[0]&0xA200 != 0xA200))  {
		/*
		 * astoria device is not found
		 */
		printk(KERN_ERR "ERROR: astoria device is not found, "
			"CY_AS_MEM_CM_WB_CFG_ID %4.4x", data16[0]);
		goto bus_acc_error;
	}

	cy_as_hal_print_message(KERN_INFO" register access test:"
				"\n CY_AS_MEM_CM_WB_CFG_ID:%4.4x\n"
				"after cfg_wr:%4.4x\n\n",
				data16[0], data16[1]);

	dev_p->thread_flag = 1 ;
	spin_lock_init(&int_lock) ;
	dev_p->m_next_p = m_omap_list_p ;

	m_omap_list_p = dev_p ;
	*tag = dev_p;

	cy_as_hal_configure_interrupts((void *)dev_p);

	cy_as_hal_print_message(KERN_INFO"OMAP3430__hal started tag:%p"
				", kernel HZ:%d\n", dev_p, HZ);

	/*
	 *make processor to storage endpoints SG assisted by default
	 */
	cy_as_hal_set_ep_dma_mode(4, true);
	cy_as_hal_set_ep_dma_mode(8, true);

	return 1 ;

	/*
	 * there's been a NAND bus access error or
	 * astoria device is not connected
	 */
bus_acc_error:
	/*
	 * at this point hal tag hasn't been set yet
	 * so the device will not call omap_stop
	 */
	cy_as_hal_omap_hardware_deinit(dev_p);
	cy_as_hal_free(dev_p) ;
	return 0;
}
Пример #22
0
static int cyasblkdev_add_disks(int bus_num,
	struct cyasblkdev_blk_data *bd,
	int total_media_count,
	int devidx)
{
	int ret = 0;
	uint64_t disk_cap;
	int lcl_unit_no;
	cy_as_storage_query_unit_data unit_data = {0};

	#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("%s:query device: "
		"type:%d, removable:%d, writable:%d, "
		"blksize %d, units:%d, locked:%d, "
		"erase_sz:%d\n",
		__func__,
		dev_data.desc_p.type,
		dev_data.desc_p.removable,
		dev_data.desc_p.writeable,
		dev_data.desc_p.block_size,
		dev_data.desc_p.number_units,
		dev_data.desc_p.locked,
		dev_data.desc_p.erase_unit_size
		);
	#endif

	/*  make sure that device is not locked  */
	if (dev_data.desc_p.locked) {
		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message(
			"%s: device is locked\n", __func__);
		#endif
		ret = cy_as_storage_release(
			bd->dev_handle, bus_num, 0, 0, 0);
		if (ret != CY_AS_ERROR_SUCCESS) {
			#ifndef WESTBRIDGE_NDEBUG
			cy_as_hal_print_message("%s cannot release"
				" storage\n", __func__);
			#endif
			goto out;
		}
		goto out;
	}

	unit_data.device = 0;
	unit_data.unit   = 0;
	unit_data.bus    = bus_num;
	ret = cy_as_storage_query_unit(bd->dev_handle,
		&unit_data, 0, 0);
	if (ret != CY_AS_ERROR_SUCCESS) {
		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("%s: cannot query "
			"%d device unit - reason code %d\n",
			__func__, bus_num, ret);
		#endif
		goto out;
	}

	if (private_partition_bus == bus_num) {
		if (private_partition_size > 0) {
			ret = cy_as_storage_create_p_partition(
				bd->dev_handle, bus_num, 0,
				private_partition_size, 0, 0);
			if ((ret != CY_AS_ERROR_SUCCESS) &&
			(ret != CY_AS_ERROR_ALREADY_PARTITIONED)) {
			#ifndef WESTBRIDGE_NDEBUG
				cy_as_hal_print_message("%s: cy_as_storage_"
				"create_p_partition after size > 0 check "
				"failed with error code %d\n",
				__func__, ret);
			#endif

				disk_cap = (uint64_t)
					(unit_data.desc_p.unit_size);
				lcl_unit_no = 0;

			} else if (ret == CY_AS_ERROR_ALREADY_PARTITIONED) {
				#ifndef WESTBRIDGE_NDEBUG
				cy_as_hal_print_message(
				"%s: cy_as_storage_create_p_partition "
				"indicates memory already partitioned\n",
				__func__);
				#endif

				/*check to see that partition
				 * matches size */
				if (unit_data.desc_p.unit_size !=
					private_partition_size) {
					ret = cy_as_storage_remove_p_partition(
						bd->dev_handle,
						bus_num, 0, 0, 0);
					if (ret == CY_AS_ERROR_SUCCESS) {
						ret = cy_as_storage_create_p_partition(
							bd->dev_handle, bus_num, 0,
							private_partition_size, 0, 0);
						if (ret == CY_AS_ERROR_SUCCESS) {
							unit_data.bus = bus_num;
							unit_data.device = 0;
							unit_data.unit = 1;
						} else {
							#ifndef WESTBRIDGE_NDEBUG
							cy_as_hal_print_message(
							"%s: cy_as_storage_create_p_partition "
							"after removal unexpectedly failed "
							"with error %d\n", __func__, ret);
							#endif

							/* need to requery bus
							 * seeing as delete
							 * successful and create
							 * failed we have changed
							 * the disk properties */
							unit_data.bus	= bus_num;
							unit_data.device = 0;
							unit_data.unit   = 0;
						}

						ret = cy_as_storage_query_unit(
						bd->dev_handle,
						&unit_data, 0, 0);
						if (ret != CY_AS_ERROR_SUCCESS) {
							#ifndef WESTBRIDGE_NDEBUG
							cy_as_hal_print_message(
							"%s: cannot query %d "
							"device unit - reason code %d\n",
							__func__, bus_num, ret);
							#endif
							goto out;
						} else {
							disk_cap = (uint64_t)
								(unit_data.desc_p.unit_size);
							lcl_unit_no =
								unit_data.unit;
						}
					} else {
					#ifndef WESTBRIDGE_NDEBUG
					cy_as_hal_print_message(
					"%s: cy_as_storage_remove_p_partition "
					"failed with error %d\n",
					__func__, ret);
					#endif

						unit_data.bus = bus_num;
						unit_data.device = 0;
						unit_data.unit = 1;

						ret = cy_as_storage_query_unit(
							bd->dev_handle, &unit_data, 0, 0);
						if (ret != CY_AS_ERROR_SUCCESS) {
						#ifndef WESTBRIDGE_NDEBUG
							cy_as_hal_print_message(
							"%s: cannot query %d "
							"device unit - reason "
							"code %d\n", __func__,
							bus_num, ret);
						#endif
							goto out;
						}

						disk_cap = (uint64_t)
							(unit_data.desc_p.unit_size);
						lcl_unit_no =
							unit_data.unit;
					}
				} else {
					#ifndef WESTBRIDGE_NDEBUG
					cy_as_hal_print_message("%s: partition "
						"exists and sizes equal\n",
						__func__);
					#endif

					/*partition already existed,
					 * need to query second unit*/
					unit_data.bus = bus_num;
					unit_data.device = 0;
					unit_data.unit = 1;

					ret = cy_as_storage_query_unit(
						bd->dev_handle, &unit_data, 0, 0);
					if (ret != CY_AS_ERROR_SUCCESS) {
					#ifndef WESTBRIDGE_NDEBUG
						cy_as_hal_print_message(
							"%s: cannot query %d "
							"device unit "
							"- reason code %d\n",
							__func__, bus_num, ret);
					#endif
						goto out;
					} else {
						disk_cap = (uint64_t)
						(unit_data.desc_p.unit_size);
						lcl_unit_no = unit_data.unit;
					}
				}
			} else {
				#ifndef WESTBRIDGE_NDEBUG
				cy_as_hal_print_message(
				"%s: cy_as_storage_create_p_partition "
				"created successfully\n", __func__);
				#endif

				disk_cap = (uint64_t)
				(unit_data.desc_p.unit_size -
				private_partition_size);

				lcl_unit_no = 1;
			}
		}
		#ifndef WESTBRIDGE_NDEBUG
		else {
			cy_as_hal_print_message(
			"%s: invalid partition_size%d\n", __func__,
			private_partition_size);

			disk_cap = (uint64_t)
				(unit_data.desc_p.unit_size);
			lcl_unit_no = 0;
		}
		#endif
	} else {
		disk_cap = (uint64_t)
			(unit_data.desc_p.unit_size);
		lcl_unit_no = 0;
	}

	if ((bus_num == 0) ||
		(total_media_count == 1)) {
		sprintf(bd->user_disk_0->disk_name,
			"cyasblkdevblk%d", devidx);

		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message(
			"%s: disk unit_sz:%lu blk_sz:%d, "
			"start_blk:%lu, capacity:%llu\n",
			__func__, (unsigned long)
			unit_data.desc_p.unit_size,
			unit_data.desc_p.block_size,
			(unsigned long)
			unit_data.desc_p.start_block,
			(uint64_t)disk_cap
		);
		#endif

		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("%s: setting gendisk disk "
			"capacity to %d\n", __func__, (int) disk_cap);
		#endif

		/* initializing bd->queue */
		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("%s: init bd->queue\n",
			__func__);
		#endif

		/* this will create a
		 * queue kernel thread */
		cyasblkdev_init_queue(
			&bd->queue, &bd->lock);

		bd->queue.prep_fn = cyasblkdev_blk_prep_rq;
		bd->queue.issue_fn = cyasblkdev_blk_issue_rq;
		bd->queue.data = bd;

		/*blk_size should always
		 * be a multiple of 512,
		 * set to the max to ensure
		 * that all accesses aligned
		 * to the greatest multiple,
		 * can adjust request to
		 * smaller block sizes
		 * dynamically*/

		bd->user_disk_0_read_only = !dev_data.desc_p.writeable;
		bd->user_disk_0_blk_size = dev_data.desc_p.block_size;
		bd->user_disk_0_type = dev_data.desc_p.type;
		bd->user_disk_0_bus_num = bus_num;
		bd->user_disk_0->major = major;
		bd->user_disk_0->first_minor = devidx << CYASBLKDEV_SHIFT;
		bd->user_disk_0->minors = 8;
		bd->user_disk_0->fops = &cyasblkdev_bdops;
		bd->user_disk_0->events = DISK_EVENT_MEDIA_CHANGE;
		bd->user_disk_0->private_data = bd;
		bd->user_disk_0->queue = bd->queue.queue;
		bd->dbgprn_flags = DBGPRN_RD_RQ;
		bd->user_disk_0_unit_no = lcl_unit_no;

		blk_queue_logical_block_size(bd->queue.queue,
			bd->user_disk_0_blk_size);

		set_capacity(bd->user_disk_0,
			disk_cap);

		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message(
			"%s: returned from set_capacity %d\n",
			__func__, (int) disk_cap);
		#endif

		/* need to start search from
		 * public partition beginning */
		if (vfat_search) {
			bd->user_disk_0_first_sector =
				cyasblkdev_get_vfat_offset(
					bd->user_disk_0_bus_num,
					bd->user_disk_0_unit_no);
		} else {
			bd->user_disk_0_first_sector = 0;
		}

		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message(
			"%s: set user_disk_0_first "
			"sector to %d\n", __func__,
			 bd->user_disk_0_first_sector);
		cy_as_hal_print_message(
			"%s: add_disk: disk->major=0x%x\n",
			__func__,
			bd->user_disk_0->major);
		cy_as_hal_print_message(
			"%s: add_disk: "
			"disk->first_minor=0x%x\n", __func__,
			bd->user_disk_0->first_minor);
		cy_as_hal_print_message(
			"%s: add_disk: "
			"disk->minors=0x%x\n", __func__,
			bd->user_disk_0->minors);
		cy_as_hal_print_message(
			"%s: add_disk: "
			"disk->disk_name=%s\n",
			__func__,
			bd->user_disk_0->disk_name);
		cy_as_hal_print_message(
			"%s: add_disk: "
			"disk->part_tbl=0x%x\n", __func__,
			(unsigned int)
			bd->user_disk_0->part_tbl);
		cy_as_hal_print_message(
			"%s: add_disk: "
			"disk->queue=0x%x\n", __func__,
			(unsigned int)
			bd->user_disk_0->queue);
		cy_as_hal_print_message(
			"%s: add_disk: "
			"disk->flags=0x%x\n",
			__func__, (unsigned int)
			bd->user_disk_0->flags);
		cy_as_hal_print_message(
			"%s: add_disk: "
			"disk->driverfs_dev=0x%x\n",
			__func__, (unsigned int)
			bd->user_disk_0->driverfs_dev);
		cy_as_hal_print_message(
			"%s: add_disk: "
			"disk->slave_dir=0x%x\n",
			__func__, (unsigned int)
			bd->user_disk_0->slave_dir);
		cy_as_hal_print_message(
			"%s: add_disk: "
			"disk->random=0x%x\n",
			__func__, (unsigned int)
			bd->user_disk_0->random);
		cy_as_hal_print_message(
			"%s: add_disk: "
			"disk->node_id=0x%x\n",
			__func__, (unsigned int)
			bd->user_disk_0->node_id);

		#endif

		add_disk(bd->user_disk_0);

	} else if ((bus_num == 1) &&
		(total_media_count == 2)) {
		bd->user_disk_1_read_only = !dev_data.desc_p.writeable;
		bd->user_disk_1_blk_size = dev_data.desc_p.block_size;
		bd->user_disk_1_type = dev_data.desc_p.type;
		bd->user_disk_1_bus_num = bus_num;
		bd->user_disk_1->major	= major;
		bd->user_disk_1->first_minor = (devidx + 1) << CYASBLKDEV_SHIFT;
		bd->user_disk_1->minors = 8;
		bd->user_disk_1->fops = &cyasblkdev_bdops;
		bd->user_disk_1->events = DISK_EVENT_MEDIA_CHANGE;
		bd->user_disk_1->private_data = bd;
		bd->user_disk_1->queue = bd->queue.queue;
		bd->dbgprn_flags = DBGPRN_RD_RQ;
		bd->user_disk_1_unit_no = lcl_unit_no;

		sprintf(bd->user_disk_1->disk_name,
			"cyasblkdevblk%d", (devidx + 1));

		#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message(
			"%s: disk unit_sz:%lu "
			"blk_sz:%d, "
			"start_blk:%lu, "
			"capacity:%llu\n",
			__func__,
			(unsigned long)
			unit_data.desc_p.unit_size,
			unit_data.desc_p.block_size,
			(unsigned long)
			unit_data.desc_p.start_block,
			(uint64_t)disk_cap
		);
		#endif

		/*blk_size should always be a
		 * multiple of 512, set to the max
		 * to ensure that all accesses
		 * aligned to the greatest multiple,
		 * can adjust request to smaller
		 * block sizes dynamically*/
		if (bd->user_disk_0_blk_size >
		bd->user_disk_1_blk_size) {
			blk_queue_logical_block_size(bd->queue.queue,
				bd->user_disk_0_blk_size);
			#ifndef WESTBRIDGE_NDEBUG
			cy_as_hal_print_message(
			"%s: set hard sect_sz:%d\n",
			__func__,
			bd->user_disk_0_blk_size);
			#endif
		} else {
			blk_queue_logical_block_size(bd->queue.queue,
				bd->user_disk_1_blk_size);
			#ifndef WESTBRIDGE_NDEBUG
			cy_as_hal_print_message(
			"%s: set hard sect_sz:%d\n",
			__func__,
			bd->user_disk_1_blk_size);
			#endif
		}

		set_capacity(bd->user_disk_1, disk_cap);
		if (vfat_search) {
			bd->user_disk_1_first_sector =
				cyasblkdev_get_vfat_offset(
					bd->user_disk_1_bus_num,
					bd->user_disk_1_unit_no);
		} else {
			bd->user_disk_1_first_sector
				= 0;
		}

		add_disk(bd->user_disk_1);
	}

	if (lcl_unit_no > 0) {
		if (bd->system_disk == NULL) {
			bd->system_disk =
				alloc_disk(8);

			if (bd->system_disk == NULL) {
				kfree(bd);
				bd = ERR_PTR(-ENOMEM);
				return bd;
			}
			disk_cap = (uint64_t)
				(private_partition_size);

			/* set properties of
			 * system disk */
			bd->system_disk_read_only = !dev_data.desc_p.writeable;
			bd->system_disk_blk_size = dev_data.desc_p.block_size;
			bd->system_disk_bus_num = bus_num;
			bd->system_disk->major = major;
			bd->system_disk->first_minor =
				(devidx + 2) << CYASBLKDEV_SHIFT;
			bd->system_disk->minors = 8;
			bd->system_disk->fops = &cyasblkdev_bdops;
			bd->system_disk->events = DISK_EVENT_MEDIA_CHANGE;
			bd->system_disk->private_data = bd;
			bd->system_disk->queue = bd->queue.queue;
			/* don't search for vfat
			 * with system disk */
			bd->system_disk_first_sector = 0;
			sprintf(
				bd->system_disk->disk_name,
				"cyasblkdevblk%d", (devidx + 2));

			set_capacity(bd->system_disk,
				disk_cap);

			add_disk(bd->system_disk);
		}
		#ifndef WESTBRIDGE_NDEBUG
		else {
			cy_as_hal_print_message(
				"%s: system disk already allocated %d\n",
				__func__, bus_num);
		}
		#endif
	}
out:
	return ret;
}
/*
 * HANDLE DRQINT from Astoria (called in AS_Intr context
 */
static void cy_handle_d_r_q_interrupt(cy_as_omap_dev_kernel *dev_p)
{
	uint16_t v ;
	static uint8_t service_ep = 2 ;

	/*
	 * We've got DRQ INT, read DRQ STATUS Register */
	v = cy_as_hal_read_register((cy_as_hal_device_tag)dev_p,
			CY_AS_MEM_P0_DRQ) ;

	if (v == 0) {
#ifndef WESTBRIDGE_NDEBUG
		cy_as_hal_print_message("stray DRQ interrupt detected\n") ;
#endif
		return;
	}

	/*
	 * Now, pick a given DMA request to handle, for now, we just
	 * go round robin.  Each bit position in the service_mask
	 * represents an endpoint from EP2 to EP15.  We rotate through
	 * each of the endpoints to find one that needs to be serviced.
	 */
	while ((v & (1 << service_ep)) == 0) {

		if (service_ep == 15)
			service_ep = 2 ;
		else
			service_ep++ ;
	}

	if (end_points[service_ep].type == cy_as_hal_write) {
		/*
		 * handle DMA WRITE REQUEST: app_cpu will
		 * write data into astoria EP buffer
		 */
		cy_service_e_p_dma_write_request(dev_p, service_ep) ;
	} else if (end_points[service_ep].type == cy_as_hal_read) {
		/*
		 * handle DMA READ REQUEST: cpu will
		 * read EP buffer from Astoria
		 */
		cy_service_e_p_dma_read_request(dev_p, service_ep) ;
	}
#ifndef WESTBRIDGE_NDEBUG
	else
		cy_as_hal_print_message("cyashalomap:interrupt,"
					" w/o pending DMA job,"
					"-check DRQ_MASK logic\n") ;
#endif

	/*
	 * Now bump the EP ahead, so other endpoints get
	 * a shot before the one we just serviced
	 */
	if (end_points[service_ep].type == cy_as_hal_none) {
		if (service_ep == 15)
			service_ep = 2 ;
		else
			service_ep++ ;
	}

}