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; }
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; }
/* 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; }
/* * 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; }
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"); }
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; }
/* 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; }
static int __devexit wb_remove(struct platform_device *devptr) { cy_as_hal_print_message("%s called\n", __func__); return 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; }
/*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); } }
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; }
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; }
/* 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"); }
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; } }
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") ; }
/* 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; }
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++ ; } }