This source file includes following definitions.
- flashattach
- flashdetach
- flashactivate
- flash_reg8_read
- flash_reg8_read_page
- flash_reg8_write
- flash_reg8_write_page
- flash_wait_ready
- flash_wait_complete
- flash_chip_enable
- flash_chip_disable
- flash_chip_reset
- flash_chip_identify
- flash_chip_erase_block
- flash_chip_read_block
- flash_chip_read_page
- flash_chip_read_oob
- flash_chip_write_block
- flash_chip_write_page
- flash_chip_verify_block
- flash_chip_verify_page
- flashopen
- flashclose
- flashstrategy
- flashioctl
- flashdump
- flashsize
- flashstart
- _flashstart
- flashdone
- flashgetdefaultlabel
- flashgetdisklabel
- flashminphys
- flashread
- flashwrite
- flashsafestrategy
- dumppage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <sys/param.h>
20 #include <sys/buf.h>
21 #include <sys/conf.h>
22 #include <sys/device.h>
23 #include <sys/disk.h>
24 #include <sys/disklabel.h>
25 #include <sys/dkio.h>
26 #include <sys/kernel.h>
27 #include <sys/stat.h>
28 #include <sys/systm.h>
29
30 #include <dev/flashvar.h>
31
32 #include <ufs/ffs/fs.h>
33
34
35 #define SAMSUNG_CMD_PTRLO 0x00
36 #define SAMSUNG_CMD_PTRHI 0x01
37 #define SAMSUNG_CMD_PTROOB 0x50
38 #define SAMSUNG_CMD_READ 0x30
39 #define SAMSUNG_CMD_SEQIN 0x80
40 #define SAMSUNG_CMD_WRITE 0x10
41 #define SAMSUNG_CMD_ERASE0 0x60
42 #define SAMSUNG_CMD_ERASE1 0xd0
43 #define SAMSUNG_CMD_STATUS 0x70
44 #define STATUS_FAIL (1<<0)
45 #define STATUS_READY (1<<6)
46 #define STATUS_NWP (1<<7)
47 #define SAMSUNG_CMD_READID 0x90
48 #define SAMSUNG_CMD_RESET 0xff
49
50 int flash_wait_ready(struct flash_softc *);
51 int flash_wait_complete(struct flash_softc *);
52
53
54 cdev_decl(flash);
55 bdev_decl(flash);
56
57 #define flashlock(sc) disk_lock(&(sc)->sc_dk)
58 #define flashunlock(sc) disk_unlock(&(sc)->sc_dk)
59 #define flashlookup(unit) \
60 (struct flash_softc *)device_lookup(&flash_cd, (unit))
61
62 void flashminphys(struct buf *);
63 void flashstart(struct flash_softc *);
64 void _flashstart(struct flash_softc *, struct buf *);
65 void flashdone(void *);
66
67 int flashsafestrategy(struct flash_softc *, struct buf *);
68 void flashgetdefaultlabel(dev_t, struct flash_softc *,
69 struct disklabel *);
70 void flashgetdisklabel(dev_t, struct flash_softc *, struct disklabel *, int);
71
72
73
74
75
76 struct flashvendor {
77 u_int8_t vendor;
78 const char *name;
79 };
80
81 static const struct flashvendor flashvendors[] = {
82 { FLASH_VENDOR_SAMSUNG, "Samsung" }
83 };
84 #define FLASH_NVENDORS (sizeof(flashvendors) / sizeof(flashvendors[0]))
85
86 static const struct flashdev flashdevs[] = {
87 { FLASH_DEVICE_SAMSUNG_K9F2808U0C, "K9F2808U0C 16Mx8 3.3V",
88 512, 16, 32, 32768 },
89 { FLASH_DEVICE_SAMSUNG_K9F1G08U0A, "K9F1G08U0A 128Mx8 3.3V",
90 2048, 64, 64, 65536 },
91 };
92 #define FLASH_NDEVS (sizeof(flashdevs) / sizeof(flashdevs[0]))
93
94 struct cfdriver flash_cd = {
95 NULL, "flash", DV_DISK
96 };
97
98 struct dkdriver flashdkdriver = { flashstrategy };
99
100 void
101 flashattach(struct flash_softc *sc, struct flash_ctl_tag *tag,
102 void *cookie)
103 {
104 u_int8_t vendor, device;
105 u_int16_t id;
106 int i;
107
108 sc->sc_tag = tag;
109 sc->sc_cookie = cookie;
110
111 if (sc->sc_maxwaitready <= 0)
112 sc->sc_maxwaitready = 1000;
113 if (sc->sc_maxwaitcomplete <= 0)
114 sc->sc_maxwaitcomplete = 200000;
115
116 flash_chip_enable(sc);
117
118
119 if (flash_chip_identify(sc, &vendor, &device) != 0) {
120 printf(": identification failed\n");
121 flash_chip_disable(sc);
122 return;
123 }
124 id = (vendor << 8) | device;
125
126
127 for (i = 0; i < FLASH_NVENDORS; i++) {
128 if (flashvendors[i].vendor == vendor) {
129 printf(": %s", flashvendors[i].name);
130 break;
131 }
132 }
133 if (i == FLASH_NVENDORS)
134 printf(": vendor 0x%02x", vendor);
135 for (i = 0; i < FLASH_NDEVS; i++) {
136 if (flashdevs[i].id == id) {
137 printf(" %s\n", flashdevs[i].longname);
138 break;
139 }
140 }
141 if (i == FLASH_NDEVS) {
142
143 printf(" device 0x%02x\n", device);
144 flash_chip_disable(sc);
145 return;
146 }
147 sc->sc_flashdev = &flashdevs[i];
148
149
150 if (flash_chip_reset(sc) != 0) {
151 printf("%s: reset failed\n", sc->sc_dev.dv_xname);
152 flash_chip_disable(sc);
153 return;
154 }
155
156 flash_chip_disable(sc);
157
158
159
160
161 sc->sc_dk.dk_driver = &flashdkdriver;
162 sc->sc_dk.dk_name = sc->sc_dev.dv_xname;
163 disk_attach(&sc->sc_dk);
164
165
166 }
167
168 int
169 flashdetach(struct device *self, int flags)
170 {
171 struct flash_softc *sc = (struct flash_softc *)self;
172
173
174 disk_detach(&sc->sc_dk);
175
176
177 return 0;
178 }
179
180 int
181 flashactivate(struct device *self, enum devact act)
182 {
183
184 return 0;
185 }
186
187
188
189
190
191 u_int8_t
192 flash_reg8_read(struct flash_softc *sc, int reg)
193 {
194 return sc->sc_tag->reg8_read(sc->sc_cookie, reg);
195 }
196
197 void
198 flash_reg8_read_page(struct flash_softc *sc, caddr_t data, caddr_t oob)
199 {
200 int i;
201
202 for (i = 0; i < sc->sc_flashdev->pagesize; i++)
203 data[i] = flash_reg8_read(sc, FLASH_REG_DATA);
204
205 if (oob != NULL)
206 for (i = 0; i < sc->sc_flashdev->oobsize; i++)
207 oob[i] = flash_reg8_read(sc, FLASH_REG_DATA);
208 }
209
210 void
211 flash_reg8_write(struct flash_softc *sc, int reg, u_int8_t value)
212 {
213 sc->sc_tag->reg8_write(sc->sc_cookie, reg, value);
214 }
215
216 void
217 flash_reg8_write_page(struct flash_softc *sc, caddr_t data, caddr_t oob)
218 {
219 int i;
220
221 for (i = 0; i < sc->sc_flashdev->pagesize; i++)
222 flash_reg8_write(sc, FLASH_REG_DATA, data[i]);
223
224 if (oob != NULL)
225 for (i = 0; i < sc->sc_flashdev->oobsize; i++)
226 flash_reg8_write(sc, FLASH_REG_DATA, oob[i]);
227 }
228
229
230
231
232
233 int
234 flash_wait_ready(struct flash_softc *sc)
235 {
236 int timo = sc->sc_maxwaitready;
237 u_int8_t ready;
238
239 ready = flash_reg8_read(sc, FLASH_REG_READY);
240 while (ready == 0 && timo-- > 0) {
241 delay(1);
242 ready = flash_reg8_read(sc, FLASH_REG_READY);
243 }
244 return (ready == 0 ? EIO : 0);
245 }
246
247
248
249
250
251 int
252 flash_wait_complete(struct flash_softc *sc)
253 {
254 int timo = sc->sc_maxwaitcomplete;
255 u_int8_t status;
256
257 (void)flash_wait_ready(sc);
258
259 flash_reg8_write(sc, FLASH_REG_CLE, 1);
260 flash_reg8_write(sc, FLASH_REG_CMD, SAMSUNG_CMD_STATUS);
261 flash_reg8_write(sc, FLASH_REG_CLE, 0);
262
263 status = flash_reg8_read(sc, FLASH_REG_DATA);
264 while ((status & STATUS_READY) == 0 && timo-- > 0) {
265 if (flash_reg8_read(sc, FLASH_REG_READY))
266 break;
267 delay(1);
268 status = flash_reg8_read(sc, FLASH_REG_DATA);
269 }
270
271 status = flash_reg8_read(sc, FLASH_REG_DATA);
272 return ((status & STATUS_FAIL) != 0 ? EIO : 0);
273 }
274
275 void
276 flash_chip_enable(struct flash_softc *sc)
277 {
278
279 flash_reg8_write(sc, FLASH_REG_CE, 1);
280 }
281
282 void
283 flash_chip_disable(struct flash_softc *sc)
284 {
285 flash_reg8_write(sc, FLASH_REG_CE, 0);
286
287 }
288
289 int
290 flash_chip_reset(struct flash_softc *sc)
291 {
292 flash_reg8_write(sc, FLASH_REG_CLE, 1);
293 flash_reg8_write(sc, FLASH_REG_CMD, SAMSUNG_CMD_RESET);
294 flash_reg8_write(sc, FLASH_REG_CLE, 0);
295
296 return flash_wait_ready(sc);
297 }
298
299 int
300 flash_chip_identify(struct flash_softc *sc, u_int8_t *vendor,
301 u_int8_t *device)
302 {
303 int error;
304
305 (void)flash_wait_ready(sc);
306
307 flash_reg8_write(sc, FLASH_REG_CLE, 1);
308 flash_reg8_write(sc, FLASH_REG_CMD, SAMSUNG_CMD_READID);
309 flash_reg8_write(sc, FLASH_REG_CLE, 0);
310
311 error = flash_wait_ready(sc);
312 if (error == 0) {
313 *vendor = flash_reg8_read(sc, FLASH_REG_DATA);
314 *device = flash_reg8_read(sc, FLASH_REG_DATA);
315 }
316 return error;
317 }
318
319 int
320 flash_chip_erase_block(struct flash_softc *sc, long blkno)
321 {
322 long pageno = blkno * sc->sc_flashdev->blkpages;
323 int error;
324
325 (void)flash_wait_ready(sc);
326
327
328 flash_reg8_write(sc, FLASH_REG_WP, 0);
329
330 switch (sc->sc_flashdev->id) {
331 case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
332 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
333 flash_reg8_write(sc, FLASH_REG_CLE, 1);
334 flash_reg8_write(sc, FLASH_REG_CMD, SAMSUNG_CMD_ERASE0);
335 flash_reg8_write(sc, FLASH_REG_CLE, 0);
336 break;
337 }
338
339 switch (sc->sc_flashdev->id) {
340 case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
341 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
342 flash_reg8_write(sc, FLASH_REG_ALE, 1);
343 flash_reg8_write(sc, FLASH_REG_ROW, pageno);
344 flash_reg8_write(sc, FLASH_REG_ROW, pageno >> 8);
345 flash_reg8_write(sc, FLASH_REG_ALE, 0);
346 break;
347 }
348
349 switch (sc->sc_flashdev->id) {
350 case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
351 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
352 flash_reg8_write(sc, FLASH_REG_CLE, 1);
353 flash_reg8_write(sc, FLASH_REG_CMD, SAMSUNG_CMD_ERASE1);
354 flash_reg8_write(sc, FLASH_REG_CLE, 0);
355 break;
356 }
357
358 error = flash_wait_complete(sc);
359
360
361 flash_reg8_write(sc, FLASH_REG_WP, 1);
362
363 return error;
364 }
365
366 int
367 flash_chip_read_block(struct flash_softc *sc, long blkno, caddr_t data)
368 {
369 long pageno;
370 long blkend;
371 int error;
372
373 pageno = blkno * sc->sc_flashdev->blkpages;
374 blkend = pageno + sc->sc_flashdev->blkpages;
375
376 while (pageno < blkend) {
377 error = flash_chip_read_page(sc, pageno, data, NULL);
378 if (error != 0)
379 return error;
380 data += sc->sc_flashdev->pagesize;
381 pageno++;
382 }
383 return 0;
384 }
385
386 int
387 flash_chip_read_page(struct flash_softc *sc, long pageno, caddr_t data,
388 caddr_t oob)
389 {
390 int error;
391
392 (void)flash_wait_ready(sc);
393
394 switch (sc->sc_flashdev->id) {
395 case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
396 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
397 flash_reg8_write(sc, FLASH_REG_CLE, 1);
398 flash_reg8_write(sc, FLASH_REG_CMD, SAMSUNG_CMD_PTRLO);
399 flash_reg8_write(sc, FLASH_REG_CLE, 0);
400 break;
401 }
402
403 switch (sc->sc_flashdev->id) {
404 case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
405 flash_reg8_write(sc, FLASH_REG_ALE, 1);
406 flash_reg8_write(sc, FLASH_REG_COL, 0x00);
407 flash_reg8_write(sc, FLASH_REG_ALE, 0);
408 break;
409 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
410 flash_reg8_write(sc, FLASH_REG_ALE, 1);
411 flash_reg8_write(sc, FLASH_REG_COL, 0x00);
412 flash_reg8_write(sc, FLASH_REG_COL, 0x00);
413 flash_reg8_write(sc, FLASH_REG_ALE, 0);
414 break;
415 }
416
417 switch (sc->sc_flashdev->id) {
418 case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
419 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
420 flash_reg8_write(sc, FLASH_REG_ALE, 1);
421 flash_reg8_write(sc, FLASH_REG_ROW, pageno);
422 flash_reg8_write(sc, FLASH_REG_ROW, pageno >> 8);
423 flash_reg8_write(sc, FLASH_REG_ALE, 0);
424 break;
425 }
426
427 switch (sc->sc_flashdev->id) {
428 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
429 flash_reg8_write(sc, FLASH_REG_CLE, 1);
430 flash_reg8_write(sc, FLASH_REG_CMD, SAMSUNG_CMD_READ);
431 flash_reg8_write(sc, FLASH_REG_CLE, 0);
432 break;
433 }
434
435 if ((error = flash_wait_ready(sc)) != 0)
436 return error;
437
438
439 if (sc->sc_tag->regx_read_page) {
440 error = sc->sc_tag->regx_read_page(sc->sc_cookie, data,
441 oob);
442 if (error != 0)
443 return error;
444 } else
445 flash_reg8_read_page(sc, data, oob);
446
447 return 0;
448 }
449
450 int
451 flash_chip_read_oob(struct flash_softc *sc, long pageno, caddr_t oob)
452 {
453 u_int8_t *p = (u_int8_t *)oob;
454 int error;
455 int i;
456
457 (void)flash_wait_ready(sc);
458
459 switch (sc->sc_flashdev->id) {
460 case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
461 flash_reg8_write(sc, FLASH_REG_CLE, 1);
462 flash_reg8_write(sc, FLASH_REG_CMD, SAMSUNG_CMD_PTROOB);
463 flash_reg8_write(sc, FLASH_REG_CLE, 0);
464 break;
465 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
466 flash_reg8_write(sc, FLASH_REG_CLE, 1);
467 flash_reg8_write(sc, FLASH_REG_CMD, SAMSUNG_CMD_PTRLO);
468 flash_reg8_write(sc, FLASH_REG_CLE, 0);
469 break;
470 }
471
472 switch (sc->sc_flashdev->id) {
473 case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
474 flash_reg8_write(sc, FLASH_REG_ALE, 1);
475 flash_reg8_write(sc, FLASH_REG_COL, 0x00);
476 flash_reg8_write(sc, FLASH_REG_ALE, 0);
477 break;
478 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
479 flash_reg8_write(sc, FLASH_REG_ALE, 1);
480 flash_reg8_write(sc, FLASH_REG_COL, 0x00);
481 flash_reg8_write(sc, FLASH_REG_COL, 0x08);
482 flash_reg8_write(sc, FLASH_REG_ALE, 0);
483 break;
484 }
485
486 switch (sc->sc_flashdev->id) {
487 case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
488 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
489 flash_reg8_write(sc, FLASH_REG_ALE, 1);
490 flash_reg8_write(sc, FLASH_REG_ROW, pageno);
491 flash_reg8_write(sc, FLASH_REG_ROW, pageno >> 8);
492 flash_reg8_write(sc, FLASH_REG_ALE, 0);
493 break;
494 }
495
496 switch (sc->sc_flashdev->id) {
497 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
498 flash_reg8_write(sc, FLASH_REG_CLE, 1);
499 flash_reg8_write(sc, FLASH_REG_CMD, SAMSUNG_CMD_READ);
500 flash_reg8_write(sc, FLASH_REG_CLE, 0);
501 break;
502 }
503
504 if ((error = flash_wait_ready(sc)) != 0)
505 return error;
506
507 for (i = 0; i < sc->sc_flashdev->oobsize; i++)
508 p[i] = flash_reg8_read(sc, FLASH_REG_DATA);
509
510 return 0;
511 }
512
513 int
514 flash_chip_write_block(struct flash_softc *sc, long blkno, caddr_t data,
515 caddr_t oob)
516 {
517 long pageno;
518 long blkend;
519 caddr_t p;
520 int error;
521
522 pageno = blkno * sc->sc_flashdev->blkpages;
523 blkend = pageno + sc->sc_flashdev->blkpages;
524
525 p = data;
526 while (pageno < blkend) {
527 error = flash_chip_write_page(sc, pageno, p, oob);
528 if (error != 0)
529 return error;
530 p += sc->sc_flashdev->pagesize;
531 pageno++;
532 }
533
534
535 return flash_chip_verify_block(sc, blkno, data, oob);
536 }
537
538 int
539 flash_chip_write_page(struct flash_softc *sc, long pageno, caddr_t data,
540 caddr_t oob)
541 {
542 int error;
543
544 (void)flash_wait_ready(sc);
545
546
547 flash_reg8_write(sc, FLASH_REG_WP, 0);
548
549 switch (sc->sc_flashdev->id) {
550 case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
551 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
552 flash_reg8_write(sc, FLASH_REG_CLE, 1);
553 flash_reg8_write(sc, FLASH_REG_CMD, SAMSUNG_CMD_PTRLO);
554 flash_reg8_write(sc, FLASH_REG_CLE, 0);
555 break;
556 }
557
558 switch (sc->sc_flashdev->id) {
559 case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
560 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
561 flash_reg8_write(sc, FLASH_REG_CLE, 1);
562 flash_reg8_write(sc, FLASH_REG_CMD, SAMSUNG_CMD_SEQIN);
563 flash_reg8_write(sc, FLASH_REG_CLE, 0);
564 break;
565 }
566
567 switch (sc->sc_flashdev->id) {
568 case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
569 flash_reg8_write(sc, FLASH_REG_ALE, 1);
570 flash_reg8_write(sc, FLASH_REG_COL, 0x00);
571 flash_reg8_write(sc, FLASH_REG_ALE, 0);
572 break;
573 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
574 flash_reg8_write(sc, FLASH_REG_ALE, 1);
575 flash_reg8_write(sc, FLASH_REG_COL, 0x00);
576 flash_reg8_write(sc, FLASH_REG_COL, 0x00);
577 flash_reg8_write(sc, FLASH_REG_ALE, 0);
578 break;
579 }
580
581 switch (sc->sc_flashdev->id) {
582 case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
583 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
584 flash_reg8_write(sc, FLASH_REG_ALE, 1);
585 flash_reg8_write(sc, FLASH_REG_ROW, pageno);
586 flash_reg8_write(sc, FLASH_REG_ROW, pageno >> 8);
587 flash_reg8_write(sc, FLASH_REG_ALE, 0);
588 break;
589 }
590
591
592 if (sc->sc_tag->regx_write_page) {
593 error = sc->sc_tag->regx_write_page(sc->sc_cookie, data,
594 oob);
595 if (error != 0)
596 return error;
597 } else
598 flash_reg8_write_page(sc, data, oob);
599
600 switch (sc->sc_flashdev->id) {
601 case FLASH_DEVICE_SAMSUNG_K9F2808U0C:
602 case FLASH_DEVICE_SAMSUNG_K9F1G08U0A:
603 flash_reg8_write(sc, FLASH_REG_CLE, 1);
604 flash_reg8_write(sc, FLASH_REG_CMD, SAMSUNG_CMD_WRITE);
605 flash_reg8_write(sc, FLASH_REG_CLE, 0);
606 break;
607 }
608
609
610
611
612
613 error = flash_wait_complete(sc);
614
615
616 flash_reg8_write(sc, FLASH_REG_WP, 1);
617
618 return error;
619 }
620
621 int
622 flash_chip_verify_block(struct flash_softc *sc, long blkno, caddr_t data,
623 caddr_t oob)
624 {
625 long pageno;
626 long blkend;
627 int error;
628
629 pageno = blkno * sc->sc_flashdev->blkpages;
630 blkend = pageno + sc->sc_flashdev->blkpages;
631
632 while (pageno < blkend) {
633 error = flash_chip_verify_page(sc, pageno, data, oob);
634 if (error != 0) {
635 printf("block %d page %d verify failed\n",
636 blkno, pageno);
637 return error;
638 }
639 data += sc->sc_flashdev->pagesize;
640 pageno++;
641 }
642 return 0;
643 }
644
645 int
646 flash_chip_verify_page(struct flash_softc *sc, long pageno, caddr_t data,
647 caddr_t oob)
648 {
649 static u_char rbuf[FLASH_MAXPAGESIZE];
650 static u_char roob[FLASH_MAXOOBSIZE];
651 int error;
652
653 error = flash_chip_read_page(sc, pageno, rbuf,
654 oob == NULL ? NULL : roob);
655 if (error != 0)
656 return error;
657
658 if (memcmp((const void *)&rbuf[0], (const void *)data,
659 sc->sc_flashdev->pagesize) != 0)
660 return EIO;
661
662 if (oob != NULL && memcmp((const void *)&roob[0],
663 (const void *)oob, sc->sc_flashdev->oobsize) != 0)
664 return EIO;
665
666 return 0;
667 }
668
669
670
671
672
673 int
674 flashopen(dev_t dev, int oflags, int devtype, struct proc *p)
675 {
676 struct flash_softc *sc;
677 int error;
678 int part;
679
680 sc = flashlookup(flashunit(dev));
681 if (sc == NULL)
682 return ENXIO;
683
684 if ((error = flashlock(sc)) != 0) {
685 device_unref(&sc->sc_dev);
686 return error;
687 }
688
689
690
691
692
693
694 if (sc->sc_dk.dk_openmask == 0) {
695 if ((sc->sc_flags & FDK_LOADED) == 0 ||
696 ((sc->sc_flags & FDK_SAFE) == 0) !=
697 (flashsafe(dev) == 0)) {
698 sc->sc_flags &= ~FDK_SAFE;
699 sc->sc_flags |= FDK_LOADED;
700 if (flashsafe(dev))
701 sc->sc_flags |= FDK_SAFE;
702 flashgetdisklabel(dev, sc, sc->sc_dk.dk_label, 0);
703 }
704 } else if (((sc->sc_flags & FDK_SAFE) == 0) !=
705 (flashsafe(dev) == 0)) {
706 flashunlock(sc);
707 device_unref(&sc->sc_dev);
708 return EBUSY;
709 }
710
711
712 part = flashpart(dev);
713 if (part != RAW_PART &&
714 (part >= sc->sc_dk.dk_label->d_npartitions ||
715 sc->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
716 flashunlock(sc);
717 device_unref(&sc->sc_dev);
718 return ENXIO;
719 }
720
721
722 switch (devtype) {
723 case S_IFCHR:
724 sc->sc_dk.dk_copenmask |= (1 << part);
725 break;
726 case S_IFBLK:
727 sc->sc_dk.dk_bopenmask |= (1 << part);
728 break;
729 }
730 sc->sc_dk.dk_openmask =
731 sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
732
733 flashunlock(sc);
734 device_unref(&sc->sc_dev);
735 return 0;
736 }
737
738 int
739 flashclose(dev_t dev, int fflag, int devtype, struct proc *p)
740 {
741 struct flash_softc *sc;
742 int error;
743 int part;
744
745 sc = flashlookup(flashunit(dev));
746 if (sc == NULL)
747 return ENXIO;
748
749 if ((error = flashlock(sc)) != 0) {
750 device_unref(&sc->sc_dev);
751 return error;
752 }
753
754
755 part = flashpart(dev);
756 switch (devtype) {
757 case S_IFCHR:
758 sc->sc_dk.dk_copenmask &= ~(1 << part);
759 break;
760 case S_IFBLK:
761 sc->sc_dk.dk_bopenmask &= ~(1 << part);
762 break;
763 }
764 sc->sc_dk.dk_openmask =
765 sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
766
767 if (sc->sc_dk.dk_openmask == 0) {
768
769 }
770
771 flashunlock(sc);
772 device_unref(&sc->sc_dev);
773 return 0;
774 }
775
776
777
778
779 void
780 flashstrategy(struct buf *bp)
781 {
782 struct flash_softc *sc;
783 int s;
784
785 sc = flashlookup(flashunit(bp->b_dev));
786 if (sc == NULL) {
787 bp->b_error = ENXIO;
788 goto bad;
789 }
790
791
792 if ((bp->b_bcount % sc->sc_flashdev->pagesize) != 0) {
793 bp->b_error = EINVAL;
794 goto bad;
795 }
796
797
798 if ((sc->sc_flags & FDK_LOADED) == 0) {
799 bp->b_error = EIO;
800 goto bad;
801 }
802
803
804 if (flashsafe(bp->b_dev) && flashsafestrategy(sc, bp) <= 0)
805 goto done;
806
807
808 if (bp->b_bcount == 0)
809 goto done;
810
811
812 if (flashpart(bp->b_dev) != RAW_PART &&
813 bounds_check_with_label(bp, sc->sc_dk.dk_label, 0) <= 0)
814 goto done;
815
816
817 s = splbio();
818 disksort(&sc->sc_q, bp);
819 flashstart(sc);
820 splx(s);
821 device_unref(&sc->sc_dev);
822 return;
823
824 bad:
825 bp->b_flags |= B_ERROR;
826 done:
827 if ((bp->b_flags & B_ERROR) != 0)
828 bp->b_resid = bp->b_bcount;
829 s = splbio();
830 biodone(bp);
831 splx(s);
832 if (sc != NULL)
833 device_unref(&sc->sc_dev);
834 }
835
836 int
837 flashioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p)
838 {
839 struct flash_softc *sc;
840 int error = 0;
841
842 sc = flashlookup(flashunit(dev));
843 if (sc == NULL)
844 return ENXIO;
845
846 if ((sc->sc_flags & FDK_LOADED) == 0) {
847 device_unref(&sc->sc_dev);
848 return EIO;
849 }
850
851 switch (cmd) {
852 case DIOCGDINFO:
853 *(struct disklabel *)data = *sc->sc_dk.dk_label;
854 break;
855 default:
856 error = ENOTTY;
857 break;
858 }
859
860 device_unref(&sc->sc_dev);
861 return error;
862 }
863
864 int
865 flashdump(dev_t dev, daddr64_t blkno, caddr_t va, size_t size)
866 {
867 printf("flashdump\n");
868 return ENODEV;
869 }
870
871 daddr64_t
872 flashsize(dev_t dev)
873 {
874 printf("flashsize\n");
875 return ENODEV;
876 }
877
878 void
879 flashstart(struct flash_softc *sc)
880 {
881 struct buf *dp, *bp;
882
883 while (1) {
884
885 dp = &sc->sc_q;
886 bp = dp->b_actf;
887 if (bp == NULL)
888 return;
889 dp->b_actf = bp->b_actf;
890
891
892 _flashstart(sc, bp);
893 }
894 }
895
896 void
897 _flashstart(struct flash_softc *sc, struct buf *bp)
898 {
899 int part;
900 daddr64_t offset;
901 long pgno;
902
903 part = flashpart(bp->b_dev);
904 offset = DL_GETPOFFSET(&sc->sc_dk.dk_label->d_partitions[part]) +
905 bp->b_blkno;
906 pgno = offset / (sc->sc_flashdev->pagesize / DEV_BSIZE);
907
908
909
910
911
912 if (!flashsafe(bp->b_dev) && pgno == sc->sc_flashdev->capacity) {
913 bp->b_resid = bp->b_bcount;
914 biodone(bp);
915 return;
916 } else if (pgno >= sc->sc_flashdev->capacity) {
917 bp->b_error = EINVAL;
918 bp->b_flags |= B_ERROR;
919 biodone(bp);
920 return;
921 }
922
923 sc->sc_bp = bp;
924
925
926 disk_busy(&sc->sc_dk);
927
928
929 flash_chip_enable(sc);
930 if ((bp->b_flags & B_READ) != 0)
931 bp->b_error = flash_chip_read_page(sc, pgno, bp->b_data,
932 NULL);
933 else
934 bp->b_error = flash_chip_write_page(sc, pgno, bp->b_data,
935 NULL);
936 if (bp->b_error == 0)
937 bp->b_resid = bp->b_bcount - sc->sc_flashdev->pagesize;
938 flash_chip_disable(sc);
939 flashdone(sc);
940 }
941
942 void
943 flashdone(void *v)
944 {
945 struct flash_softc *sc = v;
946 struct buf *bp = sc->sc_bp;
947
948
949 disk_unbusy(&sc->sc_dk, bp->b_bcount - bp->b_resid,
950 (bp->b_flags & B_READ) != 0);
951
952 if (bp->b_error != 0)
953 bp->b_flags |= B_ERROR;
954
955 biodone(bp);
956 flashstart(sc);
957 }
958
959 void
960 flashgetdefaultlabel(dev_t dev, struct flash_softc *sc,
961 struct disklabel *lp)
962 {
963 size_t len;
964
965 bzero(lp, sizeof(struct disklabel));
966
967 lp->d_type = 0;
968 lp->d_subtype = 0;
969 strncpy(lp->d_typename, "NAND flash", sizeof(lp->d_typename));
970
971
972 strncpy(lp->d_packname, sc->sc_flashdev->longname,
973 sizeof(lp->d_packname));
974 for (len = 0; len < sizeof(lp->d_packname); len++)
975 if (lp->d_packname[len] == ' ') {
976 lp->d_packname[len] = '\0';
977 break;
978 }
979
980
981 lp->d_ncylinders = 1;
982 lp->d_ntracks = 16;
983 lp->d_secsize = sc->sc_flashdev->pagesize;
984 lp->d_nsectors = sc->sc_flashdev->capacity / lp->d_ntracks
985 / lp->d_ncylinders;
986 lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
987 DL_SETDSIZE(lp, (daddr64_t)lp->d_ncylinders * lp->d_secpercyl);
988
989
990 lp->d_rpm = 3600;
991 lp->d_interleave = 1;
992 lp->d_version = 1;
993
994
995 lp->d_bbsize = BBSIZE;
996 lp->d_sbsize = SBSIZE;
997
998
999 lp->d_magic = DISKMAGIC;
1000 lp->d_magic2 = DISKMAGIC;
1001 lp->d_checksum = dkcksum(lp);
1002 }
1003
1004 void
1005 flashgetdisklabel(dev_t dev, struct flash_softc *sc,
1006 struct disklabel *lp, int spoofonly)
1007 {
1008 char *errstring;
1009 dev_t labeldev;
1010
1011 flashgetdefaultlabel(dev, sc, lp);
1012
1013 if (sc->sc_tag->default_disklabel != NULL)
1014 sc->sc_tag->default_disklabel(sc->sc_cookie, dev, lp);
1015
1016
1017 labeldev = flashlabeldev(dev);
1018 errstring = readdisklabel(labeldev, flashstrategy, lp, spoofonly);
1019 if (errstring != NULL) {
1020
1021 }
1022 }
1023
1024
1025
1026
1027
1028 void
1029 flashminphys(struct buf *bp)
1030 {
1031 struct flash_softc *sc;
1032
1033 sc = flashlookup(flashunit(bp->b_dev));
1034
1035 if (bp->b_bcount > sc->sc_flashdev->pagesize)
1036 bp->b_bcount = sc->sc_flashdev->pagesize;
1037 }
1038
1039 int
1040 flashread(dev_t dev, struct uio *uio, int ioflag)
1041 {
1042 return physio(flashstrategy, NULL, dev, B_READ, flashminphys, uio);
1043 }
1044
1045 int
1046 flashwrite(dev_t dev, struct uio *uio, int ioflag)
1047 {
1048 return physio(flashstrategy, NULL, dev, B_WRITE, flashminphys, uio);
1049 }
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060 int
1061 flashsafestrategy(struct flash_softc *sc, struct buf *bp)
1062 {
1063 if (sc->sc_tag->safe_strategy) {
1064 return sc->sc_tag->safe_strategy(sc->sc_cookie, bp);
1065 }
1066
1067
1068 return 1;
1069 }
1070
1071 void dumppage(u_char *);
1072 void dumppage(u_char *buf)
1073 {
1074 int i;
1075 for (i = 0; i < 512; i++) {
1076 if ((i % 16) == 0)
1077 printf("%04x: ", i);
1078 if ((i % 16) == 8)
1079 printf(" ");
1080 printf(" %02x", buf[i]);
1081 if ((i % 16) == 15)
1082 printf("\n");
1083 }
1084 if ((i % 16) != 0)
1085 printf("\n");
1086 }