Fri Jul 29 20:48:33 2011 UTC ()
add a function to get the size of the flash device


(ahoka)
diff -r1.8 -r1.9 src/sys/dev/flash/flash.c
diff -r1.6 -r1.7 src/sys/dev/flash/flash.h

cvs diff -r1.8 -r1.9 src/sys/dev/flash/flash.c (switch to unified diff)

--- src/sys/dev/flash/flash.c 2011/07/15 19:19:57 1.8
+++ src/sys/dev/flash/flash.c 2011/07/29 20:48:33 1.9
@@ -1,673 +1,683 @@ @@ -1,673 +1,683 @@
1/* $NetBSD: flash.c,v 1.8 2011/07/15 19:19:57 cliff Exp $ */ 1/* $NetBSD: flash.c,v 1.9 2011/07/29 20:48:33 ahoka Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 Department of Software Engineering, 4 * Copyright (c) 2011 Department of Software Engineering,
5 * University of Szeged, Hungary 5 * University of Szeged, Hungary
6 * Copyright (c) 2011 Adam Hoka <ahoka@NetBSD.org> 6 * Copyright (c) 2011 Adam Hoka <ahoka@NetBSD.org>
7 * Copyright (c) 2010 David Tengeri <dtengeri@inf.u-szeged.hu> 7 * Copyright (c) 2010 David Tengeri <dtengeri@inf.u-szeged.hu>
8 * All rights reserved. 8 * All rights reserved.
9 * 9 *
10 * This code is derived from software contributed to The NetBSD Foundation 10 * This code is derived from software contributed to The NetBSD Foundation
11 * by the Department of Software Engineering, University of Szeged, Hungary 11 * by the Department of Software Engineering, University of Szeged, Hungary
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions 14 * modification, are permitted provided that the following conditions
15 * are met: 15 * are met:
16 * 1. Redistributions of source code must retain the above copyright 16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer. 17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright 18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the 19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution. 20 * documentation and/or other materials provided with the distribution.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 */ 33 */
34 34
35/*- 35/*-
36 * Framework for storage devices based on Flash technology 36 * Framework for storage devices based on Flash technology
37 */ 37 */
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40__KERNEL_RCSID(0, "$NetBSD: flash.c,v 1.8 2011/07/15 19:19:57 cliff Exp $"); 40__KERNEL_RCSID(0, "$NetBSD: flash.c,v 1.9 2011/07/29 20:48:33 ahoka Exp $");
41 41
42#include <sys/param.h> 42#include <sys/param.h>
43#include <sys/types.h> 43#include <sys/types.h>
44#include <sys/proc.h> 44#include <sys/proc.h>
45#include <sys/errno.h> 45#include <sys/errno.h>
46#include <sys/ioctl.h> 46#include <sys/ioctl.h>
47#include <sys/device.h> 47#include <sys/device.h>
48#include <sys/conf.h> 48#include <sys/conf.h>
49#include <sys/kmem.h> 49#include <sys/kmem.h>
50#include <sys/uio.h> 50#include <sys/uio.h>
51#include <sys/kernel.h> 51#include <sys/kernel.h>
52 52
53#include <sys/atomic.h> 53#include <sys/atomic.h>
54#include <sys/buf.h> 54#include <sys/buf.h>
55#include <sys/bufq.h> 55#include <sys/bufq.h>
56#include <sys/disk.h> 56#include <sys/disk.h>
57#include <sys/disklabel.h> 57#include <sys/disklabel.h>
58#include <sys/malloc.h> 58#include <sys/malloc.h>
59#include <sys/reboot.h> 59#include <sys/reboot.h>
60 60
61#include <sys/flashio.h> 61#include <sys/flashio.h>
62#include "flash.h" 62#include "flash.h"
63 63
64#ifdef FLASH_DEBUG 64#ifdef FLASH_DEBUG
65int flashdebug = FLASH_DEBUG; 65int flashdebug = FLASH_DEBUG;
66#endif 66#endif
67 67
68extern struct cfdriver flash_cd; 68extern struct cfdriver flash_cd;
69 69
70dev_type_open(flashopen); 70dev_type_open(flashopen);
71dev_type_close(flashclose); 71dev_type_close(flashclose);
72dev_type_read(flashread); 72dev_type_read(flashread);
73dev_type_write(flashwrite); 73dev_type_write(flashwrite);
74dev_type_ioctl(flashioctl); 74dev_type_ioctl(flashioctl);
75dev_type_strategy(flashstrategy); 75dev_type_strategy(flashstrategy);
76dev_type_dump(flashdump); 76dev_type_dump(flashdump);
77 77
78int flash_print(void *aux, const char *pnp); 78int flash_print(void *aux, const char *pnp);
79 79
80bool flash_shutdown(device_t dev, int how); 80bool flash_shutdown(device_t dev, int how);
81int flash_nsectors(struct buf *bp); 81int flash_nsectors(struct buf *bp);
82int flash_sector(struct buf *bp); 82int flash_sector(struct buf *bp);
83 83
84int flash_match(device_t parent, cfdata_t match, void *aux); 84int flash_match(device_t parent, cfdata_t match, void *aux);
85void flash_attach(device_t parent, device_t self, void *aux); 85void flash_attach(device_t parent, device_t self, void *aux);
86int flash_detach(device_t device, int flags); 86int flash_detach(device_t device, int flags);
87 87
88CFATTACH_DECL_NEW(flash, sizeof(struct flash_softc), 88CFATTACH_DECL_NEW(flash, sizeof(struct flash_softc),
89 flash_match, flash_attach, flash_detach, NULL); 89 flash_match, flash_attach, flash_detach, NULL);
90 90
91/** 91/**
92 * Block device's operation 92 * Block device's operation
93 */ 93 */
94const struct bdevsw flash_bdevsw = { 94const struct bdevsw flash_bdevsw = {
95 .d_open = flashopen, 95 .d_open = flashopen,
96 .d_close = flashclose, 96 .d_close = flashclose,
97 .d_strategy = flashstrategy, 97 .d_strategy = flashstrategy,
98 .d_ioctl = flashioctl, 98 .d_ioctl = flashioctl,
99 .d_dump = flashdump, 99 .d_dump = flashdump,
100 .d_psize = nosize, 100 .d_psize = nosize,
101 .d_flag = D_DISK | D_MPSAFE 101 .d_flag = D_DISK | D_MPSAFE
102}; 102};
103 103
104/** 104/**
105 * Character device's operations 105 * Character device's operations
106 */ 106 */
107const struct cdevsw flash_cdevsw = { 107const struct cdevsw flash_cdevsw = {
108 .d_open = flashopen, 108 .d_open = flashopen,
109 .d_close = flashclose, 109 .d_close = flashclose,
110 .d_read = flashread, 110 .d_read = flashread,
111 .d_write = flashwrite, 111 .d_write = flashwrite,
112 .d_ioctl = flashioctl, 112 .d_ioctl = flashioctl,
113 .d_stop = nostop, 113 .d_stop = nostop,
114 .d_tty = notty, 114 .d_tty = notty,
115 .d_poll = nopoll, 115 .d_poll = nopoll,
116 .d_mmap = nommap, 116 .d_mmap = nommap,
117 .d_kqfilter = nokqfilter, 117 .d_kqfilter = nokqfilter,
118 .d_flag = D_DISK | D_MPSAFE 118 .d_flag = D_DISK | D_MPSAFE
119}; 119};
120 120
121/* ARGSUSED */ 121/* ARGSUSED */
122int 122int
123flash_match(device_t parent, cfdata_t match, void *aux) 123flash_match(device_t parent, cfdata_t match, void *aux)
124{ 124{
125 /* pseudo device, always attaches */ 125 /* pseudo device, always attaches */
126 return 1; 126 return 1;
127} 127}
128 128
129/* ARGSUSED */ 129/* ARGSUSED */
130void 130void
131flash_attach(device_t parent, device_t self, void *aux) 131flash_attach(device_t parent, device_t self, void *aux)
132{ 132{
133 struct flash_softc * const sc = device_private(self); 133 struct flash_softc * const sc = device_private(self);
134 struct flash_attach_args * const faa = aux; 134 struct flash_attach_args * const faa = aux;
135 char pbuf[2][sizeof("9999 KB")]; 135 char pbuf[2][sizeof("9999 KB")];
136 136
137 sc->sc_dev = self; 137 sc->sc_dev = self;
138 sc->sc_parent_dev = parent; 138 sc->sc_parent_dev = parent;
139 sc->flash_if = faa->flash_if; 139 sc->flash_if = faa->flash_if;
140 sc->sc_partinfo = faa->partinfo; 140 sc->sc_partinfo = faa->partinfo;
141 sc->hw_softc = device_private(parent); 141 sc->hw_softc = device_private(parent);
142 142
143 format_bytes(pbuf[0], sizeof(pbuf[0]), sc->sc_partinfo.part_size); 143 format_bytes(pbuf[0], sizeof(pbuf[0]), sc->sc_partinfo.part_size);
144 format_bytes(pbuf[1], sizeof(pbuf[1]), sc->flash_if->erasesize); 144 format_bytes(pbuf[1], sizeof(pbuf[1]), sc->flash_if->erasesize);
145 145
146 aprint_naive("\n"); 146 aprint_naive("\n");
147 147
148 switch (sc->flash_if->type) { 148 switch (sc->flash_if->type) {
149 case FLASH_TYPE_NOR: 149 case FLASH_TYPE_NOR:
150 aprint_normal(": NOR flash partition size %s, offset %#jx", 150 aprint_normal(": NOR flash partition size %s, offset %#jx",
151 pbuf[0], (uintmax_t )sc->sc_partinfo.part_offset); 151 pbuf[0], (uintmax_t )sc->sc_partinfo.part_offset);
152 break; 152 break;
153 153
154 case FLASH_TYPE_NAND: 154 case FLASH_TYPE_NAND:
155 aprint_normal(": NAND flash partition size %s, offset %#jx", 155 aprint_normal(": NAND flash partition size %s, offset %#jx",
156 pbuf[0], (uintmax_t )sc->sc_partinfo.part_offset); 156 pbuf[0], (uintmax_t )sc->sc_partinfo.part_offset);
157 break; 157 break;
158 158
159 default: 159 default:
160 aprint_normal(": %s unknown flash", pbuf[0]); 160 aprint_normal(": %s unknown flash", pbuf[0]);
161 } 161 }
162 162
163 if (sc->sc_partinfo.part_flags & FLASH_PART_READONLY) { 163 if (sc->sc_partinfo.part_flags & FLASH_PART_READONLY) {
164 sc->sc_readonly = true; 164 sc->sc_readonly = true;
165 aprint_normal(", read only"); 165 aprint_normal(", read only");
166 } else { 166 } else {
167 sc->sc_readonly = false; 167 sc->sc_readonly = false;
168 } 168 }
169 169
170 aprint_normal("\n"); 170 aprint_normal("\n");
171 171
172 if (sc->sc_partinfo.part_size == 0) { 172 if (sc->sc_partinfo.part_size == 0) {
173 aprint_error_dev(self, 173 aprint_error_dev(self,
174 "partition size must be larger than 0\n"); 174 "partition size must be larger than 0\n");
175 return; 175 return;
176 } 176 }
177 177
178 switch (sc->flash_if->type) { 178 switch (sc->flash_if->type) {
179 case FLASH_TYPE_NOR: 179 case FLASH_TYPE_NOR:
180 aprint_normal_dev(sc->sc_dev, 180 aprint_normal_dev(sc->sc_dev,
181 "erase size %s bytes, write size %d bytes\n", 181 "erase size %s bytes, write size %d bytes\n",
182 pbuf[1], sc->flash_if->writesize); 182 pbuf[1], sc->flash_if->writesize);
183 break; 183 break;
184 184
185 case FLASH_TYPE_NAND: 185 case FLASH_TYPE_NAND:
186 default: 186 default:
187 aprint_normal_dev(sc->sc_dev, 187 aprint_normal_dev(sc->sc_dev,
188 "erase size %s, page size %d bytes, write size %d bytes\n", 188 "erase size %s, page size %d bytes, write size %d bytes\n",
189 pbuf[1], sc->flash_if->page_size, 189 pbuf[1], sc->flash_if->page_size,
190 sc->flash_if->writesize); 190 sc->flash_if->writesize);
191 break; 191 break;
192 } 192 }
193 193
194 if (!pmf_device_register1(sc->sc_dev, NULL, NULL, flash_shutdown)) 194 if (!pmf_device_register1(sc->sc_dev, NULL, NULL, flash_shutdown))
195 aprint_error_dev(sc->sc_dev, 195 aprint_error_dev(sc->sc_dev,
196 "couldn't establish power handler\n"); 196 "couldn't establish power handler\n");
197} 197}
198 198
199int 199int
200flash_detach(device_t device, int flags) 200flash_detach(device_t device, int flags)
201{ 201{
202 struct flash_softc * const sc = device_private(device); 202 struct flash_softc * const sc = device_private(device);
203 203
204 pmf_device_deregister(sc->sc_dev); 204 pmf_device_deregister(sc->sc_dev);
205 205
206 /* freeing flash_if is our responsibility */ 206 /* freeing flash_if is our responsibility */
207 kmem_free(sc->flash_if, sizeof(*sc->flash_if)); 207 kmem_free(sc->flash_if, sizeof(*sc->flash_if));
208 208
209 return 0; 209 return 0;
210} 210}
211 211
212int 212int
213flash_print(void *aux, const char *pnp) 213flash_print(void *aux, const char *pnp)
214{ 214{
215 struct flash_attach_args *arg; 215 struct flash_attach_args *arg;
216 const char *type; 216 const char *type;
217 217
218 if (pnp != NULL) { 218 if (pnp != NULL) {
219 arg = aux; 219 arg = aux;
220 switch (arg->flash_if->type) { 220 switch (arg->flash_if->type) {
221 case FLASH_TYPE_NOR: 221 case FLASH_TYPE_NOR:
222 type = "NOR"; 222 type = "NOR";
223 break; 223 break;
224 case FLASH_TYPE_NAND: 224 case FLASH_TYPE_NAND:
225 type = "NAND"; 225 type = "NAND";
226 break; 226 break;
227 default: 227 default:
228 panic("flash_print: unknown type %d", 228 panic("flash_print: unknown type %d",
229 arg->flash_if->type); 229 arg->flash_if->type);
230 } 230 }
231 aprint_normal("%s flash at %s", type, pnp); 231 aprint_normal("%s flash at %s", type, pnp);
232 } 232 }
233 return UNCONF; 233 return UNCONF;
234} 234}
235 235
236device_t 236device_t
237flash_attach_mi(struct flash_interface * const flash_if, device_t device) 237flash_attach_mi(struct flash_interface * const flash_if, device_t device)
238{ 238{
239 struct flash_attach_args arg; 239 struct flash_attach_args arg;
240 240
241#ifdef DIAGNOSTIC 241#ifdef DIAGNOSTIC
242 if (flash_if == NULL) { 242 if (flash_if == NULL) {
243 aprint_error("flash_attach_mi: NULL\n"); 243 aprint_error("flash_attach_mi: NULL\n");
244 return 0; 244 return 0;
245 } 245 }
246#endif 246#endif
247 arg.flash_if = flash_if; 247 arg.flash_if = flash_if;
248 248
249 return config_found_ia(device, "flashbus", &arg, flash_print); 249 return config_found_ia(device, "flashbus", &arg, flash_print);
250} 250}
251 251
252/** 252/**
253 * flash_open - open the character device 253 * flash_open - open the character device
254 * Checks if there is a driver registered to the minor number of the open 254 * Checks if there is a driver registered to the minor number of the open
255 * request. 255 * request.
256 */ 256 */
257int 257int
258flashopen(dev_t dev, int flags, int fmt, lwp_t *l) 258flashopen(dev_t dev, int flags, int fmt, lwp_t *l)
259{ 259{
260 int unit = minor(dev); 260 int unit = minor(dev);
261 struct flash_softc *sc; 261 struct flash_softc *sc;
262 262
263 FLDPRINTFN(1, ("flash: opening device unit %d\n", unit)); 263 FLDPRINTFN(1, ("flash: opening device unit %d\n", unit));
264 264
265 if ((sc = device_lookup_private(&flash_cd, unit)) == NULL) 265 if ((sc = device_lookup_private(&flash_cd, unit)) == NULL)
266 return ENXIO; 266 return ENXIO;
267 267
268 /* TODO return eperm if want to open for writing a read only dev */ 268 /* TODO return eperm if want to open for writing a read only dev */
269 269
270 /* reset buffer length */ 270 /* reset buffer length */
271// sc->sc_cache->fc_len = 0; 271// sc->sc_cache->fc_len = 0;
272 272
273 return 0; 273 return 0;
274} 274}
275 275
276/** 276/**
277 * flash_close - close device 277 * flash_close - close device
278 * We don't have to release any resources, so just return 0. 278 * We don't have to release any resources, so just return 0.
279 */ 279 */
280int 280int
281flashclose(dev_t dev, int flags, int fmt, lwp_t *l) 281flashclose(dev_t dev, int flags, int fmt, lwp_t *l)
282{ 282{
283 int unit = minor(dev); 283 int unit = minor(dev);
284 struct flash_softc *sc; 284 struct flash_softc *sc;
285 int err; 285 int err;
286 286
287 FLDPRINTFN(1, ("flash: closing flash device unit %d\n", unit)); 287 FLDPRINTFN(1, ("flash: closing flash device unit %d\n", unit));
288 288
289 if ((sc = device_lookup_private(&flash_cd, unit)) == NULL) 289 if ((sc = device_lookup_private(&flash_cd, unit)) == NULL)
290 return ENXIO; 290 return ENXIO;
291 291
292 if (!sc->sc_readonly) { 292 if (!sc->sc_readonly) {
293 err = flash_sync(sc->sc_dev); 293 err = flash_sync(sc->sc_dev);
294 if (err) 294 if (err)
295 return err; 295 return err;
296 } 296 }
297 297
298 return 0; 298 return 0;
299} 299}
300 300
301/** 301/**
302 * flash_read - read from character device 302 * flash_read - read from character device
303 * This function uses the registered driver's read function to read the 303 * This function uses the registered driver's read function to read the
304 * requested length to * a buffer and then moves this buffer to userspace. 304 * requested length to * a buffer and then moves this buffer to userspace.
305 */ 305 */
306int 306int
307flashread(dev_t dev, struct uio * const uio, int flag) 307flashread(dev_t dev, struct uio * const uio, int flag)
308{ 308{
309 return physio(flashstrategy, NULL, dev, B_READ, minphys, uio); 309 return physio(flashstrategy, NULL, dev, B_READ, minphys, uio);
310} 310}
311 311
312/** 312/**
313 * flash_write - write to character device 313 * flash_write - write to character device
314 * This function moves the data into a buffer from userspace to kernel space, 314 * This function moves the data into a buffer from userspace to kernel space,
315 * then uses the registered driver's write function to write out the data to 315 * then uses the registered driver's write function to write out the data to
316 * the media. 316 * the media.
317 */ 317 */
318int 318int
319flashwrite(dev_t dev, struct uio * const uio, int flag) 319flashwrite(dev_t dev, struct uio * const uio, int flag)
320{ 320{
321 return physio(flashstrategy, NULL, dev, B_WRITE, minphys, uio); 321 return physio(flashstrategy, NULL, dev, B_WRITE, minphys, uio);
322} 322}
323 323
324void 324void
325flashstrategy(struct buf * const bp) 325flashstrategy(struct buf * const bp)
326{ 326{
327 struct flash_softc *sc; 327 struct flash_softc *sc;
328 const struct flash_interface *flash_if; 328 const struct flash_interface *flash_if;
329 const struct flash_partition *part; 329 const struct flash_partition *part;
330 int unit, device_blks; 330 int unit, device_blks;
331 331
332 unit = minor(bp->b_dev); 332 unit = minor(bp->b_dev);
333 sc = device_lookup_private(&flash_cd, unit); 333 sc = device_lookup_private(&flash_cd, unit);
334 if (sc == NULL) { 334 if (sc == NULL) {
335 bp->b_error = ENXIO; 335 bp->b_error = ENXIO;
336 goto done; 336 goto done;
337 } 337 }
338 338
339 flash_if = sc->flash_if; 339 flash_if = sc->flash_if;
340 part = &sc->sc_partinfo; 340 part = &sc->sc_partinfo;
341 341
342 /* divider */ 342 /* divider */
343 KASSERT(flash_if->writesize != 0); 343 KASSERT(flash_if->writesize != 0);
344 344
345 aprint_debug_dev(sc->sc_dev, "flash_strategy()\n"); 345 aprint_debug_dev(sc->sc_dev, "flash_strategy()\n");
346 346
347 if (!(bp->b_flags & B_READ) && sc->sc_readonly) { 347 if (!(bp->b_flags & B_READ) && sc->sc_readonly) {
348 bp->b_error = EACCES; 348 bp->b_error = EACCES;
349 goto done; 349 goto done;
350 } 350 }
351 351
352 /* check if length is not negative */ 352 /* check if length is not negative */
353 if (bp->b_blkno < 0) { 353 if (bp->b_blkno < 0) {
354 bp->b_error = EINVAL; 354 bp->b_error = EINVAL;
355 goto done; 355 goto done;
356 } 356 }
357 357
358 /* zero lenght i/o */ 358 /* zero lenght i/o */
359 if (bp->b_bcount == 0) { 359 if (bp->b_bcount == 0) {
360 goto done; 360 goto done;
361 } 361 }
362 362
363 device_blks = sc->sc_partinfo.part_size / DEV_BSIZE; 363 device_blks = sc->sc_partinfo.part_size / DEV_BSIZE;
364 KASSERT(part->part_offset % DEV_BSIZE == 0); 364 KASSERT(part->part_offset % DEV_BSIZE == 0);
365 bp->b_rawblkno = bp->b_blkno + (part->part_offset / DEV_BSIZE); 365 bp->b_rawblkno = bp->b_blkno + (part->part_offset / DEV_BSIZE);
366 366
367 if (bounds_check_with_mediasize(bp, DEV_BSIZE, device_blks) <= 0) { 367 if (bounds_check_with_mediasize(bp, DEV_BSIZE, device_blks) <= 0) {
368 goto done; 368 goto done;
369 } 369 }
370 370
371 bp->b_resid = bp->b_bcount; 371 bp->b_resid = bp->b_bcount;
372 flash_if->submit(sc->sc_parent_dev, bp); 372 flash_if->submit(sc->sc_parent_dev, bp);
373 373
374 return; 374 return;
375done: 375done:
376 bp->b_resid = bp->b_bcount; 376 bp->b_resid = bp->b_bcount;
377 biodone(bp); 377 biodone(bp);
378} 378}
379 379
380/* 380/*
381 * Handle the ioctl for the device 381 * Handle the ioctl for the device
382 */ 382 */
383int 383int
384flashioctl(dev_t dev, u_long command, void * const data, int flags, lwp_t *l) 384flashioctl(dev_t dev, u_long command, void * const data, int flags, lwp_t *l)
385{ 385{
386 struct flash_erase_params *ep; 386 struct flash_erase_params *ep;
387 struct flash_info_params *ip; 387 struct flash_info_params *ip;
388 struct flash_dump_params *dp; 388 struct flash_dump_params *dp;
389 struct flash_badblock_params *bbp; 389 struct flash_badblock_params *bbp;
390 struct flash_erase_instruction ei; 390 struct flash_erase_instruction ei;
391 struct flash_softc *sc; 391 struct flash_softc *sc;
392 int unit, err; 392 int unit, err;
393 size_t retlen; 393 size_t retlen;
394 flash_off_t offset; 394 flash_off_t offset;
395 bool bad; 395 bool bad;
396 396
397 unit = minor(dev); 397 unit = minor(dev);
398 if ((sc = device_lookup_private(&flash_cd, unit)) == NULL) 398 if ((sc = device_lookup_private(&flash_cd, unit)) == NULL)
399 return ENXIO; 399 return ENXIO;
400 400
401 err = 0; 401 err = 0;
402 switch (command) { 402 switch (command) {
403 case FLASH_ERASE_BLOCK: 403 case FLASH_ERASE_BLOCK:
404 /** 404 /**
405 * Set up an erase instruction then call the registered 405 * Set up an erase instruction then call the registered
406 * driver's erase operation. 406 * driver's erase operation.
407 */ 407 */
408 ep = data; 408 ep = data;
409 409
410 if (sc->sc_readonly) { 410 if (sc->sc_readonly) {
411 return EACCES; 411 return EACCES;
412 } 412 }
413 413
414 ei.ei_addr = ep->ep_addr; 414 ei.ei_addr = ep->ep_addr;
415 ei.ei_len = ep->ep_len; 415 ei.ei_len = ep->ep_len;
416 ei.ei_callback = NULL; 416 ei.ei_callback = NULL;
417 417
418 err = flash_erase(sc->sc_dev, &ei); 418 err = flash_erase(sc->sc_dev, &ei);
419 if (err) { 419 if (err) {
420 return err; 420 return err;
421 } 421 }
422 422
423 break; 423 break;
424 case FLASH_BLOCK_ISBAD: 424 case FLASH_BLOCK_ISBAD:
425 /** 425 /**
426 * Set up an erase instruction then call the registered 426 * Set up an erase instruction then call the registered
427 * driver's erase operation. 427 * driver's erase operation.
428 */ 428 */
429 bbp = data; 429 bbp = data;
430 430
431 err = flash_block_isbad(sc->sc_dev, bbp->bbp_addr, &bad); 431 err = flash_block_isbad(sc->sc_dev, bbp->bbp_addr, &bad);
432 if (err) { 432 if (err) {
433 return err; 433 return err;
434 } 434 }
435 bbp->bbp_isbad = bad; 435 bbp->bbp_isbad = bad;
436 436
437 break; 437 break;
438 case FLASH_BLOCK_MARKBAD: 438 case FLASH_BLOCK_MARKBAD:
439 bbp = data; 439 bbp = data;
440 440
441 err = flash_block_markbad(sc->sc_dev, bbp->bbp_addr); 441 err = flash_block_markbad(sc->sc_dev, bbp->bbp_addr);
442 442
443 break; 443 break;
444 case FLASH_DUMP: 444 case FLASH_DUMP:
445 dp = data; 445 dp = data;
446 offset = dp->dp_block * sc->flash_if->erasesize; 446 offset = dp->dp_block * sc->flash_if->erasesize;
447 FLDPRINTF(("Reading from block: %jd len: %jd\n", 447 FLDPRINTF(("Reading from block: %jd len: %jd\n",
448 (intmax_t )dp->dp_block, (intmax_t )dp->dp_len)); 448 (intmax_t )dp->dp_block, (intmax_t )dp->dp_len));
449 err = flash_read(sc->sc_parent_dev, offset, dp->dp_len, 449 err = flash_read(sc->sc_parent_dev, offset, dp->dp_len,
450 &retlen, dp->dp_buf); 450 &retlen, dp->dp_buf);
451 if (err) 451 if (err)
452 return err; 452 return err;
453 if (retlen != dp->dp_len) { 453 if (retlen != dp->dp_len) {
454 dp->dp_len = -1; 454 dp->dp_len = -1;
455 dp->dp_buf = NULL; 455 dp->dp_buf = NULL;
456 } 456 }
457 457
458 break; 458 break;
459 case FLASH_GET_INFO: 459 case FLASH_GET_INFO:
460 ip = data; 460 ip = data;
461 461
462 ip->ip_page_size = sc->flash_if->page_size; 462 ip->ip_page_size = sc->flash_if->page_size;
463 ip->ip_erase_size = sc->flash_if->erasesize; 463 ip->ip_erase_size = sc->flash_if->erasesize;
464 ip->ip_flash_type = sc->flash_if->type; 464 ip->ip_flash_type = sc->flash_if->type;
465 ip->ip_flash_size = sc->sc_partinfo.part_size; 465 ip->ip_flash_size = sc->sc_partinfo.part_size;
466 break; 466 break;
467 default: 467 default:
468 err = ENODEV; 468 err = ENODEV;
469 } 469 }
470 470
471 return err; 471 return err;
472} 472}
473 473
474int 474int
475flashdump(dev_t dev, daddr_t blkno, void *va, size_t size) 475flashdump(dev_t dev, daddr_t blkno, void *va, size_t size)
476{ 476{
477 return EACCES; 477 return EACCES;
478} 478}
479 479
480bool 480bool
481flash_shutdown(device_t self, int how) 481flash_shutdown(device_t self, int how)
482{ 482{
483 struct flash_softc * const sc = device_private(self); 483 struct flash_softc * const sc = device_private(self);
484 484
485 if ((how & RB_NOSYNC) == 0 && !sc->sc_readonly) 485 if ((how & RB_NOSYNC) == 0 && !sc->sc_readonly)
486 flash_sync(self); 486 flash_sync(self);
487 487
488 return true; 488 return true;
489} 489}
490 490
491const struct flash_interface * 491const struct flash_interface *
492flash_get_interface(dev_t dev) 492flash_get_interface(dev_t dev)
493{ 493{
494 struct flash_softc *sc; 494 struct flash_softc *sc;
495 int unit; 495 int unit;
496 496
497 unit = minor(dev); 497 unit = minor(dev);
498 if ((sc = device_lookup_private(&flash_cd, unit)) == NULL) 498 if ((sc = device_lookup_private(&flash_cd, unit)) == NULL)
499 return NULL; 499 return NULL;
500 500
501 return sc->flash_if; 501 return sc->flash_if;
502} 502}
503 503
504const struct flash_softc * 504const struct flash_softc *
505flash_get_softc(dev_t dev) 505flash_get_softc(dev_t dev)
506{ 506{
507 struct flash_softc *sc; 507 struct flash_softc *sc;
508 int unit; 508 int unit;
509 509
510 unit = minor(dev); 510 unit = minor(dev);
511 sc = device_lookup_private(&flash_cd, unit); 511 sc = device_lookup_private(&flash_cd, unit);
512 512
513 return sc; 513 return sc;
514} 514}
515 515
516device_t 516device_t
517flash_get_device(dev_t dev) 517flash_get_device(dev_t dev)
518{ 518{
519 struct flash_softc *sc; 519 struct flash_softc *sc;
520 int unit; 520 int unit;
521 521
522 unit = minor(dev); 522 unit = minor(dev);
523 sc = device_lookup_private(&flash_cd, unit); 523 sc = device_lookup_private(&flash_cd, unit);
524 524
525 return sc->sc_dev; 525 return sc->sc_dev;
526} 526}
527 527
 528flash_size_t
 529flash_get_size(dev_t dev)
 530{
 531 const struct flash_softc *sc;
 532
 533 sc = flash_get_softc(dev);
 534
 535 return sc->sc_partinfo.part_size;
 536}
 537
