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