xref: /netbsd-src/sys/arch/emips/ebus/flash_ebus.c (revision 46f5119e40af2e51998f686b2fdcc76b5488f7f3)
1 /*	$NetBSD: flash_ebus.c,v 1.1 2011/01/26 01:18:50 pooka Exp $	*/
2 
3 /*-
4  * Copyright (c) 2010 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code was written by Alessandro Forin and Neil Pittman
8  * at Microsoft Research and contributed to The NetBSD Foundation
9  * by Microsoft Corporation.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
34 __KERNEL_RCSID(0, "$NetBSD: flash_ebus.c,v 1.1 2011/01/26 01:18:50 pooka Exp $");
35 
36 /* Driver for the Intel 28F320/640/128 (J3A150) StrataFlash memory device
37  * Extended to include the Intel JS28F256P30T95.
38  */
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/proc.h>
44 #include <sys/errno.h>
45 #include <sys/ioctl.h>
46 #include <sys/device.h>
47 #include <sys/conf.h>
48 #include <sys/file.h>
49 #include <sys/stat.h>
50 #include <sys/ioctl.h>
51 #include <sys/buf.h>
52 #include <sys/bufq.h>
53 #include <sys/uio.h>
54 #include <sys/malloc.h>
55 #include <uvm/uvm_extern.h>
56 #include <sys/disklabel.h>
57 #include <sys/disk.h>
58 #include <sys/syslog.h>
59 #include <sys/vnode.h>
60 #include <sys/kthread.h>
61 #include <sys/lock.h>
62 #include <sys/queue.h>
63 
64 #if NRND > 0
65 #include <sys/rnd.h>
66 #endif
67 
68 #include "locators.h"
69 #include <prop/proplib.h>
70 
71 #include <emips/ebus/ebusvar.h>
72 #include <emips/emips/machdep.h>
73 #include <machine/emipsreg.h>
74 
75 /* Internal config switches
76  */
77 #define USE_BUFFERED_WRITES 0    /* Faster, but might not work in some (older) cases */
78 #define Verbose 0
79 
80 /* Debug tools
81  */
82 #define DEBUG_INTR   0x01
83 #define DEBUG_XFERS  0x02
84 #define DEBUG_STATUS 0x04
85 #define DEBUG_FUNCS  0x08
86 #define DEBUG_PROBE  0x10
87 #define DEBUG_WRITES 0x20
88 #define DEBUG_READS  0x40
89 #define DEBUG_ERRORS 0x80
90 #ifdef DEBUG
91 int eflash_debug = DEBUG_ERRORS;
92 #define EFLASH_DEBUG(x) (eflash_debug & (x))
93 #define DBGME(_lev_,_x_) if ((_lev_) & eflash_debug) _x_
94 #else
95 #define EFLASH_DEBUG(x) (0)
96 #define DBGME(_lev_,_x_)
97 #endif
98 #define DEBUG_PRINT(_args_,_lev_) DBGME(_lev_,printf _args_)
99 
100 /* Product ID codes
101  */
102 #define MANUF_INTEL  0x89
103 #define DEVICE_320   0x16
104 #define DEVICE_640   0x17
105 #define DEVICE_128   0x18
106 #define DEVICE_256   0x19
107 
108 /* Table of chips we understand.
109  */
110 #define nDELTAS 3
111 struct flash_type {
112     struct {
113         uint32_t nSectors;
114         uint32_t nKB;
115     } ft_deltas[nDELTAS];
116     uint8_t ft_manuf_code;
117     uint8_t ft_device_code;
118     uint16_t ft_total_sectors;
119     const char *ft_name;
120 };
121 
122 static const struct flash_type sector_maps[] = {
123     {
124      {{32,128},{0,0},},
125      MANUF_INTEL, DEVICE_320, 32,   /* a J3 part */
126      "StrataFlash 28F320"
127     },
128     {
129      {{64,128},{0,0},},
130      MANUF_INTEL, DEVICE_640, 64,   /* a J3 part */
131      "StrataFlash 28F640"
132     },
133     {
134      {{128,128},{0,0},},
135      MANUF_INTEL, DEVICE_128, 128,   /* a J3 part */
136      "StrataFlash 28F128"
137     },
138     {
139      {{255,128},{4,32},{0,0}},
140      MANUF_INTEL, DEVICE_256, 259,  /* a P30 part */
141 	 "StrataFlash 28F256"
142     }
143 };
144 #define nMAPS ((sizeof sector_maps) / (sizeof sector_maps[0]))
145 
146 /* Instead of dragging in atavar.h.. */
147 struct eflash_bio {
148 	volatile int flags;/* cmd flags */
149 #define	ATA_POLL	0x0002	/* poll for completion */
150 #define	ATA_SINGLE	0x0008	/* transfer must be done in singlesector mode */
151 #define	ATA_READ	0x0020	/* transfer is a read (otherwise a write) */
152 #define	ATA_CORR	0x0040	/* transfer had a corrected error */
153 	daddr_t		blkno;	/* block addr */
154 	daddr_t		blkdone;/* number of blks transferred */
155 	size_t		nblks;	/* number of blocks currently transferring */
156 	size_t	    nbytes;	/* number of bytes currently transferring */
157 	char		*databuf;/* data buffer address */
158 	volatile int	error;
159 	u_int32_t	r_error;/* copy of status register */
160 #ifdef HAS_BAD144_HANDLING
161 	daddr_t		badsect[127];/* 126 plus trailing -1 marker */
162 #endif
163 };
164 /* End of atavar.h*/
165 
166 /* chip-specific functions
167  */
168 struct flash_ops;
169 
170 /*
171  * Device softc
172  */
173 struct eflash_softc {
174 	device_t sc_dev;
175 
176 	/* General disk infos */
177 	struct disk sc_dk;
178 	struct bufq_state *sc_q;
179 	struct callout sc_restart_ch;
180 
181 	/* IDE disk soft states */
182 	struct buf *sc_bp; /* buf being transfered */
183 	struct buf *active_xfer; /* buf handoff to thread  */
184 	struct eflash_bio sc_bio; /* current transfer */
185 
186     struct proc *ch_thread;
187     int ch_flags;
188 #define ATACH_SHUTDOWN 0x02        /* thread is shutting down */
189 #define ATACH_IRQ_WAIT 0x10        /* thread is waiting for irq */
190 #define ATACH_DISABLED 0x80        /* channel is disabled */
191 #define ATACH_TH_RUN   0x100       /* the kernel thread is working */
192 #define ATACH_TH_RESET 0x200       /* someone ask the thread to reset */
193 
194 	int openings;
195 	int sc_flags;
196 #define	EFLASHF_WLABEL	0x004 /* label is writable */
197 #define	EFLASHF_LABELLING	0x008 /* writing label */
198 #define EFLASHF_LOADED	0x010 /* parameters loaded */
199 #define EFLASHF_WAIT	0x020 /* waiting for resources */
200 #define EFLASHF_KLABEL	0x080 /* retain label after 'full' close */
201 
202 	int retries; /* number of xfer retry */
203 
204 #if NRND > 0
205 	rndsource_element_t	rnd_source;
206 #endif
207 
208     /* flash-specific state */
209 	struct _Flash *sc_dp;
210     uint32_t sc_size;
211     uint32_t sc_capacity;
212     paddr_t  sc_base;
213     volatile uint8_t *sc_page0;
214 
215     /* current read-write sector mapping */
216     /*volatile*/ uint8_t *sc_sector;
217     uint32_t sc_sector_size;
218     uint32_t sc_sector_offset;
219 #define NOSECTOR ((uint32_t)(~0))
220     int sc_erased;
221 
222     /* device-specificity */
223     uint32_t sc_buffersize;
224     vsize_t sc_max_secsize;
225     unsigned int sc_chips;
226     const struct flash_ops *sc_ops;
227     struct flash_type sc_type;
228 };
229 
230 static int	eflash_ebus_match (struct device *, struct cfdata *, void *);
231 static void	eflash_ebus_attach (struct device *, struct device *, void *);
232 
233 CFATTACH_DECL_NEW(flash_ebus, sizeof (struct eflash_softc),
234     eflash_ebus_match, eflash_ebus_attach, NULL, NULL);
235 
236 /* implementation decls */
237 static int flash_identify(struct eflash_softc*);
238 static int KBinSector(struct flash_type * SecMap, unsigned int SecNo);
239 static uint32_t SectorStart(struct flash_type * SecMap, int SecNo);
240 static unsigned int SectorNumber(struct flash_type * SecMap, uint32_t Offset);
241 static void eflash_thread(void *arg);
242 static int eflash_read_at (struct eflash_softc *sc, daddr_t start_sector, char *buffer,
243                            size_t nblocks, size_t * pSizeRead);
244 static int eflash_write_at(struct eflash_softc *sc, daddr_t start_sector, char *buffer,
245                            size_t nblocks, size_t * pSizeWritten);
246 
247 /* Config functions
248  */
249 static int
250 eflash_ebus_match(struct device *parent, struct cfdata *match, void *aux)
251 {
252 	struct ebus_attach_args *ia = aux;
253 	struct _Flash *f = (struct _Flash *)ia->ia_vaddr;
254 
255 	if (strcmp("flash", ia->ia_name) != 0)
256 		return (0);
257 	if ((f == NULL) ||
258 	    ((f->BaseAddressAndTag & FLASHBT_TAG) != PMTTAG_FLASH))
259 		return (0);
260 
261 	return (1);
262 }
263 
264 static void
265 eflash_ebus_attach(struct device *parent, struct device *self, void *aux)
266 {
267 	struct ebus_attach_args *ia =aux;
268 	struct eflash_softc *sc = device_private(self);
269     uint32_t base, ctrl;
270     int error;
271 
272     /* Plan.
273      * - mips_map_physmem() (with uncached) first page
274      * - keep it around since we need status ops
275      * - find what type it is.
276      * - then mips_map_physmem() each sector as needed.
277      */
278 
279 	sc->sc_dev = self;
280 	sc->sc_dp = (struct _Flash*)ia->ia_vaddr;
281     base = sc->sc_dp->BaseAddressAndTag & FLASHBT_BASE;
282     ctrl = sc->sc_dp->Control;
283 
284     sc->sc_size = ctrl & FLASHST_SIZE;
285     sc->sc_capacity = sc->sc_size / DEV_BSIZE;
286     sc->sc_base = base;
287     /* The chip is 16bit, so if we get 32bit there are two */
288     sc->sc_chips = (ctrl & FLASHST_BUS_32) ? 2 : 1;
289 
290     /* Map the first page to see what chip we got */
291     sc->sc_page0 = (volatile uint8_t *) mips_map_physmem(base, PAGE_SIZE);
292 
293     if (flash_identify(sc)) {
294         printf(" base %x: %dMB flash memory (%d x %s)\n", base, sc->sc_size >> 20,
295                sc->sc_chips, sc->sc_type.ft_name);
296     } else {
297         /* BUGBUG If we dont identify it stop the driver! */
298         printf(": unknown manufacturer id %x, device id %x\n",
299                sc->sc_type.ft_manuf_code, sc->sc_type.ft_device_code);
300     }
301 
302     config_pending_incr();
303 
304 	error = kthread_create(PRI_NONE, 0, NULL,
305 	    eflash_thread, sc, NULL, "%s", device_xname(sc->sc_dev));
306 	if (error)
307 		aprint_error_dev(sc->sc_dev,
308 		    "unable to create kernel thread: error %d\n", error);
309 }
310 
311 /* Implementation functions
312  */
313 /* Returns the size in KBytes of a given sector,
314  * or -1 for bad arguments.
315  */
316 static int KBinSector(struct flash_type * SecMap, unsigned int SecNo)
317 {
318     int i;
319 
320     for (i = 0; i < nDELTAS; i++) {
321         if (SecNo < SecMap->ft_deltas[i].nSectors)
322             return SecMap->ft_deltas[i].nKB;
323         SecNo -= SecMap->ft_deltas[i].nSectors;
324     }
325 
326     return -1;
327 }
328 
329 #define SectorSize(_map_,_sector_) (1024 * KBinSector(_map_,_sector_))
330 
331 /* Whats the starting offset of sector N
332  */
333 static uint32_t SectorStart(struct flash_type * SecMap, int SecNo)
334 {
335     int i;
336     uint32_t Offset = 0;
337 
338     for (i = 0; i < nDELTAS; i++) {
339         if ((unsigned int)SecNo < SecMap->ft_deltas[i].nSectors)
340             return 1024 * (Offset + (SecMap->ft_deltas[i].nKB * SecNo));
341         SecNo -= SecMap->ft_deltas[i].nSectors;
342         Offset += SecMap->ft_deltas[i].nSectors * SecMap->ft_deltas[i].nKB;
343     }
344 
345     return ~0;
346 }
347 
348 /* What sector number corresponds to a given offset
349  */
350 static unsigned int SectorNumber(struct flash_type * SecMap, uint32_t Offset)
351 {
352     unsigned int i;
353     unsigned int SecNo = 0;
354 
355     Offset /= 1024;
356     for (i = 0; i < nDELTAS; i++) {
357         if (Offset < (unsigned int)
358             ((SecMap->ft_deltas[i].nSectors * SecMap->ft_deltas[i].nKB)))
359             return SecNo + (Offset / SecMap->ft_deltas[i].nKB);
360         SecNo += SecMap->ft_deltas[i].nSectors;
361         Offset -= SecMap->ft_deltas[i].nSectors * SecMap->ft_deltas[i].nKB;
362     }
363 
364     return ~0;
365 }
366 
367 /*
368  * Semi-generic operations
369  */
370 struct flash_ops {
371     void (*write_uint8)    (struct eflash_softc *sc, volatile void *Offset, uint8_t Value);
372     void (*read_uint8)     (struct eflash_softc *sc, volatile void *Offset, uint8_t *Value);
373     void (*write_uint16)   (struct eflash_softc *sc, volatile void *Offset, uint16_t Value);
374     void (*read_uint16)    (struct eflash_softc *sc, volatile void *Offset, uint16_t *Value);
375     void (*write_uint32)   (struct eflash_softc *sc, volatile void *Offset, uint32_t Value);
376     void (*read_uint32)    (struct eflash_softc *sc, volatile void *Offset, uint32_t *Value);
377     int  (*program_word)   (struct eflash_softc *sc, volatile void *Offset, uint16_t *pValues,
378                             int  Verify, int *nWritten);
379     int  (*program_buffer) (struct eflash_softc *sc, volatile void *Offset, uint16_t *pValues,
380                             int  Verify, int *nWritten);
381 };
382 
383 /*
384  * Hardware access proper, single-chip
385  */
386 static void single_write_uint8  (struct eflash_softc *sc,volatile void *Offset,uint8_t Value)
387 {
388     volatile uint8_t * Where = Offset;
389     *Where = Value;
390 }
391 
392 static void single_read_uint8   (struct eflash_softc *sc,volatile void *Offset,uint8_t *Value)
393 {
394     volatile uint8_t * Where = Offset;
395     *Value = *Where;
396 }
397 
398 static void single_write_uint16 (struct eflash_softc *sc,volatile void *Offset,uint16_t Value)
399 {
400     volatile uint16_t * Where = Offset;
401     *Where = Value;
402 }
403 
404 static void single_read_uint16  (struct eflash_softc *sc,volatile void *Offset,uint16_t *Value)
405 {
406     volatile uint16_t * Where = Offset;
407     *Value = *Where;
408 }
409 
410 /* This one should not be used, probably */
411 static void single_write_uint32 (struct eflash_softc *sc,volatile void *Offset,uint32_t Value)
412 {
413 #if 0
414     /* The chip cannot take back-to-back writes */
415     volatile uint32_t * Where = Offset;
416     *Where = Value;
417 #else
418     volatile uint8_t * Where = Offset;
419     uint16_t v0, v1;
420 
421     /* Unfortunately, this is bytesex dependent */
422 #if (BYTE_ORDER == BIG_ENDIAN)
423     v1 = (uint16_t) Value;
424     v0 = (uint16_t) (Value >> 16);
425 #else
426     v0 = (uint16_t) Value;
427     v1 = (uint16_t) (Value >> 16);
428 #endif
429     single_write_uint16(sc,Where,v0);
430     single_write_uint16(sc,Where+2,v1);
431 #endif
432 }
433 
434 static void single_read_uint32  (struct eflash_softc *sc,volatile void *Offset,uint32_t *Value)
435 {
436     /* back-to-back reads must be ok */
437     volatile uint32_t * Where = Offset;
438     *Value = *Where;
439 }
440 
441 /*
442  * Hardware access proper, paired-chips
443  * NB: This set of ops assumes two chips in parallel on a 32bit bus,
444  *     each operation is repeated in parallel to both chips
445  */
446 static void twin_write_uint8  (struct eflash_softc *sc,volatile void *Offset,uint8_t Value)
447 {
448     volatile uint32_t * Where = Offset;
449     uint32_t v = Value | ((uint32_t)Value << 16);
450 
451     v = le32toh(v);
452     *Where = v;
453 }
454 
455 static void twin_read_uint8   (struct eflash_softc *sc,volatile void *Offset,uint8_t *Value)
456 {
457     volatile uint32_t * Where = Offset;
458     uint32_t v;
459     v = *Where;
460     v = le32toh(v);
461     *Value = (uint8_t) v;
462 }
463 
464 /* This one should *not* be used, error-prone */
465 static void twin_write_uint16 (struct eflash_softc *sc,volatile void *Offset,uint16_t Value)
466 {
467     volatile uint16_t * Where = Offset;
468     *Where = Value;
469 }
470 
471 static void twin_read_uint16  (struct eflash_softc *sc,volatile void *Offset,uint16_t *Value)
472 {
473     volatile uint16_t * Where = Offset;
474     *Value = *Where;
475 }
476 
477 static void twin_write_uint32 (struct eflash_softc *sc,volatile void *Offset,uint32_t Value)
478 {
479     volatile uint32_t * Where = Offset;
480     Value = le32toh(Value);
481     *Where = Value;
482 }
483 
484 static void twin_read_uint32  (struct eflash_softc *sc,volatile void *Offset,uint32_t *Value)
485 {
486     volatile uint32_t * Where = Offset;
487     uint32_t v;
488     v = *Where;
489     v = le32toh(v);
490     *Value = v;
491 }
492 
493 /*
494  * Command and status definitions
495  */
496 
497 /* Defines for the STATUS register
498  */
499 #define ST_reserved          0x01
500 #define ST_BLOCK_LOCKED      0x02
501 #define ST_PROGRAM_SUSPENDED 0x04
502 #define ST_LOW_VOLTAGE       0x08
503 #define ST_LOCK_BIT_ERROR    0x10
504 #define ST_ERASE_ERROR       0x20
505 #define ST_ERASE_SUSPENDED   0x40
506 #define ST_READY             0x80
507 #define ST_ERASE_MASK        0xee  /* bits to check after erase command */
508 #define ST_MASK              0xfe  /* ignore reserved */
509 
510 /* Command set (what we use of it)
511  */
512 #define CMD_CONFIRM       0xd0
513 #define CMD_READ_ARRAY    0xff
514 #define CMD_READ_ID       0x90
515 #define CMD_READ_STATUS   0x70
516 #define CMD_CLEAR_STATUS  0x50
517 #define CMD_WRITE_WORD    0x40
518 #define CMD_WRITE_BUFFER  0xe8
519 #define CMD_ERASE_SETUP   0x20
520 #define CMD_ERASE_CONFIRM CMD_CONFIRM
521 #define CMD_SET_PREFIX    0x60  /* set read config, lock bits */
522 #define CMD_LOCK          0x01
523 #define CMD_UNLOCK        CMD_CONFIRM
524 /* What we dont use of it
525  */
526 #define CMD_READ_QUERY    0x98
527 # define BUFFER_BYTES          32
528 #define CMD_ERASE_SUSPEND 0xb0
529 #define CMD_ERASE_RESUME  CMD_CONFIRM
530 #define CMD_CONFIGURATION 0xb8
531 #define CMD_PROTECT       0xc0
532 
533 /* Enter the Product ID mode (Read Identifier Codes)
534  */
535 static void ProductIdEnter(struct eflash_softc *sc)
536 {
537     sc->sc_ops->write_uint8(sc,sc->sc_page0,CMD_READ_ID);
538 }
539 
540 /* Exit the Product ID mode (enter Read Array mode)
541  */
542 static void ProductIdExit(struct eflash_softc *sc)
543 {
544     sc->sc_ops->write_uint8(sc,sc->sc_page0,CMD_READ_ARRAY);
545 }
546 
547 /* Read the status register
548  */
549 static uint8_t ReadStatusRegister(struct eflash_softc *sc)
550 {
551     uint8_t Status;
552 
553     sc->sc_ops->write_uint8(sc,sc->sc_page0,CMD_READ_STATUS);
554     sc->sc_ops->read_uint8(sc,sc->sc_page0,&Status);
555     sc->sc_ops->write_uint8(sc,sc->sc_page0,CMD_READ_ARRAY);
556     return Status;
557 }
558 
559 /* Clear error bits in status
560  */
561 static void ClearStatusRegister(struct eflash_softc *sc)
562 {
563     sc->sc_ops->write_uint8(sc,sc->sc_page0,CMD_CLEAR_STATUS);
564 }
565 
566 #if DEBUG
567 /* Decode status bits
568  */
569 typedef const char *string;
570 
571 static void PrintStatus(uint8_t Status)
572 {
573     /* BUGBUG there's a %b format I think? */
574     string BitNames[8] = {
575         "reserved", "BLOCK_LOCKED",
576         "PROGRAM_SUSPENDED", "LOW_VOLTAGE",
577         "LOCK_BIT_ERROR", "ERASE_ERROR",
578         "ERASE_SUSPENDED", "READY"
579     };
580     int i;
581     int  OneSet = FALSE;
582 
583     printf("[status %x =",Status);
584     for (i = 0; i < 8; i++) {
585         if (Status & (1<<i)) {
586             printf("%c%s",
587                      (OneSet) ? '|' : ' ',
588                      BitNames[i]);
589             OneSet = TRUE;
590         }
591     }
592     printf("]\n");
593 }
594 #else
595 #define PrintStatus(x)
596 #endif
597 
598 /*
599  * The device can lock up under certain conditions.
600  * There is no software workaround [must toggle RP# to GND]
601  * Check if it seems that we are in that state.
602  */
603 static int  IsIrresponsive(struct eflash_softc *sc)
604 {
605     uint8_t Status = ReadStatusRegister(sc);
606 
607     if (Status & ST_READY)
608         return FALSE;
609 
610     if ((Status & ST_ERASE_MASK) ==
611         (ST_LOCK_BIT_ERROR|ST_ERASE_SUSPENDED|ST_ERASE_ERROR)) {
612         /* yes, looks that way */
613         return TRUE;
614     }
615 
616     /* Something is indeed amiss, but we dont really know for sure */
617     PrintStatus(ReadStatusRegister(sc));
618     ClearStatusRegister(sc);
619     PrintStatus(ReadStatusRegister(sc));
620 
621     if ((Status & ST_MASK) ==
622         (ST_LOCK_BIT_ERROR|ST_ERASE_SUSPENDED|ST_ERASE_ERROR)) {
623         /* yes, looks that way */
624         return TRUE;
625     }
626 
627     return FALSE;
628 }
629 
630 
631 /* Write one 16bit word
632  */
633 static int
634 single_program_word(struct eflash_softc *sc, volatile void *Offset, uint16_t *Values,
635                   int  Verify, int *nWritten)
636 {
637     uint8_t Status;
638     uint16_t i, Data16, Value;
639 
640     *nWritten = 0;
641 
642     Value = Values[0];
643 
644     if (Verify) {
645         sc->sc_ops->read_uint16(sc,Offset,&Data16);
646 #ifdef Verbose
647         if (Verbose) {
648             printf("Location %p was x%x\n",
649                    Offset, Data16);
650         }
651 #endif
652         if (Data16 != 0xffff)
653             printf("Offset %p not ERASED, wont take.\n",Offset);
654     }
655 
656     sc->sc_ops->write_uint8(sc,sc->sc_page0,CMD_WRITE_WORD);
657     sc->sc_ops->write_uint16(sc,Offset,Value);
658 
659     /* Wait until the operation is completed
660      * Specs say it takes between 210 and 630 us
661      * Errata says 360 TYP and Max=TBD (sic)
662      */
663     DELAY(800);
664 
665     for (i = 0; i < 10; i++) {
666         sc->sc_ops->read_uint8(sc,Offset,&Status);
667         if ((Status & ST_READY)) break;
668         DELAY(100);
669     }
670 
671     ProductIdExit(sc);
672 
673     if (Verify) {
674         sc->sc_ops->read_uint16(sc,Offset,&Data16);
675 #ifdef Verbose
676         if (Verbose) {
677             printf("Location %p is now x%x\n",
678                    Offset, Data16);
679         }
680 #endif
681         if ((Data16 != Value)) {
682             PrintStatus(Status);
683             printf(". That didnt work, try again.. [%x != %x]\n",
684                    Data16, Value);
685             ClearStatusRegister(sc);
686             return FALSE;
687         }
688     }
689 
690     *nWritten = 2;
691     return TRUE;
692 }
693 
694 /* Write one buffer, 16bit words at a time
695  */
696 static int
697 single_program_buffer(struct eflash_softc *sc, volatile void *Offset, uint16_t *Values,
698                   int  Verify, int *nWritten)
699 {
700     uint8_t Status;
701     uint16_t i, Data16, Value = 0;
702     volatile uint8_t *Where = Offset;
703 
704     *nWritten = 0;
705     if (sc->sc_buffersize == 0)
706         return FALSE; /* sanity */
707 
708     if (Verify) {
709         for (i = 0; i < sc->sc_buffersize; i+= 2) {
710             sc->sc_ops->read_uint16(sc,Where+i,&Data16);
711 #ifdef Verbose
712             if (Verbose) {
713                 printf("Location %p was x%x\n",
714                        Where+i, Data16);
715             }
716 #endif
717 
718             if (Data16 != 0xffff)
719                 printf("Offset %p not ERASED, wont take.\n",Where+i);
720         }
721     }
722 
723     /* Specs say to retry if necessary */
724     for (i = 0; i < 5; i++) {
725         sc->sc_ops->write_uint8(sc,Offset,CMD_WRITE_BUFFER);
726         DELAY(10);
727         sc->sc_ops->read_uint8(sc,Offset,&Status);
728         if ((Status & ST_READY)) break;
729     }
730     if (0 == (Status & ST_READY)) {
731         printf("FAILED program_buffer at Location %p, Status= x%x\n",
732                  Offset, Status);
733         return FALSE;
734     }
735 
736     /* Say how many words we'll be sending */
737     sc->sc_ops->write_uint8(sc,Offset,(uint8_t)(sc->sc_buffersize/2));
738 
739     /* Send the data */
740     for (i = 0; i < sc->sc_buffersize; i+= 2) {
741         Value = Values[i/2];
742         sc->sc_ops->write_uint16(sc,Where+i,Value);
743         DELAY(10);/*jic*/
744     }
745 
746     /* Write confirmation */
747     sc->sc_ops->write_uint8(sc,Offset,CMD_CONFIRM);
748 
749     /* Wait until the operation is completed
750      * Specs say it takes between 800 and 2400 us
751      * Errata says 1600 TYP and Max=TBD (sic), but fixed in stepping A3 and above.
752      */
753     DELAY(800);
754 
755     for (i = 0; i < 20; i++) {
756         sc->sc_ops->write_uint8(sc,Offset,CMD_READ_STATUS);
757         sc->sc_ops->read_uint8(sc,Offset,&Status);
758         if ((Status & ST_READY)) break;
759         DELAY(200);
760     }
761 
762     ProductIdExit(sc);
763 
764     /* Verify? */
765     if (Verify) {
766         for (i = 0; i < sc->sc_buffersize; i+= 2) {
767             sc->sc_ops->read_uint16(sc,Where+i,&Data16);
768 #ifdef Verbose
769             if (Verbose) {
770                 printf("Location %p is now x%x\n",
771                        Where+i, Data16);
772             }
773 #endif
774             Value = Values[i/2];
775 
776             if ((Data16 != Value)) {
777                 PrintStatus(Status);
778                 printf(". That didnt work, try again.. [%x != %x]\n",
779                        Data16, Value);
780                 ClearStatusRegister(sc);
781                 return FALSE;
782             }
783         }
784     }
785 
786     *nWritten = sc->sc_buffersize;
787     return TRUE;
788 }
789 
790 /* Write one 32bit word
791  */
792 static int
793 twin_program_word(struct eflash_softc *sc, volatile void *Offset, uint16_t *Values,
794                 int  Verify, int *nWritten)
795 {
796     uint8_t Status;
797     uint32_t i, Data32, Value;
798     uint16_t v0, v1;
799 
800     *nWritten = 0;
801 
802     v0 = Values[0];
803     v0 = le16toh(v0);
804     v1 = Values[1];
805     v1 = le16toh(v1);
806     Value = v0 | ((uint32_t)v1 << 16);
807     if (Verify) {
808         sc->sc_ops->read_uint32(sc,Offset,&Data32);
809 #ifdef Verbose
810         if (Verbose) {
811             printf("Location %p was x%x\n",
812                    Offset, Data32);
813         }
814 #endif
815         if (Data32 != 0xffffffff)
816             printf("Offset %p not ERASED, wont take.\n",Offset);
817     }
818 
819     sc->sc_ops->write_uint8(sc,sc->sc_page0,CMD_WRITE_WORD);
820     sc->sc_ops->write_uint32(sc,Offset,Value);
821 
822     /* Wait until the operation is completed
823      * Specs say it takes between 210 and 630 us
824      * Errata says 360 TYP and Max=TBD (sic)
825      */
826     DELAY(400);
827 
828     for (i = 0; i < 10; i++) {
829         sc->sc_ops->read_uint8(sc,Offset,&Status);
830         if ((Status & ST_READY)) break;
831         DELAY(100);
832     }
833 
834     ProductIdExit(sc);
835 
836     if (Verify) {
837         sc->sc_ops->read_uint32(sc,Offset,&Data32);
838 #ifdef Verbose
839         if (Verbose) {
840             printf("Location %p is now x%x\n",
841                    Offset, Data32);
842         }
843 #endif
844         if ((Data32 != Value)) {
845             PrintStatus(Status);
846             printf(". That didnt work, try again.. [%x != %x]\n",
847                    Data32, Value);
848             ClearStatusRegister(sc);
849             return FALSE;
850         }
851     }
852 
853     *nWritten = 4;
854     return TRUE;
855 }
856 
857 /* Write one buffer, 32bit words at a time
858  */
859 static int
860 twin_program_buffer(struct eflash_softc *sc, volatile void *Offset, uint16_t *Values,
861                 int  Verify, int *nWritten)
862 {
863     uint8_t Status;
864     uint32_t i, Data32, Value;
865     uint16_t v0 = 0, v1;
866     volatile uint8_t *Where = Offset;
867 
868     *nWritten = 0;
869     if (sc->sc_buffersize == 0)
870         return FALSE; /* sanity */
871 
872     if (Verify) {
873         for (i = 0; i < sc->sc_buffersize; i+= 4) {
874             sc->sc_ops->read_uint32(sc,Where+i,&Data32);
875 #ifdef Verbose
876             if (Verbose) {
877                 printf("Location %p was x%x\n",
878                        Where+i, Data32);
879             }
880 #endif
881             if (Data32 != 0xffffffff)
882                 printf("Offset %p not ERASED, wont take.\n",Where+i);
883         }
884     }
885 
886     /* Specs say to retry if necessary */
887     for (i = 0; i < 5; i++) {
888         sc->sc_ops->write_uint8(sc,Offset,CMD_WRITE_BUFFER);
889         DELAY(10);
890         sc->sc_ops->read_uint8(sc,Offset,&Status);
891         if ((Status & ST_READY)) break;
892     }
893     if (0 == (Status & ST_READY)) {
894         printf("FAILED program_buffer at Location %p, Status= x%x\n",
895                  Offset, Status);
896         return FALSE;
897     }
898 
899     /* Say how many words we'll be sending */
900     sc->sc_ops->write_uint8(sc,Offset,(uint8_t)(sc->sc_buffersize/4)); /* to each twin! */
901 
902     /* Send the data */
903     for (i = 0; i < sc->sc_buffersize; i+= 4) {
904         v0 = Values[i/2];
905         v0 = le16toh(v0);
906         v1 = Values[1+(i/2)];
907         v1 = le16toh(v1);
908         Value = v0 | ((uint32_t)v1 << 16);
909         sc->sc_ops->write_uint32(sc,Where+i,Value);
910         DELAY(10);/*jic*/
911     }
912 
913     /* Write confirmation */
914     sc->sc_ops->write_uint8(sc,Offset,CMD_CONFIRM);
915 
916     /* Wait until the operation is completed
917      * Specs say it takes between 800 and 2400 us
918      * Errata says 1600 TYP and Max=TBD (sic), but fixed in stepping A3 and above.
919      */
920     DELAY(800);
921 
922     for (i = 0; i < 20; i++) {
923         sc->sc_ops->write_uint8(sc,Offset,CMD_READ_STATUS);
924         sc->sc_ops->read_uint8(sc,Offset,&Status);
925         if ((Status & ST_READY)) break;
926         DELAY(200);
927     }
928 
929     ProductIdExit(sc);
930 
931     /* Verify */
932     if (Verify) {
933         for (i = 0; i < sc->sc_buffersize; i+= 4) {
934             sc->sc_ops->read_uint32(sc,Where+i,&Data32);
935 #ifdef Verbose
936             if (Verbose) {
937                 printf("Location %p is now x%x\n",
938                        Where+i, Data32);
939             }
940 #endif
941             v0 = Values[i/2];
942             v0 = le16toh(v0);
943             v1 = Values[1+(i/2)];
944             v1 = le16toh(v1);
945             Value = v0 | ((uint32_t)v1 << 16);
946 
947             if ((Data32 != Value)) {
948                 PrintStatus(Status);
949                 printf(". That didnt work, try again.. [%x != %x]\n",
950                        Data32, Value);
951                 ClearStatusRegister(sc);
952                 return FALSE;
953             }
954         }
955     }
956 
957     *nWritten = sc->sc_buffersize;
958     return TRUE;
959 }
960 
961 /* Is there a lock on a given sector
962  */
963 static int IsSectorLocked(struct eflash_softc *sc, uint8_t *secptr)
964 {
965     uint8_t Data, Data1;
966 
967     ProductIdEnter(sc);
968     /* Lockout info is at address 2 of the given sector, meaning A0=0 A1=1.
969      */
970     sc->sc_ops->read_uint8(sc,secptr+(0x0002*2*sc->sc_chips),&Data);
971     sc->sc_ops->read_uint8(sc,secptr+(0x0003*2*sc->sc_chips),&Data1);
972 
973     ProductIdExit(sc);
974 
975     return (Data & 1);
976 }
977 
978 /* Remove the write-lock to a sector
979  */
980 static void SectorUnLock(struct eflash_softc *sc, uint8_t *secptr)
981 {
982     uint8_t Status;
983     int i;
984 
985     DBGME(DEBUG_FUNCS,printf("%s: Unlocking sector %d [ptr %p] ...\n",
986 	device_xname(sc->sc_dev), sc->sc_sector_offset, secptr));
987 
988     sc->sc_ops->write_uint8(sc,sc->sc_page0,CMD_SET_PREFIX);
989     sc->sc_ops->write_uint8(sc,secptr,CMD_UNLOCK);
990 
991     /* Wait until the unlock is complete.
992      * Specs say this takes between 64 and 75 usecs.
993      */
994     DELAY(100);
995 
996     for (i = 0; i < 10; i++) {
997         sc->sc_ops->read_uint8(sc,secptr,&Status);
998         if ((Status & ST_READY)) break;
999         DELAY(100);
1000     }
1001 
1002     ProductIdExit(sc);
1003 
1004     if ((Status & ST_MASK) == ST_READY) {
1005         DBGME(DEBUG_FUNCS,printf("%s: Unlocked ok.\n",
1006 	    device_xname(sc->sc_dev)));
1007         return;
1008     }
1009 
1010     PrintStatus(Status);
1011     DBGME(DEBUG_ERRORS,printf("%s: Unlock of sector %d NOT completed (status=%x).\n",
1012                               device_xname(sc->sc_dev),
1013 			      sc->sc_sector_offset, Status));
1014     ClearStatusRegister(sc);
1015 }
1016 
1017 
1018 /* Erase one sector
1019  */
1020 static int  SectorErase(struct eflash_softc *sc, void *secptr)
1021 {
1022     uint8_t Status = 0;
1023     uint16_t i;
1024 
1025     DBGME(DEBUG_FUNCS,printf("%s: Erasing sector %d [ptr %p] ...\n",
1026 	device_xname(sc->sc_dev), sc->sc_sector_offset, secptr));
1027 
1028     /* On some chips we just cannot avoid the locking business.
1029      */
1030     if ((sc->sc_chips == 1) &&
1031         IsSectorLocked(sc,secptr))
1032         SectorUnLock(sc,secptr);
1033 
1034     sc->sc_ops->write_uint8(sc,secptr,CMD_ERASE_SETUP);
1035     sc->sc_ops->write_uint8(sc,secptr,CMD_ERASE_CONFIRM);
1036 
1037     /* Wait until the erase is actually completed
1038      * Specs say it will take between 1 and 5 seconds.
1039      * Errata says it takes 2 sec min and 25 sec max.
1040      * Double that before giving up.
1041      */
1042     for (i = 0; i < 20; i++) {
1043         /* Sleep for at least 2 seconds
1044          */
1045         tsleep(sc,PWAIT,"erase", hz * 2);
1046 
1047         sc->sc_ops->read_uint8(sc,secptr,&Status);
1048         if ((Status & ST_READY)) break;
1049         PrintStatus(Status);
1050     }
1051 
1052     ProductIdExit(sc);
1053 
1054     if ((Status & ST_ERASE_MASK) == ST_READY) {
1055         DBGME(DEBUG_FUNCS,printf("%s: Erased ok.\n", device_xname(sc->sc_dev)));
1056         return 0;
1057     }
1058 
1059     PrintStatus(Status);
1060     DBGME(DEBUG_ERRORS,printf("%s: Erase of sector %d NOT completed (status=%x).\n",
1061                               device_xname(sc->sc_dev),
1062 			      sc->sc_sector_offset, Status));
1063 
1064     ClearStatusRegister(sc);
1065     return EIO;
1066 }
1067 
1068 
1069 
1070 /* Write (a portion of) a sector
1071  */
1072 static size_t eflash_write_sector(struct eflash_softc *sc, char *Buffer, size_t n,
1073                                uint8_t *Offset, int Verify)
1074 {
1075     size_t i;
1076 
1077     /* Make sure the device is not screwed up
1078      */
1079     if (IsIrresponsive(sc)) {
1080         printf("FLASH is locked-up (or mapped cacheable?), wont work. ");
1081     }
1082 
1083     for (i = 0; i < n;) {
1084         int nTries;
1085         int nWritten = 0;/*we expect 2 or 4 */
1086 
1087         if (sc->sc_buffersize && ((n-i) >= sc->sc_buffersize)) {
1088             for (nTries = 0; nTries < 5; nTries++)
1089                 if (sc->sc_ops->program_buffer(sc,Offset,(uint16_t*)(Buffer+i),Verify,&nWritten))
1090                     break;
1091         } else {
1092             for (nTries = 0; nTries < 5; nTries++)
1093                 if (sc->sc_ops->program_word(sc,Offset,(uint16_t*)(Buffer+i),Verify,&nWritten))
1094                     break;
1095         }
1096         Offset += nWritten;
1097         i += nWritten;
1098         if (nWritten == 0)
1099             break;
1100     }
1101     return i;
1102 }
1103 
1104 /* Identify type and the sector map of the FLASH.
1105  * Argument is the base address of the device and the count of chips on the bus (1/2)
1106  * Returns FALSE if failed
1107  */
1108 static const struct flash_ops single_ops = {
1109     single_write_uint8,
1110     single_read_uint8,
1111     single_write_uint16,
1112     single_read_uint16,
1113     single_write_uint32,
1114     single_read_uint32,
1115     single_program_word,
1116     single_program_buffer
1117 };
1118 
1119 static const struct flash_ops twin_ops = {
1120     twin_write_uint8,
1121     twin_read_uint8,
1122     twin_write_uint16,
1123     twin_read_uint16,
1124     twin_write_uint32,
1125     twin_read_uint32,
1126     twin_program_word,
1127     twin_program_buffer
1128 };
1129 
1130 static int  flash_identify(struct eflash_softc *sc)
1131 {
1132     uint8_t Mid, Did;
1133     int i;
1134 
1135     if (sc->sc_chips > 1)
1136         sc->sc_ops = &twin_ops;
1137     else
1138         sc->sc_ops = &single_ops;
1139 
1140     sc->sc_buffersize = 0;
1141 #if USE_BUFFERED_WRITES
1142     sc->sc_buffersize = BUFFER_BYTES * sc->sc_chips;
1143 #endif
1144     sc->sc_sector = NULL;
1145     sc->sc_sector_size = 0;
1146     sc->sc_sector_offset = NOSECTOR;
1147     sc->sc_erased = FALSE;
1148 
1149     ProductIdEnter(sc);
1150     sc->sc_ops->read_uint8(sc,sc->sc_page0+(0x0000*2*sc->sc_chips),&Mid);
1151     sc->sc_ops->read_uint8(sc,sc->sc_page0+(0x0001*2*sc->sc_chips),&Did);
1152     ProductIdExit(sc);
1153 
1154     sc->sc_type.ft_manuf_code = Mid;
1155     sc->sc_type.ft_device_code = Did;
1156 
1157     for (i = 0; i < nMAPS; i++) {
1158         if ((sector_maps[i].ft_manuf_code == Mid) && (sector_maps[i].ft_device_code == Did)) {
1159             int j;
1160             uint32_t ms = 0;
1161             sc->sc_type = sector_maps[i];
1162             /* double the sector sizes if twin-chips */
1163             for (j = 0; j < nDELTAS; j++) {
1164                 sc->sc_type.ft_deltas[j].nKB *= sc->sc_chips;
1165                 if (ms < sc->sc_type.ft_deltas[j].nKB)
1166                     ms = sc->sc_type.ft_deltas[j].nKB;
1167             }
1168             sc->sc_max_secsize = ms * 1024;
1169             return TRUE;
1170         }
1171     }
1172 
1173     return FALSE;
1174 }
1175 
1176 /* Common code for read&write argument validation
1177  */
1178 static int eflash_validate(struct eflash_softc *sc, daddr_t start, size_t *pSize, void **pSrc)
1179 {
1180     daddr_t Size;
1181     uint32_t sec;
1182     size_t secsize, secstart;
1183 
1184     /* Validate args
1185      */
1186     if (start >= sc->sc_capacity) {
1187         *pSize = 0;
1188         DBGME(DEBUG_ERRORS,printf("eflash::ValidateArg(%qx) EOF\n", start));
1189         return E2BIG;
1190     }
1191 
1192     /* Map sector if not already
1193      */
1194     sec = SectorNumber(&sc->sc_type, start << DEV_BSHIFT);
1195     secsize = SectorSize( &sc->sc_type, sec);
1196     secstart = SectorStart(&sc->sc_type,sec);
1197     if (sec != sc->sc_sector_offset) {
1198         int error;
1199 
1200         /* unmap previous first */
1201         if (sc->sc_sector_offset != NOSECTOR) {
1202             DBGME(DEBUG_FUNCS,printf("%s: unmap %p %zx\n",
1203 		device_xname(sc->sc_dev), sc->sc_sector, sc->sc_sector_size));
1204             iounaccess((vaddr_t)sc->sc_sector, sc->sc_sector_size);
1205             sc->sc_sector_offset = NOSECTOR;
1206         }
1207 
1208         /* map new */
1209         error = ioaccess((vaddr_t)sc->sc_sector,
1210                          secstart + sc->sc_base,
1211                          secsize);
1212         DBGME(DEBUG_FUNCS,printf("%s: mapped %p %zx -> %lx %d\n",
1213 	    device_xname(sc->sc_dev),
1214 	    sc->sc_sector, secsize, secstart + sc->sc_base,error));
1215         if (error) return error;
1216 
1217         /* Update state. We have to assume the sector was not erased. Sigh. */
1218         sc->sc_sector_offset = sec;
1219         sc->sc_sector_size = secsize;
1220         sc->sc_erased = FALSE;
1221     }
1222 
1223     /* Adjust size if necessary
1224      */
1225     Size = start + *pSize; /* last sector */
1226     if (Size > sc->sc_capacity) {
1227         /* At most this many sectors
1228          */
1229         Size = sc->sc_capacity - start;
1230         *pSize = (size_t)Size;
1231     }
1232     if (*pSize > (secsize >> DEV_BSHIFT)) {
1233         *pSize = secsize >> DEV_BSHIFT;
1234     }
1235 
1236     *pSrc = sc->sc_sector + (start << DEV_BSHIFT) - secstart;
1237 
1238     DBGME(DEBUG_FUNCS,printf("%s: Validate %qx %zd %p\n",
1239 	device_xname(sc->sc_dev), start,*pSize, *pSrc));
1240     return 0;
1241 }
1242 
1243 static int eflash_read_at (struct eflash_softc *sc,
1244                            daddr_t start_sector, char *buffer, size_t nblocks,
1245                            size_t * pSizeRead)
1246 {
1247     int error;
1248     uint32_t SizeRead = 0;
1249     void *src;
1250 
1251     DBGME(DEBUG_XFERS|DEBUG_READS,printf("%s: EflashReadAt(%qx %p %zd %p)\n",
1252                      device_xname(sc->sc_dev), start_sector, buffer, nblocks, pSizeRead));
1253 
1254     /* Validate & trim arguments
1255      */
1256     error = eflash_validate(sc, start_sector, &nblocks, &src);
1257 
1258     /* Copy data if
1259      */
1260     if (error == 0) {
1261         SizeRead = nblocks;
1262         memcpy(buffer, src, nblocks << DEV_BSHIFT);
1263     }
1264 
1265     if (pSizeRead)
1266         *pSizeRead = SizeRead;
1267     return error;
1268 }
1269 
1270 /* Write SIZE bytes to device.
1271  */
1272 static int eflash_write_at (struct eflash_softc *sc,
1273                            daddr_t start_sector, char *buffer, size_t nblocks,
1274                            size_t * pSizeWritten)
1275 {
1276     int error;
1277     void *src;
1278     size_t SizeWritten = 0;
1279 
1280     DBGME(DEBUG_XFERS|DEBUG_WRITES,printf("%s: EflashWriteAt(%qx %p %zd %p)\n",
1281                      device_xname(sc->sc_dev), start_sector, buffer, nblocks, pSizeWritten));
1282 
1283     /* Validate & trim arguments
1284      */
1285     error = eflash_validate(sc, start_sector, &nblocks, &src);
1286 
1287     if (error == 0) {
1288         /* Do we have to erase it */
1289         if (! sc->sc_erased) {
1290 
1291             error = SectorErase(sc,src);
1292             if (error)
1293                 goto Out;
1294             sc->sc_erased = TRUE;
1295         }
1296         SizeWritten = eflash_write_sector(sc, buffer, nblocks << DEV_BSHIFT, src, TRUE);
1297         SizeWritten >>= DEV_BSHIFT;
1298     }
1299 
1300  Out:
1301     if (pSizeWritten)
1302         *pSizeWritten = SizeWritten;
1303     return error;
1304 }
1305 
1306 /* Rest of code lifted with mods from the dev\ata\wd.c driver
1307  */
1308 
1309 /*	$NetBSD: flash_ebus.c,v 1.1 2011/01/26 01:18:50 pooka Exp $ */
1310 
1311 /*
1312  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
1313  *
1314  * Redistribution and use in source and binary forms, with or without
1315  * modification, are permitted provided that the following conditions
1316  * are met:
1317  * 1. Redistributions of source code must retain the above copyright
1318  *	notice, this list of conditions and the following disclaimer.
1319  * 2. Redistributions in binary form must reproduce the above copyright
1320  *	notice, this list of conditions and the following disclaimer in the
1321  *	documentation and/or other materials provided with the distribution.
1322  * 3. All advertising materials mentioning features or use of this software
1323  *	must display the following acknowledgement:
1324  *  This product includes software developed by Manuel Bouyer.
1325  * 4. The name of the author may not be used to endorse or promote products
1326  *	derived from this software without specific prior written permission.
1327  *
1328  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1329  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1330  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1331  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1332  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1333  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1334  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1335  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1336  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1337  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1338  */
1339 
1340 /*-
1341  * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc.
1342  * All rights reserved.
1343  *
1344  * This code is derived from software contributed to The NetBSD Foundation
1345  * by Charles M. Hannum and by Onno van der Linden.
1346  *
1347  * Redistribution and use in source and binary forms, with or without
1348  * modification, are permitted provided that the following conditions
1349  * are met:
1350  * 1. Redistributions of source code must retain the above copyright
1351  *    notice, this list of conditions and the following disclaimer.
1352  * 2. Redistributions in binary form must reproduce the above copyright
1353  *    notice, this list of conditions and the following disclaimer in the
1354  *    documentation and/or other materials provided with the distribution.
1355  * 3. All advertising materials mentioning features or use of this software
1356  *    must display the following acknowledgement:
1357  *        This product includes software developed by the NetBSD
1358  *        Foundation, Inc. and its contributors.
1359  * 4. Neither the name of The NetBSD Foundation nor the names of its
1360  *    contributors may be used to endorse or promote products derived
1361  *    from this software without specific prior written permission.
1362  *
1363  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1364  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1365  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1366  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
1367  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1368  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1369  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1370  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1371  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1372  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1373  * POSSIBILITY OF SUCH DAMAGE.
1374  */
1375 
1376 static const char ST506[] = "ST506";
1377 
1378 #define	EFLASHIORETRIES_SINGLE 4	/* number of retries before single-sector */
1379 #define	EFLASHIORETRIES	5	/* number of retries before giving up */
1380 #define	RECOVERYTIME hz/2	/* time to wait before retrying a cmd */
1381 
1382 #define	EFLASHUNIT(dev)		DISKUNIT(dev)
1383 #define	EFLASHPART(dev)		DISKPART(dev)
1384 #define	EFLASHMINOR(unit, part)	DISKMINOR(unit, part)
1385 #define	MAKEEFLASHDEV(maj, unit, part)	MAKEDISKDEV(maj, unit, part)
1386 
1387 #define	EFLASHLABELDEV(dev)	(MAKEEFLASHDEV(major(dev), EFLASHUNIT(dev), RAW_PART))
1388 
1389 void	eflashperror(const struct eflash_softc *);
1390 
1391 extern struct cfdriver eflash_cd;
1392 
1393 dev_type_open(eflashopen);
1394 dev_type_close(eflashclose);
1395 dev_type_read(eflashread);
1396 dev_type_write(eflashwrite);
1397 dev_type_ioctl(eflashioctl);
1398 dev_type_strategy(eflashstrategy);
1399 dev_type_dump(eflashdump);
1400 dev_type_size(eflashsize);
1401 
1402 const struct bdevsw eflash_bdevsw = {
1403 	eflashopen, eflashclose, eflashstrategy, eflashioctl, eflashdump, eflashsize, D_DISK
1404 };
1405 
1406 const struct cdevsw eflash_cdevsw = {
1407 	eflashopen, eflashclose, eflashread, eflashwrite, eflashioctl,
1408 	nostop, notty, nopoll, nommap, nokqfilter, D_DISK
1409 };
1410 
1411 void  eflashgetdefaultlabel(struct eflash_softc *, struct disklabel *);
1412 void  eflashgetdisklabel(struct eflash_softc *);
1413 void  eflashstart(void *);
1414 void  __eflashstart(struct eflash_softc*, struct buf *);
1415 void  eflashrestart(void *);
1416 void  eflashattach(struct eflash_softc *);
1417 int   eflashdetach(struct device *, int);
1418 int   eflashactivate(struct device *, enum devact);
1419 
1420 void  eflashdone(struct eflash_softc *);
1421 static void eflash_params_to_properties(struct eflash_softc *sc);
1422 
1423 struct dkdriver eflashdkdriver = { eflashstrategy, minphys };
1424 
1425 #ifdef HAS_BAD144_HANDLING
1426 static void bad144intern(struct eflash_softc *);
1427 #endif
1428 
1429 static void eflash_wedges(void *arg);
1430 
1431 void
1432 eflashattach(struct eflash_softc *sc)
1433 {
1434 	struct device *self = sc->sc_dev;
1435 	char pbuf[9];
1436 	DEBUG_PRINT(("%s: eflashattach\n",  device_xname(sc->sc_dev)), DEBUG_FUNCS | DEBUG_PROBE);
1437 
1438 	callout_init(&sc->sc_restart_ch, 0);
1439 	bufq_alloc(&sc->sc_q, BUFQ_DISK_DEFAULT_STRAT, BUFQ_SORT_RAWBLOCK);
1440 
1441     sc->openings = 1; /* wazziz?*/
1442 
1443 	aprint_naive("\n");
1444 
1445     /* setup all required fields so that if the attach fails we are ok */
1446 	sc->sc_dk.dk_driver = &eflashdkdriver;
1447 	sc->sc_dk.dk_name = device_xname(sc->sc_dev);
1448 
1449 	format_bytes(pbuf, sizeof(pbuf), sc->sc_capacity * DEV_BSIZE);
1450 	aprint_normal("%s: %s, %d cyl, %d head, %d sec, %d bytes/sect x %llu sectors\n",
1451 	    self->dv_xname, pbuf, 1, 1, sc->sc_capacity,
1452 	    DEV_BSIZE, (unsigned long long)sc->sc_capacity);
1453 
1454     eflash_params_to_properties(sc);
1455 
1456 	/*
1457 	 * Attach the disk structure. We fill in dk_info later.
1458 	 */
1459 	disk_attach(&sc->sc_dk);
1460 
1461 #if NRND > 0
1462 	rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
1463 			  RND_TYPE_DISK, 0);
1464 #endif
1465 
1466 }
1467 
1468 int
1469 eflashactivate(struct device *self, enum devact act)
1470 {
1471 	int rv = 0;
1472 
1473 	DEBUG_PRINT(("eflashactivate %x\n",  act), DEBUG_FUNCS | DEBUG_PROBE);
1474 
1475 	switch (act) {
1476 	case DVACT_DEACTIVATE:
1477 		/*
1478 		 * Nothing to do; we key off the device's DVF_ACTIVATE.
1479 		 */
1480 		break;
1481 	default:
1482 		rv = EOPNOTSUPP;
1483 		break;
1484 	}
1485 	return (rv);
1486 }
1487 
1488 int
1489 eflashdetach(struct device *self, int flags)
1490 {
1491 	struct eflash_softc *sc = device_private(self);
1492 	int s, bmaj, cmaj, i, mn;
1493 
1494 	DEBUG_PRINT(("%s: eflashdetach\n",  device_xname(sc->sc_dev)), DEBUG_FUNCS | DEBUG_PROBE);
1495 
1496 	/* locate the major number */
1497 	bmaj = bdevsw_lookup_major(&eflash_bdevsw);
1498 	cmaj = cdevsw_lookup_major(&eflash_cdevsw);
1499 
1500 	/* Nuke the vnodes for any open instances. */
1501 	for (i = 0; i < MAXPARTITIONS; i++) {
1502 		mn = EFLASHMINOR(device_unit(self), i);
1503 		vdevgone(bmaj, mn, mn, VBLK);
1504 		vdevgone(cmaj, mn, mn, VCHR);
1505 	}
1506 
1507 	/* Delete all of our wedges. */
1508 	dkwedge_delall(&sc->sc_dk);
1509 
1510 	s = splbio();
1511 
1512 	/* Kill off any queued buffers. */
1513 	bufq_drain(sc->sc_q);
1514 
1515 	bufq_free(sc->sc_q);
1516 	/*sc->atabus->ata_killpending(sc->drvp);*/
1517 
1518 	splx(s);
1519 
1520 	/* Detach disk. */
1521 	disk_detach(&sc->sc_dk);
1522 
1523 #if NRND > 0
1524 	/* Unhook the entropy source. */
1525 	rnd_detach_source(&sc->rnd_source);
1526 #endif
1527 
1528 	/*sc->drvp->drive_flags = 0; -- no drive any more here */
1529 
1530 	return (0);
1531 }
1532 
1533 extern int	dkwedge_autodiscover;
1534 
1535 /* Aux temp thread to avoid deadlock when doing the partitio.. ahem wedges thing.
1536  */
1537 static void
1538 eflash_wedges(void *arg)
1539 {
1540 	struct eflash_softc *sc = (struct eflash_softc*)arg;
1541 
1542     DBGME(DEBUG_STATUS,printf("%s: wedges started for %p\n", sc->sc_dk.dk_name, sc));
1543 
1544 	/* Discover wedges on this disk. */
1545     dkwedge_autodiscover = 1;
1546 	dkwedge_discover(&sc->sc_dk);
1547 
1548     config_pending_decr();
1549 
1550     DBGME(DEBUG_STATUS,printf("%s: wedges thread done for %p\n", device_xname(sc->sc_dev), sc));
1551 	kthread_exit(0);
1552 }
1553 
1554 static void
1555 eflash_thread(void *arg)
1556 {
1557 	struct eflash_softc *sc = (struct eflash_softc*)arg;
1558 	struct buf *bp;
1559     vaddr_t addr;
1560 	int s, error;
1561 
1562     DBGME(DEBUG_STATUS,printf("%s: thread started for %p\n", device_xname(sc->sc_dev), sc));
1563 
1564     s = splbio();
1565     eflashattach(sc);
1566     splx(s);
1567 
1568     /* Allocate a VM window large enough to map the largest sector
1569      * BUGBUG We could risk it and allocate/free on open/close?
1570      */
1571     addr = uvm_km_alloc(kernel_map, sc->sc_max_secsize, 0, UVM_KMF_VAONLY);
1572     if (addr == 0)
1573         panic("eflash_thread: kernel map full (%lx)", (long unsigned)sc->sc_max_secsize);
1574     sc->sc_sector = (/*volatile*/ uint8_t *) addr;
1575     sc->sc_sector_size = 0;
1576     sc->sc_sector_offset = NOSECTOR;
1577 
1578 	error = kthread_create(PRI_NONE, 0, NULL,
1579 	    eflash_wedges, sc, NULL, "%s.wedges", device_xname(sc->sc_dev));
1580 	if (error) {
1581 		aprint_error_dev(sc->sc_dev, "wedges: unable to create kernel "
1582 		    "thread: error %d\n", error);
1583 		/* XXX: why continue? */
1584 	}
1585 
1586 
1587     DBGME(DEBUG_STATUS,printf("%s: thread service active for %p\n", device_xname(sc->sc_dev), sc));
1588 
1589     s = splbio();
1590 	for (;;) {
1591         /* Get next I/O request, wait if necessary
1592          */
1593 		if ((sc->ch_flags & (ATACH_TH_RESET | ATACH_SHUTDOWN)) == 0 &&
1594 		    (sc->active_xfer == NULL)) {
1595 			sc->ch_flags &= ~ATACH_TH_RUN;
1596 			(void) tsleep(&sc->ch_thread, PRIBIO, "eflashth", 0);
1597 			sc->ch_flags |= ATACH_TH_RUN;
1598 		}
1599 		if (sc->ch_flags & ATACH_SHUTDOWN) {
1600 			break;
1601         }
1602         bp = sc->active_xfer;
1603         sc->active_xfer = NULL;
1604 		if (bp != NULL) {
1605 
1606             size_t sz = DEV_BSIZE, bnow;
1607 
1608             DBGME(DEBUG_XFERS,printf("%s: task %p %x %p %qx %d (%zd)\n", device_xname(sc->sc_dev), bp,
1609                                      sc->sc_bio.flags, sc->sc_bio.databuf, sc->sc_bio.blkno,
1610                                      sc->sc_bio.nbytes, sc->sc_bio.nblks));
1611 
1612             sc->sc_bio.error = 0;
1613             for (; sc->sc_bio.nblks > 0;) {
1614 
1615                 bnow = sc->sc_bio.nblks;
1616                 if (sc->sc_bio.flags & ATA_SINGLE) bnow = 1;
1617 
1618                 if (sc->sc_bio.flags & ATA_READ) {
1619                     sc->sc_bio.error =
1620                         eflash_read_at(sc, sc->sc_bio.blkno, sc->sc_bio.databuf, bnow, &sz);
1621                 } else {
1622                     sc->sc_bio.error =
1623                         eflash_write_at(sc, sc->sc_bio.blkno, sc->sc_bio.databuf, bnow, &sz);
1624                 }
1625 
1626                 if (sc->sc_bio.error)
1627                     break;
1628 
1629                 sc->sc_bio.blkno += sz; /* in blocks */
1630                 sc->sc_bio.nblks -= sz;
1631                 sc->sc_bio.blkdone += sz;
1632                 sz = sz << DEV_BSHIFT; /* in bytes */
1633                 sc->sc_bio.databuf += sz;
1634                 sc->sc_bio.nbytes  -= sz;
1635             }
1636 
1637             eflashdone(sc);
1638         }
1639 	}
1640 
1641 	splx(s);
1642 	sc->ch_thread = NULL;
1643 	wakeup(&sc->ch_flags);
1644 
1645     DBGME(DEBUG_STATUS,printf("%s: thread service terminated for %p\n", device_xname(sc->sc_dev), sc));
1646 
1647 	kthread_exit(0);
1648 }
1649 
1650 
1651 /*
1652  * Read/write routine for a buffer.  Validates the arguments and schedules the
1653  * transfer.  Does not wait for the transfer to complete.
1654  */
1655 void
1656 eflashstrategy(struct buf *bp)
1657 {
1658 	struct eflash_softc *sc = device_lookup_private(&eflash_cd, EFLASHUNIT(bp->b_dev));
1659 	struct disklabel *lp = sc->sc_dk.dk_label;
1660 	daddr_t blkno;
1661 	int s;
1662 
1663 	DEBUG_PRINT(("%s: eflashstrategy %lld\n", device_xname(sc->sc_dev), bp->b_blkno),
1664 	    DEBUG_XFERS);
1665 
1666 	/* Valid request?  */
1667 	if (bp->b_blkno < 0 ||
1668 	    (bp->b_bcount % lp->d_secsize) != 0 ||
1669 	    (bp->b_bcount / lp->d_secsize) >= (1 << NBBY)) {
1670 		bp->b_error = EINVAL;
1671 		goto done;
1672 	}
1673 
1674 	/* If device invalidated (e.g. media change, door open), error. */
1675 	if ((sc->sc_flags & EFLASHF_LOADED) == 0) {
1676 		bp->b_error = EIO;
1677 		goto done;
1678 	}
1679 
1680 	/* If it's a null transfer, return immediately. */
1681 	if (bp->b_bcount == 0)
1682 		goto done;
1683 
1684 	/*
1685 	 * Do bounds checking, adjust transfer. if error, process.
1686 	 * If end of partition, just return.
1687 	 */
1688 	if (EFLASHPART(bp->b_dev) == RAW_PART) {
1689 		if (bounds_check_with_mediasize(bp, DEV_BSIZE,
1690 		    sc->sc_capacity) <= 0)
1691 			goto done;
1692 	} else {
1693 		if (bounds_check_with_label(&sc->sc_dk, bp,
1694 		    (sc->sc_flags & (EFLASHF_WLABEL|EFLASHF_LABELLING)) != 0) <= 0)
1695 			goto done;
1696 	}
1697 
1698 	/*
1699 	 * Now convert the block number to absolute and put it in
1700 	 * terms of the device's logical block size.
1701 	 */
1702 	if (lp->d_secsize >= DEV_BSIZE)
1703 		blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE);
1704 	else
1705 		blkno = bp->b_blkno * (DEV_BSIZE / lp->d_secsize);
1706 
1707 	if (EFLASHPART(bp->b_dev) != RAW_PART)
1708 		blkno += lp->d_partitions[EFLASHPART(bp->b_dev)].p_offset;
1709 
1710 	bp->b_rawblkno = blkno;
1711 
1712 	/* Queue transfer on drive, activate drive and controller if idle. */
1713 	s = splbio();
1714 	bufq_put(sc->sc_q, bp);
1715 	eflashstart(sc);
1716 	splx(s);
1717 	return;
1718 done:
1719 	/* Toss transfer; we're done early. */
1720 	bp->b_resid = bp->b_bcount;
1721 	biodone(bp);
1722 }
1723 
1724 /*
1725  * Queue a drive for I/O.
1726  */
1727 void
1728 eflashstart(void *arg)
1729 {
1730 	struct eflash_softc *sc = arg;
1731 	struct buf *bp = NULL;
1732 
1733 	DEBUG_PRINT(("%s: eflashstart\n", device_xname(sc->sc_dev)),
1734 	    DEBUG_XFERS);
1735 	while (sc->openings > 0) {
1736 
1737 		/* Is there a buf for us ? */
1738 		if ((bp = bufq_get(sc->sc_q)) == NULL)
1739 			return;
1740 
1741 		/*
1742 		 * Make the command. First lock the device
1743 		 */
1744 		sc->openings--;
1745 
1746 		sc->retries = 0;
1747 		__eflashstart(sc, bp);
1748 	}
1749 }
1750 
1751 void
1752 __eflashstart(struct eflash_softc *sc, struct buf *bp)
1753 {
1754 	DEBUG_PRINT(("%s: __eflashstart %p\n", device_xname(sc->sc_dev), bp),
1755 	    DEBUG_XFERS);
1756 
1757 	sc->sc_bp = bp;
1758 	/*
1759 	 * If we're retrying, retry in single-sector mode. This will give us
1760 	 * the sector number of the problem, and will eventually allow the
1761 	 * transfer to succeed.
1762 	 */
1763 	if (sc->retries >= EFLASHIORETRIES_SINGLE)
1764 		sc->sc_bio.flags = ATA_SINGLE;
1765 	else
1766 		sc->sc_bio.flags = 0;
1767 	if (bp->b_flags & B_READ)
1768 		sc->sc_bio.flags |= ATA_READ;
1769 	sc->sc_bio.blkno = bp->b_rawblkno;
1770 	sc->sc_bio.blkdone = 0;
1771 	sc->sc_bio.nbytes = bp->b_bcount;
1772 	sc->sc_bio.nblks  = bp->b_bcount >> DEV_BSHIFT;
1773 	sc->sc_bio.databuf = bp->b_data;
1774 	/* Instrumentation. */
1775 	disk_busy(&sc->sc_dk);
1776     sc->active_xfer = bp;
1777     wakeup(&sc->ch_thread);
1778 }
1779 
1780 void
1781 eflashdone(struct eflash_softc *sc)
1782 {
1783 	struct buf *bp = sc->sc_bp;
1784 	const char *errmsg;
1785 	int do_perror = 0;
1786 
1787 	DEBUG_PRINT(("%s: eflashdone %p\n", device_xname(sc->sc_dev), bp),
1788 	    DEBUG_XFERS);
1789 
1790 	if (bp == NULL)
1791 		return;
1792 
1793 	bp->b_resid = sc->sc_bio.nbytes;
1794 	switch (sc->sc_bio.error) {
1795 	case ETIMEDOUT:
1796 		errmsg = "device timeout";
1797         do_perror = 1;
1798 		goto retry;
1799 	case EBUSY:
1800 		errmsg = "device stuck";
1801 retry:		/* Just reset and retry. Can we do more ? */
1802 		/*eflash_reset(sc);*/
1803 		diskerr(bp, "flash", errmsg, LOG_PRINTF,
1804 		    sc->sc_bio.blkdone, sc->sc_dk.dk_label);
1805 		if (sc->retries < EFLASHIORETRIES)
1806 			printf(", retrying");
1807 		printf("\n");
1808 		if (do_perror)
1809 			eflashperror(sc);
1810 		if (sc->retries < EFLASHIORETRIES) {
1811 			sc->retries++;
1812 			callout_reset(&sc->sc_restart_ch, RECOVERYTIME,
1813 			    eflashrestart, sc);
1814 			return;
1815 		}
1816 
1817 		bp->b_error = EIO;
1818 		break;
1819 	case 0:
1820         if ((sc->sc_bio.flags & ATA_CORR) || sc->retries > 0)
1821 			printf("%s: soft error (corrected)\n",
1822 			    device_xname(sc->sc_dev));
1823 		break;
1824 	case ENODEV:
1825 	case E2BIG:
1826 		bp->b_error = EIO;
1827 		break;
1828 	}
1829 	disk_unbusy(&sc->sc_dk, (bp->b_bcount - bp->b_resid),
1830 	    (bp->b_flags & B_READ));
1831 #if NRND > 0
1832 	rnd_add_uint32(&sc->rnd_source, bp->b_blkno);
1833 #endif
1834     biodone(bp);
1835     sc->openings++;
1836 	eflashstart(sc);
1837 }
1838 
1839 void
1840 eflashrestart(void *v)
1841 {
1842 	struct eflash_softc *sc = v;
1843 	struct buf *bp = sc->sc_bp;
1844 	int s;
1845 	DEBUG_PRINT(("%s: eflashrestart\n", device_xname(sc->sc_dev)),
1846 	    DEBUG_XFERS);
1847 
1848 	s = splbio();
1849 	__eflashstart(v, bp);
1850 	splx(s);
1851 }
1852 
1853 int
1854 eflashread(dev_t dev, struct uio *uio, int flags)
1855 {
1856 	DEBUG_PRINT(("eflashread\n"), DEBUG_XFERS);
1857 	return (physio(eflashstrategy, NULL, dev, B_READ, minphys, uio));
1858 }
1859 
1860 int
1861 eflashwrite(dev_t dev, struct uio *uio, int flags)
1862 {
1863 	DEBUG_PRINT(("eflashwrite\n"), DEBUG_XFERS);
1864 	return (physio(eflashstrategy, NULL, dev, B_WRITE, minphys, uio));
1865 }
1866 
1867 int
1868 eflashopen(dev_t dev, int flag, int fmt, struct lwp *l)
1869 {
1870 	struct eflash_softc *sc;
1871 	int part, error;
1872 
1873 	DEBUG_PRINT(("eflashopen %zx\n", dev), DEBUG_FUNCS);
1874 	sc = device_lookup_private(&eflash_cd, EFLASHUNIT(dev));
1875 	if (sc == NULL)
1876 		return (ENXIO);
1877 
1878 	if (! device_is_active(sc->sc_dev))
1879 		return (ENODEV);
1880 
1881 	part = EFLASHPART(dev);
1882 
1883 	mutex_enter(&sc->sc_dk.dk_openlock);
1884 
1885 	/*
1886 	 * If there are wedges, and this is not RAW_PART, then we
1887 	 * need to fail.
1888 	 */
1889 	if (sc->sc_dk.dk_nwedges != 0 && part != RAW_PART) {
1890 		error = EBUSY;
1891 		goto bad;
1892 	}
1893 
1894 	if (sc->sc_dk.dk_openmask != 0) {
1895 		/*
1896 		 * If any partition is open, but the disk has been invalidated,
1897 		 * disallow further opens.
1898 		 */
1899 		if ((sc->sc_flags & EFLASHF_LOADED) == 0) {
1900 			error = EIO;
1901 			goto bad;
1902 		}
1903 	} else {
1904 		if ((sc->sc_flags & EFLASHF_LOADED) == 0) {
1905 			sc->sc_flags |= EFLASHF_LOADED;
1906 
1907 			/* Load the partition info if not already loaded. */
1908 			eflashgetdisklabel(sc);
1909 		}
1910 	}
1911 
1912 	/* Check that the partition exists. */
1913 	if (part != RAW_PART &&
1914 	    (part >= sc->sc_dk.dk_label->d_npartitions ||
1915 	     sc->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
1916 		error = ENXIO;
1917 		goto bad;
1918 	}
1919 
1920 	/* Insure only one open at a time. */
1921 	switch (fmt) {
1922 	case S_IFCHR:
1923 		sc->sc_dk.dk_copenmask |= (1 << part);
1924 		break;
1925 	case S_IFBLK:
1926 		sc->sc_dk.dk_bopenmask |= (1 << part);
1927 		break;
1928 	}
1929 	sc->sc_dk.dk_openmask =
1930 	    sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
1931 
1932 	mutex_exit(&sc->sc_dk.dk_openlock);
1933 	return 0;
1934 
1935  bad:
1936 	mutex_exit(&sc->sc_dk.dk_openlock);
1937 	DEBUG_PRINT(("%s: eflashopen -> %d\n", device_xname(sc->sc_dev), error),
1938 	    DEBUG_XFERS);
1939 	return error;
1940 }
1941 
1942 int
1943 eflashclose(dev_t dev, int flag, int fmt, struct lwp *l)
1944 {
1945 	struct eflash_softc *sc = device_lookup_private(&eflash_cd, EFLASHUNIT(dev));
1946 	int part = EFLASHPART(dev);
1947 
1948 	DEBUG_PRINT(("eflashclose %zx\n", dev), DEBUG_FUNCS);
1949 
1950 	mutex_enter(&sc->sc_dk.dk_openlock);
1951 
1952 	switch (fmt) {
1953 	case S_IFCHR:
1954 		sc->sc_dk.dk_copenmask &= ~(1 << part);
1955 		break;
1956 	case S_IFBLK:
1957 		sc->sc_dk.dk_bopenmask &= ~(1 << part);
1958 		break;
1959 	}
1960 	sc->sc_dk.dk_openmask =
1961 	    sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
1962 
1963 	if (sc->sc_dk.dk_openmask == 0) {
1964 
1965 		if (! (sc->sc_flags & EFLASHF_KLABEL))
1966 			sc->sc_flags &= ~EFLASHF_LOADED;
1967 
1968         DEBUG_PRINT(("%s: eflashclose flg %x\n", device_xname(sc->sc_dev), sc->sc_flags),
1969                     DEBUG_XFERS);
1970 
1971 	}
1972 
1973 	mutex_exit(&sc->sc_dk.dk_openlock);
1974 	return 0;
1975 }
1976 
1977 void
1978 eflashgetdefaultlabel(struct eflash_softc *sc, struct disklabel *lp)
1979 {
1980 
1981 	DEBUG_PRINT(("%s: eflashgetdefaultlabel\n", device_xname(sc->sc_dev)), DEBUG_FUNCS);
1982 	memset(lp, 0, sizeof(struct disklabel));
1983 
1984 	lp->d_secsize = DEV_BSIZE;
1985 	lp->d_ntracks = 1;
1986 	lp->d_nsectors = sc->sc_capacity;
1987 	lp->d_ncylinders = 1;
1988 	lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
1989 
1990     lp->d_type = DTYPE_ST506; /* ?!? */
1991 
1992 	strncpy(lp->d_typename, ST506, 16);
1993 	strncpy(lp->d_packname, "fictitious", 16);
1994 	if (sc->sc_capacity > UINT32_MAX)
1995 		lp->d_secperunit = UINT32_MAX;
1996 	else
1997 		lp->d_secperunit = sc->sc_capacity;
1998 	lp->d_rpm = 3600;
1999 	lp->d_interleave = 1;
2000 	lp->d_flags = 0;
2001 
2002 	lp->d_partitions[RAW_PART].p_offset = 0;
2003 	lp->d_partitions[RAW_PART].p_size =
2004 	    lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
2005 	lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
2006 	lp->d_npartitions = RAW_PART + 1;
2007 
2008 	lp->d_magic = DISKMAGIC;
2009 	lp->d_magic2 = DISKMAGIC;
2010 	lp->d_checksum = dkcksum(lp);
2011 }
2012 
2013 /*
2014  * Fabricate a default disk label, and try to read the correct one.
2015  */
2016 void
2017 eflashgetdisklabel(struct eflash_softc *sc)
2018 {
2019 	struct disklabel *lp = sc->sc_dk.dk_label;
2020 	const char *errstring;
2021 
2022 	DEBUG_PRINT(("%s: eflashgetdisklabel\n",  device_xname(sc->sc_dev)), DEBUG_FUNCS);
2023 
2024 	memset(sc->sc_dk.dk_cpulabel, 0, sizeof(struct cpu_disklabel));
2025 
2026 	eflashgetdefaultlabel(sc, lp);
2027 
2028 #ifdef HAS_BAD144_HANDLING
2029 	sc->sc_bio.badsect[0] = -1;
2030 #endif
2031 
2032     /* BUGBUG: maj==0?? why is this not EFLASHLABELDEV(??sc->sc_dev) */
2033 	errstring = readdisklabel(MAKEEFLASHDEV(0, device_unit(sc->sc_dev),
2034 				  RAW_PART), eflashstrategy, lp,
2035 				  sc->sc_dk.dk_cpulabel);
2036 	if (errstring) {
2037 		printf("%s: %s\n", device_xname(sc->sc_dev), errstring);
2038 		return;
2039 	}
2040 
2041 #if DEBUG
2042     if (EFLASH_DEBUG(DEBUG_WRITES)) {
2043         int i, n = sc->sc_dk.dk_label->d_npartitions;
2044         printf("%s: %d parts\n", device_xname(sc->sc_dev), n);
2045         for (i = 0; i < n; i++) {
2046             printf("\t[%d]: t=%x s=%d o=%d\n", i,
2047                    sc->sc_dk.dk_label->d_partitions[i].p_fstype,
2048                    sc->sc_dk.dk_label->d_partitions[i].p_size,
2049                    sc->sc_dk.dk_label->d_partitions[i].p_offset);
2050         }
2051     }
2052 #endif
2053 
2054 #ifdef HAS_BAD144_HANDLING
2055 	if ((lp->d_flags & D_BADSECT) != 0)
2056 		bad144intern(sc);
2057 #endif
2058 }
2059 
2060 void
2061 eflashperror(const struct eflash_softc *sc)
2062 {
2063 	const char *devname = device_xname(sc->sc_dev);
2064 	u_int32_t Status = sc->sc_bio.r_error;
2065 
2066 	printf("%s: (", devname);
2067 
2068 	if (Status == 0)
2069 		printf("error not notified");
2070     else
2071         printf("status=x%x", Status);
2072 
2073 	printf(")\n");
2074 }
2075 
2076 int
2077 eflashioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l)
2078 {
2079 	struct eflash_softc *sc = device_lookup_private(&eflash_cd, EFLASHUNIT(dev));
2080 	int error = 0, s;
2081 
2082 	DEBUG_PRINT(("eflashioctl(%lx)\n",xfer), DEBUG_FUNCS);
2083 
2084 	if ((sc->sc_flags & EFLASHF_LOADED) == 0)
2085 		return EIO;
2086 
2087 	error = disk_ioctl(&sc->sc_dk, xfer, addr, flag, l);
2088 	if (error != EPASSTHROUGH)
2089 		return (error);
2090 
2091 	switch (xfer) {
2092 #ifdef HAS_BAD144_HANDLING
2093 	case DIOCSBAD:
2094 		if ((flag & FWRITE) == 0)
2095 			return EBADF;
2096 		sc->sc_dk.dk_cpulabel->bad = *(struct dkbad *)addr;
2097 		sc->sc_dk.dk_label->d_flags |= D_BADSECT;
2098 		bad144intern(sc);
2099 		return 0;
2100 #endif
2101 	case DIOCGDINFO:
2102 		*(struct disklabel *)addr = *(sc->sc_dk.dk_label);
2103 		return 0;
2104 
2105 	case DIOCGPART:
2106 		((struct partinfo *)addr)->disklab = sc->sc_dk.dk_label;
2107 		((struct partinfo *)addr)->part =
2108 		    &sc->sc_dk.dk_label->d_partitions[EFLASHPART(dev)];
2109 		return 0;
2110 
2111 	case DIOCWDINFO:
2112 	case DIOCSDINFO:
2113 	{
2114 		struct disklabel *lp;
2115 
2116 		if ((flag & FWRITE) == 0)
2117 			return EBADF;
2118 
2119 		lp = (struct disklabel *)addr;
2120 
2121 		mutex_enter(&sc->sc_dk.dk_openlock);
2122 		sc->sc_flags |= EFLASHF_LABELLING;
2123 
2124 		error = setdisklabel(sc->sc_dk.dk_label,
2125 		    lp, /*sc->sc_dk.dk_openmask : */0,
2126 		    sc->sc_dk.dk_cpulabel);
2127 		if (error == 0) {
2128 			if (xfer == DIOCWDINFO)
2129 				error = writedisklabel(EFLASHLABELDEV(dev),
2130 				    eflashstrategy, sc->sc_dk.dk_label,
2131 				    sc->sc_dk.dk_cpulabel);
2132 		}
2133 
2134 		sc->sc_flags &= ~EFLASHF_LABELLING;
2135 		mutex_exit(&sc->sc_dk.dk_openlock);
2136 		return error;
2137 	}
2138 
2139 	case DIOCKLABEL:
2140 		if (*(int *)addr)
2141 			sc->sc_flags |= EFLASHF_KLABEL;
2142 		else
2143 			sc->sc_flags &= ~EFLASHF_KLABEL;
2144 		return 0;
2145 
2146 	case DIOCWLABEL:
2147 		if ((flag & FWRITE) == 0)
2148 			return EBADF;
2149 		if (*(int *)addr)
2150 			sc->sc_flags |= EFLASHF_WLABEL;
2151 		else
2152 			sc->sc_flags &= ~EFLASHF_WLABEL;
2153 		return 0;
2154 
2155 	case DIOCGDEFLABEL:
2156 		eflashgetdefaultlabel(sc, (struct disklabel *)addr);
2157 		return 0;
2158 
2159 	case DIOCCACHESYNC:
2160 		return 0;
2161 
2162 	case DIOCAWEDGE:
2163 	    {
2164 	    	struct dkwedge_info *dkw = (void *) addr;
2165 
2166 		if ((flag & FWRITE) == 0)
2167 			return (EBADF);
2168 
2169 		/* If the ioctl happens here, the parent is us. */
2170 		strcpy(dkw->dkw_parent, device_xname(sc->sc_dev));
2171 		return (dkwedge_add(dkw));
2172 	    }
2173 
2174 	case DIOCDWEDGE:
2175 	    {
2176 	    	struct dkwedge_info *dkw = (void *) addr;
2177 
2178 		if ((flag & FWRITE) == 0)
2179 			return (EBADF);
2180 
2181 		/* If the ioctl happens here, the parent is us. */
2182 		strcpy(dkw->dkw_parent, device_xname(sc->sc_dev));
2183 		return (dkwedge_del(dkw));
2184 	    }
2185 
2186 	case DIOCLWEDGES:
2187 	    {
2188 	    	struct dkwedge_list *dkwl = (void *) addr;
2189 
2190 		return (dkwedge_list(&sc->sc_dk, dkwl, l));
2191 	    }
2192 
2193 	case DIOCGSTRATEGY:
2194 	    {
2195 		struct disk_strategy *dks = (void *)addr;
2196 
2197 		s = splbio();
2198 		strlcpy(dks->dks_name, bufq_getstrategyname(sc->sc_q),
2199 		    sizeof(dks->dks_name));
2200 		splx(s);
2201 		dks->dks_paramlen = 0;
2202 
2203 		return 0;
2204 	    }
2205 
2206 	case DIOCSSTRATEGY:
2207 	    {
2208 		struct disk_strategy *dks = (void *)addr;
2209 		struct bufq_state *new;
2210 		struct bufq_state *old;
2211 
2212 		if ((flag & FWRITE) == 0) {
2213 			return EBADF;
2214 		}
2215 		if (dks->dks_param != NULL) {
2216 			return EINVAL;
2217 		}
2218 		dks->dks_name[sizeof(dks->dks_name) - 1] = 0; /* ensure term */
2219 		error = bufq_alloc(&new, dks->dks_name,
2220 		    BUFQ_EXACT|BUFQ_SORT_RAWBLOCK);
2221 		if (error) {
2222 			return error;
2223 		}
2224 		s = splbio();
2225 		old = sc->sc_q;
2226 		bufq_move(new, old);
2227 		sc->sc_q = new;
2228 		splx(s);
2229 		bufq_free(old);
2230 
2231 		return 0;
2232 	    }
2233 
2234 	default:
2235         /* NB: we get a DIOCGWEDGEINFO, but nobody else handles it either */
2236         DEBUG_PRINT(("eflashioctl: unsup x%lx\n", xfer), DEBUG_FUNCS);
2237 		return ENOTTY;
2238 	}
2239 }
2240 
2241 int
2242 eflashsize(dev_t dev)
2243 {
2244 	struct eflash_softc *sc;
2245 	int part, omask;
2246 	int size;
2247 
2248 	DEBUG_PRINT(("eflashsize\n"), DEBUG_FUNCS);
2249 
2250 	sc = device_lookup_private(&eflash_cd, EFLASHUNIT(dev));
2251 	if (sc == NULL)
2252 		return (-1);
2253 
2254 	part = EFLASHPART(dev);
2255 	omask = sc->sc_dk.dk_openmask & (1 << part);
2256 
2257 	if (omask == 0 && eflashopen(dev, 0, S_IFBLK, NULL) != 0)
2258 		return (-1);
2259 	if (sc->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
2260 		size = -1;
2261 	else
2262 		size = sc->sc_dk.dk_label->d_partitions[part].p_size *
2263 		    (sc->sc_dk.dk_label->d_secsize / DEV_BSIZE);
2264 	if (omask == 0 && eflashclose(dev, 0, S_IFBLK, NULL) != 0)
2265 		return (-1);
2266 	return (size);
2267 }
2268 
2269 /*
2270  * Dump core after a system crash.
2271  */
2272 int
2273 eflashdump(dev_t dev, daddr_t blkno, void *va, size_t size)
2274 {
2275     /* no we dont */
2276     return (ENXIO);
2277 }
2278 
2279 #ifdef HAS_BAD144_HANDLING
2280 /*
2281  * Internalize the bad sector table.
2282  */
2283 void
2284 bad144intern(struct eflash_softc *sc)
2285 {
2286 	struct dkbad *bt = &sc->sc_dk.dk_cpulabel->bad;
2287 	struct disklabel *lp = sc->sc_dk.dk_label;
2288 	int i = 0;
2289 
2290 	DEBUG_PRINT(("bad144intern\n"), DEBUG_XFERS);
2291 
2292 	for (; i < NBT_BAD; i++) {
2293 		if (bt->bt_bad[i].bt_cyl == 0xffff)
2294 			break;
2295 		sc->sc_bio.badsect[i] =
2296 		    bt->bt_bad[i].bt_cyl * lp->d_secpercyl +
2297 		    (bt->bt_bad[i].bt_trksec >> 8) * lp->d_nsectors +
2298 		    (bt->bt_bad[i].bt_trksec & 0xff);
2299 	}
2300 	for (; i < NBT_BAD+1; i++)
2301 		sc->sc_bio.badsect[i] = -1;
2302 }
2303 #endif
2304 
2305 static void
2306 eflash_params_to_properties(struct eflash_softc *sc)
2307 {
2308 	prop_dictionary_t disk_info, odisk_info, geom;
2309 	const char *cp;
2310 
2311 	disk_info = prop_dictionary_create();
2312 
2313     cp = ST506;
2314 
2315 	prop_dictionary_set_cstring_nocopy(disk_info, "type", cp);
2316 
2317 	geom = prop_dictionary_create();
2318 
2319 	prop_dictionary_set_uint64(geom, "sectors-per-unit", sc->sc_capacity);
2320 
2321 	prop_dictionary_set_uint32(geom, "sector-size",
2322 				   DEV_BSIZE /* XXX 512? */);
2323 
2324 	prop_dictionary_set_uint16(geom, "sectors-per-track",
2325 				   sc->sc_capacity);
2326 
2327 	prop_dictionary_set_uint16(geom, "tracks-per-cylinder", 1);
2328 
2329     prop_dictionary_set_uint64(geom, "cylinders-per-unit", sc->sc_capacity);
2330 
2331 	prop_dictionary_set(disk_info, "geometry", geom);
2332 	prop_object_release(geom);
2333 
2334 	prop_dictionary_set(device_properties(sc->sc_dev),
2335 			    "disk-info", disk_info);
2336 
2337 	/*
2338 	 * Don't release disk_info here; we keep a reference to it.
2339 	 * disk_detach() will release it when we go away.
2340 	 */
2341 
2342 	odisk_info = sc->sc_dk.dk_info;
2343 	sc->sc_dk.dk_info = disk_info;
2344 	if (odisk_info)
2345 		prop_object_release(odisk_info);
2346 }
2347 
2348