528static inline flash_off_t 538static inline flash_off_t
529flash_get_part_offset(struct flash_softc * const sc, size_t poffset) 539flash_get_part_offset(struct flash_softc * const sc, size_t poffset)
530{ 540{
531 return sc->sc_partinfo.part_offset + poffset; 541 return sc->sc_partinfo.part_offset + poffset;
532} 542}
533 543
534int 544int
535flash_erase(device_t self, struct flash_erase_instruction * const ei) 545flash_erase(device_t self, struct flash_erase_instruction * const ei)
536{ 546{
537 struct flash_softc * const sc = device_private(self); 547 struct flash_softc * const sc = device_private(self);
538 KASSERT(ei != NULL); 548 KASSERT(ei != NULL);
539 struct flash_erase_instruction e = *ei; 549 struct flash_erase_instruction e = *ei;
540 550
541 if (sc->sc_readonly) 551 if (sc->sc_readonly)
542 return EACCES; 552 return EACCES;
543 553
544 /* adjust for flash partition */ 554 /* adjust for flash partition */
545 e.ei_addr += sc->sc_partinfo.part_offset; 555 e.ei_addr += sc->sc_partinfo.part_offset;
546 556
547 /* bounds check for flash partition */ 557 /* bounds check for flash partition */
548 if (e.ei_addr + e.ei_len > sc->sc_partinfo.part_size + 558 if (e.ei_addr + e.ei_len > sc->sc_partinfo.part_size +
549 sc->sc_partinfo.part_offset) 559 sc->sc_partinfo.part_offset)
550 return EINVAL; 560 return EINVAL;
551 561
552 return sc->flash_if->erase(device_parent(self), &e); 562 return sc->flash_if->erase(device_parent(self), &e);
553} 563}
554 564
555int 565int
556flash_read(device_t self, flash_off_t offset, size_t len, size_t * const retlen, 566flash_read(device_t self, flash_off_t offset, size_t len, size_t * const retlen,
557 uint8_t * const buf) 567 uint8_t * const buf)
558{ 568{
559 struct flash_softc * const sc = device_private(self); 569 struct flash_softc * const sc = device_private(self);
560 570
561 offset += sc->sc_partinfo.part_offset; 571 offset += sc->sc_partinfo.part_offset;
562 572
563 if (offset + len > sc->sc_partinfo.part_size + 573 if (offset + len > sc->sc_partinfo.part_size +
564 sc->sc_partinfo.part_offset) 574 sc->sc_partinfo.part_offset)
565 return EINVAL; 575 return EINVAL;
566 576
567 return sc->flash_if->read(device_parent(self), 577 return sc->flash_if->read(device_parent(self),
568 offset, len, retlen, buf); 578 offset, len, retlen, buf);
569} 579}
570 580
571int 581int
572flash_write(device_t self, flash_off_t offset, size_t len, 582flash_write(device_t self, flash_off_t offset, size_t len,
573 size_t * const retlen, const uint8_t * const buf) 583 size_t * const retlen, const uint8_t * const buf)
574{ 584{
575 struct flash_softc * const sc = device_private(self); 585 struct flash_softc * const sc = device_private(self);
576 586
577 if (sc->sc_readonly) 587 if (sc->sc_readonly)
578 return EACCES; 588 return EACCES;
579 589
580 offset += sc->sc_partinfo.part_offset; 590 offset += sc->sc_partinfo.part_offset;
581 591
582 if (offset + len > sc->sc_partinfo.part_size + 592 if (offset + len > sc->sc_partinfo.part_size +
583 sc->sc_partinfo.part_offset) 593 sc->sc_partinfo.part_offset)
584 return EINVAL; 594 return EINVAL;
585 595
586 return sc->flash_if->write(device_parent(self), 596 return sc->flash_if->write(device_parent(self),
587 offset, len, retlen, buf); 597 offset, len, retlen, buf);
588} 598}
589 599
590int 600int
591flash_block_markbad(device_t self, flash_off_t offset) 601flash_block_markbad(device_t self, flash_off_t offset)
592{ 602{
593 struct flash_softc * const sc = device_private(self); 603 struct flash_softc * const sc = device_private(self);
594 604
595 if (sc->sc_readonly) 605 if (sc->sc_readonly)
596 return EACCES; 606 return EACCES;
597 607
598 offset += sc->sc_partinfo.part_offset; 608 offset += sc->sc_partinfo.part_offset;
599 609
600 if (offset + sc->flash_if->erasesize >= 610 if (offset + sc->flash_if->erasesize >=
601 sc->sc_partinfo.part_size + 611 sc->sc_partinfo.part_size +
602 sc->sc_partinfo.part_offset) 612 sc->sc_partinfo.part_offset)
603 return EINVAL; 613 return EINVAL;
604 614
605 return sc->flash_if->block_markbad(device_parent(self), offset); 615 return sc->flash_if->block_markbad(device_parent(self), offset);
606} 616}
607 617
608int 618int
609flash_block_isbad(device_t self, flash_off_t offset, bool * const bad) 619flash_block_isbad(device_t self, flash_off_t offset, bool * const bad)
610{ 620{
611 struct flash_softc * const sc = device_private(self); 621 struct flash_softc * const sc = device_private(self);
612 622
613 offset += sc->sc_partinfo.part_offset; 623 offset += sc->sc_partinfo.part_offset;
614 624
615 if (offset + sc->flash_if->erasesize > 625 if (offset + sc->flash_if->erasesize >
616 sc->sc_partinfo.part_size + 626 sc->sc_partinfo.part_size +
617 sc->sc_partinfo.part_offset) 627 sc->sc_partinfo.part_offset)
618 return EINVAL; 628 return EINVAL;
619 629
620 return sc->flash_if->block_isbad(device_parent(self), offset, bad); 630 return sc->flash_if->block_isbad(device_parent(self), offset, bad);
621} 631}
622 632
623int 633int
624flash_sync(device_t self) 634flash_sync(device_t self)
625{ 635{
626 struct flash_softc * const sc = device_private(self); 636 struct flash_softc * const sc = device_private(self);
627 637
628 if (sc->sc_readonly) 638 if (sc->sc_readonly)
629 return EACCES; 639 return EACCES;
630 640
631 /* noop now TODO: implement */ 641 /* noop now TODO: implement */
632 return 0; 642 return 0;
633} 643}
634 644
635MODULE(MODULE_CLASS_DRIVER, flash, NULL); 645MODULE(MODULE_CLASS_DRIVER, flash, NULL);
636 646
637#ifdef _MODULE 647#ifdef _MODULE
638#include "ioconf.c" 648#include "ioconf.c"
639#endif 649#endif
640 650
641static int 651static int
642flash_modcmd(modcmd_t cmd, void *opaque) 652flash_modcmd(modcmd_t cmd, void *opaque)
643{ 653{
644 int error = 0; 654 int error = 0;
645#ifdef _MODULE 655#ifdef _MODULE
646 int bmaj = -1, cmaj = -1; 656 int bmaj = -1, cmaj = -1;
647#endif 657#endif
648 658
649 switch (cmd) { 659 switch (cmd) {
650 case MODULE_CMD_INIT: 660 case MODULE_CMD_INIT:
651#ifdef _MODULE 661#ifdef _MODULE
652 error = config_init_component(cfdriver_ioconf_flash, 662 error = config_init_component(cfdriver_ioconf_flash,
653 cfattach_ioconf_flash, cfdata_ioconf_flash); 663 cfattach_ioconf_flash, cfdata_ioconf_flash);
654 if (error) 664 if (error)
655 return error; 665 return error;
656 error = devsw_attach("flash", &flash_bdevsw, &bmaj, 666 error = devsw_attach("flash", &flash_bdevsw, &bmaj,
657 &flash_cdevsw, &cmaj); 667 &flash_cdevsw, &cmaj);
658 if (error) 668 if (error)
659 config_fini_component(cfdriver_ioconf_flash, 669 config_fini_component(cfdriver_ioconf_flash,
660 cfattach_ioconf_flash, cfdata_ioconf_flash); 670 cfattach_ioconf_flash, cfdata_ioconf_flash);
661#endif 671#endif
662 return error; 672 return error;
663 case MODULE_CMD_FINI: 673 case MODULE_CMD_FINI:
664#ifdef _MODULE 674#ifdef _MODULE
665 devsw_detach(&flash_bdevsw, &flash_cdevsw); 675 devsw_detach(&flash_bdevsw, &flash_cdevsw);
666 error = config_fini_component(cfdriver_ioconf_flash, 676 error = config_fini_component(cfdriver_ioconf_flash,
667 cfattach_ioconf_flash, cfdata_ioconf_flash); 677 cfattach_ioconf_flash, cfdata_ioconf_flash);
668#endif 678#endif
669 return error; 679 return error;
670 default: 680 default:
671 return ENOTTY; 681 return ENOTTY;
672 } 682 }
673} 683}

