summaryrefslogtreecommitdiff
path: root/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/westbridge/astoria/block/cyasblkdev_block.c')
-rw-r--r--drivers/staging/westbridge/astoria/block/cyasblkdev_block.c1631
1 files changed, 0 insertions, 1631 deletions
diff --git a/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c b/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c
deleted file mode 100644
index 87452bde7c93..000000000000
--- a/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c
+++ /dev/null
@@ -1,1631 +0,0 @@
-/* cyanblkdev_block.c - West Bridge Linux Block Driver source file
-## ===========================
-## Copyright (C) 2010 Cypress Semiconductor
-##
-## This program is free software; you can redistribute it and/or
-## modify it under the terms of the GNU General Public License
-## as published by the Free Software Foundation; either version 2
-## of the License, or (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 51 Franklin Street, Fifth Floor
-## Boston, MA 02110-1301, USA.
-## ===========================
-*/
-
-/*
- * Linux block driver implementation for Cypress West Bridge.
- * Based on the mmc block driver implementation by Andrew Christian
- * for the linux 2.6.26 kernel.
- * mmc_block.c, 5/28/2002
- */
-
-/*
- * Block driver for media (i.e., flash cards)
- *
- * Copyright 2002 Hewlett-Packard Company
- *
- * Use consistent with the GNU GPL is permitted,
- * provided that this copyright notice is
- * preserved in its entirety in all copies and derived works.
- *
- * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
- * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
- * FITNESS FOR ANY PARTICULAR PURPOSE.
- *
- * Many thanks to Alessandro Rubini and Jonathan Corbet!
- *
- * Author: Andrew Christian
- * 28 May 2002
- */
-
-#include <linux/moduleparam.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
-#include <linux/errno.h>
-#include <linux/hdreg.h>
-#include <linux/kdev_t.h>
-#include <linux/blkdev.h>
-
-#include <asm/system.h>
-#include <linux/uaccess.h>
-
-#include <linux/scatterlist.h>
-#include <linux/time.h>
-#include <linux/signal.h>
-#include <linux/delay.h>
-
-#include "cyasblkdev_queue.h"
-
-#define CYASBLKDEV_SHIFT 0 /* Only a single partition. */
-#define CYASBLKDEV_MAX_REQ_LEN (256)
-#define CYASBLKDEV_NUM_MINORS (256 >> CYASBLKDEV_SHIFT)
-#define CY_AS_TEST_NUM_BLOCKS (64)
-#define CYASBLKDEV_MINOR_0 1
-#define CYASBLKDEV_MINOR_1 2
-#define CYASBLKDEV_MINOR_2 3
-
-static int major;
-module_param(major, int, 0444);
-MODULE_PARM_DESC(major,
- "specify the major device number for cyasblkdev block driver");
-
-/* parameters passed from the user space */
-static int vfat_search;
-module_param(vfat_search, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(vfat_search,
- "dynamically find the location of the first sector");
-
-static int private_partition_bus = -1;
-module_param(private_partition_bus, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(private_partition_bus,
- "bus number for private partition");
-
-static int private_partition_size = -1;
-module_param(private_partition_size, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(private_partition_size,
- "size of the private partition");
-
-/*
- * There is one cyasblkdev_blk_data per slot.
- */
-struct cyasblkdev_blk_data {
- spinlock_t lock;
- int media_count[2];
- const struct block_device_operations *blkops;
- unsigned int usage;
- unsigned int suspended;
-
- /* handle to the west bridge device this handle, typdefed as *void */
- cy_as_device_handle dev_handle;
-
- /* our custom structure, in addition to request queue,
- * adds lock & semaphore items*/
- struct cyasblkdev_queue queue;
-
- /* 16 entries is enough given max request size
- * 16 * 4K (64 K per request)*/
- struct scatterlist sg[16];
-
- /* non-zero enables printk of executed reqests */
- unsigned int dbgprn_flags;
-
- /*gen_disk for private, system disk */
- struct gendisk *system_disk;
- cy_as_media_type system_disk_type;
- cy_bool system_disk_read_only;
- cy_bool system_disk_bus_num;
-
- /* sector size for the medium */
- unsigned int system_disk_blk_size;
- unsigned int system_disk_first_sector;
- unsigned int system_disk_unit_no;
-
- /*gen_disk for bus 0 */
- struct gendisk *user_disk_0;
- cy_as_media_type user_disk_0_type;
- cy_bool user_disk_0_read_only;
- cy_bool user_disk_0_bus_num;
-
- /* sector size for the medium */
- unsigned int user_disk_0_blk_size;
- unsigned int user_disk_0_first_sector;
- unsigned int user_disk_0_unit_no;
-
- /*gen_disk for bus 1 */
- struct gendisk *user_disk_1;
- cy_as_media_type user_disk_1_type;
- cy_bool user_disk_1_read_only;
- cy_bool user_disk_1_bus_num;
-
- /* sector size for the medium */
- unsigned int user_disk_1_blk_size;
- unsigned int user_disk_1_first_sector;
- unsigned int user_disk_1_unit_no;
-};
-
-/* pointer to west bridge block data device superstructure */
-static struct cyasblkdev_blk_data *gl_bd;
-
-static DEFINE_SEMAPHORE(open_lock);
-
-/* local forwardd declarationss */
-static cy_as_device_handle *cyas_dev_handle;
-static void cyasblkdev_blk_deinit(struct cyasblkdev_blk_data *bd);
-
-/*change debug print options */
- #define DBGPRN_RD_RQ (1 < 0)
- #define DBGPRN_WR_RQ (1 < 1)
- #define DBGPRN_RQ_END (1 < 2)
-
-int blkdev_ctl_dbgprn(
- int prn_flags
- )
-{
- int cur_options = gl_bd->dbgprn_flags;
-
- DBGPRN_FUNC_NAME;
-
- /* set new debug print options */
- gl_bd->dbgprn_flags = prn_flags;
-
- /* return previous */
- return cur_options;
-}
-EXPORT_SYMBOL(blkdev_ctl_dbgprn);
-
-static struct cyasblkdev_blk_data *cyasblkdev_blk_get(
- struct gendisk *disk
- )
-{
- struct cyasblkdev_blk_data *bd;
-
- DBGPRN_FUNC_NAME;
-
- down(&open_lock);
-
- bd = disk->private_data;
-
- if (bd && (bd->usage == 0))
- bd = NULL;
-
- if (bd) {
- bd->usage++;
- #ifndef NBDEBUG
- cy_as_hal_print_message(
- "cyasblkdev_blk_get: usage = %d\n", bd->usage);
- #endif
- }
- up(&open_lock);
-
- return bd;
-}
-
-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);
-}
-
-static int cyasblkdev_blk_open(
- struct block_device *bdev,
- fmode_t mode
- )
-{
- struct cyasblkdev_blk_data *bd = cyasblkdev_blk_get(bdev->bd_disk);
- int ret = -ENXIO;
-
- DBGPRN_FUNC_NAME;
-
- if (bd) {
- if (bd->usage == 2)
- check_disk_change(bdev);
-
- ret = 0;
-
- if (bdev->bd_disk == bd->user_disk_0) {
- if ((mode & FMODE_WRITE) && bd->user_disk_0_read_only) {
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "device marked as readonly "
- "and write requested\n");
- #endif
-
- cyasblkdev_blk_put(bd);
- ret = -EROFS;
- }
- } else if (bdev->bd_disk == bd->user_disk_1) {
- if ((mode & FMODE_WRITE) && bd->user_disk_1_read_only) {
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "device marked as readonly "
- "and write requested\n");
- #endif
-
- cyasblkdev_blk_put(bd);
- ret = -EROFS;
- }
- } else if (bdev->bd_disk == bd->system_disk) {
- if ((mode & FMODE_WRITE) && bd->system_disk_read_only) {
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "device marked as readonly "
- "and write requested\n");
- #endif
-
- cyasblkdev_blk_put(bd);
- ret = -EROFS;
- }
- }
- }
-
- return ret;
-}
-
-static int cyasblkdev_blk_release(
- struct gendisk *disk,
- fmode_t mode
- )
-{
- struct cyasblkdev_blk_data *bd = disk->private_data;
-
- DBGPRN_FUNC_NAME;
-
- cyasblkdev_blk_put(bd);
- return 0;
-}
-
-static int cyasblkdev_blk_ioctl(
- struct block_device *bdev,
- fmode_t mode,
- unsigned int cmd,
- unsigned long arg
- )
-{
- DBGPRN_FUNC_NAME;
-
- if (cmd == HDIO_GETGEO) {
- /*for now we only process geometry IOCTL*/
- struct hd_geometry geo;
-
- memset(&geo, 0, sizeof(struct hd_geometry));
-
- geo.cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
- geo.heads = 4;
- geo.sectors = 16;
- geo.start = get_start_sect(bdev);
-
- /* copy to user space */
- return copy_to_user((void __user *)arg, &geo, sizeof(geo))
- ? -EFAULT : 0;
- }
-
- return -ENOTTY;
-}
-
-/* check_events block_device opp
- * this one is called by kernel to confirm if the media really changed
- * as we indicated by issuing check_disk_change() call */
-unsigned int cyasblkdev_check_events(struct gendisk *gd, unsigned int clearing)
-{
- struct cyasblkdev_blk_data *bd;
-
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message("cyasblkdev_media_changed() is called\n");
- #endif
-
- if (gd)
- bd = gd->private_data;
- else {
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "cyasblkdev_media_changed() is called, "
- "but gd is null\n");
- #endif
- }
-
- /* return media change state - DISK_EVENT_MEDIA_CHANGE yes, 0 no */
- return 0;
-}
-
-/* this one called by kernel to give us a chence
- * to prep the new media before it starts to rescaning
- * of the newlly inserted SD media */
-int cyasblkdev_revalidate_disk(struct gendisk *gd)
-{
- /*int (*revalidate_disk) (struct gendisk *); */
-
- #ifndef WESTBRIDGE_NDEBUG
- if (gd)
- cy_as_hal_print_message(
- "cyasblkdev_revalidate_disk() is called, "
- "(gl_bd->usage:%d)\n", gl_bd->usage);
- #endif
-
- /* 0 means ok, kern can go ahead with partition rescan */
- return 0;
-}
-
-
-/*standard block device driver interface */
-static struct block_device_operations cyasblkdev_bdops = {
- .open = cyasblkdev_blk_open,
- .release = cyasblkdev_blk_release,
- .ioctl = cyasblkdev_blk_ioctl,
- /* .getgeo = cyasblkdev_blk_getgeo, */
- /* added to support media removal( real and simulated) media */
- .check_events = cyasblkdev_check_events,
- /* added to support media removal( real and simulated) media */
- .revalidate_disk = cyasblkdev_revalidate_disk,
- .owner = THIS_MODULE,
-};
-
-/* west bridge block device prep request function */
-static int cyasblkdev_blk_prep_rq(
- struct cyasblkdev_queue *bq,
- struct request *req
- )
-{
- struct cyasblkdev_blk_data *bd = bq->data;
- int stat = BLKPREP_OK;
-
- DBGPRN_FUNC_NAME;
-
- /* If we have no device, we haven't finished initialising. */
- if (!bd || !bd->dev_handle) {
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(KERN_ERR
- "cyasblkdev %s: killing request - no device/host\n",
- req->rq_disk->disk_name);
- #endif
- stat = BLKPREP_KILL;
- }
-
- if (bd->suspended) {
- blk_plug_device(bd->queue.queue);
- stat = BLKPREP_DEFER;
- }
-
- /* Check for excessive requests.*/
- if (blk_rq_pos(req) + blk_rq_sectors(req) > get_capacity(req->rq_disk)) {
- cy_as_hal_print_message("cyasblkdev: bad request address\n");
- stat = BLKPREP_KILL;
- }
-
- return stat;
-}
-
-/*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);
- }
-}
-
-/* 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;
-}
-
-static unsigned long
-dev_use[CYASBLKDEV_NUM_MINORS / (8 * sizeof(unsigned long))];
-
-
-/* storage event callback (note: called in astoria isr context) */
-static void cyasblkdev_storage_callback(
- cy_as_device_handle dev_h,
- cy_as_bus_number_t bus,
- uint32_t device,
- cy_as_storage_event evtype,
- void *evdata
- )
-{
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message("%s: bus:%d, device:%d, evtype:%d, "
- "evdata:%p\n ", __func__, bus, device, evtype, evdata);
- #endif
-
- switch (evtype) {
- case cy_as_storage_processor:
- break;
-
- case cy_as_storage_removed:
- break;
-
- case cy_as_storage_inserted:
- break;
-
- default:
- break;
- }
-}
-
-#define SECTORS_TO_SCAN 4096
-
-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;
- }
-}
-
-cy_as_storage_query_device_data dev_data = {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;
-}
-
-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;
-}
-
-
-/*init west bridge block device */
-static int cyasblkdev_blk_initialize(void)
-{
- struct cyasblkdev_blk_data *bd;
- int res;
-
- DBGPRN_FUNC_NAME;
-
- res = register_blkdev(major, "cyasblkdev");
-
- if (res < 0) {
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(KERN_WARNING
- "%s unable to get major %d for cyasblkdev media: %d\n",
- __func__, major, res);
- #endif
- return res;
- }
-
- if (major == 0)
- major = res;
-
- #ifndef WESTBRIDGE_NDEBUG
- cy_as_hal_print_message(
- "%s cyasblkdev registered with major number: %d\n",
- __func__, major);
- #endif
-
- bd = cyasblkdev_blk_alloc();
- if (IS_ERR(bd))
- return PTR_ERR(bd);
-
- 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;
-}
-
-
-static void cyasblkdev_blk_deinit(struct cyasblkdev_blk_data *bd)
-{
- DBGPRN_FUNC_NAME;
-
- if (bd) {
- int devidx;
-
- if (bd->user_disk_0 != NULL) {
- del_gendisk(bd->user_disk_0);
- devidx = bd->user_disk_0->first_minor
- >> CYASBLKDEV_SHIFT;
- __clear_bit(devidx, dev_use);
- }
-
- if (bd->user_disk_1 != NULL) {
- del_gendisk(bd->user_disk_1);
- devidx = bd->user_disk_1->first_minor
- >> CYASBLKDEV_SHIFT;
- __clear_bit(devidx, dev_use);
- }
-
- if (bd->system_disk != NULL) {
- del_gendisk(bd->system_disk);
- devidx = bd->system_disk->first_minor
- >> CYASBLKDEV_SHIFT;
- __clear_bit(devidx, dev_use);
- }
-
- cyasblkdev_blk_put(bd);
- }
-}
-
-/* block device exit */
-static void __exit cyasblkdev_blk_exit(void)
-{
- DBGPRN_FUNC_NAME;
-
- cyasblkdev_blk_deinit(gl_bd);
- unregister_blkdev(major, "cyasblkdev");
-
-}
-
-module_init(cyasblkdev_blk_init);
-module_exit(cyasblkdev_blk_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("antioch (cyasblkdev) block device driver");
-MODULE_AUTHOR("cypress semiconductor");
-
-/*[]*/