• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  * drivers/bch/bchlib_setup.c
3  *
4  *   Copyright (C) 2008-2009, 2011, 2016 Gregory Nutt. All rights reserved.
5  *   Author: Gregory Nutt <gnutt@nuttx.org>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name NuttX nor the names of its contributors may be
18  *    used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  ****************************************************************************/
35 
36 /****************************************************************************
37  * Included Files
38  ****************************************************************************/
39 #include <sys/types.h>
40 #include <sys/mount.h>
41 #include <stdint.h>
42 #include <stdbool.h>
43 #include <stdlib.h>
44 #include <errno.h>
45 #include <assert.h>
46 #include <securec.h>
47 #include "bch.h"
48 
49 /****************************************************************************
50  * Public Functions
51  ****************************************************************************/
52 
53 /****************************************************************************
54  * Name: bchlib_setup
55  *
56  * Description:
57  *   Setup so that the block driver referenced by 'blkdev' can be accessed
58  *   similar to a character device.
59  *
60  ****************************************************************************/
61 
bchlib_setup(const char * blkdev,bool readonly,void ** handle)62 int bchlib_setup(const char *blkdev, bool readonly, void **handle)
63 {
64   struct bchlib_s *bch;
65   struct geometry geo;
66   los_part *part;
67   int ret;
68 
69   DEBUGASSERT(blkdev);
70 
71   /* Allocate the BCH state structure */
72 
73   bch = (struct bchlib_s *)zalloc(sizeof(struct bchlib_s));
74   if (!bch)
75     {
76       PRINTK("ERROR: Failed to allocate BCH structure\n");
77       return -ENOMEM;
78     }
79 
80   /* Open the block driver */
81 
82   ret = open_blockdriver(blkdev, readonly ? MS_RDONLY : 0, &bch->vnode);
83   if (ret < 0)
84     {
85       PRINTK("ERROR: Failed to open driver %s: %d\n", blkdev, -ret);
86       goto errout_with_bch;
87     }
88 
89   struct drv_data *drv = (struct drv_data *)bch->vnode->data;
90   struct block_operations *bops = (struct block_operations *)drv->ops;
91 
92   DEBUGASSERT(bch->vnode && bops && bops->geometry);
93 
94   ret = bops->geometry(bch->vnode, &geo);
95   if (ret < 0)
96     {
97       PRINTK("ERROR: geometry failed: %d\n", -ret);
98       goto errout_with_bch;
99     }
100 
101   if (!geo.geo_available)
102     {
103       PRINTK("ERROR: geometry failed: %d\n", -ret);
104       ret = -ENODEV;
105       goto errout_with_bch;
106     }
107 
108   if (!readonly && (!bops->write || !geo.geo_writeenabled))
109     {
110       PRINTK("ERROR: write access not supported\n");
111       ret = -EACCES;
112       goto errout_with_bch;
113     }
114 
115   /* Save the geometry info and complete initialization of the structure */
116 
117   (void)sem_init(&bch->sem, 0, 1);
118   bch->nsectors = geo.geo_nsectors;
119   bch->sectsize = geo.geo_sectorsize;
120   bch->sector   = (size_t)-1;
121   bch->readonly = readonly;
122   bch->dirty    = false;
123   bch->unlinked = false;
124 
125   part = los_part_find(bch->vnode);
126   if (part != NULL)
127     {
128       bch->sectstart = part->sector_start;
129       bch->nsectors = part->sector_count;
130       bch->disk = get_disk(part->disk_id);
131     }
132   else
133     {
134       PRINTK("ERROR: los_part_find failed\n");
135       ret = -ENODEV;
136       goto errout_with_bch;
137     }
138 
139   /* Allocate the sector I/O buffer */
140 
141   bch->buffer = (uint8_t *)malloc(bch->sectsize);
142   if (!bch->buffer)
143     {
144       PRINTK("ERROR: Failed to allocate sector buffer\n");
145       ret = -ENOMEM;
146       goto errout_with_bch;
147     }
148 
149   *handle = bch;
150   return OK;
151 
152 errout_with_bch:
153   (void)sem_destroy(&bch->sem);
154   free(bch);
155   return ret;
156 }
157