示例#1
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;
}
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;
}