1beacf11bSopenharmony_ci/**************************************************************************** 2beacf11bSopenharmony_ci * drivers/bch/bchlib_setup.c 3beacf11bSopenharmony_ci * 4beacf11bSopenharmony_ci * Licensed to the Apache Software Foundation (ASF) under one or more 5beacf11bSopenharmony_ci * contributor license agreements. See the NOTICE file distributed with 6beacf11bSopenharmony_ci * this work for additional information regarding copyright ownership. The 7beacf11bSopenharmony_ci * ASF licenses this file to you under the Apache License, Version 2.0 (the 8beacf11bSopenharmony_ci * "License"); you may not use this file except in compliance with the 9beacf11bSopenharmony_ci * License. You may obtain a copy of the License at 10beacf11bSopenharmony_ci * 11beacf11bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12beacf11bSopenharmony_ci * 13beacf11bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14beacf11bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15beacf11bSopenharmony_ci * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16beacf11bSopenharmony_ci * License for the specific language governing permissions and limitations 17beacf11bSopenharmony_ci * under the License. 18beacf11bSopenharmony_ci * 19beacf11bSopenharmony_ci ****************************************************************************/ 20beacf11bSopenharmony_ci 21beacf11bSopenharmony_ci/**************************************************************************** 22beacf11bSopenharmony_ci * Included Files 23beacf11bSopenharmony_ci ****************************************************************************/ 24beacf11bSopenharmony_ci#include <sys/types.h> 25beacf11bSopenharmony_ci#include <sys/mount.h> 26beacf11bSopenharmony_ci#include <stdint.h> 27beacf11bSopenharmony_ci#include <stdbool.h> 28beacf11bSopenharmony_ci#include <stdlib.h> 29beacf11bSopenharmony_ci#include <errno.h> 30beacf11bSopenharmony_ci#include <assert.h> 31beacf11bSopenharmony_ci#include <securec.h> 32beacf11bSopenharmony_ci#include "bch.h" 33beacf11bSopenharmony_ci 34beacf11bSopenharmony_ci/**************************************************************************** 35beacf11bSopenharmony_ci * Public Functions 36beacf11bSopenharmony_ci ****************************************************************************/ 37beacf11bSopenharmony_ci 38beacf11bSopenharmony_ci/**************************************************************************** 39beacf11bSopenharmony_ci * Name: bchlib_setup 40beacf11bSopenharmony_ci * 41beacf11bSopenharmony_ci * Description: 42beacf11bSopenharmony_ci * Setup so that the block driver referenced by 'blkdev' can be accessed 43beacf11bSopenharmony_ci * similar to a character device. 44beacf11bSopenharmony_ci * 45beacf11bSopenharmony_ci ****************************************************************************/ 46beacf11bSopenharmony_ci 47beacf11bSopenharmony_ciint bchlib_setup(const char *blkdev, bool readonly, void **handle) 48beacf11bSopenharmony_ci{ 49beacf11bSopenharmony_ci struct bchlib_s *bch; 50beacf11bSopenharmony_ci struct geometry geo; 51beacf11bSopenharmony_ci los_part *part; 52beacf11bSopenharmony_ci int ret; 53beacf11bSopenharmony_ci 54beacf11bSopenharmony_ci DEBUGASSERT(blkdev); 55beacf11bSopenharmony_ci 56beacf11bSopenharmony_ci /* Allocate the BCH state structure */ 57beacf11bSopenharmony_ci 58beacf11bSopenharmony_ci bch = (struct bchlib_s *)zalloc(sizeof(struct bchlib_s)); 59beacf11bSopenharmony_ci if (!bch) 60beacf11bSopenharmony_ci { 61beacf11bSopenharmony_ci PRINTK("ERROR: Failed to allocate BCH structure\n"); 62beacf11bSopenharmony_ci return -ENOMEM; 63beacf11bSopenharmony_ci } 64beacf11bSopenharmony_ci 65beacf11bSopenharmony_ci /* Open the block driver */ 66beacf11bSopenharmony_ci 67beacf11bSopenharmony_ci ret = open_blockdriver(blkdev, readonly ? MS_RDONLY : 0, &bch->vnode); 68beacf11bSopenharmony_ci if (ret < 0) 69beacf11bSopenharmony_ci { 70beacf11bSopenharmony_ci PRINTK("ERROR: Failed to open driver %s: %d\n", blkdev, -ret); 71beacf11bSopenharmony_ci goto errout_with_bch; 72beacf11bSopenharmony_ci } 73beacf11bSopenharmony_ci 74beacf11bSopenharmony_ci struct drv_data *drv = (struct drv_data *)bch->vnode->data; 75beacf11bSopenharmony_ci struct block_operations *bops = (struct block_operations *)drv->ops; 76beacf11bSopenharmony_ci 77beacf11bSopenharmony_ci DEBUGASSERT(bch->vnode && bops && bops->geometry); 78beacf11bSopenharmony_ci 79beacf11bSopenharmony_ci ret = bops->geometry(bch->vnode, &geo); 80beacf11bSopenharmony_ci if (ret < 0) 81beacf11bSopenharmony_ci { 82beacf11bSopenharmony_ci PRINTK("ERROR: geometry failed: %d\n", -ret); 83beacf11bSopenharmony_ci goto errout_with_bch; 84beacf11bSopenharmony_ci } 85beacf11bSopenharmony_ci 86beacf11bSopenharmony_ci if (!geo.geo_available) 87beacf11bSopenharmony_ci { 88beacf11bSopenharmony_ci PRINTK("ERROR: geometry failed: %d\n", -ret); 89beacf11bSopenharmony_ci ret = -ENODEV; 90beacf11bSopenharmony_ci goto errout_with_bch; 91beacf11bSopenharmony_ci } 92beacf11bSopenharmony_ci 93beacf11bSopenharmony_ci if (!readonly && (!bops->write || !geo.geo_writeenabled)) 94beacf11bSopenharmony_ci { 95beacf11bSopenharmony_ci PRINTK("ERROR: write access not supported\n"); 96beacf11bSopenharmony_ci ret = -EACCES; 97beacf11bSopenharmony_ci goto errout_with_bch; 98beacf11bSopenharmony_ci } 99beacf11bSopenharmony_ci 100beacf11bSopenharmony_ci /* Save the geometry info and complete initialization of the structure */ 101beacf11bSopenharmony_ci 102beacf11bSopenharmony_ci (void)sem_init(&bch->sem, 0, 1); 103beacf11bSopenharmony_ci bch->nsectors = geo.geo_nsectors; 104beacf11bSopenharmony_ci bch->sectsize = geo.geo_sectorsize; 105beacf11bSopenharmony_ci bch->sector = (size_t)-1; 106beacf11bSopenharmony_ci bch->readonly = readonly; 107beacf11bSopenharmony_ci bch->dirty = false; 108beacf11bSopenharmony_ci bch->unlinked = false; 109beacf11bSopenharmony_ci 110beacf11bSopenharmony_ci part = los_part_find(bch->vnode); 111beacf11bSopenharmony_ci if (part != NULL) 112beacf11bSopenharmony_ci { 113beacf11bSopenharmony_ci bch->sectstart = part->sector_start; 114beacf11bSopenharmony_ci bch->nsectors = part->sector_count; 115beacf11bSopenharmony_ci bch->disk = get_disk(part->disk_id); 116beacf11bSopenharmony_ci } 117beacf11bSopenharmony_ci else 118beacf11bSopenharmony_ci { 119beacf11bSopenharmony_ci PRINTK("ERROR: los_part_find failed\n"); 120beacf11bSopenharmony_ci ret = -ENODEV; 121beacf11bSopenharmony_ci goto errout_with_bch; 122beacf11bSopenharmony_ci } 123beacf11bSopenharmony_ci 124beacf11bSopenharmony_ci /* Allocate the sector I/O buffer */ 125beacf11bSopenharmony_ci 126beacf11bSopenharmony_ci bch->buffer = (uint8_t *)malloc(bch->sectsize); 127beacf11bSopenharmony_ci if (!bch->buffer) 128beacf11bSopenharmony_ci { 129beacf11bSopenharmony_ci PRINTK("ERROR: Failed to allocate sector buffer\n"); 130beacf11bSopenharmony_ci ret = -ENOMEM; 131beacf11bSopenharmony_ci goto errout_with_bch; 132beacf11bSopenharmony_ci } 133beacf11bSopenharmony_ci 134beacf11bSopenharmony_ci *handle = bch; 135beacf11bSopenharmony_ci return OK; 136beacf11bSopenharmony_ci 137beacf11bSopenharmony_cierrout_with_bch: 138beacf11bSopenharmony_ci (void)sem_destroy(&bch->sem); 139beacf11bSopenharmony_ci free(bch); 140beacf11bSopenharmony_ci return ret; 141beacf11bSopenharmony_ci} 142