cvs diff -r1.6 -r1.7 src/sys/dev/flash/flash.h (switch to unified diff)

--- src/sys/dev/flash/flash.h 2011/07/15 19:19:57 1.6
+++ src/sys/dev/flash/flash.h 2011/07/29 20:48:33 1.7
@@ -1,152 +1,153 @@ @@ -1,152 +1,153 @@
1/* $NetBSD: flash.h,v 1.6 2011/07/15 19:19:57 cliff Exp $ */ 1/* $NetBSD: flash.h,v 1.7 2011/07/29 20:48:33 ahoka Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 Department of Software Engineering, 4 * Copyright (c) 2011 Department of Software Engineering,
5 * University of Szeged, Hungary 5 * University of Szeged, Hungary
6 * Copyright (c) 2011 Adam Hoka <ahoka@NetBSD.org> 6 * Copyright (c) 2011 Adam Hoka <ahoka@NetBSD.org>
7 * Copyright (c) 2010 David Tengeri <dtengeri@inf.u-szeged.hu> 7 * Copyright (c) 2010 David Tengeri <dtengeri@inf.u-szeged.hu>
8 * All rights reserved. 8 * All rights reserved.
9 * 9 *
10 * This code is derived from software contributed to The NetBSD Foundation 10 * This code is derived from software contributed to The NetBSD Foundation
11 * by the Department of Software Engineering, University of Szeged, Hungary 11 * by the Department of Software Engineering, University of Szeged, Hungary
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions 14 * modification, are permitted provided that the following conditions
15 * are met: 15 * are met:
16 * 1. Redistributions of source code must retain the above copyright 16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer. 17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright 18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the 19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution. 20 * documentation and/or other materials provided with the distribution.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 */ 33 */
34 34
35#ifndef _FLASH_H_ 35#ifndef _FLASH_H_
36#define _FLASH_H_ 36#define _FLASH_H_
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/device.h> 39#include <sys/device.h>
40#include <sys/module.h> 40#include <sys/module.h>
41#include <sys/buf.h> 41#include <sys/buf.h>
42#include <sys/flashio.h> 42#include <sys/flashio.h>
43 43
44#ifdef FLASH_DEBUG 44#ifdef FLASH_DEBUG
45#define FLDPRINTF(x) if (flashdebug) printf x 45#define FLDPRINTF(x) if (flashdebug) printf x
46#define FLDPRINTFN(n,x) if (flashdebug>(n)) printf x 46#define FLDPRINTFN(n,x) if (flashdebug>(n)) printf x
47#else 47#else
48#define FLDPRINTF(x) 48#define FLDPRINTF(x)
49#define FLDPRINTFN(n,x) 49#define FLDPRINTFN(n,x)
50#endif 50#endif
51 51
52struct flash_partition { 52struct flash_partition {
53 flash_off_t part_offset; 53 flash_off_t part_offset;
54 flash_size_t part_size; 54 flash_size_t part_size;
55 int part_flags; 55 int part_flags;
56}; 56};
57 57
58/** 58/**
59 * flash_softc - private structure for flash layer driver 59 * flash_softc - private structure for flash layer driver
60 */ 60 */
61 61
62struct flash_softc { 62struct flash_softc {
63 device_t sc_dev; 63 device_t sc_dev;
64 device_t sc_parent_dev; /* Hardware (parent) device */ 64 device_t sc_parent_dev; /* Hardware (parent) device */
65 void *hw_softc; /* Hardware device private softc */ 65 void *hw_softc; /* Hardware device private softc */
66 struct flash_interface *flash_if; /* Hardware interface */ 66 struct flash_interface *flash_if; /* Hardware interface */
67 struct flash_partition sc_partinfo; /* partition information */ 67 struct flash_partition sc_partinfo; /* partition information */
68 68
69 bool sc_readonly; /* read only flash device */ 69 bool sc_readonly; /* read only flash device */
70}; 70};
71 71
72struct flash_attach_args { 72struct flash_attach_args {
73 struct flash_interface *flash_if; /* Hardware interface */ 73 struct flash_interface *flash_if; /* Hardware interface */
74 struct flash_partition partinfo; 74 struct flash_partition partinfo;
75}; 75};
76 76
77/** 77/**
78 * struct erase_instruction - instructions to erase a flash eraseblock 78 * struct erase_instruction - instructions to erase a flash eraseblock
79 */ 79 */
80struct flash_erase_instruction { 80struct flash_erase_instruction {
81 flash_off_t ei_addr; 81 flash_off_t ei_addr;
82 flash_off_t ei_len; 82 flash_off_t ei_len;
83 void (*ei_callback)(struct flash_erase_instruction *); 83 void (*ei_callback)(struct flash_erase_instruction *);
84 u_long ei_priv; 84 u_long ei_priv;
85 u_char ei_state; 85 u_char ei_state;
86}; 86};
87 87
88enum { 88enum {
89 FLASH_PART_READONLY = (1<<0), 89 FLASH_PART_READONLY = (1<<0),
90 FLASH_PART_FILESYSTEM = (1<<2) 90 FLASH_PART_FILESYSTEM = (1<<2)
91}; 91};
92 92
93/** 93/**
94 * struct flash_interface - interface for flash operations 94 * struct flash_interface - interface for flash operations
95 */ 95 */
96struct flash_interface { 96struct flash_interface {
97 int (*erase)(device_t, struct flash_erase_instruction *); 97 int (*erase)(device_t, struct flash_erase_instruction *);
98 int (*read)(device_t, flash_off_t, size_t, size_t *, uint8_t *); 98 int (*read)(device_t, flash_off_t, size_t, size_t *, uint8_t *);
99 int (*write)(device_t, flash_off_t, size_t, size_t *, const uint8_t *); 99 int (*write)(device_t, flash_off_t, size_t, size_t *, const uint8_t *);
100 int (*block_markbad)(device_t, flash_off_t); 100 int (*block_markbad)(device_t, flash_off_t);
101 int (*block_isbad)(device_t, flash_off_t, bool *); 101 int (*block_isbad)(device_t, flash_off_t, bool *);
102 int (*sync)(device_t); 102 int (*sync)(device_t);
103 103
104 int (*submit)(device_t, struct buf *); 104 int (*submit)(device_t, struct buf *);
105 105
106 uint32_t page_size; 106 uint32_t page_size;
107 uint32_t erasesize; 107 uint32_t erasesize;
108 uint32_t writesize; 108 uint32_t writesize;
109 uint32_t minor; 109 uint32_t minor;
110 uint8_t type; 110 uint8_t type;
111}; 111};
112 112
113/** 113/**
114 * struct cache - for caching writes on block device 114 * struct cache - for caching writes on block device
115 */ 115 */
116struct flash_cache { 116struct flash_cache {
117 size_t fc_len; 117 size_t fc_len;
118 flash_off_t fc_block; 118 flash_off_t fc_block;
119 uint8_t *fc_data; 119 uint8_t *fc_data;
120}; 120};
121 121
122device_t flash_attach_mi(struct flash_interface *, device_t); 122device_t flash_attach_mi(struct flash_interface *, device_t);
123const struct flash_interface *flash_get_interface(dev_t); 123const struct flash_interface *flash_get_interface(dev_t);
124const struct flash_softc *flash_get_softc(dev_t); 124const struct flash_softc *flash_get_softc(dev_t);
125device_t flash_get_device(dev_t); 125device_t flash_get_device(dev_t);
 126flash_size_t flash_get_size(dev_t);
