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