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