• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  * drivers/bch/bchlib_read.c
3  *
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.  The
7  * ASF licenses this file to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance with the
9  * License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
16  * License for the specific language governing permissions and limitations
17  * under the License.
18  *
19  ****************************************************************************/
20 
21 /****************************************************************************
22  * Included Files
23  ****************************************************************************/
24 #include <sys/types.h>
25 #include <stdint.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <assert.h>
29 #include "bch.h"
30 #include <stdlib.h>
31 
32 /****************************************************************************
33  * Private Types
34  ****************************************************************************/
35 
36 /****************************************************************************
37  * Private Function Prototypes
38  ****************************************************************************/
39 
40 /****************************************************************************
41  * Private Data
42  ****************************************************************************/
43 
44 /****************************************************************************
45  * Private Functions
46  ****************************************************************************/
47 
48 /****************************************************************************
49  * Public Functions
50  ****************************************************************************/
51 
52 /****************************************************************************
53  * Name: bchlib_read
54  *
55  * Description:
56  *   Read from the block device set-up by bchlib_setup as if it were a character
57  *   device.
58  *
59  ****************************************************************************/
60 
bchlib_read(void * handle,char * buffer,loff_t offset,size_t len)61 ssize_t bchlib_read(void *handle, char *buffer, loff_t offset, size_t len)
62 {
63   struct bchlib_s *bch = (struct bchlib_s *)handle;
64   size_t   nsectors;
65   unsigned long long   sector;
66   uint16_t sectoffset;
67   size_t   nbytes;
68   size_t   bytesread;
69   int      ret;
70 
71   /* Get rid of this special case right away */
72 
73   if (len < 1)
74     {
75       return 0;
76     }
77 
78   /* Convert the file position into a sector number an offset. */
79 
80   sector     = offset / bch->sectsize;
81   sectoffset = offset - sector * bch->sectsize;
82 
83   if (sector >= bch->nsectors)
84     {
85       /* Return end-of-file */
86 
87       return 0;
88     }
89 
90   /* Read the initial partial sector */
91 
92   bytesread = 0;
93   if (sectoffset > 0)
94     {
95       /* Read the sector into the sector buffer */
96 
97       ret = bchlib_readsector(bch, sector + bch->sectstart);
98       if (ret < 0)
99         {
100           return bytesread;
101         }
102 
103       /* Copy the tail end of the sector to the user buffer */
104 
105       if (sectoffset + len > bch->sectsize)
106         {
107           nbytes = bch->sectsize - sectoffset;
108         }
109       else
110         {
111           nbytes = len;
112         }
113 
114       ret = LOS_CopyFromKernel(buffer, len, &bch->buffer[sectoffset], nbytes);
115       if (ret != EOK)
116         {
117           PRINTK("ERROR: bchlib_read failed: %d\n", ret);
118           return bytesread;
119         }
120 
121       /* Adjust pointers and counts */
122 
123       ++sector;
124 
125       if (sector >= bch->nsectors)
126         {
127           return nbytes;
128         }
129 
130       bytesread  = nbytes;
131       buffer    += nbytes;
132       len       -= nbytes;
133     }
134 
135   /* Then read all of the full sectors following the partial sector directly
136    * into the user buffer.
137    */
138 
139   if (len >= bch->sectsize)
140     {
141       nsectors = len / bch->sectsize;
142       if (sector + nsectors > bch->nsectors)
143         {
144           nsectors = bch->nsectors - sector;
145         }
146       /* No need for reading large contiguous data, useRead(param 4) is set TRUE */
147       ret = los_disk_read(bch->disk->disk_id, (void *)buffer, sector + bch->sectstart, nsectors, TRUE);
148 
149       if (ret < 0)
150         {
151           PRINTK("ERROR: Read failed: %d\n", ret);
152           return bytesread;
153         }
154 
155       /* Adjust pointers and counts */
156 
157       sector    += nsectors;
158       nbytes     = nsectors * bch->sectsize;
159       bytesread += nbytes;
160 
161       if (sector >= bch->nsectors)
162         {
163           return bytesread;
164         }
165 
166       buffer    += nbytes;
167       len       -= nbytes;
168     }
169 
170   /* Then read any partial final sector */
171 
172   if (len > 0)
173     {
174       /* Read the sector into the sector buffer */
175 
176       ret = bchlib_readsector(bch, sector + bch->sectstart);
177       if (ret < 0)
178         {
179           return bytesread;
180         }
181 
182       /* Copy the head end of the sector to the user buffer */
183 
184       ret = LOS_CopyFromKernel(buffer, len, bch->buffer, len);
185       if (ret != EOK)
186         {
187           PRINTK("ERROR: bchlib_read failed: %d\n", ret);
188           return bytesread;
189         }
190 
191       /* Adjust counts */
192 
193       bytesread += len;
194     }
195 
196   return bytesread;
197 }
198