126 127
127/* flash operations should be used through these */ 128/* flash operations should be used through these */
128int flash_erase(device_t, struct flash_erase_instruction *); 129int flash_erase(device_t, struct flash_erase_instruction *);
129int flash_read(device_t, flash_off_t, size_t, size_t *, uint8_t *); 130int flash_read(device_t, flash_off_t, size_t, size_t *, uint8_t *);
130int flash_write(device_t, flash_off_t, size_t, size_t *, const uint8_t *); 131int flash_write(device_t, flash_off_t, size_t, size_t *, const uint8_t *);
131int flash_block_markbad(device_t, flash_off_t); 132int flash_block_markbad(device_t, flash_off_t);
132int flash_block_isbad(device_t, flash_off_t, bool *); 133int flash_block_isbad(device_t, flash_off_t, bool *);
133int flash_sync(device_t); 134int flash_sync(device_t);
134 135
135/* 136/*
136 * check_pattern - checks the buffer only contains the byte pattern 137 * check_pattern - checks the buffer only contains the byte pattern
137 * 138 *
138 * This functions checks if the buffer only contains a specified byte pattern. 139 * This functions checks if the buffer only contains a specified byte pattern.
139 * Returns %0 if found something else, %1 otherwise. 140 * Returns %0 if found something else, %1 otherwise.
140 */ 141 */
141static inline int 142static inline int
142check_pattern(const void *buf, uint8_t patt, size_t offset, size_t size) 143check_pattern(const void *buf, uint8_t patt, size_t offset, size_t size)
143{ 144{
144 size_t i; 145 size_t i;
145 for (i = offset; i < size; i++) { 146 for (i = offset; i < size; i++) {
146 if (((const uint8_t *)buf)[i] != patt) 147 if (((const uint8_t *)buf)[i] != patt)
147 return 0; 148 return 0;
148 } 149 }
149 return 1; 150 return 1;
150} 151}
151 152
152#endif /* _FLASH_H_ */ 153#endif /* _FLASH_H_ */