Sun Dec 8 14:43:16 2019 UTC ()
Pull up following revision(s) (requested by bouyer in ticket #517):

	sys/arch/emips/ebus/flash_ebus.c: revision 1.21
	sys/arch/emips/ebus/ace_ebus.c: revision 1.21

Drop advertisement clause from my licenses


(martin)
diff -r1.20 -r1.20.20.1 src/sys/arch/emips/ebus/ace_ebus.c
diff -r1.20 -r1.20.8.1 src/sys/arch/emips/ebus/flash_ebus.c

cvs diff -r1.20 -r1.20.20.1 src/sys/arch/emips/ebus/ace_ebus.c (switch to unified diff)

--- src/sys/arch/emips/ebus/ace_ebus.c 2016/11/20 03:30:11 1.20
+++ src/sys/arch/emips/ebus/ace_ebus.c 2019/12/08 14:43:16 1.20.20.1
@@ -1,2458 +1,2453 @@ @@ -1,2458 +1,2453 @@
1/* $NetBSD: ace_ebus.c,v 1.20 2016/11/20 03:30:11 pgoyette Exp $ */ 1/* $NetBSD: ace_ebus.c,v 1.20.20.1 2019/12/08 14:43:16 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2010 The NetBSD Foundation, Inc. 4 * Copyright (c) 2010 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code was written by Alessandro Forin and Neil Pittman 7 * This code was written by Alessandro Forin and Neil Pittman
8 * at Microsoft Research and contributed to The NetBSD Foundation 8 * at Microsoft Research and contributed to The NetBSD Foundation
9 * by Microsoft Corporation. 9 * by Microsoft Corporation.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: ace_ebus.c,v 1.20 2016/11/20 03:30:11 pgoyette Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: ace_ebus.c,v 1.20.20.1 2019/12/08 14:43:16 martin Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38#include <sys/kernel.h> 38#include <sys/kernel.h>
39#include <sys/conf.h> 39#include <sys/conf.h>
40#include <sys/file.h> 40#include <sys/file.h>
41#include <sys/stat.h> 41#include <sys/stat.h>
42#include <sys/ioctl.h> 42#include <sys/ioctl.h>
43#include <sys/buf.h> 43#include <sys/buf.h>
44#include <sys/bufq.h> 44#include <sys/bufq.h>
45#include <sys/uio.h> 45#include <sys/uio.h>
46#include <sys/malloc.h> 46#include <sys/malloc.h>
47#include <sys/device.h> 47#include <sys/device.h>
48#include <sys/disklabel.h> 48#include <sys/disklabel.h>
49#include <sys/disk.h> 49#include <sys/disk.h>
50#include <sys/syslog.h> 50#include <sys/syslog.h>
51#include <sys/proc.h> 51#include <sys/proc.h>
52#include <sys/vnode.h> 52#include <sys/vnode.h>
53#include <sys/kthread.h> 53#include <sys/kthread.h>
54#include <sys/lock.h> 54#include <sys/lock.h>
55#include <sys/queue.h> 55#include <sys/queue.h>
56 56
57#include <sys/rndsource.h> 57#include <sys/rndsource.h>
58 58
59#include <machine/intr.h> 59#include <machine/intr.h>
60#include <machine/bus.h> 60#include <machine/bus.h>
61 61
62#include "locators.h" 62#include "locators.h"
63#include <prop/proplib.h> 63#include <prop/proplib.h>
64 64
65#include <emips/ebus/ebusvar.h> 65#include <emips/ebus/ebusvar.h>
66#include <emips/emips/machdep.h> 66#include <emips/emips/machdep.h>
67#include <machine/emipsreg.h> 67#include <machine/emipsreg.h>
68 68
69/* Structure returned by the Identify command (see CFlash specs) 69/* Structure returned by the Identify command (see CFlash specs)
70 * NB: We only care for the first sector so that is what we define here. 70 * NB: We only care for the first sector so that is what we define here.
71 * NB: Beware of mis-alignment for all 32bit things 71 * NB: Beware of mis-alignment for all 32bit things
72 */ 72 */
73typedef struct _CFLASH_IDENTIFY { 73typedef struct _CFLASH_IDENTIFY {
74 uint16_t Signature; /* Word 0 */ 74 uint16_t Signature; /* Word 0 */
75#define CFLASH_SIGNATURE 0x848a 75#define CFLASH_SIGNATURE 0x848a
76 uint16_t DefaultNumberOfCylinders; /* Word 1 */ 76 uint16_t DefaultNumberOfCylinders; /* Word 1 */
77 uint16_t Reserved1; /* Word 2 */ 77 uint16_t Reserved1; /* Word 2 */
78 uint16_t DefaultNumberOfHeads; /* Word 3 */ 78 uint16_t DefaultNumberOfHeads; /* Word 3 */
79 uint16_t Obsolete1[2]; /* Word 4 */ 79 uint16_t Obsolete1[2]; /* Word 4 */
80 uint16_t DefaultSectorsPerTrack; /* Word 6 */ 80 uint16_t DefaultSectorsPerTrack; /* Word 6 */
81 uint16_t SectorsPerCard[2]; /* Word 7 */ 81 uint16_t SectorsPerCard[2]; /* Word 7 */
82 uint16_t Obsolete2; /* Word 9 */ 82 uint16_t Obsolete2; /* Word 9 */
83 uint8_t SerialNumber[20]; /* padded, right-justified Word 10 */ 83 uint8_t SerialNumber[20]; /* padded, right-justified Word 10 */
84 uint16_t Obsolete3[2]; /* Word 20 */ 84 uint16_t Obsolete3[2]; /* Word 20 */
85 uint16_t EccBytesInRWLong; /* Word 22 */ 85 uint16_t EccBytesInRWLong; /* Word 22 */
86 uint8_t FirmwareRevision[8]; /* Word 23 */ 86 uint8_t FirmwareRevision[8]; /* Word 23 */
87 uint8_t ModelNumber[40]; /* Word 27 */ 87 uint8_t ModelNumber[40]; /* Word 27 */
88 uint16_t SectorsInRWMultiple; /* Word 47 */ 88 uint16_t SectorsInRWMultiple; /* Word 47 */
89 uint16_t Reserved2; /* Word 48 */ 89 uint16_t Reserved2; /* Word 48 */
90 uint16_t Capabilities; /* Word 49 */ 90 uint16_t Capabilities; /* Word 49 */
91 uint16_t Reserved3; /* Word 50 */ 91 uint16_t Reserved3; /* Word 50 */
92 uint16_t PioMode; /* Word 51 */ 92 uint16_t PioMode; /* Word 51 */
93 uint16_t Obsolete4; /* Word 52 */ 93 uint16_t Obsolete4; /* Word 52 */
94 uint16_t FieldValidity; /* Word 53 */ 94 uint16_t FieldValidity; /* Word 53 */
95 uint16_t CurrentNumberOfCylinders; /* Word 54 */ 95 uint16_t CurrentNumberOfCylinders; /* Word 54 */
96 uint16_t CurrentNumberOfHeads; /* Word 55 */ 96 uint16_t CurrentNumberOfHeads; /* Word 55 */
97 uint16_t CurrentSectorsPerTrack; /* Word 56 */ 97 uint16_t CurrentSectorsPerTrack; /* Word 56 */
98 uint16_t CurrentCapacity[2]; /* Word 57 */ 98 uint16_t CurrentCapacity[2]; /* Word 57 */
99 uint16_t MultiSectorSettings; /* Word 59 */ 99 uint16_t MultiSectorSettings; /* Word 59 */
100 uint16_t NumberOfAddressableSectors[2]; /* Word 60 */ 100 uint16_t NumberOfAddressableSectors[2]; /* Word 60 */
101 uint16_t Reserved4; /* Word 62 */ 101 uint16_t Reserved4; /* Word 62 */
102 uint16_t MultiWordDmaTransfer; /* Word 63 */ 102 uint16_t MultiWordDmaTransfer; /* Word 63 */
103 uint16_t AdvancedPioModes; /* Word 64 */ 103 uint16_t AdvancedPioModes; /* Word 64 */
104 uint16_t MinimumMultiWordDmaTiming; /* Word 65 */ 104 uint16_t MinimumMultiWordDmaTiming; /* Word 65 */
105 uint16_t RecommendedMultiWordDmaTiming; /* Word 66 */ 105 uint16_t RecommendedMultiWordDmaTiming; /* Word 66 */
106 uint16_t PioTimingNoFlowControl; /* Word 67 */ 106 uint16_t PioTimingNoFlowControl; /* Word 67 */
107 uint16_t PioTimingWithFlowControl; /* Word 68 */ 107 uint16_t PioTimingWithFlowControl; /* Word 68 */
108 uint16_t Reserved5[13]; /* Word 69 */ 108 uint16_t Reserved5[13]; /* Word 69 */
109 uint16_t FeaturesSupported[3]; /* Word 82 */ 109 uint16_t FeaturesSupported[3]; /* Word 82 */
110 uint16_t FeaturesEnabled[3]; /* Word 85 */ 110 uint16_t FeaturesEnabled[3]; /* Word 85 */
111 uint16_t UdmaMode; /* Word 88 */ 111 uint16_t UdmaMode; /* Word 88 */
112 uint16_t SecurityEraseTime; /* Word 89 */ 112 uint16_t SecurityEraseTime; /* Word 89 */
113 uint16_t EnhancedSecurityEraseTime; /* Word 90 */ 113 uint16_t EnhancedSecurityEraseTime; /* Word 90 */
114 uint16_t CurrentPowerManagementValue; /* Word 91 */ 114 uint16_t CurrentPowerManagementValue; /* Word 91 */
115 uint8_t Reserved6[72]; /* Word 92-127 */ 115 uint8_t Reserved6[72]; /* Word 92-127 */
116 uint8_t SecondHalf[256]; /* Word 128-255 */ 116 uint8_t SecondHalf[256]; /* Word 128-255 */
117} CFLASH_IDENTIFY, *PCFLASH_IDENTIFY; 117} CFLASH_IDENTIFY, *PCFLASH_IDENTIFY;
118 118
119#define SIZEOF_IDENTIFY CF_SECTOR_SIZE /* must be a sector multiple */ 119#define SIZEOF_IDENTIFY CF_SECTOR_SIZE /* must be a sector multiple */
120 120
121/* Instead of dragging in atavar.h.. */ 121/* Instead of dragging in atavar.h.. */
122/* 122/*
123 * Parameters/state needed by the controller to perform an ATA bio. 123 * Parameters/state needed by the controller to perform an ATA bio.
124 */ 124 */
125struct ace_bio { 125struct ace_bio {
126 volatile int flags;/* cmd flags */ 126 volatile int flags;/* cmd flags */
127#define ATA_POLL 0x0002 /* poll for completion */ 127#define ATA_POLL 0x0002 /* poll for completion */
128#define ATA_SINGLE 0x0008 /* transfer must be done in singlesector mode */ 128#define ATA_SINGLE 0x0008 /* transfer must be done in singlesector mode */
129#define ATA_READ 0x0020 /* transfer is a read (otherwise a write) */ 129#define ATA_READ 0x0020 /* transfer is a read (otherwise a write) */
130#define ATA_CORR 0x0040 /* transfer had a corrected error */ 130#define ATA_CORR 0x0040 /* transfer had a corrected error */
131 daddr_t blkno; /* block addr */ 131 daddr_t blkno; /* block addr */
132 daddr_t blkdone;/* number of blks transferred */ 132 daddr_t blkdone;/* number of blks transferred */
133 size_t nblks; /* number of blocks currently transferring */ 133 size_t nblks; /* number of blocks currently transferring */
134 size_t nbytes; /* number of bytes currently transferring */ 134 size_t nbytes; /* number of bytes currently transferring */
135 char *databuf;/* data buffer address */ 135 char *databuf;/* data buffer address */
136 volatile int error; 136 volatile int error;
137#define NOERROR 0 /* There was no error (r_error invalid), 137#define NOERROR 0 /* There was no error (r_error invalid),
138 else see acedone()*/ 138 else see acedone()*/
139#define FAILED(er) (er != 0) 139#define FAILED(er) (er != 0)
140#define EDOOFUS EIO 140#define EDOOFUS EIO
141 141
142 uint32_t r_error;/* copy of status register */ 142 uint32_t r_error;/* copy of status register */
143#ifdef HAS_BAD144_HANDLING 143#ifdef HAS_BAD144_HANDLING
144 daddr_t badsect[127];/* 126 plus trailing -1 marker */ 144 daddr_t badsect[127];/* 126 plus trailing -1 marker */
145#endif 145#endif
146}; 146};
147/* End of atavar.h*/ 147/* End of atavar.h*/
148 148
149struct ace_softc { 149struct ace_softc {
150 /* General disk infos */ 150 /* General disk infos */
151 device_t sc_dev; 151 device_t sc_dev;
152 152
153 struct disk sc_dk; 153 struct disk sc_dk;
154 struct bufq_state *sc_q; 154 struct bufq_state *sc_q;
155 struct callout sc_restart_ch; 155 struct callout sc_restart_ch;
156 156
157 /* IDE disk soft states */ 157 /* IDE disk soft states */
158 struct buf *sc_bp; /* buf being transfered */ 158 struct buf *sc_bp; /* buf being transfered */
159 struct buf *active_xfer; /* buf handoff to thread */ 159 struct buf *active_xfer; /* buf handoff to thread */
160 /* current transfer data */ 160 /* current transfer data */
161 struct ace_bio sc_bio; /* current transfer */ 161 struct ace_bio sc_bio; /* current transfer */
162 162
163 struct proc *ch_thread; 163 struct proc *ch_thread;
164 int ch_flags; 164 int ch_flags;
165#define ATACH_SHUTDOWN 0x02 /* thread is shutting down */ 165#define ATACH_SHUTDOWN 0x02 /* thread is shutting down */
166#define ATACH_IRQ_WAIT 0x10 /* thread is waiting for irq */ 166#define ATACH_IRQ_WAIT 0x10 /* thread is waiting for irq */
167#define ATACH_DISABLED 0x80 /* channel is disabled */ 167#define ATACH_DISABLED 0x80 /* channel is disabled */
168#define ATACH_TH_RUN 0x100 /* the kernel thread is working */ 168#define ATACH_TH_RUN 0x100 /* the kernel thread is working */
169#define ATACH_TH_RESET 0x200 /* someone ask the thread to reset */ 169#define ATACH_TH_RESET 0x200 /* someone ask the thread to reset */
170 170
171 int openings; 171 int openings;
172 int media_has_changed; 172 int media_has_changed;
173#define ACECE_MC 0x20 /* media changed */ 173#define ACECE_MC 0x20 /* media changed */
174#define ACECE_MCR 0x08 /* media change requested */ 174#define ACECE_MCR 0x08 /* media change requested */
175 struct _CFLASH_IDENTIFY sc_params;/* drive characteristics found */ 175 struct _CFLASH_IDENTIFY sc_params;/* drive characteristics found */
176 176
177 int sc_flags; 177 int sc_flags;
178#define ACEF_WLABEL 0x004 /* label is writable */ 178#define ACEF_WLABEL 0x004 /* label is writable */
179#define ACEF_LABELLING 0x008 /* writing label */ 179#define ACEF_LABELLING 0x008 /* writing label */
180#define ACEF_LOADED 0x010 /* parameters loaded */ 180#define ACEF_LOADED 0x010 /* parameters loaded */
181#define ACEF_WAIT 0x020 /* waiting for resources */ 181#define ACEF_WAIT 0x020 /* waiting for resources */
182#define ACEF_KLABEL 0x080 /* retain label after 'full' close */ 182#define ACEF_KLABEL 0x080 /* retain label after 'full' close */
183 183
184 uint64_t sc_capacity; 184 uint64_t sc_capacity;
185 uint32_t sc_multi; /* max sectors per xfer */ 185 uint32_t sc_multi; /* max sectors per xfer */
186 186
187 struct _Sac *sc_dr; /* reg pointers */ 187 struct _Sac *sc_dr; /* reg pointers */
188 int hw_busy; 188 int hw_busy;
189 int retries; /* number of xfer retry */ 189 int retries; /* number of xfer retry */
190 190
191 krndsource_t rnd_source; 191 krndsource_t rnd_source;
192}; 192};
193 193
194int ace_ebus_match(device_t, cfdata_t, void *); 194int ace_ebus_match(device_t, cfdata_t, void *);
195void ace_ebus_attach(device_t, device_t, void *); 195void ace_ebus_attach(device_t, device_t, void *);
196void aceattach(struct ace_softc *); 196void aceattach(struct ace_softc *);
197int acedetach(device_t, int); 197int acedetach(device_t, int);
198int aceactivate(device_t, enum devact); 198int aceactivate(device_t, enum devact);
199 199
200void acedone(struct ace_softc *); 200void acedone(struct ace_softc *);
201static void ace_set_geometry(struct ace_softc *ace); 201static void ace_set_geometry(struct ace_softc *ace);
202 202
203CFATTACH_DECL_NEW(ace_ebus, sizeof(struct ace_softc), 203CFATTACH_DECL_NEW(ace_ebus, sizeof(struct ace_softc),
204 ace_ebus_match, ace_ebus_attach, acedetach, aceactivate); 204 ace_ebus_match, ace_ebus_attach, acedetach, aceactivate);
205 205
206int ace_ebus_intr(void *cookie, void *f); 206int ace_ebus_intr(void *cookie, void *f);
207 207
208static void sysace_thread(void *arg); 208static void sysace_thread(void *arg);
209 209
210int 210int
211ace_ebus_match(device_t parent, cfdata_t cf, void *aux) 211ace_ebus_match(device_t parent, cfdata_t cf, void *aux)
212{ 212{
213 struct ebus_attach_args *d = aux; 213 struct ebus_attach_args *d = aux;
214 struct _Sac *sac = (struct _Sac *)d->ia_vaddr; 214 struct _Sac *sac = (struct _Sac *)d->ia_vaddr;
215 215
216 if (strcmp("ace", d->ia_name) != 0) 216 if (strcmp("ace", d->ia_name) != 0)
217 return 0; 217 return 0;
218 if ((sac == NULL) || 218 if ((sac == NULL) ||
219 ((sac->Tag & SAC_TAG) != PMTTAG_SYSTEM_ACE)) 219 ((sac->Tag & SAC_TAG) != PMTTAG_SYSTEM_ACE))
220 return 0; 220 return 0;
221 return 1; 221 return 1;
222} 222}
223 223
224void 224void
225ace_ebus_attach(device_t parent, device_t self, void *aux) 225ace_ebus_attach(device_t parent, device_t self, void *aux)
226{ 226{
227 struct ace_softc *ace = device_private(self); 227 struct ace_softc *ace = device_private(self);
228 struct ebus_attach_args *ia = aux; 228 struct ebus_attach_args *ia = aux;
229 int error; 229 int error;
230 230
231 ace->sc_dev = self; 231 ace->sc_dev = self;
232 232
233 /* 233 /*
234 * It's on the baseboard, with a dedicated interrupt line. 234 * It's on the baseboard, with a dedicated interrupt line.
235 */ 235 */
236 ace->sc_dr = (struct _Sac *)ia->ia_vaddr; 236 ace->sc_dr = (struct _Sac *)ia->ia_vaddr;
237#if DEBUG 237#if DEBUG
238 printf(" virt=%p", (void*)ace->sc_dr); 238 printf(" virt=%p", (void*)ace->sc_dr);
239#endif 239#endif
240 printf(" : System ACE\n"); 240 printf(" : System ACE\n");
241 241
242 ebus_intr_establish(parent, (void*)ia->ia_cookie, IPL_BIO, 242 ebus_intr_establish(parent, (void*)ia->ia_cookie, IPL_BIO,
243 ace_ebus_intr, ace); 243 ace_ebus_intr, ace);
244 244
245 config_pending_incr(self); 245 config_pending_incr(self);
246 246
247 error = kthread_create(PRI_NONE, 0, NULL, sysace_thread, 247 error = kthread_create(PRI_NONE, 0, NULL, sysace_thread,
248 ace, NULL, "%s", device_xname(ace->sc_dev)); 248 ace, NULL, "%s", device_xname(ace->sc_dev));
249 if (error) 249 if (error)
250 aprint_error_dev(ace->sc_dev, "unable to create kernel " 250 aprint_error_dev(ace->sc_dev, "unable to create kernel "
251 "thread: error %d\n", error); 251 "thread: error %d\n", error);
252} 252}
253 253
254/* 254/*
255 * Sysace driver I(af) wrote for FreeBsd. 255 * Sysace driver I(af) wrote for FreeBsd.
256 */ 256 */
257#define CF_SECBITS 9 257#define CF_SECBITS 9
258#define CF_SECTOR_SIZE (1 << CF_SECBITS) 258#define CF_SECTOR_SIZE (1 << CF_SECBITS)
259 259
260static int sysace_attach(struct ace_softc *sc); 260static int sysace_attach(struct ace_softc *sc);
261static int sysace_reset(struct ace_softc *sc); 261static int sysace_reset(struct ace_softc *sc);
262static int sysace_identify(struct ace_softc *sc); 262static int sysace_identify(struct ace_softc *sc);
263static int sysace_lock_registers(struct ace_softc *sc); 263static int sysace_lock_registers(struct ace_softc *sc);
264static int sysace_unlock_registers(struct ace_softc *sc); 264static int sysace_unlock_registers(struct ace_softc *sc);
265static int sysace_start(struct ace_softc *sc, uint32_t Command, uint32_t Lba, 265static int sysace_start(struct ace_softc *sc, uint32_t Command, uint32_t Lba,
266 uint32_t nSectors); 266 uint32_t nSectors);
267static int sysace_validate(struct ace_softc *sc, daddr_t start, size_t *pSize); 267static int sysace_validate(struct ace_softc *sc, daddr_t start, size_t *pSize);
268static int sysace_read_at (struct ace_softc *sc, daddr_t start_sector, 268static int sysace_read_at (struct ace_softc *sc, daddr_t start_sector,
269 char *buffer, size_t nblocks, size_t * pSizeRead); 269 char *buffer, size_t nblocks, size_t * pSizeRead);
270static int sysace_write_at(struct ace_softc *sc, daddr_t start_sector, 270static int sysace_write_at(struct ace_softc *sc, daddr_t start_sector,
271 char *buffer, size_t nblocks, size_t * pSizeWritten); 271 char *buffer, size_t nblocks, size_t * pSizeWritten);
272#ifdef USE_ACE_FOR_RECONFIG /* Old code, despised and replaced by ICAP */ 272#ifdef USE_ACE_FOR_RECONFIG /* Old code, despised and replaced by ICAP */
273static int sysace_send_config(struct ace_softc *sc, 273static int sysace_send_config(struct ace_softc *sc,
274 uint32_t *Data, unsigned int nBytes); 274 uint32_t *Data, unsigned int nBytes);
275#endif 275#endif
276 276
277#define DEBUG_INTR 0x01 277#define DEBUG_INTR 0x01
278#define DEBUG_XFERS 0x02 278#define DEBUG_XFERS 0x02
279#define DEBUG_STATUS 0x04 279#define DEBUG_STATUS 0x04
280#define DEBUG_FUNCS 0x08 280#define DEBUG_FUNCS 0x08
281#define DEBUG_PROBE 0x10 281#define DEBUG_PROBE 0x10
282#define DEBUG_WRITES 0x20 282#define DEBUG_WRITES 0x20
283#define DEBUG_READS 0x40 283#define DEBUG_READS 0x40
284#define DEBUG_ERRORS 0x80 284#define DEBUG_ERRORS 0x80
285#ifdef DEBUG 285#ifdef DEBUG
286int ace_debug = DEBUG_ERRORS /*|DEBUG_WRITES*/; 286int ace_debug = DEBUG_ERRORS /*|DEBUG_WRITES*/;
287#define ACE_DEBUG(x) (ace_debug & (x)) 287#define ACE_DEBUG(x) (ace_debug & (x))
288#define DBGME(_lev_,_x_) if ((_lev_) & ace_debug) _x_ 288#define DBGME(_lev_,_x_) if ((_lev_) & ace_debug) _x_
289#else 289#else
290#define ACE_DEBUG(x) (0) 290#define ACE_DEBUG(x) (0)
291#define DBGME(_lev_,_x_) 291#define DBGME(_lev_,_x_)
292#endif 292#endif
293#define DEBUG_PRINT(_args_,_lev_) DBGME(_lev_,printf _args_) 293#define DEBUG_PRINT(_args_,_lev_) DBGME(_lev_,printf _args_)
294 294
295static int 295static int
296sysace_attach(struct ace_softc *sc) 296sysace_attach(struct ace_softc *sc)
297{ 297{
298 int error; 298 int error;
299 299
300 DBGME(DEBUG_FUNCS, printf("Sysace::delayed_attach %p\n", sc)); 300 DBGME(DEBUG_FUNCS, printf("Sysace::delayed_attach %p\n", sc));
301 301
302 sc->media_has_changed = TRUE; 302 sc->media_has_changed = TRUE;
303 sc->sc_capacity = 0; 303 sc->sc_capacity = 0;
304 304
305 error = sysace_reset(sc); 305 error = sysace_reset(sc);
306 if (error) { 306 if (error) {
307 device_printf(sc->sc_dev, 307 device_printf(sc->sc_dev,
308 "failed to reset, errno=%d\n", error); 308 "failed to reset, errno=%d\n", error);
309 goto Out; 309 goto Out;
310 } 310 }
311 311
312 error = sysace_identify(sc); 312 error = sysace_identify(sc);
313 if (error) { 313 if (error) {
314 device_printf(sc->sc_dev, 314 device_printf(sc->sc_dev,
315 "failed to identify card, errno=%d.\n", error); 315 "failed to identify card, errno=%d.\n", error);
316 goto Out; 316 goto Out;
317 } 317 }
318 318
319 DBGME(DEBUG_PROBE, device_printf(sc->sc_dev, 319 DBGME(DEBUG_PROBE, device_printf(sc->sc_dev,
320 "Card has %qx sectors.\n", sc->sc_capacity)); 320 "Card has %qx sectors.\n", sc->sc_capacity));
321 if (sc->sc_capacity == 0) { 321 if (sc->sc_capacity == 0) {
322 device_printf(sc->sc_dev, "size 0, no card? Wont work.\n"); 322 device_printf(sc->sc_dev, "size 0, no card? Wont work.\n");
323 error = EDOOFUS; 323 error = EDOOFUS;
324 goto Out; 324 goto Out;
325 } 325 }
326 326
327 sc->media_has_changed = FALSE; 327 sc->media_has_changed = FALSE;
328Out: 328Out:
329 return error; 329 return error;
330} 330}
331 331
332static void 332static void
333sysace_wedges(void *arg); 333sysace_wedges(void *arg);
334extern int dkwedge_autodiscover; 334extern int dkwedge_autodiscover;
335 335
336/* 336/*
337 * Aux temp thread to avoid deadlock when doing 337 * Aux temp thread to avoid deadlock when doing
338 * the partitio.. ahem wedges thing. 338 * the partitio.. ahem wedges thing.
339 */ 339 */
340static void 340static void
341sysace_wedges(void *arg) 341sysace_wedges(void *arg)
342{ 342{
343 struct ace_softc *sc = arg; 343 struct ace_softc *sc = arg;
344 344
345 DBGME(DEBUG_STATUS, printf("Sysace::wedges started for %p\n", sc)); 345 DBGME(DEBUG_STATUS, printf("Sysace::wedges started for %p\n", sc));
346 346
347 /* Discover wedges on this disk. */ 347 /* Discover wedges on this disk. */
348 dkwedge_autodiscover = 1; 348 dkwedge_autodiscover = 1;
349 dkwedge_discover(&sc->sc_dk); 349 dkwedge_discover(&sc->sc_dk);
350 350
351 config_pending_decr(sc->sc_dev); 351 config_pending_decr(sc->sc_dev);
352 352
353 DBGME(DEBUG_STATUS, printf("Sysace::thread done for %p\n", sc)); 353 DBGME(DEBUG_STATUS, printf("Sysace::thread done for %p\n", sc));
354 kthread_exit(0); 354 kthread_exit(0);
355} 355}
356 356
357static void 357static void
358sysace_thread(void *arg) 358sysace_thread(void *arg)
359{ 359{
360 struct ace_softc *sc = arg; 360 struct ace_softc *sc = arg;
361 struct buf *bp; 361 struct buf *bp;
362 int s, error; 362 int s, error;
363 363
364 DBGME(DEBUG_STATUS, printf("Sysace::thread started for %p\n", sc)); 364 DBGME(DEBUG_STATUS, printf("Sysace::thread started for %p\n", sc));
365 365
366 s = splbio(); 366 s = splbio();
367 aceattach(sc); 367 aceattach(sc);
368 splx(s); 368 splx(s);
369 369
370 error = kthread_create(PRI_NONE, 0 /* MPSAFE??? */, NULL, 370 error = kthread_create(PRI_NONE, 0 /* MPSAFE??? */, NULL,
371 sysace_wedges, sc, NULL, "%s.wedges", device_xname(sc->sc_dev)); 371 sysace_wedges, sc, NULL, "%s.wedges", device_xname(sc->sc_dev));
372 if (error) 372 if (error)
373 aprint_error_dev(sc->sc_dev, "wedges: unable to create " 373 aprint_error_dev(sc->sc_dev, "wedges: unable to create "
374 "kernel thread: error %d\n", error); 374 "kernel thread: error %d\n", error);
375 375
376 DBGME(DEBUG_STATUS, 376 DBGME(DEBUG_STATUS,
377 printf("Sysace::thread service active for %p\n", sc)); 377 printf("Sysace::thread service active for %p\n", sc));
378 378
379 s = splbio(); 379 s = splbio();
380 for (;;) { 380 for (;;) {
381 /* Get next I/O request, wait if necessary */ 381 /* Get next I/O request, wait if necessary */
382 if ((sc->ch_flags & (ATACH_TH_RESET | ATACH_SHUTDOWN)) == 0 && 382 if ((sc->ch_flags & (ATACH_TH_RESET | ATACH_SHUTDOWN)) == 0 &&
383 (sc->active_xfer == NULL)) { 383 (sc->active_xfer == NULL)) {
384 sc->ch_flags &= ~ATACH_TH_RUN; 384 sc->ch_flags &= ~ATACH_TH_RUN;
385 (void) tsleep(&sc->ch_thread, PRIBIO, "aceth", 0); 385 (void) tsleep(&sc->ch_thread, PRIBIO, "aceth", 0);
386 sc->ch_flags |= ATACH_TH_RUN; 386 sc->ch_flags |= ATACH_TH_RUN;
387 } 387 }
388 if (sc->ch_flags & ATACH_SHUTDOWN) 388 if (sc->ch_flags & ATACH_SHUTDOWN)
389 break; 389 break;
390 bp = sc->active_xfer; 390 bp = sc->active_xfer;
391 sc->active_xfer = NULL; 391 sc->active_xfer = NULL;
392 if (bp != NULL) { 392 if (bp != NULL) {
393 size_t sz, bnow; 393 size_t sz, bnow;
394 394
395 DBGME(DEBUG_XFERS, 395 DBGME(DEBUG_XFERS,
396 printf("Sysace::task %p %p %x %p %qx %d (%zd)\n", 396 printf("Sysace::task %p %p %x %p %qx %d (%zd)\n",
397 sc, bp, sc->sc_bio.flags, sc->sc_bio.databuf, 397 sc, bp, sc->sc_bio.flags, sc->sc_bio.databuf,
398 sc->sc_bio.blkno, sc->sc_bio.nbytes, 398 sc->sc_bio.blkno, sc->sc_bio.nbytes,
399 sc->sc_bio.nblks)); 399 sc->sc_bio.nblks));
400 400
401 sc->sc_bio.error = 0; 401 sc->sc_bio.error = 0;
402 for (; sc->sc_bio.nblks > 0;) { 402 for (; sc->sc_bio.nblks > 0;) {
403 403
404 bnow = sc->sc_bio.nblks; 404 bnow = sc->sc_bio.nblks;
405 if (sc->sc_bio.flags & ATA_SINGLE) 405 if (sc->sc_bio.flags & ATA_SINGLE)
406 bnow = 1; 406 bnow = 1;
407 407
408 if (sc->sc_bio.flags & ATA_READ) { 408 if (sc->sc_bio.flags & ATA_READ) {
409 sc->sc_bio.error = 409 sc->sc_bio.error =
410 sysace_read_at(sc, 410 sysace_read_at(sc,
411 sc->sc_bio.blkno, 411 sc->sc_bio.blkno,
412 sc->sc_bio.databuf, bnow, &sz); 412 sc->sc_bio.databuf, bnow, &sz);
413 } else { 413 } else {
414 sc->sc_bio.error = 414 sc->sc_bio.error =
415 sysace_write_at(sc, 415 sysace_write_at(sc,
416 sc->sc_bio.blkno, 416 sc->sc_bio.blkno,
417 sc->sc_bio.databuf, bnow, &sz); 417 sc->sc_bio.databuf, bnow, &sz);
418 } 418 }
419 419
420 if (FAILED(sc->sc_bio.error)) 420 if (FAILED(sc->sc_bio.error))
421 break; 421 break;
422 422
423 sc->sc_bio.blkno += sz; /* in blocks */ 423 sc->sc_bio.blkno += sz; /* in blocks */
424 sc->sc_bio.nblks -= sz; 424 sc->sc_bio.nblks -= sz;
425 sc->sc_bio.blkdone += sz; 425 sc->sc_bio.blkdone += sz;
426 sz = sz << CF_SECBITS; /* in bytes */ 426 sz = sz << CF_SECBITS; /* in bytes */
427 sc->sc_bio.databuf += sz; 427 sc->sc_bio.databuf += sz;
428 sc->sc_bio.nbytes -= sz; 428 sc->sc_bio.nbytes -= sz;
429 } 429 }
430 430
431 acedone(sc); 431 acedone(sc);
432 } 432 }
433 } 433 }
434 434
435 splx(s); 435 splx(s);
436 sc->ch_thread = NULL; 436 sc->ch_thread = NULL;
437 wakeup(&sc->ch_flags); 437 wakeup(&sc->ch_flags);
438 kthread_exit(0); 438 kthread_exit(0);
439} 439}
440 440
441/* Worker routines 441/* Worker routines
442 */ 442 */
443#if _DEBUG 443#if _DEBUG
444typedef char *NAME; 444typedef char *NAME;
445typedef struct _REGDESC { 445typedef struct _REGDESC {
446 NAME RegisterName; 446 NAME RegisterName;
447 NAME BitNames[32]; 447 NAME BitNames[32];
448} REGDESC, *PREGDESC; 448} REGDESC, *PREGDESC;
449 449
450static void 450static void
451SysacePrintRegister(const REGDESC *Desc, uint32_t Value) 451SysacePrintRegister(const REGDESC *Desc, uint32_t Value)
452{ 452{
453 int i; 453 int i;
454 454
455 printf("\t%s %x =", Desc->RegisterName, Value); 455 printf("\t%s %x =", Desc->RegisterName, Value);
456 for (i = 31; i >= 0; i--) { 456 for (i = 31; i >= 0; i--) {
457 if (Value & (1 << i)) 457 if (Value & (1 << i))
458 printf(" %s", 458 printf(" %s",
459 (Desc->BitNames[i]) ? Desc->BitNames[i] : "?"); 459 (Desc->BitNames[i]) ? Desc->BitNames[i] : "?");
460 } 460 }
461 printf("\n"); 461 printf("\n");
462} 462}
463 463
464static uint32_t 464static uint32_t
465SysaceDumpRegisters(struct _Sac *regs) 465SysaceDumpRegisters(struct _Sac *regs)
466{ 466{
467 const REGDESC Control_Names = { 467 const REGDESC Control_Names = {
468 "Control", 468 "Control",
469 { 469 {
470 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 470 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
471 "RST", /* 0x00010000 */ 471 "RST", /* 0x00010000 */
472 "BUS8", /* 0x00020000 */ 472 "BUS8", /* 0x00020000 */
473 "BUS16", /* 0x00040000 */ 473 "BUS16", /* 0x00040000 */
474 "BUS32", /* 0x00080000 */ 474 "BUS32", /* 0x00080000 */
475 "IRQ", /* 0x00100000 */ 475 "IRQ", /* 0x00100000 */
476 "BRDY", /* 0x00200000 */ 476 "BRDY", /* 0x00200000 */
477 "IMSK0", /* 0x00400000 */ 477 "IMSK0", /* 0x00400000 */
478 "IMSK1", /* 0x00800000 */ 478 "IMSK1", /* 0x00800000 */
479 "TD0", /* 0x0f000000 */ 479 "TD0", /* 0x0f000000 */
480 "TD1", /* 0x0f000000 */ 480 "TD1", /* 0x0f000000 */
481 "TD2", /* 0x0f000000 */ 481 "TD2", /* 0x0f000000 */
482 "TD3", /* 0x0f000000 */ 482 "TD3", /* 0x0f000000 */
483 "BUFW8", /* 0x10000000 */ 483 "BUFW8", /* 0x10000000 */
484 "BUFW16", /* 0x20000000 */ 484 "BUFW16", /* 0x20000000 */
485 "BUFW32", /* 0x40000000 */ 485 "BUFW32", /* 0x40000000 */
486 "DEBUG" /* 0x80000000 */ 486 "DEBUG" /* 0x80000000 */
487 } 487 }
488 }; 488 };
489 489
490 const REGDESC STATUS_Names = { 490 const REGDESC STATUS_Names = {
491 "STATUS", 491 "STATUS",
492 { 492 {
493 "CFGLOCK", /* 0x00000001 */ 493 "CFGLOCK", /* 0x00000001 */
494 "MPULOCK", /* 0x00000002 */ 494 "MPULOCK", /* 0x00000002 */
495 "CFGERROR", /* 0x00000004 */ 495 "CFGERROR", /* 0x00000004 */
496 "CFCERROR", /* 0x00000008 */ 496 "CFCERROR", /* 0x00000008 */
497 "CFDETECT", /* 0x00000010 */ 497 "CFDETECT", /* 0x00000010 */
498 "DATABUFRDY", /* 0x00000020 */ 498 "DATABUFRDY", /* 0x00000020 */
499 "DATABUFWRITE", /* 0x00000040 */ 499 "DATABUFWRITE", /* 0x00000040 */
500 "CFGDONE", /* 0x00000080 */ 500 "CFGDONE", /* 0x00000080 */
501 "RDYFORCFCMD", /* 0x00000100 */ 501 "RDYFORCFCMD", /* 0x00000100 */
502 "CFGMODEPIN", /* 0x00000200 */ 502 "CFGMODEPIN", /* 0x00000200 */
503 0,0,0, 503 0,0,0,
504 "CFGADDRPIN0", /* 0x0000e000 */ 504 "CFGADDRPIN0", /* 0x0000e000 */
505 "CFGADDRPIN1", /* 0x0000e000 */ 505 "CFGADDRPIN1", /* 0x0000e000 */
506 "CFGADDRPIN2", /* 0x0000e000 */ 506 "CFGADDRPIN2", /* 0x0000e000 */
507 0, 507 0,
508 "CFBSY", /* 0x00020000 */ 508 "CFBSY", /* 0x00020000 */
509 "CFRDY", /* 0x00040000 */ 509 "CFRDY", /* 0x00040000 */
510 "CFDWF", /* 0x00080000 */ 510 "CFDWF", /* 0x00080000 */
511 "CFDSC", /* 0x00100000 */ 511 "CFDSC", /* 0x00100000 */
512 "CFDRQ", /* 0x00200000 */ 512 "CFDRQ", /* 0x00200000 */
513 "CFCORR", /* 0x00400000 */ 513 "CFCORR", /* 0x00400000 */
514 "CFERR", /* 0x00800000 */ 514 "CFERR", /* 0x00800000 */
515 0, 515 0,
516 } 516 }
517 }; 517 };
518 518
519 const REGDESC ERRORREG_Names = { 519 const REGDESC ERRORREG_Names = {
520 "ERRORREG", 520 "ERRORREG",
521 { 521 {
522 "CARDRESETERR", /* 0x00000001 */ 522 "CARDRESETERR", /* 0x00000001 */
523 "CARDRDYERR", /* 0x00000002 */ 523 "CARDRDYERR", /* 0x00000002 */
524 "CARDREADERR", /* 0x00000004 */ 524 "CARDREADERR", /* 0x00000004 */
525 "CARDWRITEERR", /* 0x00000008 */ 525 "CARDWRITEERR", /* 0x00000008 */
526 "SECTORRDYERR", /* 0x00000010 */ 526 "SECTORRDYERR", /* 0x00000010 */
527 "CFGADDRERR", /* 0x00000020 */ 527 "CFGADDRERR", /* 0x00000020 */
528 "CFGFAILED", /* 0x00000040 */ 528 "CFGFAILED", /* 0x00000040 */
529 "CFGREADERR", /* 0x00000080 */ 529 "CFGREADERR", /* 0x00000080 */
530 "CFGINSTRERR", /* 0x00000100 */ 530 "CFGINSTRERR", /* 0x00000100 */
531 "CFGINITERR", /* 0x00000200 */ 531 "CFGINITERR", /* 0x00000200 */
532 0, 532 0,
533 "CFBBK", /* 0x00000800 */ 533 "CFBBK", /* 0x00000800 */
534 "CFUNC", /* 0x00001000 */ 534 "CFUNC", /* 0x00001000 */
535 "CFIDNF", /* 0x00002000 */ 535 "CFIDNF", /* 0x00002000 */
536 "CFABORT", /* 0x00004000 */ 536 "CFABORT", /* 0x00004000 */
537 "CFAMNF", /* 0x00008000 */ 537 "CFAMNF", /* 0x00008000 */
538 0, 538 0,
539 } 539 }
540 }; 540 };
541 541
542 const NAME CommandNames[8] = { 542 const NAME CommandNames[8] = {
543 "0", /* 0x0000 */ 543 "0", /* 0x0000 */
544 "RESETMEMCARD", /* 0x0100 */ 544 "RESETMEMCARD", /* 0x0100 */
545 "IDENTIFYMEMCARD", /* 0x0200 */ 545 "IDENTIFYMEMCARD", /* 0x0200 */
546 "READMEMCARDDATA", /* 0x0300 */ 546 "READMEMCARDDATA", /* 0x0300 */
547 "WRITEMEMCARDDATA", /* 0x0400 */ 547 "WRITEMEMCARDDATA", /* 0x0400 */
548 "5", /* 0x0500 */ 548 "5", /* 0x0500 */
549 "ABORT", /* 0x0600 */ 549 "ABORT", /* 0x0600 */
550 "7" /* 0x0700 */ 550 "7" /* 0x0700 */
551 }; 551 };
552 552
553 const REGDESC CONTROLREG_Names = { 553 const REGDESC CONTROLREG_Names = {
554 "CONTROLREG", 554 "CONTROLREG",
555 { 555 {
556 "FORCELOCKREQ", /* 0x00000001 */ 556 "FORCELOCKREQ", /* 0x00000001 */
557 "LOCKREQ", /* 0x00000002 */ 557 "LOCKREQ", /* 0x00000002 */
558 "FORCECFGADDR", /* 0x00000004 */ 558 "FORCECFGADDR", /* 0x00000004 */
559 "FORCECFGMODE", /* 0x00000008 */ 559 "FORCECFGMODE", /* 0x00000008 */
560 "CFGMODE", /* 0x00000010 */ 560 "CFGMODE", /* 0x00000010 */
561 "CFGSTART", /* 0x00000020 */ 561 "CFGSTART", /* 0x00000020 */
562 "CFGSEL_MPU", /* 0x00000040 */ 562 "CFGSEL_MPU", /* 0x00000040 */
563 "CFGRESET", /* 0x00000080 */ 563 "CFGRESET", /* 0x00000080 */
564 "DATABUFRDYIRQ",/* 0x00000100 */ 564 "DATABUFRDYIRQ",/* 0x00000100 */
565 "ERRORIRQ", /* 0x00000200 */ 565 "ERRORIRQ", /* 0x00000200 */
566 "CFGDONEIRQ", /* 0x00000400 */ 566 "CFGDONEIRQ", /* 0x00000400 */
567 "RESETIRQ", /* 0x00000800 */ 567 "RESETIRQ", /* 0x00000800 */
568 "CFGPROG", /* 0x00001000 */ 568 "CFGPROG", /* 0x00001000 */
569 "CFGADDR_B0", /* 0x00002000 */ 569 "CFGADDR_B0", /* 0x00002000 */
570 "CFGADDR_B1", /* 0x00004000 */ 570 "CFGADDR_B1", /* 0x00004000 */
571 "CFGADDR_B2", /* 0x00008000 */ 571 "CFGADDR_B2", /* 0x00008000 */
572 0, 572 0,
573 } 573 }
574 }; 574 };
575 575
576 const REGDESC FATSTATREG_Names = { 576 const REGDESC FATSTATREG_Names = {
577 "FATSTATREG", 577 "FATSTATREG",
578 { 578 {
579 "MBRVALID", /* 0x00000001 */ 579 "MBRVALID", /* 0x00000001 */
580 "PBRVALID", /* 0x00000002 */ 580 "PBRVALID", /* 0x00000002 */
581 "MBRFAT12", /* 0x00000004 */ 581 "MBRFAT12", /* 0x00000004 */
582 "PBRFAT12", /* 0x00000008 */ 582 "PBRFAT12", /* 0x00000008 */
583 "MBRFAT16", /* 0x00000010 */ 583 "MBRFAT16", /* 0x00000010 */
584 "PBRFAT16", /* 0x00000020 */ 584 "PBRFAT16", /* 0x00000020 */
585 "CALCFAT12", /* 0x00000040 */ 585 "CALCFAT12", /* 0x00000040 */
586 "CALCFAT16", /* 0x00000080 */ 586 "CALCFAT16", /* 0x00000080 */
587 0, 587 0,
588 } 588 }
589 }; 589 };
590 590
591 printf("Sysace@%p:\n", regs); 591 printf("Sysace@%p:\n", regs);
592 printf("\tTag %x\n", regs->Tag); 592 printf("\tTag %x\n", regs->Tag);
593 SysacePrintRegister(&Control_Names, regs->Control); 593 SysacePrintRegister(&Control_Names, regs->Control);
594 printf("\tBUSMODEREG %x\n", regs->BUSMODEREG); 594 printf("\tBUSMODEREG %x\n", regs->BUSMODEREG);
595 SysacePrintRegister(&STATUS_Names, regs->STATUS); 595 SysacePrintRegister(&STATUS_Names, regs->STATUS);
596 SysacePrintRegister(&ERRORREG_Names, regs->ERRORREG); 596 SysacePrintRegister(&ERRORREG_Names, regs->ERRORREG);
597 printf("\tCFGLBAREG %x\n", regs->CFGLBAREG); 597 printf("\tCFGLBAREG %x\n", regs->CFGLBAREG);
598 printf("\tMPULBAREG %x\n", regs->MPULBAREG); 598 printf("\tMPULBAREG %x\n", regs->MPULBAREG);
599 printf("\tVERSIONREG %x\n", regs->VERSIONREG); 599 printf("\tVERSIONREG %x\n", regs->VERSIONREG);
600 printf("\tSECCNTCMDREG %x = %s cnt=%d\n", regs->SECCNTCMDREG, 600 printf("\tSECCNTCMDREG %x = %s cnt=%d\n", regs->SECCNTCMDREG,
601 CommandNames[(regs->SECCNTCMDREG >> 8) & 7], 601 CommandNames[(regs->SECCNTCMDREG >> 8) & 7],
602 regs->SECCNTCMDREG & SAC_SECCCNT); 602 regs->SECCNTCMDREG & SAC_SECCCNT);
603 SysacePrintRegister(&CONTROLREG_Names, regs->CONTROLREG); 603 SysacePrintRegister(&CONTROLREG_Names, regs->CONTROLREG);
604 SysacePrintRegister(&FATSTATREG_Names, regs->FATSTATREG); 604 SysacePrintRegister(&FATSTATREG_Names, regs->FATSTATREG);
605 605
606 return 1; 606 return 1;
607} 607}
608 608
609#else 609#else
610#define SysaceDumpRegisters(_c_) 610#define SysaceDumpRegisters(_c_)
611#endif 611#endif
612 612
613/* 613/*
614 * Reset the device and the interface 614 * Reset the device and the interface
615 */ 615 */
616static int 616static int
617sysace_reset(struct ace_softc *sc) 617sysace_reset(struct ace_softc *sc)
618{ 618{
619 struct _Sac *regs = sc->sc_dr; 619 struct _Sac *regs = sc->sc_dr;
620 620
621 DBGME(DEBUG_FUNCS, printf("Sysace::Reset %p\n", sc)); 621 DBGME(DEBUG_FUNCS, printf("Sysace::Reset %p\n", sc));
622 622
623 /* 16bit etc etc */ 623 /* 16bit etc etc */
624 uint32_t BusMode, Control; 624 uint32_t BusMode, Control;
625 625
626 /* reset our interface */ 626 /* reset our interface */
627 regs->Control = SAC_RST; 627 regs->Control = SAC_RST;
628 DELAY(200); 628 DELAY(200);
629 629
630 /* repeat on both byte lanes */ 630 /* repeat on both byte lanes */
631 regs->BUSMODEREG = SAC_MODE16 | (SAC_MODE16 << 8); 631 regs->BUSMODEREG = SAC_MODE16 | (SAC_MODE16 << 8);
632 DELAY(1); 632 DELAY(1);
633 633
634 /* check what our interface does and what the SysACE expects */ 634 /* check what our interface does and what the SysACE expects */
635 Control = regs->Control; 635 Control = regs->Control;
636 BusMode = regs->BUSMODEREG; 636 BusMode = regs->BUSMODEREG;
637 637
638 /* get them to agree */ 638 /* get them to agree */
639 if (BusMode & SAC_MODE16) { 639 if (BusMode & SAC_MODE16) {
640 regs->Control = Control | SAC_BUS16; 640 regs->Control = Control | SAC_BUS16;
641 regs->Control = regs->Control & ~SAC_BUS8; 641 regs->Control = regs->Control & ~SAC_BUS8;
642 } else { 642 } else {
643 regs->Control = Control | SAC_BUS8; 643 regs->Control = Control | SAC_BUS8;
644 regs->Control = regs->Control & ~SAC_BUS16; 644 regs->Control = regs->Control & ~SAC_BUS16;
645 } 645 }
646 646
647 /* check that it worked */ 647 /* check that it worked */
648 BusMode = regs->BUSMODEREG; 648 BusMode = regs->BUSMODEREG;
649 Control = regs->Control; 649 Control = regs->Control;
650 650
651 if (((BusMode & SAC_MODE16) == 0) && ((Control & SAC_BUS8) == 0)) 651 if (((BusMode & SAC_MODE16) == 0) && ((Control & SAC_BUS8) == 0))
652 return EDOOFUS; 652 return EDOOFUS;
653 if (((BusMode & SAC_MODE16) > 0) && ((Control & SAC_BUS16) == 0)) 653 if (((BusMode & SAC_MODE16) > 0) && ((Control & SAC_BUS16) == 0))
654 return EDOOFUS; 654 return EDOOFUS;
655 655
656 /* interrupts off for now */ 656 /* interrupts off for now */
657 regs->Control &= ~SAC_INTMASK; 657 regs->Control &= ~SAC_INTMASK;
658#define SAC_INTERRUPTS (SAC_DATABUFRDYIRQ | SAC_ERRORIRQ /* | SAC_CFGDONEIRQ */) 658#define SAC_INTERRUPTS (SAC_DATABUFRDYIRQ | SAC_ERRORIRQ /* | SAC_CFGDONEIRQ */)
659 Control = regs->CONTROLREG; 659 Control = regs->CONTROLREG;
660 Control = (Control & ~SAC_INTERRUPTS) | SAC_RESETIRQ | SAC_FORCECFGMODE; 660 Control = (Control & ~SAC_INTERRUPTS) | SAC_RESETIRQ | SAC_FORCECFGMODE;
661 regs->CONTROLREG = Control; 661 regs->CONTROLREG = Control;
662 regs->CONTROLREG = Control & ~SAC_RESETIRQ; 662 regs->CONTROLREG = Control & ~SAC_RESETIRQ;
663 663
664 /* no command */ 664 /* no command */
665 regs->MPULBAREG = 0; 665 regs->MPULBAREG = 0;
666 666
667 return 0; 667 return 0;
668} 668}
669 669
670/* 670/*
671 * Take control of the ACE datapath 671 * Take control of the ACE datapath
672 */ 672 */
673static int 673static int
674sysace_lock_registers(struct ace_softc *sc) 674sysace_lock_registers(struct ace_softc *sc)
675{ 675{
676 uint32_t Status; 676 uint32_t Status;
677 int i; 677 int i;
678 678
679 DBGME(DEBUG_FUNCS, printf("Sysace::Lock %p\n", sc)); 679 DBGME(DEBUG_FUNCS, printf("Sysace::Lock %p\n", sc));
680 680
681 /* 681 /*
682 * Locked already? 682 * Locked already?
683 */ 683 */
684 Status = sc->sc_dr->STATUS; 684 Status = sc->sc_dr->STATUS;
685 if (Status & SAC_MPULOCK) 685 if (Status & SAC_MPULOCK)
686 return TRUE; 686 return TRUE;
687 687
688 /* 688 /*
689 * Request lock 689 * Request lock
690 */ 690 */
691 sc->sc_dr->CONTROLREG |= SAC_LOCKREQ; 691 sc->sc_dr->CONTROLREG |= SAC_LOCKREQ;
692 692
693 /* 693 /*
694 * Spin a bit until we get it 694 * Spin a bit until we get it
695 */ 695 */
696 for (i = 0; i < 200; i++) { 696 for (i = 0; i < 200; i++) {
697 Status = sc->sc_dr->STATUS; 697 Status = sc->sc_dr->STATUS;
698 if (Status & SAC_MPULOCK) 698 if (Status & SAC_MPULOCK)
699 return TRUE; 699 return TRUE;
700 DELAY(100); 700 DELAY(100);
701 DBGME(DEBUG_FUNCS, 701 DBGME(DEBUG_FUNCS,
702 printf("Sysace::Lock loops.. (st=%x)\n",Status)); 702 printf("Sysace::Lock loops.. (st=%x)\n",Status));
703 } 703 }
704 704
705 /* 705 /*
706 * oopsie! 706 * oopsie!
707 */ 707 */
708 DBGME(DEBUG_ERRORS, printf("Sysace::Lock timeout (st=%x)\n",Status)); 708 DBGME(DEBUG_ERRORS, printf("Sysace::Lock timeout (st=%x)\n",Status));
709 SysaceDumpRegisters(sc->sc_dr); 709 SysaceDumpRegisters(sc->sc_dr);
710 return FALSE; 710 return FALSE;
711} 711}
712 712
713/* 713/*
714 * Release control of the ACE datapath 714 * Release control of the ACE datapath
715 */ 715 */
716static int 716static int
717sysace_unlock_registers(struct ace_softc *sc) 717sysace_unlock_registers(struct ace_softc *sc)
718{ 718{
719 uint32_t Status; 719 uint32_t Status;
720 int i; 720 int i;
721 721
722 DBGME(DEBUG_FUNCS, printf("Sysace::Unlock %p\n", sc)); 722 DBGME(DEBUG_FUNCS, printf("Sysace::Unlock %p\n", sc));
723 723
724 /* 724 /*
725 * Clear reset 725 * Clear reset
726 */ 726 */
727 sc->sc_dr->CONTROLREG &= ~SAC_CFGRESET; 727 sc->sc_dr->CONTROLREG &= ~SAC_CFGRESET;
728 728
729 /* 729 /*
730 * Unlocked already? 730 * Unlocked already?
731 */ 731 */
732 Status = sc->sc_dr->STATUS; 732 Status = sc->sc_dr->STATUS;
733 if ((Status & SAC_MPULOCK) == 0) 733 if ((Status & SAC_MPULOCK) == 0)
734 return TRUE; 734 return TRUE;
735 735
736 /* 736 /*
737 * Request unlock 737 * Request unlock
738 */ 738 */
739 sc->sc_dr->CONTROLREG &= ~SAC_LOCKREQ; 739 sc->sc_dr->CONTROLREG &= ~SAC_LOCKREQ;
740 740
741 /* 741 /*
742 * Spin a bit until we get it 742 * Spin a bit until we get it
743 */ 743 */
744 for (i = 0; i < 200; i++) { 744 for (i = 0; i < 200; i++) {
745 Status = sc->sc_dr->STATUS; 745 Status = sc->sc_dr->STATUS;
746 if ((Status & SAC_MPULOCK) == 0) 746 if ((Status & SAC_MPULOCK) == 0)
747 return TRUE; 747 return TRUE;
748 DELAY(100); 748 DELAY(100);
749 DBGME(DEBUG_FUNCS, 749 DBGME(DEBUG_FUNCS,
750 printf("Sysace::Unlock loops.. (st=%x)\n",Status)); 750 printf("Sysace::Unlock loops.. (st=%x)\n",Status));
751 } 751 }
752 752
753 /* 753 /*
754 * oopsie! 754 * oopsie!
755 */ 755 */
756 DBGME(DEBUG_ERRORS, printf("Sysace::Unlock timeout (st=%x)\n",Status)); 756 DBGME(DEBUG_ERRORS, printf("Sysace::Unlock timeout (st=%x)\n",Status));
757 SysaceDumpRegisters(sc->sc_dr); 757 SysaceDumpRegisters(sc->sc_dr);
758 return FALSE; 758 return FALSE;
759} 759}
760 760
761/* 761/*
762 * Check if the ACE is waiting for a comamnd 762 * Check if the ACE is waiting for a comamnd
763 */ 763 */
764#define sysace_ready(_s_) ((_s_)->sc_dr->STATUS & SAC_RDYFORCFCMD) 764#define sysace_ready(_s_) ((_s_)->sc_dr->STATUS & SAC_RDYFORCFCMD)
765 765
766/* 766/*
767 * Check if the ACE is executing a comamnd 767 * Check if the ACE is executing a comamnd
768 */ 768 */
769#define sysace_busy(_s_) ((_s_)->sc_dr->STATUS & SAC_CFBSY) 769#define sysace_busy(_s_) ((_s_)->sc_dr->STATUS & SAC_CFBSY)
770 770
771/* 771/*
772 * Turn on interrupts from the ACE 772 * Turn on interrupts from the ACE
773 */ 773 */
774#define sysace_inton(_s_) { \ 774#define sysace_inton(_s_) { \
775 (_s_)->sc_dr->CONTROLREG |= SAC_INTERRUPTS; \ 775 (_s_)->sc_dr->CONTROLREG |= SAC_INTERRUPTS; \
776 (_s_)->sc_dr->Control |= SAC_INTMASK; \ 776 (_s_)->sc_dr->Control |= SAC_INTMASK; \
777} 777}
778 778
779/* 779/*
780 * Turn off interrupts from the ACE 780 * Turn off interrupts from the ACE
781 */ 781 */
782#define sysace_intoff(_s_) { \ 782#define sysace_intoff(_s_) { \
783 (_s_)->sc_dr->CONTROLREG &= ~SAC_INTERRUPTS; \ 783 (_s_)->sc_dr->CONTROLREG &= ~SAC_INTERRUPTS; \
784 (_s_)->sc_dr->Control &= ~SAC_INTMASK; \ 784 (_s_)->sc_dr->Control &= ~SAC_INTMASK; \
785} 785}
786 786
787/* 787/*
788 * Start a command on the ACE, such as read or identify. 788 * Start a command on the ACE, such as read or identify.
789 */ 789 */
790static int 790static int
791sysace_start(struct ace_softc *sc, uint32_t Command, uint32_t Lba, 791sysace_start(struct ace_softc *sc, uint32_t Command, uint32_t Lba,
792 uint32_t nSectors) 792 uint32_t nSectors)
793{ 793{
794 794
795 /* 795 /*
796 * Lock it if not already 796 * Lock it if not already
797 */ 797 */
798 if (!sysace_lock_registers(sc)) { 798 if (!sysace_lock_registers(sc)) {
799 /* printed already */ 799 /* printed already */
800 return ETIMEDOUT; 800 return ETIMEDOUT;
801 } 801 }
802 802
803 /* 803 /*
804 * Is there a CF inserted 804 * Is there a CF inserted
805 */ 805 */
806 if (!(sc->sc_dr->STATUS & SAC_CFDETECT)) { 806 if (!(sc->sc_dr->STATUS & SAC_CFDETECT)) {
807 /* NB: Not a failure state */ 807 /* NB: Not a failure state */
808 DBGME(DEBUG_ERRORS, 808 DBGME(DEBUG_ERRORS,
809 printf("Sysace:: no media (st=%x)\n", sc->sc_dr->STATUS)); 809 printf("Sysace:: no media (st=%x)\n", sc->sc_dr->STATUS));
810 if (sc->sc_capacity) { 810 if (sc->sc_capacity) {
811 sc->media_has_changed = TRUE; 811 sc->media_has_changed = TRUE;
812 sc->sc_capacity = 0; 812 sc->sc_capacity = 0;
813 } 813 }
814 return ENODEV; 814 return ENODEV;
815 } 815 }
816 816
817 /* 817 /*
818 * Is it ready for a command 818 * Is it ready for a command
819 */ 819 */
820 if (!sysace_ready(sc)) { 820 if (!sysace_ready(sc)) {
821 DBGME(DEBUG_ERRORS, 821 DBGME(DEBUG_ERRORS,
822 printf("Sysace:: not ready (st=%x)\n", sc->sc_dr->STATUS)); 822 printf("Sysace:: not ready (st=%x)\n", sc->sc_dr->STATUS));
823 SysaceDumpRegisters(sc->sc_dr); 823 SysaceDumpRegisters(sc->sc_dr);
824 return EBUSY; 824 return EBUSY;
825 } 825 }
826 826
827 /* 827 /*
828 * sector number and command 828 * sector number and command
829 */ 829 */
830 sc->sc_dr->MPULBAREG = Lba; 830 sc->sc_dr->MPULBAREG = Lba;
831 sc->sc_dr->SECCNTCMDREG = 831 sc->sc_dr->SECCNTCMDREG =
832 (uint16_t)(Command | (nSectors & SAC_SECCCNT)); 832 (uint16_t)(Command | (nSectors & SAC_SECCCNT));
833 833
834 /* 834 /*
835 * re-route the chip 835 * re-route the chip
836 * NB: The "RESET" is actually not much of a misnomer. 836 * NB: The "RESET" is actually not much of a misnomer.
837 * The chip was designed for a one-shot execution at reset time, 837 * The chip was designed for a one-shot execution at reset time,
838 * namely loading the configuration data into the FPGA. So. 838 * namely loading the configuration data into the FPGA. So.
839 */ 839 */
840 sc->hw_busy = TRUE; 840 sc->hw_busy = TRUE;
841 sc->sc_dr->CONTROLREG |= SAC_CFGRESET; 841 sc->sc_dr->CONTROLREG |= SAC_CFGRESET;
842 return 0; 842 return 0;
843} 843}
844 844
845/* 845/*
846 * Identify the (size of the) CompactFlash card inserted in the slot. 846 * Identify the (size of the) CompactFlash card inserted in the slot.
847 */ 847 */
848static int 848static int
849sysace_identify(struct ace_softc *sc) 849sysace_identify(struct ace_softc *sc)
850{ 850{
851 PCFLASH_IDENTIFY Identify = &sc->sc_params; 851 PCFLASH_IDENTIFY Identify = &sc->sc_params;
852 uint32_t Status = 0; 852 uint32_t Status = 0;
853 int i, j, error; 853 int i, j, error;
854 854
855 DBGME(DEBUG_FUNCS, printf("Sysace::Identify %p\n", sc)); 855 DBGME(DEBUG_FUNCS, printf("Sysace::Identify %p\n", sc));
856 856
857 /* 857 /*
858 * Turn on interrupts before we start the command 858 * Turn on interrupts before we start the command
859 */ 859 */
860 sysace_inton(sc); /* BUGBUG we should add polling mode (for dump too) */ 860 sysace_inton(sc); /* BUGBUG we should add polling mode (for dump too) */
861 861
862 /* 862 /*
863 * This will invalidate the ACE's current sector data 863 * This will invalidate the ACE's current sector data
864 */ 864 */
865 sc->sc_capacity = 0; 865 sc->sc_capacity = 0;
866 866
867 /* 867 /*
868 * Get it going 868 * Get it going
869 */ 869 */
870 error = sysace_start(sc, SAC_CMD_IDENTIFYMEMCARD, 0, 1); 870 error = sysace_start(sc, SAC_CMD_IDENTIFYMEMCARD, 0, 1);
871 871
872 /* 872 /*
873 * Wait until its done 873 * Wait until its done
874 */ 874 */
875 if (!FAILED(error)) { 875 if (!FAILED(error)) {
876 876
877 /* Might be called during autoconf, no interrupts */ 877 /* Might be called during autoconf, no interrupts */
878 if (cold) { 878 if (cold) {
879 do { 879 do {
880 DELAY(10); 880 DELAY(10);
881 Status = sc->sc_dr->STATUS; 881 Status = sc->sc_dr->STATUS;
882 } while ((Status & 882 } while ((Status &
883 (SAC_DATABUFRDY|SAC_CFCERROR|SAC_CFGERROR)) == 0); 883 (SAC_DATABUFRDY|SAC_CFCERROR|SAC_CFGERROR)) == 0);
884 } else { 884 } else {
885 while (sc->hw_busy) { 885 while (sc->hw_busy) {
886 DBGME(DEBUG_FUNCS, 886 DBGME(DEBUG_FUNCS,
887 printf("Sysace:: cwait.. (st=%x)" 887 printf("Sysace:: cwait.. (st=%x)"
888 " sizeof=%d\n", 888 " sizeof=%d\n",
889 sc->sc_dr->STATUS, sizeof(*Identify))); 889 sc->sc_dr->STATUS, sizeof(*Identify)));
890 error = tsleep(&sc->media_has_changed, PRIBIO, 890 error = tsleep(&sc->media_has_changed, PRIBIO,
891 "aceidfy", 0); 891 "aceidfy", 0);
892 } 892 }
893 } 893 }
894 894
895 /* 895 /*
896 * Did it work? 896 * Did it work?
897 */ 897 */
898 Status = sc->sc_dr->STATUS; 898 Status = sc->sc_dr->STATUS;
899 899
900 if (Status & SAC_DATABUFRDY) { 900 if (Status & SAC_DATABUFRDY) {
901 901
902 /* 902 /*
903 * Yes, pull out all the data. 903 * Yes, pull out all the data.
904 * NB: Until we do so the chip will not be ready for 904 * NB: Until we do so the chip will not be ready for
905 * another command 905 * another command
906 */ 906 */
907 for (i = 0; i < sizeof(*Identify); i += 4) { 907 for (i = 0; i < sizeof(*Identify); i += 4) {
908 908
909 /* 909 /*
910 * Verify the (32-bytes) FIFO has reloaded 910 * Verify the (32-bytes) FIFO has reloaded
911 */ 911 */
912 for (j = 0; j < 10; j++) { 912 for (j = 0; j < 10; j++) {
913 Status = sc->sc_dr->STATUS; 913 Status = sc->sc_dr->STATUS;
914 if (Status & SAC_DATABUFRDY) 914 if (Status & SAC_DATABUFRDY)
915 break; 915 break;
916 DELAY(10); 916 DELAY(10);
917 } 917 }
918 if (Status & SAC_DATABUFRDY) { 918 if (Status & SAC_DATABUFRDY) {
919 uint32_t Data32; 919 uint32_t Data32;
920 920
921 /* 921 /*
922 * This pulls two 16-bit words out of 922 * This pulls two 16-bit words out of
923 * the FIFO. 923 * the FIFO.
924 * They are ordered in LE. 924 * They are ordered in LE.
925 * NB: Yes this is different from 925 * NB: Yes this is different from
926 * regular data accesses 926 * regular data accesses
927 */ 927 */
928 Data32 = sc->sc_dr->DATABUFREG[0]; 928 Data32 = sc->sc_dr->DATABUFREG[0];
929#if _BYTE_ORDER == _LITTLE_ENDIAN 929#if _BYTE_ORDER == _LITTLE_ENDIAN
930 /* all is fine */ 930 /* all is fine */
931#else 931#else
932 Data32 = 932 Data32 =
933 (Data32 >> 16) | (Data32 << 16); 933 (Data32 >> 16) | (Data32 << 16);
934#endif 934#endif
935 memcpy(((char *)Identify) + i, 935 memcpy(((char *)Identify) + i,
936 &Data32, 4); 936 &Data32, 4);
937 } else { 937 } else {
938 /* 938 /*
939 * Ooops, what's going on here? 939 * Ooops, what's going on here?
940 */ 940 */
941 DBGME(DEBUG_ERRORS, 941 DBGME(DEBUG_ERRORS,
942 printf("Sysace::!DATABUFRDY %x\n", 942 printf("Sysace::!DATABUFRDY %x\n",
943 Status)); 943 Status));
944 error = EIO; 944 error = EIO;
945 break; 945 break;
946 } 946 }
947 } 947 }
948 948
949 /* 949 /*
950 * Make sure we did ok and pick up the relevant info 950 * Make sure we did ok and pick up the relevant info
951 */ 951 */
952 if (Status & SAC_DATABUFRDY) { 952 if (Status & SAC_DATABUFRDY) {
953 DBGME(DEBUG_XFERS, 953 DBGME(DEBUG_XFERS,
954 device_printf(sc->sc_dev, 954 device_printf(sc->sc_dev,
955 "model: %.40s/%.20s\n", 955 "model: %.40s/%.20s\n",
956 Identify->ModelNumber, 956 Identify->ModelNumber,
957 Identify->SerialNumber)); 957 Identify->SerialNumber));
958 if (Identify->Signature == CFLASH_SIGNATURE) { 958 if (Identify->Signature == CFLASH_SIGNATURE) {
959 DBGME(DEBUG_PROBE, 959 DBGME(DEBUG_PROBE,
960 printf("Sysace::Card is" 960 printf("Sysace::Card is"
961 " %.40s::%.20s\n", 961 " %.40s::%.20s\n",
962 Identify->ModelNumber, 962 Identify->ModelNumber,
963 Identify->SerialNumber)); 963 Identify->SerialNumber));
964 964
965 sc->sc_capacity = 965 sc->sc_capacity =
966 (Identify->SectorsPerCard[0] << 16) 966 (Identify->SectorsPerCard[0] << 16)
967 | Identify->SectorsPerCard[1]; 967 | Identify->SectorsPerCard[1];
968 DBGME(DEBUG_PROBE, 968 DBGME(DEBUG_PROBE,
969 printf("Sysace::sc_capacity x%qx\n", 969 printf("Sysace::sc_capacity x%qx\n",
970 sc->sc_capacity)); 970 sc->sc_capacity));
971 ace_set_geometry(sc); 971 ace_set_geometry(sc);
972 } else { 972 } else {
973 DBGME(DEBUG_ERRORS, 973 DBGME(DEBUG_ERRORS,
974 printf("Sysace::Bad card signature?" 974 printf("Sysace::Bad card signature?"
975 " %x != %x\n", 975 " %x != %x\n",
976 Identify->Signature, 976 Identify->Signature,
977 CFLASH_SIGNATURE)); 977 CFLASH_SIGNATURE));
978 sc->sc_capacity = 0; 978 sc->sc_capacity = 0;
979 error = ENXIO; 979 error = ENXIO;
980 } 980 }
981 } else { 981 } else {
982 error = ETIMEDOUT; 982 error = ETIMEDOUT;
983 } 983 }
984 } else { 984 } else {
985 /* 985 /*
986 * No, it did not work. Maybe there is no card inserted 986 * No, it did not work. Maybe there is no card inserted
987 */ 987 */
988 DBGME(DEBUG_ERRORS, 988 DBGME(DEBUG_ERRORS,
989 printf("Sysace::Identify failed," 989 printf("Sysace::Identify failed,"
990 " missing CFLASH card?\n")); 990 " missing CFLASH card?\n"));
991 SysaceDumpRegisters(sc->sc_dr); 991 SysaceDumpRegisters(sc->sc_dr);
992 /* BUGBUG Fix the error code accordingly */ 992 /* BUGBUG Fix the error code accordingly */
993 error = ETIMEDOUT; 993 error = ETIMEDOUT;
994 } 994 }
995 } 995 }
996 996
997 /* remember this jic */ 997 /* remember this jic */
998 sc->sc_bio.r_error = Status; 998 sc->sc_bio.r_error = Status;
999 999
1000 /* Free the ACE for the JTAG, just in case */ 1000 /* Free the ACE for the JTAG, just in case */
1001 sysace_unlock_registers(sc); 1001 sysace_unlock_registers(sc);
1002 1002
1003 /* 1003 /*
1004 * Done 1004 * Done
1005 */ 1005 */
1006 return error; 1006 return error;
1007} 1007}
1008 1008
1009/* 1009/*
1010 * Common code for read&write argument validation 1010 * Common code for read&write argument validation
1011 */ 1011 */
1012static int 1012static int
1013sysace_validate(struct ace_softc *sc, daddr_t start, size_t *pSize) 1013sysace_validate(struct ace_softc *sc, daddr_t start, size_t *pSize)
1014{ 1014{
1015 daddr_t Size; 1015 daddr_t Size;
1016 1016
1017 /* 1017 /*
1018 * Verify that we know the media size 1018 * Verify that we know the media size
1019 */ 1019 */
1020 if (sc->sc_capacity == 0) { 1020 if (sc->sc_capacity == 0) {
1021 int error = sysace_identify(sc); 1021 int error = sysace_identify(sc);
1022 if (FAILED(error)) 1022 if (FAILED(error))
1023 return error; 1023 return error;
1024 } 1024 }
1025 1025
1026 /* 1026 /*
1027 * Validate args 1027 * Validate args
1028 */ 1028 */
1029 if (start >= sc->sc_capacity) { 1029 if (start >= sc->sc_capacity) {
1030 *pSize = 0; 1030 *pSize = 0;
1031 DBGME(DEBUG_ERRORS, 1031 DBGME(DEBUG_ERRORS,
1032 printf("Sysace::ValidateArg(%qx) EOF\n", start)); 1032 printf("Sysace::ValidateArg(%qx) EOF\n", start));
1033 return E2BIG; 1033 return E2BIG;
1034 } 1034 }
1035 1035
1036 /* 1036 /*
1037 * Adjust size if necessary 1037 * Adjust size if necessary
1038 */ 1038 */
1039 Size = start + *pSize; 1039 Size = start + *pSize;
1040 if (Size > sc->sc_capacity) { 1040 if (Size > sc->sc_capacity) {
1041 /* 1041 /*
1042 * At most this many sectors 1042 * At most this many sectors
1043 */ 1043 */
1044 Size = sc->sc_capacity - start; 1044 Size = sc->sc_capacity - start;
1045 *pSize = (size_t)Size; 1045 *pSize = (size_t)Size;
1046 } 1046 }
1047 1047
1048 DBGME(DEBUG_FUNCS, 1048 DBGME(DEBUG_FUNCS,
1049 printf("Sysace::Validate %qx %zd\n", start, *pSize)); 1049 printf("Sysace::Validate %qx %zd\n", start, *pSize));
1050 return 0; 1050 return 0;
1051} 1051}
1052 1052
1053/* Read SIZE bytes from sysace device, at offset Position 1053/* Read SIZE bytes from sysace device, at offset Position
1054 */ 1054 */
1055uint32_t ace_maxatatime = 255; 1055uint32_t ace_maxatatime = 255;
1056#define MAXATATIME ace_maxatatime //255 /* BUGBUG test me on real hardware!! */ 1056#define MAXATATIME ace_maxatatime //255 /* BUGBUG test me on real hardware!! */
1057 1057
1058static int 1058static int
1059sysace_read_at(struct ace_softc *sc, daddr_t start_sector, char *buffer, 1059sysace_read_at(struct ace_softc *sc, daddr_t start_sector, char *buffer,
1060 size_t nblocks, size_t *pSizeRead) 1060 size_t nblocks, size_t *pSizeRead)
1061{ 1061{
1062 int error; 1062 int error;
1063 uint32_t BlocksThisTime; 1063 uint32_t BlocksThisTime;
1064 uint32_t Status = 0, SizeRead = 0; 1064 uint32_t Status = 0, SizeRead = 0;
1065 uint32_t i, j; 1065 uint32_t i, j;
1066 1066
1067 DBGME(DEBUG_XFERS|DEBUG_READS, 1067 DBGME(DEBUG_XFERS|DEBUG_READS,
1068 printf("SysaceReadAt(%p %qx %p %zd %p)\n", 1068 printf("SysaceReadAt(%p %qx %p %zd %p)\n",
1069 sc, start_sector, buffer, nblocks, pSizeRead)); 1069 sc, start_sector, buffer, nblocks, pSizeRead));
1070 1070
1071 /* 1071 /*
1072 * Validate & trim arguments 1072 * Validate & trim arguments
1073 */ 1073 */
1074 error = sysace_validate(sc, start_sector, &nblocks); 1074 error = sysace_validate(sc, start_sector, &nblocks);
1075 1075
1076 /* 1076 /*
1077 * Repeat until we are done or error 1077 * Repeat until we are done or error
1078 */ 1078 */
1079 while (error == 0) { 1079 while (error == 0) {
1080 1080
1081 /* 1081 /*
1082 * .. one bunch of sectors at a time 1082 * .. one bunch of sectors at a time
1083 */ 1083 */
1084 BlocksThisTime = nblocks; 1084 BlocksThisTime = nblocks;
1085 if (BlocksThisTime > MAXATATIME) 1085 if (BlocksThisTime > MAXATATIME)
1086 BlocksThisTime = MAXATATIME; 1086 BlocksThisTime = MAXATATIME;
1087 1087
1088 /* 1088 /*
1089 * Yes, start a sector read 1089 * Yes, start a sector read
1090 */ 1090 */
1091 sysace_inton(sc); 1091 sysace_inton(sc);
1092 error = sysace_start(sc, 1092 error = sysace_start(sc,
1093 SAC_CMD_READMEMCARDDATA, 1093 SAC_CMD_READMEMCARDDATA,
1094 (uint32_t)start_sector, /* BUGBUG trims here, no warn. */ 1094 (uint32_t)start_sector, /* BUGBUG trims here, no warn. */
1095 BlocksThisTime); 1095 BlocksThisTime);
1096 /* 1096 /*
1097 * And wait until done, if ok 1097 * And wait until done, if ok
1098 */ 1098 */
1099 if (!FAILED(error)) { 1099 if (!FAILED(error)) {
1100 start_sector += BlocksThisTime; 1100 start_sector += BlocksThisTime;
1101 /* Might be called during autoconf, no interrupts */ 1101 /* Might be called during autoconf, no interrupts */
1102 /* BUGBUG timeouts! */ 1102 /* BUGBUG timeouts! */
1103 if (cold) { 1103 if (cold) {
1104 do { 1104 do {
1105 DELAY(10); 1105 DELAY(10);
1106 Status = sc->sc_dr->STATUS; 1106 Status = sc->sc_dr->STATUS;
1107 } while ((Status & 1107 } while ((Status &
1108 (SAC_DATABUFRDY|SAC_CFCERROR|SAC_CFGERROR)) 1108 (SAC_DATABUFRDY|SAC_CFCERROR|SAC_CFGERROR))
1109 == 0); 1109 == 0);
1110 } else { 1110 } else {
1111 while (sc->hw_busy) { 1111 while (sc->hw_busy) {
1112 error = tsleep(&sc->media_has_changed, 1112 error = tsleep(&sc->media_has_changed,
1113 PRIBIO, "aceread", 0); 1113 PRIBIO, "aceread", 0);
1114 } 1114 }
1115 } 1115 }
1116 } 1116 }
1117 1117
1118 /* 1118 /*
1119 * Are we doing ok 1119 * Are we doing ok
1120 */ 1120 */
1121 if (!FAILED(error)) { 1121 if (!FAILED(error)) {
1122 1122
1123 /* 1123 /*
1124 * Get the data out of the ACE 1124 * Get the data out of the ACE
1125 */ 1125 */
1126 for (i = 0; i < (BlocksThisTime << CF_SECBITS); 1126 for (i = 0; i < (BlocksThisTime << CF_SECBITS);
1127 i += 4) { 1127 i += 4) {
1128 1128
1129 /* 1129 /*
1130 * Make sure the FIFO is ready 1130 * Make sure the FIFO is ready
1131 */ 1131 */
1132 for (j = 0; j < 10; j++) { 1132 for (j = 0; j < 10; j++) {
1133 Status = sc->sc_dr->STATUS; 1133 Status = sc->sc_dr->STATUS;
1134 if (Status & SAC_DATABUFRDY) 1134 if (Status & SAC_DATABUFRDY)
1135 break; 1135 break;
1136 DELAY(1000); 1136 DELAY(1000);
1137 } 1137 }
1138 1138
1139 /* 1139 /*
1140 * Got it? 1140 * Got it?
1141 */ 1141 */
1142 if (Status & SAC_DATABUFRDY) { 1142 if (Status & SAC_DATABUFRDY) {
1143 uint32_t Data32; 1143 uint32_t Data32;
1144 1144
1145 Data32 = sc->sc_dr->DATABUFREG[0]; 1145 Data32 = sc->sc_dr->DATABUFREG[0];
1146 Data32 = le32toh(Data32); 1146 Data32 = le32toh(Data32);
1147 memcpy(buffer + i, &Data32, 4); 1147 memcpy(buffer + i, &Data32, 4);
1148 } else { 1148 } else {
1149 /* 1149 /*
1150 * Ooops, get out of here 1150 * Ooops, get out of here
1151 */ 1151 */
1152 DBGME(DEBUG_ERRORS, 1152 DBGME(DEBUG_ERRORS,
1153 printf("Sysace::READ timeout\n")); 1153 printf("Sysace::READ timeout\n"));
1154 SysaceDumpRegisters(sc->sc_dr); 1154 SysaceDumpRegisters(sc->sc_dr);
1155 error = ETIMEDOUT; 1155 error = ETIMEDOUT;
1156 break; 1156 break;
1157 } 1157 }
1158 } 1158 }
1159 1159
1160 /* 1160 /*
1161 * Still doing ok? 1161 * Still doing ok?
1162 */ 1162 */
1163 if (!FAILED(error)) { 1163 if (!FAILED(error)) {
1164 nblocks -= BlocksThisTime; 1164 nblocks -= BlocksThisTime;
1165 SizeRead += BlocksThisTime; 1165 SizeRead += BlocksThisTime;
1166 buffer += BlocksThisTime << CF_SECBITS; 1166 buffer += BlocksThisTime << CF_SECBITS;
1167 } else { 1167 } else {
1168 /* remember this jic */ 1168 /* remember this jic */
1169 sc->sc_bio.r_error = Status; 1169 sc->sc_bio.r_error = Status;
1170 } 1170 }
1171 } 1171 }
1172 1172
1173 /* Free the ACE for the JTAG, just in case */ 1173 /* Free the ACE for the JTAG, just in case */
1174 sysace_unlock_registers(sc); 1174 sysace_unlock_registers(sc);
1175 1175
1176 /* 1176 /*
1177 * Are we done yet? 1177 * Are we done yet?
1178 */ 1178 */
1179 if (nblocks == 0) 1179 if (nblocks == 0)
1180 break; 1180 break;
1181 } 1181 }
1182 1182
1183 if (pSizeRead) 1183 if (pSizeRead)
1184 *pSizeRead = SizeRead; 1184 *pSizeRead = SizeRead;
1185 return error; 1185 return error;
1186} 1186}
1187 1187
1188/* 1188/*
1189 * Write SIZE bytes to device. 1189 * Write SIZE bytes to device.
1190 */ 1190 */
1191static int 1191static int
1192sysace_write_at(struct ace_softc *sc, daddr_t start_sector, char *buffer, 1192sysace_write_at(struct ace_softc *sc, daddr_t start_sector, char *buffer,
1193 size_t nblocks, size_t *pSizeWritten) 1193 size_t nblocks, size_t *pSizeWritten)
1194{ 1194{
1195 int error; 1195 int error;
1196 uint32_t BlocksThisTime; 1196 uint32_t BlocksThisTime;
1197 uint32_t Status = 0, SizeWritten = 0; 1197 uint32_t Status = 0, SizeWritten = 0;
1198 uint32_t i, j; 1198 uint32_t i, j;
1199 1199
1200 DBGME(DEBUG_XFERS|DEBUG_WRITES, 1200 DBGME(DEBUG_XFERS|DEBUG_WRITES,
1201 printf("SysaceWriteAt(%p %qx %p %zd %p)\n", 1201 printf("SysaceWriteAt(%p %qx %p %zd %p)\n",
1202 sc, start_sector, buffer, nblocks, pSizeWritten)); 1202 sc, start_sector, buffer, nblocks, pSizeWritten));
1203 1203
1204 /* 1204 /*
1205 * Validate & trim arguments 1205 * Validate & trim arguments
1206 */ 1206 */
1207 error = sysace_validate(sc, start_sector, &nblocks); 1207 error = sysace_validate(sc, start_sector, &nblocks);
1208 1208
1209 /* 1209 /*
1210 * Repeat until we are done or error 1210 * Repeat until we are done or error
1211 */ 1211 */
1212 while (error == 0) { 1212 while (error == 0) {
1213 1213
1214 /* 1214 /*
1215 * .. one sector at a time 1215 * .. one sector at a time
1216 * BUGBUG Supposedly we can do up to 256 sectors? 1216 * BUGBUG Supposedly we can do up to 256 sectors?
1217 */ 1217 */
1218 BlocksThisTime = nblocks; 1218 BlocksThisTime = nblocks;
1219 if (BlocksThisTime > MAXATATIME) 1219 if (BlocksThisTime > MAXATATIME)
1220 BlocksThisTime = MAXATATIME; 1220 BlocksThisTime = MAXATATIME;
1221 1221
1222 /* 1222 /*
1223 * Yes, start a sector write 1223 * Yes, start a sector write
1224 */ 1224 */
1225 sysace_inton(sc); 1225 sysace_inton(sc);
1226 error = sysace_start(sc, 1226 error = sysace_start(sc,
1227 SAC_CMD_WRITEMEMCARDDATA, 1227 SAC_CMD_WRITEMEMCARDDATA,
1228 (uint32_t)start_sector, /* BUGBUG trims here, no warn. */ 1228 (uint32_t)start_sector, /* BUGBUG trims here, no warn. */
1229 BlocksThisTime); 1229 BlocksThisTime);
1230 /* 1230 /*
1231 * And wait until done, if ok 1231 * And wait until done, if ok
1232 */ 1232 */
1233 if (!FAILED(error)) { 1233 if (!FAILED(error)) {
1234 start_sector += BlocksThisTime; 1234 start_sector += BlocksThisTime;
1235 /* BUGBUG timeouts! */ 1235 /* BUGBUG timeouts! */
1236 while (sc->hw_busy) { 1236 while (sc->hw_busy) {
1237 error = tsleep(&sc->media_has_changed, 1237 error = tsleep(&sc->media_has_changed,
1238 PRIBIO, "acewrite", 0); 1238 PRIBIO, "acewrite", 0);
1239 } 1239 }
1240 } 1240 }
1241 1241
1242 /* 1242 /*
1243 * Are we doing ok 1243 * Are we doing ok
1244 */ 1244 */
1245 if (!FAILED(error)) { 1245 if (!FAILED(error)) {
1246 1246
1247 /* 1247 /*
1248 * Get the data out to the ACE 1248 * Get the data out to the ACE
1249 */ 1249 */
1250 for (i = 0; i < (BlocksThisTime << CF_SECBITS); 1250 for (i = 0; i < (BlocksThisTime << CF_SECBITS);
1251 i += 4) { 1251 i += 4) {
1252 1252
1253 /* 1253 /*
1254 * Make sure the FIFO is ready 1254 * Make sure the FIFO is ready
1255 */ 1255 */
1256 for (j = 0; j < 10; j++) { 1256 for (j = 0; j < 10; j++) {
1257 Status = sc->sc_dr->STATUS; 1257 Status = sc->sc_dr->STATUS;
1258 if (Status & SAC_DATABUFRDY) 1258 if (Status & SAC_DATABUFRDY)
1259 break; 1259 break;
1260 DELAY(1000); 1260 DELAY(1000);
1261 } 1261 }
1262 1262
1263 /* 1263 /*
1264 * Got it? 1264 * Got it?
1265 */ 1265 */
1266 if (Status & SAC_DATABUFRDY) { 1266 if (Status & SAC_DATABUFRDY) {
1267 uint32_t Data32; 1267 uint32_t Data32;
1268 1268
1269 memcpy(&Data32, buffer + i, 4); 1269 memcpy(&Data32, buffer + i, 4);
1270 Data32 = htole32(Data32); 1270 Data32 = htole32(Data32);
1271 sc->sc_dr->DATABUFREG[0] = Data32; 1271 sc->sc_dr->DATABUFREG[0] = Data32;
1272 } else { 1272 } else {
1273 /* 1273 /*
1274 * Ooops, get out of here 1274 * Ooops, get out of here
1275 */ 1275 */
1276 DBGME(DEBUG_ERRORS, 1276 DBGME(DEBUG_ERRORS,
1277 printf("Sysace::WRITE timeout\n")); 1277 printf("Sysace::WRITE timeout\n"));
1278 SysaceDumpRegisters(sc->sc_dr); 1278 SysaceDumpRegisters(sc->sc_dr);
1279 error = ETIMEDOUT; 1279 error = ETIMEDOUT;
1280 /* remember this jic */ 1280 /* remember this jic */
1281 sc->sc_bio.r_error = Status; 1281 sc->sc_bio.r_error = Status;
1282 break; 1282 break;
1283 } 1283 }
1284 } 1284 }
1285 1285
1286 /* 1286 /*
1287 * Still doing ok? 1287 * Still doing ok?
1288 */ 1288 */
1289 if (!FAILED(error)) { 1289 if (!FAILED(error)) {
1290 nblocks -= BlocksThisTime; 1290 nblocks -= BlocksThisTime;
1291 SizeWritten += BlocksThisTime; 1291 SizeWritten += BlocksThisTime;
1292 buffer += BlocksThisTime << CF_SECBITS; 1292 buffer += BlocksThisTime << CF_SECBITS;
1293 } 1293 }
1294 } 1294 }
1295 1295
1296 /* 1296 /*
1297 * We need to wait until the device is ready for the 1297 * We need to wait until the device is ready for the
1298 * next command 1298 * next command
1299 * Experimentation shows that it can take longer than 10msec. 1299 * Experimentation shows that it can take longer than 10msec.
1300 */ 1300 */
1301 if (!FAILED(error)) { 1301 if (!FAILED(error)) {
1302 for (j = 0; j < 300; j++) { 1302 for (j = 0; j < 300; j++) {
1303 Status = sc->sc_dr->STATUS; 1303 Status = sc->sc_dr->STATUS;
1304 if (Status & SAC_RDYFORCFCMD) 1304 if (Status & SAC_RDYFORCFCMD)
1305 break; 1305 break;
1306 (void)tsleep(&sc->media_has_changed, 1306 (void)tsleep(&sc->media_has_changed,
1307 PRIBIO, "acewrite", 2); 1307 PRIBIO, "acewrite", 2);
1308 } 1308 }
1309 if (!(Status & SAC_RDYFORCFCMD)) { 1309 if (!(Status & SAC_RDYFORCFCMD)) {
1310 DBGME(DEBUG_ERRORS, 1310 DBGME(DEBUG_ERRORS,
1311 printf("Sysace::WRITE-COMPLETE timeout" 1311 printf("Sysace::WRITE-COMPLETE timeout"
1312 " St=%x\n", Status)); 1312 " St=%x\n", Status));
1313 SysaceDumpRegisters(sc->sc_dr); 1313 SysaceDumpRegisters(sc->sc_dr);
1314 /* 1314 /*
1315 * Ignore, we'll handle it the next time around 1315 * Ignore, we'll handle it the next time around
1316 * BUGBUG To be revised along with non-existant 1316 * BUGBUG To be revised along with non-existant
1317 * error handling 1317 * error handling
1318 */ 1318 */
1319 } 1319 }
1320 } 1320 }
1321 1321
1322 /* Free the ACE for the JTAG, just in case */ 1322 /* Free the ACE for the JTAG, just in case */
1323 sysace_unlock_registers(sc); 1323 sysace_unlock_registers(sc);
1324 1324
1325 /* 1325 /*
1326 * Are we done yet? 1326 * Are we done yet?
1327 */ 1327 */
1328 if (nblocks == 0) 1328 if (nblocks == 0)
1329 break; 1329 break;
1330 } 1330 }
1331 1331
1332 if (pSizeWritten) 1332 if (pSizeWritten)
1333 *pSizeWritten = SizeWritten; 1333 *pSizeWritten = SizeWritten;
1334 return error; 1334 return error;
1335} 1335}
1336 1336
1337int 1337int
1338ace_ebus_intr(void *cookie, void *f) 1338ace_ebus_intr(void *cookie, void *f)
1339{ 1339{
1340 struct ace_softc *sc = cookie; 1340 struct ace_softc *sc = cookie;
1341 uint32_t Control; 1341 uint32_t Control;
1342 1342
1343 /* 1343 /*
1344 * Turn off interrupts and ACK them 1344 * Turn off interrupts and ACK them
1345 */ 1345 */
1346 sysace_intoff(sc); 1346 sysace_intoff(sc);
1347 1347
1348 Control = sc->sc_dr->CONTROLREG & (~(SAC_RESETIRQ|SAC_INTERRUPTS)); 1348 Control = sc->sc_dr->CONTROLREG & (~(SAC_RESETIRQ|SAC_INTERRUPTS));
1349 sc->sc_dr->CONTROLREG = Control | SAC_RESETIRQ; 1349 sc->sc_dr->CONTROLREG = Control | SAC_RESETIRQ;
1350 sc->sc_dr->CONTROLREG = Control; 1350 sc->sc_dr->CONTROLREG = Control;
1351 1351
1352 /* ... read status and do whatever ... */ 1352 /* ... read status and do whatever ... */
1353 1353
1354 sc->hw_busy = FALSE; 1354 sc->hw_busy = FALSE;
1355 wakeup(&sc->media_has_changed); 1355 wakeup(&sc->media_has_changed);
1356 return 1; 1356 return 1;
1357} 1357}
1358 1358
1359#ifdef USE_ACE_FOR_RECONFIG 1359#ifdef USE_ACE_FOR_RECONFIG
1360static int 1360static int
1361sysace_send_config(struct ace_softc *sc, uint32_t *Data, unsigned int nBytes) 1361sysace_send_config(struct ace_softc *sc, uint32_t *Data, unsigned int nBytes)
1362{ 1362{
1363 struct _Sac *Interface = sc->sc_dr; 1363 struct _Sac *Interface = sc->sc_dr;
1364 unsigned int i, j, nWords; 1364 unsigned int i, j, nWords;
1365 uint32_t CtlWas; 1365 uint32_t CtlWas;
1366 uint32_t Status; 1366 uint32_t Status;
1367 1367
1368 CtlWas = Interface->CONTROLREG; 1368 CtlWas = Interface->CONTROLREG;
1369 1369
1370 /* Set the bits but in RESET (pag 49-50 of specs)*/ 1370 /* Set the bits but in RESET (pag 49-50 of specs)*/
1371#define CFGCMD (SAC_FORCELOCKREQ | SAC_LOCKREQ | SAC_CFGSEL | \ 1371#define CFGCMD (SAC_FORCELOCKREQ | SAC_LOCKREQ | SAC_CFGSEL | \
1372 SAC_FORCECFGMODE |/* SAC_CFGMODE |*/ SAC_CFGSTART) 1372 SAC_FORCECFGMODE |/* SAC_CFGMODE |*/ SAC_CFGSTART)
1373 1373
1374 Interface->CONTROLREG = CFGCMD | SAC_CFGRESET; 1374 Interface->CONTROLREG = CFGCMD | SAC_CFGRESET;
1375 1375
1376 /* Take it out of RESET */ 1376 /* Take it out of RESET */
1377 Interface->CONTROLREG = CFGCMD; 1377 Interface->CONTROLREG = CFGCMD;
1378 1378
1379 /* 1379 /*
1380 * Must wait till it says READY 1380 * Must wait till it says READY
1381 * It can take a looong time 1381 * It can take a looong time
1382 */ 1382 */
1383 for (j = 0; j < 1000; j++) { 1383 for (j = 0; j < 1000; j++) {
1384 Status = Interface->STATUS; 1384 Status = Interface->STATUS;
1385 if (Status & SAC_RDYFORCFCMD) 1385 if (Status & SAC_RDYFORCFCMD)
1386 break; 1386 break;
1387 DELAY(1000); 1387 DELAY(1000);
1388 } 1388 }
1389 1389
1390 if (0 == (Status & SAC_RDYFORCFCMD)) { 1390 if (0 == (Status & SAC_RDYFORCFCMD)) {
1391 DBGME(DEBUG_ERRORS, 1391 DBGME(DEBUG_ERRORS,
1392 printf("Sysace::CMD error %x (j=%d)\n", Status, j)); 1392 printf("Sysace::CMD error %x (j=%d)\n", Status, j));
1393 goto Error; 1393 goto Error;
1394 } 1394 }
1395 1395
1396 /* 1396 /*
1397 * Get the data out to the ACE 1397 * Get the data out to the ACE
1398 */ 1398 */
1399#define ACEROUNDUP 32 1399#define ACEROUNDUP 32
1400 nBytes = (nBytes + ACEROUNDUP - 1) & ~(ACEROUNDUP-1); 1400 nBytes = (nBytes + ACEROUNDUP - 1) & ~(ACEROUNDUP-1);
1401 nWords = (nBytes + 3) / 4; 1401 nWords = (nBytes + 3) / 4;
1402 DBGME(DEBUG_FUNCS, 1402 DBGME(DEBUG_FUNCS,
1403 printf("Sending %d bytes (as %d words) to %p ", 1403 printf("Sending %d bytes (as %d words) to %p ",
1404 nBytes, nWords, Interface)); 1404 nBytes, nWords, Interface));
1405 for (i = 0; i < nWords; i += 1/*word*/) { 1405 for (i = 0; i < nWords; i += 1/*word*/) {
1406 1406
1407 /* Stop on errors */ 1407 /* Stop on errors */
1408 Status = Interface->ERRORREG; 1408 Status = Interface->ERRORREG;
1409 if (Status) { 1409 if (Status) {
1410 /* 1410 /*
1411 * Ooops, get out of here 1411 * Ooops, get out of here
1412 */ 1412 */
1413 DBGME(DEBUG_ERRORS, 1413 DBGME(DEBUG_ERRORS,
1414 printf("Sysace::CFG error %x (i=%d)\n", Status, i)); 1414 printf("Sysace::CFG error %x (i=%d)\n", Status, i));
1415 goto Error; 1415 goto Error;
1416 } 1416 }
1417 1417
1418 /* 1418 /*
1419 * Make sure the FIFO is ready 1419 * Make sure the FIFO is ready
1420 */ 1420 */
1421 for (j = 0; j < 100; j++) { 1421 for (j = 0; j < 100; j++) {
1422 Status = Interface->STATUS; 1422 Status = Interface->STATUS;
1423 if (Status & SAC_DATABUFRDY) 1423 if (Status & SAC_DATABUFRDY)
1424 break; 1424 break;
1425 DELAY(1000); 1425 DELAY(1000);
1426 } 1426 }
1427 1427
1428 /* 1428 /*
1429 * Got it? 1429 * Got it?
1430 */ 1430 */
1431 if (Status & SAC_DATABUFRDY) { 1431 if (Status & SAC_DATABUFRDY) {
1432 uint32_t Data32; 1432 uint32_t Data32;
1433 1433
1434 Data32 = Data[i]; 1434 Data32 = Data[i];
1435 Data32 = htole32(Data32); 1435 Data32 = htole32(Data32);
1436 Interface->DATABUFREG[0] = Data32; 1436 Interface->DATABUFREG[0] = Data32;
1437 } else { 1437 } else {
1438 /* 1438 /*
1439 * Ooops, get out of here 1439 * Ooops, get out of here
1440 */ 1440 */
1441 DBGME(DEBUG_ERRORS, 1441 DBGME(DEBUG_ERRORS,
1442 printf("Sysace::WRITE timeout %x (i=%d)\n", 1442 printf("Sysace::WRITE timeout %x (i=%d)\n",
1443 Status, i)); 1443 Status, i));
1444 goto Error; 1444 goto Error;
1445 } 1445 }
1446 } 1446 }
1447 DBGME(DEBUG_FUNCS, printf("done ok.\n")); 1447 DBGME(DEBUG_FUNCS, printf("done ok.\n"));
1448 1448
1449 /* Put it back the way it was (try to.. :-( )*/ 1449 /* Put it back the way it was (try to.. :-( )*/
1450 Interface->CONTROLREG = CtlWas; 1450 Interface->CONTROLREG = CtlWas;
1451 return 0; 1451 return 0;
1452 1452
1453 Error: 1453 Error:
1454 SysaceDumpRegisters(Interface); 1454 SysaceDumpRegisters(Interface);
1455 Interface->CONTROLREG = CtlWas; 1455 Interface->CONTROLREG = CtlWas;
1456 return EIO; 1456 return EIO;
1457} 1457}
1458#endif /* USE_ACE_FOR_RECONFIG */ 1458#endif /* USE_ACE_FOR_RECONFIG */
1459 1459
1460 1460
1461/* 1461/*
1462 * Rest of code lifted with mods from the dev\ata\wd.c driver 1462 * Rest of code lifted with mods from the dev\ata\wd.c driver
1463 */ 1463 */
1464 1464
1465/* 1465/*
1466 * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. 1466 * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
1467 * 1467 *
1468 * Redistribution and use in source and binary forms, with or without 1468 * Redistribution and use in source and binary forms, with or without
1469 * modification, are permitted provided that the following conditions 1469 * modification, are permitted provided that the following conditions
1470 * are met: 1470 * are met:
1471 * 1. Redistributions of source code must retain the above copyright 1471 * 1. Redistributions of source code must retain the above copyright
1472 * notice, this list of conditions and the following disclaimer. 1472 * notice, this list of conditions and the following disclaimer.
1473 * 2. Redistributions in binary form must reproduce the above copyright 1473 * 2. Redistributions in binary form must reproduce the above copyright
1474 * notice, this list of conditions and the following disclaimer in the 1474 * notice, this list of conditions and the following disclaimer in the
1475 * documentation and/or other materials provided with the distribution. 1475 * documentation and/or other materials provided with the distribution.
1476 * 3. All advertising materials mentioning features or use of this software 
1477 * must display the following acknowledgement: 
1478 * This product includes software developed by Manuel Bouyer. 
1479 * 4. The name of the author may not be used to endorse or promote products 
1480 * derived from this software without specific prior written permission. 
1481 * 1476 *
1482 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1477 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1483 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1478 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1484 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1479 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1485 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1480 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1486 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1481 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1487 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1482 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1488 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1483 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1489 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1484 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1490 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 1485 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1491 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1486 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1492 */ 1487 */
1493 1488
1494/*- 1489/*-
1495 * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc. 1490 * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc.
1496 * All rights reserved. 1491 * All rights reserved.
1497 * 1492 *
1498 * This code is derived from software contributed to The NetBSD Foundation 1493 * This code is derived from software contributed to The NetBSD Foundation
1499 * by Charles M. Hannum and by Onno van der Linden. 1494 * by Charles M. Hannum and by Onno van der Linden.
1500 * 1495 *
1501 * Redistribution and use in source and binary forms, with or without 1496 * Redistribution and use in source and binary forms, with or without
1502 * modification, are permitted provided that the following conditions 1497 * modification, are permitted provided that the following conditions
1503 * are met: 1498 * are met:
1504 * 1. Redistributions of source code must retain the above copyright 1499 * 1. Redistributions of source code must retain the above copyright
1505 * notice, this list of conditions and the following disclaimer. 1500 * notice, this list of conditions and the following disclaimer.
1506 * 2. Redistributions in binary form must reproduce the above copyright 1501 * 2. Redistributions in binary form must reproduce the above copyright
1507 * notice, this list of conditions and the following disclaimer in the 1502 * notice, this list of conditions and the following disclaimer in the
1508 * documentation and/or other materials provided with the distribution. 1503 * documentation and/or other materials provided with the distribution.
1509 * 3. All advertising materials mentioning features or use of this software 1504 * 3. All advertising materials mentioning features or use of this software
1510 * must display the following acknowledgement: 1505 * must display the following acknowledgement:
1511 * This product includes software developed by the NetBSD 1506 * This product includes software developed by the NetBSD
1512 * Foundation, Inc. and its contributors. 1507 * Foundation, Inc. and its contributors.
1513 * 4. Neither the name of The NetBSD Foundation nor the names of its 1508 * 4. Neither the name of The NetBSD Foundation nor the names of its
1514 * contributors may be used to endorse or promote products derived 1509 * contributors may be used to endorse or promote products derived
1515 * from this software without specific prior written permission. 1510 * from this software without specific prior written permission.
1516 * 1511 *
1517 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 1512 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1518 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 1513 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1519 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1514 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1520 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 1515 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
1521 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1516 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1522 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1517 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1523 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1518 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1524 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1519 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1525 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1520 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1526 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 1521 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1527 * POSSIBILITY OF SUCH DAMAGE. 1522 * POSSIBILITY OF SUCH DAMAGE.
1528 */ 1523 */
1529 1524
1530static const char ST506[] = "ST506"; 1525static const char ST506[] = "ST506";
1531 1526
1532#define ACEIORETRIES_SINGLE 4 /* number of retries before single-sector */ 1527#define ACEIORETRIES_SINGLE 4 /* number of retries before single-sector */
1533#define ACEIORETRIES 5 /* number of retries before giving up */ 1528#define ACEIORETRIES 5 /* number of retries before giving up */
1534#define RECOVERYTIME hz/2 /* time to wait before retrying a cmd */ 1529#define RECOVERYTIME hz/2 /* time to wait before retrying a cmd */
1535 1530
1536#define ACEUNIT(dev) DISKUNIT(dev) 1531#define ACEUNIT(dev) DISKUNIT(dev)
1537#define ACEPART(dev) DISKPART(dev) 1532#define ACEPART(dev) DISKPART(dev)
1538#define ACEMINOR(unit, part) DISKMINOR(unit, part) 1533#define ACEMINOR(unit, part) DISKMINOR(unit, part)
1539#define MAKEACEDEV(maj, unit, part) MAKEDISKDEV(maj, unit, part) 1534#define MAKEACEDEV(maj, unit, part) MAKEDISKDEV(maj, unit, part)
1540 1535
1541#define ACELABELDEV(dev) (MAKEACEDEV(major(dev), ACEUNIT(dev), RAW_PART)) 1536#define ACELABELDEV(dev) (MAKEACEDEV(major(dev), ACEUNIT(dev), RAW_PART))
1542 1537
1543void aceperror(const struct ace_softc *); 1538void aceperror(const struct ace_softc *);
1544 1539
1545extern struct cfdriver ace_cd; 1540extern struct cfdriver ace_cd;
1546 1541
1547dev_type_open(aceopen); 1542dev_type_open(aceopen);
1548dev_type_close(aceclose); 1543dev_type_close(aceclose);
1549dev_type_read(aceread); 1544dev_type_read(aceread);
1550dev_type_write(acewrite); 1545dev_type_write(acewrite);
1551dev_type_ioctl(aceioctl); 1546dev_type_ioctl(aceioctl);
1552dev_type_strategy(acestrategy); 1547dev_type_strategy(acestrategy);
1553dev_type_dump(acedump); 1548dev_type_dump(acedump);
1554dev_type_size(acesize); 1549dev_type_size(acesize);
1555 1550
1556const struct bdevsw ace_bdevsw = { 1551const struct bdevsw ace_bdevsw = {
1557 .d_open = aceopen, 1552 .d_open = aceopen,
1558 .d_close = aceclose, 1553 .d_close = aceclose,
1559 .d_strategy = acestrategy, 1554 .d_strategy = acestrategy,
1560 .d_ioctl = aceioctl, 1555 .d_ioctl = aceioctl,
1561 .d_dump = acedump, 1556 .d_dump = acedump,
1562 .d_psize = acesize, 1557 .d_psize = acesize,
1563 .d_discard = nodiscard, 1558 .d_discard = nodiscard,
1564 .d_flag = D_DISK 1559 .d_flag = D_DISK
1565}; 1560};
1566 1561
1567const struct cdevsw ace_cdevsw = { 1562const struct cdevsw ace_cdevsw = {
1568 .d_open = aceopen, 1563 .d_open = aceopen,
1569 .d_close = aceclose, 1564 .d_close = aceclose,
1570 .d_read = aceread, 1565 .d_read = aceread,
1571 .d_write = acewrite, 1566 .d_write = acewrite,
1572 .d_ioctl = aceioctl, 1567 .d_ioctl = aceioctl,
1573 .d_stop = nostop, 1568 .d_stop = nostop,
1574 .d_tty = notty, 1569 .d_tty = notty,
1575 .d_poll = nopoll, 1570 .d_poll = nopoll,
1576 .d_mmap = nommap, 1571 .d_mmap = nommap,
1577 .d_kqfilter = nokqfilter, 1572 .d_kqfilter = nokqfilter,
1578 .d_discard = nodiscard, 1573 .d_discard = nodiscard,
1579 .d_flag = D_DISK 1574 .d_flag = D_DISK
1580}; 1575};
1581 1576
1582void acegetdefaultlabel(struct ace_softc *, struct disklabel *); 1577void acegetdefaultlabel(struct ace_softc *, struct disklabel *);
1583void acegetdisklabel(struct ace_softc *); 1578void acegetdisklabel(struct ace_softc *);
1584void acestart(void *); 1579void acestart(void *);
1585void __acestart(struct ace_softc*, struct buf *); 1580void __acestart(struct ace_softc*, struct buf *);
1586void acerestart(void *); 1581void acerestart(void *);
1587 1582
1588struct dkdriver acedkdriver = { 1583struct dkdriver acedkdriver = {
1589 .d_strategy = acestrategy, 1584 .d_strategy = acestrategy,
1590 .d_minphys = minphys 1585 .d_minphys = minphys
1591}; 1586};
1592 1587
1593#ifdef HAS_BAD144_HANDLING 1588#ifdef HAS_BAD144_HANDLING
1594static void bad144intern(struct ace_softc *); 1589static void bad144intern(struct ace_softc *);
1595#endif 1590#endif
1596 1591
1597void 1592void
1598aceattach(struct ace_softc *ace) 1593aceattach(struct ace_softc *ace)
1599{ 1594{
1600 device_t self = ace->sc_dev; 1595 device_t self = ace->sc_dev;
1601 char tbuf[41], pbuf[9], c, *p, *q; 1596 char tbuf[41], pbuf[9], c, *p, *q;
1602 int i, blank; 1597 int i, blank;
1603 DEBUG_PRINT(("aceattach\n"), DEBUG_FUNCS | DEBUG_PROBE); 1598 DEBUG_PRINT(("aceattach\n"), DEBUG_FUNCS | DEBUG_PROBE);
1604 1599
1605 callout_init(&ace->sc_restart_ch, 0); 1600 callout_init(&ace->sc_restart_ch, 0);
1606 bufq_alloc(&ace->sc_q, BUFQ_DISK_DEFAULT_STRAT, BUFQ_SORT_RAWBLOCK); 1601 bufq_alloc(&ace->sc_q, BUFQ_DISK_DEFAULT_STRAT, BUFQ_SORT_RAWBLOCK);
1607 1602
1608 ace->openings = 1; /* wazziz?*/ 1603 ace->openings = 1; /* wazziz?*/
1609 ace->sc_multi = MAXATATIME; 1604 ace->sc_multi = MAXATATIME;
1610 1605
1611 aprint_naive("\n"); 1606 aprint_naive("\n");
1612 1607
1613 /* setup all required fields so that if the attach fails we are ok */ 1608 /* setup all required fields so that if the attach fails we are ok */
1614 ace->sc_dk.dk_driver = &acedkdriver; 1609 ace->sc_dk.dk_driver = &acedkdriver;
1615 ace->sc_dk.dk_name = device_xname(ace->sc_dev); 1610 ace->sc_dk.dk_name = device_xname(ace->sc_dev);
1616 1611
1617 /* read our drive info */ 1612 /* read our drive info */
1618 if (sysace_attach(ace) != 0) { 1613 if (sysace_attach(ace) != 0) {
1619 aprint_error_dev(ace->sc_dev, "attach failed\n"); 1614 aprint_error_dev(ace->sc_dev, "attach failed\n");
1620 return; 1615 return;
1621 } 1616 }
1622 1617
1623 aprint_normal_dev(ace->sc_dev, "drive supports %d-sector PIO xfers\n", 1618 aprint_normal_dev(ace->sc_dev, "drive supports %d-sector PIO xfers\n",
1624 ace->sc_multi); 1619 ace->sc_multi);
1625 1620
1626 for (blank = 0, p = ace->sc_params.ModelNumber, q = tbuf, i = 0; 1621 for (blank = 0, p = ace->sc_params.ModelNumber, q = tbuf, i = 0;
1627 i < sizeof(ace->sc_params.ModelNumber); i++) { 1622 i < sizeof(ace->sc_params.ModelNumber); i++) {
1628 c = *p++; 1623 c = *p++;
1629 if (c == '\0') 1624 if (c == '\0')
1630 break; 1625 break;
1631 if (c != ' ') { 1626 if (c != ' ') {
1632 if (blank) { 1627 if (blank) {
1633 *q++ = ' '; 1628 *q++ = ' ';
1634 blank = 0; 1629 blank = 0;
1635 } 1630 }
1636 *q++ = c; 1631 *q++ = c;
1637 } else 1632 } else
1638 blank = 1; 1633 blank = 1;
1639 } 1634 }
1640 *q++ = '\0'; 1635 *q++ = '\0';
1641 1636
1642 aprint_normal_dev(ace->sc_dev, "card is <%s>\n", tbuf); 1637 aprint_normal_dev(ace->sc_dev, "card is <%s>\n", tbuf);
1643 1638
1644 format_bytes(pbuf, sizeof(pbuf), ace->sc_capacity * DEV_BSIZE); 1639 format_bytes(pbuf, sizeof(pbuf), ace->sc_capacity * DEV_BSIZE);
1645 aprint_normal("%s: %s, %d cyl, %d head, %d sec, " 1640 aprint_normal("%s: %s, %d cyl, %d head, %d sec, "
1646 "%d bytes/sect x %llu sectors\n", 1641 "%d bytes/sect x %llu sectors\n",
1647 device_xname(self), pbuf, 1642 device_xname(self), pbuf,
1648 (int)(ace->sc_capacity / 1643 (int)(ace->sc_capacity /
1649 (ace->sc_params.CurrentNumberOfHeads * 1644 (ace->sc_params.CurrentNumberOfHeads *
1650 ace->sc_params.CurrentSectorsPerTrack)), 1645 ace->sc_params.CurrentSectorsPerTrack)),
1651 ace->sc_params.CurrentNumberOfHeads, 1646 ace->sc_params.CurrentNumberOfHeads,
1652 ace->sc_params.CurrentSectorsPerTrack, 1647 ace->sc_params.CurrentSectorsPerTrack,
1653 DEV_BSIZE, (unsigned long long)ace->sc_capacity); 1648 DEV_BSIZE, (unsigned long long)ace->sc_capacity);
1654 1649
1655 /* 1650 /*
1656 * Attach the disk structure. We fill in dk_info later. 1651 * Attach the disk structure. We fill in dk_info later.
1657 */ 1652 */
1658 disk_attach(&ace->sc_dk); 1653 disk_attach(&ace->sc_dk);
1659 1654
1660 rnd_attach_source(&ace->rnd_source, device_xname(ace->sc_dev), 1655 rnd_attach_source(&ace->rnd_source, device_xname(ace->sc_dev),
1661 RND_TYPE_DISK, RND_FLAG_DEFAULT); 1656 RND_TYPE_DISK, RND_FLAG_DEFAULT);
1662 1657
1663} 1658}
1664 1659
1665int 1660int
1666aceactivate(device_t self, enum devact act) 1661aceactivate(device_t self, enum devact act)
1667{ 1662{
1668 int rv = 0; 1663 int rv = 0;
1669 1664
1670 switch (act) { 1665 switch (act) {
1671 case DVACT_DEACTIVATE: 1666 case DVACT_DEACTIVATE:
1672 /* 1667 /*
1673 * Nothing to do; we key off the device's DVF_ACTIVATE. 1668 * Nothing to do; we key off the device's DVF_ACTIVATE.
1674 */ 1669 */
1675 break; 1670 break;
1676 default: 1671 default:
1677 rv = EOPNOTSUPP; 1672 rv = EOPNOTSUPP;
1678 } 1673 }
1679 return rv; 1674 return rv;
1680} 1675}
1681 1676
1682int 1677int
1683acedetach(device_t self, int flags) 1678acedetach(device_t self, int flags)
1684{ 1679{
1685 struct ace_softc *sc = device_private(self); 1680 struct ace_softc *sc = device_private(self);
1686 int s, bmaj, cmaj, i, mn; 1681 int s, bmaj, cmaj, i, mn;
1687 1682
1688 /* locate the major number */ 1683 /* locate the major number */
1689 bmaj = bdevsw_lookup_major(&ace_bdevsw); 1684 bmaj = bdevsw_lookup_major(&ace_bdevsw);
1690 cmaj = cdevsw_lookup_major(&ace_cdevsw); 1685 cmaj = cdevsw_lookup_major(&ace_cdevsw);
1691 1686
1692 /* Nuke the vnodes for any open instances. */ 1687 /* Nuke the vnodes for any open instances. */
1693 for (i = 0; i < MAXPARTITIONS; i++) { 1688 for (i = 0; i < MAXPARTITIONS; i++) {
1694 mn = ACEMINOR(device_unit(self), i); 1689 mn = ACEMINOR(device_unit(self), i);
1695 vdevgone(bmaj, mn, mn, VBLK); 1690 vdevgone(bmaj, mn, mn, VBLK);
1696 vdevgone(cmaj, mn, mn, VCHR); 1691 vdevgone(cmaj, mn, mn, VCHR);
1697 } 1692 }
1698 1693
1699 /* Delete all of our wedges. */ 1694 /* Delete all of our wedges. */
1700 dkwedge_delall(&sc->sc_dk); 1695 dkwedge_delall(&sc->sc_dk);
1701 1696
1702 s = splbio(); 1697 s = splbio();
1703 1698
1704 /* Kill off any queued buffers. */ 1699 /* Kill off any queued buffers. */
1705 bufq_drain(sc->sc_q); 1700 bufq_drain(sc->sc_q);
1706 1701
1707#if 0 1702#if 0
1708 sc->atabus->ata_killpending(sc->drvp); 1703 sc->atabus->ata_killpending(sc->drvp);
1709#endif 1704#endif
1710 1705
1711 splx(s); 1706 splx(s);
1712 bufq_free(sc->sc_q); 1707 bufq_free(sc->sc_q);
1713 1708
1714 /* Detach disk. */ 1709 /* Detach disk. */
1715 disk_detach(&sc->sc_dk); 1710 disk_detach(&sc->sc_dk);
1716 1711
1717 /* Unhook the entropy source. */ 1712 /* Unhook the entropy source. */
1718 rnd_detach_source(&sc->rnd_source); 1713 rnd_detach_source(&sc->rnd_source);
1719 1714
1720#if 0 1715#if 0
1721 sc->drvp->drive_flags = 0; /* no drive any more here */ 1716 sc->drvp->drive_flags = 0; /* no drive any more here */
1722#endif 1717#endif
1723 1718
1724 return 0; 1719 return 0;
1725} 1720}
1726 1721
1727/* 1722/*
1728 * Read/write routine for a buffer. Validates the arguments and schedules the 1723 * Read/write routine for a buffer. Validates the arguments and schedules the
1729 * transfer. Does not wait for the transfer to complete. 1724 * transfer. Does not wait for the transfer to complete.
1730 */ 1725 */
1731void 1726void
1732acestrategy(struct buf *bp) 1727acestrategy(struct buf *bp)
1733{ 1728{
1734 struct ace_softc *ace; 1729 struct ace_softc *ace;
1735 struct disklabel *lp; 1730 struct disklabel *lp;
1736 daddr_t blkno; 1731 daddr_t blkno;
1737 int s; 1732 int s;
1738 1733
1739 ace = device_lookup_private(&ace_cd, ACEUNIT(bp->b_dev)); 1734 ace = device_lookup_private(&ace_cd, ACEUNIT(bp->b_dev));
1740 1735
1741 if (ace == NULL) { 1736 if (ace == NULL) {
1742 bp->b_error = ENXIO; 1737 bp->b_error = ENXIO;
1743 biodone(bp); 1738 biodone(bp);
1744 return; 1739 return;
1745 } 1740 }
1746 lp = ace->sc_dk.dk_label; 1741 lp = ace->sc_dk.dk_label;
1747 1742
1748 DEBUG_PRINT(("acestrategy (%s) %lld\n", 1743 DEBUG_PRINT(("acestrategy (%s) %lld\n",
1749 device_xname(ace->sc_dev), bp->b_blkno), DEBUG_XFERS); 1744 device_xname(ace->sc_dev), bp->b_blkno), DEBUG_XFERS);
1750 1745
1751 /* Valid request? */ 1746 /* Valid request? */
1752 if (bp->b_blkno < 0 || 1747 if (bp->b_blkno < 0 ||
1753 (bp->b_bcount % lp->d_secsize) != 0 || 1748 (bp->b_bcount % lp->d_secsize) != 0 ||
1754 (bp->b_bcount / lp->d_secsize) >= (1 << NBBY)) { 1749 (bp->b_bcount / lp->d_secsize) >= (1 << NBBY)) {
1755 bp->b_error = EINVAL; 1750 bp->b_error = EINVAL;
1756 goto done; 1751 goto done;
1757 } 1752 }
1758 1753
1759 /* If device invalidated (e.g. media change, door open), error. */ 1754 /* If device invalidated (e.g. media change, door open), error. */
1760 if ((ace->sc_flags & ACEF_LOADED) == 0) { 1755 if ((ace->sc_flags & ACEF_LOADED) == 0) {
1761 bp->b_error = EIO; 1756 bp->b_error = EIO;
1762 goto done; 1757 goto done;
1763 } 1758 }
1764 1759
1765 /* If it's a null transfer, return immediately. */ 1760 /* If it's a null transfer, return immediately. */
1766 if (bp->b_bcount == 0) 1761 if (bp->b_bcount == 0)
1767 goto done; 1762 goto done;
1768 1763
1769 /* 1764 /*
1770 * Do bounds checking, adjust transfer. if error, process. 1765 * Do bounds checking, adjust transfer. if error, process.
1771 * If end of partition, just return. 1766 * If end of partition, just return.
1772 */ 1767 */
1773 if (ACEPART(bp->b_dev) == RAW_PART) { 1768 if (ACEPART(bp->b_dev) == RAW_PART) {
1774 if (bounds_check_with_mediasize(bp, DEV_BSIZE, 1769 if (bounds_check_with_mediasize(bp, DEV_BSIZE,
1775 ace->sc_capacity) <= 0) 1770 ace->sc_capacity) <= 0)
1776 goto done; 1771 goto done;
1777 } else { 1772 } else {
1778 if (bounds_check_with_label(&ace->sc_dk, bp, 1773 if (bounds_check_with_label(&ace->sc_dk, bp,
1779 (ace->sc_flags & (ACEF_WLABEL|ACEF_LABELLING)) != 0) <= 0) 1774 (ace->sc_flags & (ACEF_WLABEL|ACEF_LABELLING)) != 0) <= 0)
1780 goto done; 1775 goto done;
1781 } 1776 }
1782 1777
1783 /* 1778 /*
1784 * Now convert the block number to absolute and put it in 1779 * Now convert the block number to absolute and put it in
1785 * terms of the device's logical block size. 1780 * terms of the device's logical block size.
1786 */ 1781 */
1787 if (lp->d_secsize >= DEV_BSIZE) 1782 if (lp->d_secsize >= DEV_BSIZE)
1788 blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE); 1783 blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE);
1789 else 1784 else
1790 blkno = bp->b_blkno * (DEV_BSIZE / lp->d_secsize); 1785 blkno = bp->b_blkno * (DEV_BSIZE / lp->d_secsize);
1791 1786
1792 if (ACEPART(bp->b_dev) != RAW_PART) 1787 if (ACEPART(bp->b_dev) != RAW_PART)
1793 blkno += lp->d_partitions[ACEPART(bp->b_dev)].p_offset; 1788 blkno += lp->d_partitions[ACEPART(bp->b_dev)].p_offset;
1794 1789
1795 bp->b_rawblkno = blkno; 1790 bp->b_rawblkno = blkno;
1796 1791
1797 /* Queue transfer on drive, activate drive and controller if idle. */ 1792 /* Queue transfer on drive, activate drive and controller if idle. */
1798 s = splbio(); 1793 s = splbio();
1799 bufq_put(ace->sc_q, bp); 1794 bufq_put(ace->sc_q, bp);
1800 acestart(ace); 1795 acestart(ace);
1801 splx(s); 1796 splx(s);
1802 return; 1797 return;
1803done: 1798done:
1804 /* Toss transfer; we're done early. */ 1799 /* Toss transfer; we're done early. */
1805 bp->b_resid = bp->b_bcount; 1800 bp->b_resid = bp->b_bcount;
1806 biodone(bp); 1801 biodone(bp);
1807} 1802}
1808 1803
1809/* 1804/*
1810 * Queue a drive for I/O. 1805 * Queue a drive for I/O.
1811 */ 1806 */
1812void 1807void
1813acestart(void *arg) 1808acestart(void *arg)
1814{ 1809{
1815 struct ace_softc *ace = arg; 1810 struct ace_softc *ace = arg;
1816 struct buf *bp = NULL; 1811 struct buf *bp = NULL;
1817 1812
1818 DEBUG_PRINT(("acestart %s\n", device_xname(ace->sc_dev)), DEBUG_XFERS); 1813 DEBUG_PRINT(("acestart %s\n", device_xname(ace->sc_dev)), DEBUG_XFERS);
1819 while (ace->openings > 0) { 1814 while (ace->openings > 0) {
1820 1815
1821 /* Is there a buf for us ? */ 1816 /* Is there a buf for us ? */
1822 if ((bp = bufq_get(ace->sc_q)) == NULL) 1817 if ((bp = bufq_get(ace->sc_q)) == NULL)
1823 return; 1818 return;
1824 1819
1825 /* 1820 /*
1826 * Make the command. First lock the device 1821 * Make the command. First lock the device
1827 */ 1822 */
1828 ace->openings--; 1823 ace->openings--;
1829 1824
1830 ace->retries = 0; 1825 ace->retries = 0;
1831 __acestart(ace, bp); 1826 __acestart(ace, bp);
1832 } 1827 }
1833} 1828}
1834 1829
1835void 1830void
1836__acestart(struct ace_softc *sc, struct buf *bp) 1831__acestart(struct ace_softc *sc, struct buf *bp)
1837{ 1832{
1838 1833
1839 sc->sc_bp = bp; 1834 sc->sc_bp = bp;
1840 /* 1835 /*
1841 * If we're retrying, retry in single-sector mode. This will give us 1836 * If we're retrying, retry in single-sector mode. This will give us
1842 * the sector number of the problem, and will eventually allow the 1837 * the sector number of the problem, and will eventually allow the
1843 * transfer to succeed. 1838 * transfer to succeed.
1844 */ 1839 */
1845 if (sc->retries >= ACEIORETRIES_SINGLE) 1840 if (sc->retries >= ACEIORETRIES_SINGLE)
1846 sc->sc_bio.flags = ATA_SINGLE; 1841 sc->sc_bio.flags = ATA_SINGLE;
1847 else 1842 else
1848 sc->sc_bio.flags = 0; 1843 sc->sc_bio.flags = 0;
1849 if (bp->b_flags & B_READ) 1844 if (bp->b_flags & B_READ)
1850 sc->sc_bio.flags |= ATA_READ; 1845 sc->sc_bio.flags |= ATA_READ;
1851 sc->sc_bio.blkno = bp->b_rawblkno; 1846 sc->sc_bio.blkno = bp->b_rawblkno;
1852 sc->sc_bio.blkdone = 0; 1847 sc->sc_bio.blkdone = 0;
1853 sc->sc_bio.nbytes = bp->b_bcount; 1848 sc->sc_bio.nbytes = bp->b_bcount;
1854 sc->sc_bio.nblks = bp->b_bcount >> CF_SECBITS; 1849 sc->sc_bio.nblks = bp->b_bcount >> CF_SECBITS;
1855 sc->sc_bio.databuf = bp->b_data; 1850 sc->sc_bio.databuf = bp->b_data;
1856 /* Instrumentation. */ 1851 /* Instrumentation. */
1857 disk_busy(&sc->sc_dk); 1852 disk_busy(&sc->sc_dk);
1858 sc->active_xfer = bp; 1853 sc->active_xfer = bp;
1859 wakeup(&sc->ch_thread); 1854 wakeup(&sc->ch_thread);
1860} 1855}
1861 1856
1862void 1857void
1863acedone(struct ace_softc *ace) 1858acedone(struct ace_softc *ace)
1864{ 1859{
1865 struct buf *bp = ace->sc_bp; 1860 struct buf *bp = ace->sc_bp;
1866 const char *errmsg; 1861 const char *errmsg;
1867 int do_perror = 0; 1862 int do_perror = 0;
1868 1863
1869 DEBUG_PRINT(("acedone %s\n", device_xname(ace->sc_dev)), DEBUG_XFERS); 1864 DEBUG_PRINT(("acedone %s\n", device_xname(ace->sc_dev)), DEBUG_XFERS);
1870 1865
1871 if (bp == NULL) 1866 if (bp == NULL)
1872 return; 1867 return;
1873 1868
1874 bp->b_resid = ace->sc_bio.nbytes; 1869 bp->b_resid = ace->sc_bio.nbytes;
1875 switch (ace->sc_bio.error) { 1870 switch (ace->sc_bio.error) {
1876 case ETIMEDOUT: 1871 case ETIMEDOUT:
1877 errmsg = "device timeout"; 1872 errmsg = "device timeout";
1878 do_perror = 1; 1873 do_perror = 1;
1879 goto retry; 1874 goto retry;
1880 case EBUSY: 1875 case EBUSY:
1881 case EDOOFUS: 1876 case EDOOFUS:
1882 errmsg = "device stuck"; 1877 errmsg = "device stuck";
1883retry: /* Just reset and retry. Can we do more ? */ 1878retry: /* Just reset and retry. Can we do more ? */
1884 sysace_reset(ace); 1879 sysace_reset(ace);
1885 diskerr(bp, "ace", errmsg, LOG_PRINTF, 1880 diskerr(bp, "ace", errmsg, LOG_PRINTF,
1886 ace->sc_bio.blkdone, ace->sc_dk.dk_label); 1881 ace->sc_bio.blkdone, ace->sc_dk.dk_label);
1887 if (ace->retries < ACEIORETRIES) 1882 if (ace->retries < ACEIORETRIES)
1888 printf(", retrying"); 1883 printf(", retrying");
1889 printf("\n"); 1884 printf("\n");
1890 if (do_perror) 1885 if (do_perror)
1891 aceperror(ace); 1886 aceperror(ace);
1892 if (ace->retries < ACEIORETRIES) { 1887 if (ace->retries < ACEIORETRIES) {
1893 ace->retries++; 1888 ace->retries++;
1894 callout_reset(&ace->sc_restart_ch, RECOVERYTIME, 1889 callout_reset(&ace->sc_restart_ch, RECOVERYTIME,
1895 acerestart, ace); 1890 acerestart, ace);
1896 return; 1891 return;
1897 } 1892 }
1898 1893
1899 bp->b_error = EIO; 1894 bp->b_error = EIO;
1900 break; 1895 break;
1901 case 0: 1896 case 0:
1902 if ((ace->sc_bio.flags & ATA_CORR) || ace->retries > 0) 1897 if ((ace->sc_bio.flags & ATA_CORR) || ace->retries > 0)
1903 printf("%s: soft error (corrected)\n", 1898 printf("%s: soft error (corrected)\n",
1904 device_xname(ace->sc_dev)); 1899 device_xname(ace->sc_dev));
1905 break; 1900 break;
1906 case ENODEV: 1901 case ENODEV:
1907 case E2BIG: 1902 case E2BIG:
1908 bp->b_error = EIO; 1903 bp->b_error = EIO;
1909 break; 1904 break;
1910 } 1905 }
1911 disk_unbusy(&ace->sc_dk, (bp->b_bcount - bp->b_resid), 1906 disk_unbusy(&ace->sc_dk, (bp->b_bcount - bp->b_resid),
1912 (bp->b_flags & B_READ)); 1907 (bp->b_flags & B_READ));
1913 rnd_add_uint32(&ace->rnd_source, bp->b_blkno); 1908 rnd_add_uint32(&ace->rnd_source, bp->b_blkno);
1914 biodone(bp); 1909 biodone(bp);
1915 ace->openings++; 1910 ace->openings++;
1916 acestart(ace); 1911 acestart(ace);
1917} 1912}
1918 1913
1919void 1914void
1920acerestart(void *v) 1915acerestart(void *v)
1921{ 1916{
1922 struct ace_softc *ace = v; 1917 struct ace_softc *ace = v;
1923 struct buf *bp = ace->sc_bp; 1918 struct buf *bp = ace->sc_bp;
1924 int s; 1919 int s;
1925 DEBUG_PRINT(("acerestart %s\n", 1920 DEBUG_PRINT(("acerestart %s\n",
1926 device_xname(ace->sc_dev)), DEBUG_XFERS); 1921 device_xname(ace->sc_dev)), DEBUG_XFERS);
1927 1922
1928 s = splbio(); 1923 s = splbio();
1929 __acestart(v, bp); 1924 __acestart(v, bp);
1930 splx(s); 1925 splx(s);
1931} 1926}
1932 1927
1933int 1928int
1934aceread(dev_t dev, struct uio *uio, int flags) 1929aceread(dev_t dev, struct uio *uio, int flags)
1935{ 1930{
1936 int r; 1931 int r;
1937 1932
1938 DEBUG_PRINT(("aceread\n"), DEBUG_XFERS); 1933 DEBUG_PRINT(("aceread\n"), DEBUG_XFERS);
1939 r = physio(acestrategy, NULL, dev, B_READ, minphys, uio); 1934 r = physio(acestrategy, NULL, dev, B_READ, minphys, uio);
1940 DEBUG_PRINT(("aceread -> x%x resid=%x\n",r,uio->uio_resid),DEBUG_XFERS); 1935 DEBUG_PRINT(("aceread -> x%x resid=%x\n",r,uio->uio_resid),DEBUG_XFERS);
1941 1936
1942 return r; 1937 return r;
1943} 1938}
1944 1939
1945int 1940int
1946acewrite(dev_t dev, struct uio *uio, int flags) 1941acewrite(dev_t dev, struct uio *uio, int flags)
1947{ 1942{
1948 1943
1949 DEBUG_PRINT(("acewrite\n"), DEBUG_XFERS); 1944 DEBUG_PRINT(("acewrite\n"), DEBUG_XFERS);
1950 return physio(acestrategy, NULL, dev, B_WRITE, minphys, uio); 1945 return physio(acestrategy, NULL, dev, B_WRITE, minphys, uio);
1951} 1946}
1952 1947
1953int 1948int
1954aceopen(dev_t dev, int flag, int fmt, struct lwp *l) 1949aceopen(dev_t dev, int flag, int fmt, struct lwp *l)
1955{ 1950{
1956 struct ace_softc *ace; 1951 struct ace_softc *ace;
1957 int part, error; 1952 int part, error;
1958 1953
1959 DEBUG_PRINT(("aceopen\n"), DEBUG_FUNCS); 1954 DEBUG_PRINT(("aceopen\n"), DEBUG_FUNCS);
1960 ace = device_lookup_private(&ace_cd, ACEUNIT(dev)); 1955 ace = device_lookup_private(&ace_cd, ACEUNIT(dev));
1961 if (ace == NULL) 1956 if (ace == NULL)
1962 return ENXIO; 1957 return ENXIO;
1963 1958
1964 if (! device_is_active(ace->sc_dev)) 1959 if (! device_is_active(ace->sc_dev))
1965 return ENODEV; 1960 return ENODEV;
1966 1961
1967 part = ACEPART(dev); 1962 part = ACEPART(dev);
1968 1963
1969 mutex_enter(&ace->sc_dk.dk_openlock); 1964 mutex_enter(&ace->sc_dk.dk_openlock);
1970 1965
1971 /* 1966 /*
1972 * If there are wedges, and this is not RAW_PART, then we 1967 * If there are wedges, and this is not RAW_PART, then we
1973 * need to fail. 1968 * need to fail.
1974 */ 1969 */
1975 if (ace->sc_dk.dk_nwedges != 0 && part != RAW_PART) { 1970 if (ace->sc_dk.dk_nwedges != 0 && part != RAW_PART) {
1976 error = EBUSY; 1971 error = EBUSY;
1977 goto bad; 1972 goto bad;
1978 } 1973 }
1979 1974
1980 if (ace->sc_dk.dk_openmask != 0) { 1975 if (ace->sc_dk.dk_openmask != 0) {
1981 /* 1976 /*
1982 * If any partition is open, but the disk has been invalidated, 1977 * If any partition is open, but the disk has been invalidated,
1983 * disallow further opens. 1978 * disallow further opens.
1984 */ 1979 */
1985 if ((ace->sc_flags & ACEF_LOADED) == 0) { 1980 if ((ace->sc_flags & ACEF_LOADED) == 0) {
1986 error = EIO; 1981 error = EIO;
1987 goto bad; 1982 goto bad;
1988 } 1983 }
1989 } else { 1984 } else {
1990 if ((ace->sc_flags & ACEF_LOADED) == 0) { 1985 if ((ace->sc_flags & ACEF_LOADED) == 0) {
1991 ace->sc_flags |= ACEF_LOADED; 1986 ace->sc_flags |= ACEF_LOADED;
1992 1987
1993 /* Load the physical device parameters. */ 1988 /* Load the physical device parameters. */
1994 if (ace->sc_capacity == 0) { 1989 if (ace->sc_capacity == 0) {
1995 error = sysace_identify(ace); 1990 error = sysace_identify(ace);
1996 if (error) 1991 if (error)
1997 goto bad; 1992 goto bad;
1998 } 1993 }
1999 1994
2000 /* Load the partition info if not already loaded. */ 1995 /* Load the partition info if not already loaded. */
2001 acegetdisklabel(ace); 1996 acegetdisklabel(ace);
2002 } 1997 }
2003 } 1998 }
2004 1999
2005 /* Check that the partition exists. */ 2000 /* Check that the partition exists. */
2006 if (part != RAW_PART && 2001 if (part != RAW_PART &&
2007 (part >= ace->sc_dk.dk_label->d_npartitions || 2002 (part >= ace->sc_dk.dk_label->d_npartitions ||
2008 ace->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) { 2003 ace->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
2009 error = ENXIO; 2004 error = ENXIO;
2010 goto bad; 2005 goto bad;
2011 } 2006 }
2012 2007
2013 /* Insure only one open at a time. */ 2008 /* Insure only one open at a time. */
2014 switch (fmt) { 2009 switch (fmt) {
2015 case S_IFCHR: 2010 case S_IFCHR:
2016 ace->sc_dk.dk_copenmask |= (1 << part); 2011 ace->sc_dk.dk_copenmask |= (1 << part);
2017 break; 2012 break;
2018 case S_IFBLK: 2013 case S_IFBLK:
2019 ace->sc_dk.dk_bopenmask |= (1 << part); 2014 ace->sc_dk.dk_bopenmask |= (1 << part);
2020 break; 2015 break;
2021 } 2016 }
2022 ace->sc_dk.dk_openmask = 2017 ace->sc_dk.dk_openmask =
2023 ace->sc_dk.dk_copenmask | ace->sc_dk.dk_bopenmask; 2018 ace->sc_dk.dk_copenmask | ace->sc_dk.dk_bopenmask;
2024 2019
2025 mutex_exit(&ace->sc_dk.dk_openlock); 2020 mutex_exit(&ace->sc_dk.dk_openlock);
2026 return 0; 2021 return 0;
2027 2022
2028 bad: 2023 bad:
2029 mutex_exit(&ace->sc_dk.dk_openlock); 2024 mutex_exit(&ace->sc_dk.dk_openlock);
2030 return error; 2025 return error;
2031} 2026}
2032 2027
2033int 2028int
2034aceclose(dev_t dev, int flag, int fmt, struct lwp *l) 2029aceclose(dev_t dev, int flag, int fmt, struct lwp *l)
2035{ 2030{
2036 struct ace_softc *ace = device_lookup_private(&ace_cd, ACEUNIT(dev)); 2031 struct ace_softc *ace = device_lookup_private(&ace_cd, ACEUNIT(dev));
2037 int part = ACEPART(dev); 2032 int part = ACEPART(dev);
2038 2033
2039 DEBUG_PRINT(("aceclose\n"), DEBUG_FUNCS); 2034 DEBUG_PRINT(("aceclose\n"), DEBUG_FUNCS);
2040 if (ace == NULL) 2035 if (ace == NULL)
2041 return ENXIO; 2036 return ENXIO;
2042 2037
2043 mutex_enter(&ace->sc_dk.dk_openlock); 2038 mutex_enter(&ace->sc_dk.dk_openlock);
2044 2039
2045 switch (fmt) { 2040 switch (fmt) {
2046 case S_IFCHR: 2041 case S_IFCHR:
2047 ace->sc_dk.dk_copenmask &= ~(1 << part); 2042 ace->sc_dk.dk_copenmask &= ~(1 << part);
2048 break; 2043 break;
2049 case S_IFBLK: 2044 case S_IFBLK:
2050 ace->sc_dk.dk_bopenmask &= ~(1 << part); 2045 ace->sc_dk.dk_bopenmask &= ~(1 << part);
2051 break; 2046 break;
2052 } 2047 }
2053 ace->sc_dk.dk_openmask = 2048 ace->sc_dk.dk_openmask =
2054 ace->sc_dk.dk_copenmask | ace->sc_dk.dk_bopenmask; 2049 ace->sc_dk.dk_copenmask | ace->sc_dk.dk_bopenmask;
2055 2050
2056 if (ace->sc_dk.dk_openmask == 0) { 2051 if (ace->sc_dk.dk_openmask == 0) {
2057 2052
2058 if (!(ace->sc_flags & ACEF_KLABEL)) 2053 if (!(ace->sc_flags & ACEF_KLABEL))
2059 ace->sc_flags &= ~ACEF_LOADED; 2054 ace->sc_flags &= ~ACEF_LOADED;
2060 2055
2061 } 2056 }
2062 2057
2063 mutex_exit(&ace->sc_dk.dk_openlock); 2058 mutex_exit(&ace->sc_dk.dk_openlock);
2064 return 0; 2059 return 0;
2065} 2060}
2066 2061
2067void 2062void
2068acegetdefaultlabel(struct ace_softc *ace, struct disklabel *lp) 2063acegetdefaultlabel(struct ace_softc *ace, struct disklabel *lp)
2069{ 2064{
2070 2065
2071 DEBUG_PRINT(("acegetdefaultlabel\n"), DEBUG_FUNCS); 2066 DEBUG_PRINT(("acegetdefaultlabel\n"), DEBUG_FUNCS);
2072 memset(lp, 0, sizeof(struct disklabel)); 2067 memset(lp, 0, sizeof(struct disklabel));
2073 2068
2074 lp->d_secsize = DEV_BSIZE; 2069 lp->d_secsize = DEV_BSIZE;
2075 lp->d_ntracks = ace->sc_params.CurrentNumberOfHeads; 2070 lp->d_ntracks = ace->sc_params.CurrentNumberOfHeads;
2076 lp->d_nsectors = ace->sc_params.CurrentSectorsPerTrack; 2071 lp->d_nsectors = ace->sc_params.CurrentSectorsPerTrack;
2077 lp->d_ncylinders = ace->sc_capacity / 2072 lp->d_ncylinders = ace->sc_capacity /
2078 (ace->sc_params.CurrentNumberOfHeads * 2073 (ace->sc_params.CurrentNumberOfHeads *
2079 ace->sc_params.CurrentSectorsPerTrack); 2074 ace->sc_params.CurrentSectorsPerTrack);
2080 lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors; 2075 lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
2081 2076
2082 lp->d_type = DKTYPE_ST506; /* ?!? */ 2077 lp->d_type = DKTYPE_ST506; /* ?!? */
2083 2078
2084 strncpy(lp->d_typename, ace->sc_params.ModelNumber, 16); 2079 strncpy(lp->d_typename, ace->sc_params.ModelNumber, 16);
2085 strncpy(lp->d_packname, "fictitious", 16); 2080 strncpy(lp->d_packname, "fictitious", 16);
2086 if (ace->sc_capacity > UINT32_MAX) 2081 if (ace->sc_capacity > UINT32_MAX)
2087 lp->d_secperunit = UINT32_MAX; 2082 lp->d_secperunit = UINT32_MAX;
2088 else 2083 else
2089 lp->d_secperunit = ace->sc_capacity; 2084 lp->d_secperunit = ace->sc_capacity;
2090 lp->d_rpm = 3600; 2085 lp->d_rpm = 3600;
2091 lp->d_interleave = 1; 2086 lp->d_interleave = 1;
2092 lp->d_flags = 0; 2087 lp->d_flags = 0;
2093 2088
2094 lp->d_partitions[RAW_PART].p_offset = 0; 2089 lp->d_partitions[RAW_PART].p_offset = 0;
2095 lp->d_partitions[RAW_PART].p_size = 2090 lp->d_partitions[RAW_PART].p_size =
2096 lp->d_secperunit * (lp->d_secsize / DEV_BSIZE); 2091 lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
2097 lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED; 2092 lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
2098 lp->d_npartitions = RAW_PART + 1; 2093 lp->d_npartitions = RAW_PART + 1;
2099 2094
2100 lp->d_magic = DISKMAGIC; 2095 lp->d_magic = DISKMAGIC;
2101 lp->d_magic2 = DISKMAGIC; 2096 lp->d_magic2 = DISKMAGIC;
2102 lp->d_checksum = dkcksum(lp); 2097 lp->d_checksum = dkcksum(lp);
2103} 2098}
2104 2099
2105/* 2100/*
2106 * Fabricate a default disk label, and try to read the correct one. 2101 * Fabricate a default disk label, and try to read the correct one.
2107 */ 2102 */
2108void 2103void
2109acegetdisklabel(struct ace_softc *ace) 2104acegetdisklabel(struct ace_softc *ace)
2110{ 2105{
2111 struct disklabel *lp = ace->sc_dk.dk_label; 2106 struct disklabel *lp = ace->sc_dk.dk_label;
2112 const char *errstring; 2107 const char *errstring;
2113 2108
2114 DEBUG_PRINT(("acegetdisklabel\n"), DEBUG_FUNCS); 2109 DEBUG_PRINT(("acegetdisklabel\n"), DEBUG_FUNCS);
2115 2110
2116 memset(ace->sc_dk.dk_cpulabel, 0, sizeof(struct cpu_disklabel)); 2111 memset(ace->sc_dk.dk_cpulabel, 0, sizeof(struct cpu_disklabel));
2117 2112
2118 acegetdefaultlabel(ace, lp); 2113 acegetdefaultlabel(ace, lp);
2119 2114
2120#ifdef HAS_BAD144_HANDLING 2115#ifdef HAS_BAD144_HANDLING
2121 ace->sc_bio.badsect[0] = -1; 2116 ace->sc_bio.badsect[0] = -1;
2122#endif 2117#endif
2123 2118
2124 errstring = readdisklabel(MAKEACEDEV(0, device_unit(ace->sc_dev), 2119 errstring = readdisklabel(MAKEACEDEV(0, device_unit(ace->sc_dev),
2125 RAW_PART), acestrategy, lp, 2120 RAW_PART), acestrategy, lp,
2126 ace->sc_dk.dk_cpulabel); 2121 ace->sc_dk.dk_cpulabel);
2127 if (errstring) { 2122 if (errstring) {
2128 printf("%s: %s\n", device_xname(ace->sc_dev), errstring); 2123 printf("%s: %s\n", device_xname(ace->sc_dev), errstring);
2129 return; 2124 return;
2130 } 2125 }
2131 2126
2132#if DEBUG 2127#if DEBUG
2133 if (ACE_DEBUG(DEBUG_WRITES)) { 2128 if (ACE_DEBUG(DEBUG_WRITES)) {
2134 int i, n = ace->sc_dk.dk_label->d_npartitions; 2129 int i, n = ace->sc_dk.dk_label->d_npartitions;
2135 printf("%s: %d parts\n", device_xname(ace->sc_dev), n); 2130 printf("%s: %d parts\n", device_xname(ace->sc_dev), n);
2136 for (i = 0; i < n; i++) { 2131 for (i = 0; i < n; i++) {
2137 printf("\t[%d]: t=%x s=%d o=%d\n", i, 2132 printf("\t[%d]: t=%x s=%d o=%d\n", i,
2138 ace->sc_dk.dk_label->d_partitions[i].p_fstype, 2133 ace->sc_dk.dk_label->d_partitions[i].p_fstype,
2139 ace->sc_dk.dk_label->d_partitions[i].p_size, 2134 ace->sc_dk.dk_label->d_partitions[i].p_size,
2140 ace->sc_dk.dk_label->d_partitions[i].p_offset); 2135 ace->sc_dk.dk_label->d_partitions[i].p_offset);
2141 } 2136 }
2142 } 2137 }
2143#endif 2138#endif
2144 2139
2145#ifdef HAS_BAD144_HANDLING 2140#ifdef HAS_BAD144_HANDLING
2146 if ((lp->d_flags & D_BADSECT) != 0) 2141 if ((lp->d_flags & D_BADSECT) != 0)
2147 bad144intern(ace); 2142 bad144intern(ace);
2148#endif 2143#endif
2149} 2144}
2150 2145
2151void 2146void
2152aceperror(const struct ace_softc *ace) 2147aceperror(const struct ace_softc *ace)
2153{ 2148{
2154 const char *devname = device_xname(ace->sc_dev); 2149 const char *devname = device_xname(ace->sc_dev);
2155 uint32_t Status = ace->sc_bio.r_error; 2150 uint32_t Status = ace->sc_bio.r_error;
2156 2151
2157 printf("%s: (", devname); 2152 printf("%s: (", devname);
2158 2153
2159 if (Status == 0) 2154 if (Status == 0)
2160 printf("error not notified"); 2155 printf("error not notified");
2161 else 2156 else
2162 printf("status=x%x", Status); 2157 printf("status=x%x", Status);
2163 2158
2164 printf(")\n"); 2159 printf(")\n");
2165} 2160}
2166 2161
2167int 2162int
2168aceioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l) 2163aceioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l)
2169{ 2164{
2170 struct ace_softc *ace = device_lookup_private(&ace_cd, ACEUNIT(dev)); 2165 struct ace_softc *ace = device_lookup_private(&ace_cd, ACEUNIT(dev));
2171 int error = 0, s; 2166 int error = 0, s;
2172 2167
2173 DEBUG_PRINT(("aceioctl\n"), DEBUG_FUNCS); 2168 DEBUG_PRINT(("aceioctl\n"), DEBUG_FUNCS);
2174 2169
2175 if ((ace->sc_flags & ACEF_LOADED) == 0) 2170 if ((ace->sc_flags & ACEF_LOADED) == 0)
2176 return EIO; 2171 return EIO;
2177 2172
2178 error = disk_ioctl(&ace->sc_dk, dev, xfer, addr, flag, l); 2173 error = disk_ioctl(&ace->sc_dk, dev, xfer, addr, flag, l);
2179 if (error != EPASSTHROUGH) 2174 if (error != EPASSTHROUGH)
2180 return error; 2175 return error;
2181 2176
2182 switch (xfer) { 2177 switch (xfer) {
2183#ifdef HAS_BAD144_HANDLING 2178#ifdef HAS_BAD144_HANDLING
2184 case DIOCSBAD: 2179 case DIOCSBAD:
2185 if ((flag & FWRITE) == 0) 2180 if ((flag & FWRITE) == 0)
2186 return EBADF; 2181 return EBADF;
2187 ace->sc_dk.dk_cpulabel->bad = *(struct dkbad *)addr; 2182 ace->sc_dk.dk_cpulabel->bad = *(struct dkbad *)addr;
2188 ace->sc_dk.dk_label->d_flags |= D_BADSECT; 2183 ace->sc_dk.dk_label->d_flags |= D_BADSECT;
2189 bad144intern(ace); 2184 bad144intern(ace);
2190 return 0; 2185 return 0;
2191#endif 2186#endif
2192 2187
2193 case DIOCWDINFO: 2188 case DIOCWDINFO:
2194 case DIOCSDINFO: 2189 case DIOCSDINFO:
2195 { 2190 {
2196 struct disklabel *lp; 2191 struct disklabel *lp;
2197 2192
2198 if ((flag & FWRITE) == 0) 2193 if ((flag & FWRITE) == 0)
2199 return EBADF; 2194 return EBADF;
2200 2195
2201 lp = (struct disklabel *)addr; 2196 lp = (struct disklabel *)addr;
2202 2197
2203 mutex_enter(&ace->sc_dk.dk_openlock); 2198 mutex_enter(&ace->sc_dk.dk_openlock);
2204 ace->sc_flags |= ACEF_LABELLING; 2199 ace->sc_flags |= ACEF_LABELLING;
2205 2200
2206 error = setdisklabel(ace->sc_dk.dk_label, 2201 error = setdisklabel(ace->sc_dk.dk_label,
2207 lp, /*ace->sc_dk.dk_openmask : */0, 2202 lp, /*ace->sc_dk.dk_openmask : */0,
2208 ace->sc_dk.dk_cpulabel); 2203 ace->sc_dk.dk_cpulabel);
2209 if (error == 0) { 2204 if (error == 0) {
2210 if (xfer == DIOCWDINFO) 2205 if (xfer == DIOCWDINFO)
2211 error = writedisklabel(ACELABELDEV(dev), 2206 error = writedisklabel(ACELABELDEV(dev),
2212 acestrategy, ace->sc_dk.dk_label, 2207 acestrategy, ace->sc_dk.dk_label,
2213 ace->sc_dk.dk_cpulabel); 2208 ace->sc_dk.dk_cpulabel);
2214 } 2209 }
2215 2210
2216 ace->sc_flags &= ~ACEF_LABELLING; 2211 ace->sc_flags &= ~ACEF_LABELLING;
2217 mutex_exit(&ace->sc_dk.dk_openlock); 2212 mutex_exit(&ace->sc_dk.dk_openlock);
2218 return error; 2213 return error;
2219 } 2214 }
2220 2215
2221 case DIOCKLABEL: 2216 case DIOCKLABEL:
2222 if (*(int *)addr) 2217 if (*(int *)addr)
2223 ace->sc_flags |= ACEF_KLABEL; 2218 ace->sc_flags |= ACEF_KLABEL;
2224 else 2219 else
2225 ace->sc_flags &= ~ACEF_KLABEL; 2220 ace->sc_flags &= ~ACEF_KLABEL;
2226 return 0; 2221 return 0;
2227 2222
2228 case DIOCWLABEL: 2223 case DIOCWLABEL:
2229 if ((flag & FWRITE) == 0) 2224 if ((flag & FWRITE) == 0)
2230 return EBADF; 2225 return EBADF;
2231 if (*(int *)addr) 2226 if (*(int *)addr)
2232 ace->sc_flags |= ACEF_WLABEL; 2227 ace->sc_flags |= ACEF_WLABEL;
2233 else 2228 else
2234 ace->sc_flags &= ~ACEF_WLABEL; 2229 ace->sc_flags &= ~ACEF_WLABEL;
2235 return 0; 2230 return 0;
2236 2231
2237 case DIOCGDEFLABEL: 2232 case DIOCGDEFLABEL:
2238 acegetdefaultlabel(ace, (struct disklabel *)addr); 2233 acegetdefaultlabel(ace, (struct disklabel *)addr);
2239 return 0; 2234 return 0;
2240 2235
2241 case DIOCCACHESYNC: 2236 case DIOCCACHESYNC:
2242 return 0; 2237 return 0;
2243 2238
2244 case DIOCGSTRATEGY: 2239 case DIOCGSTRATEGY:
2245 { 2240 {
2246 struct disk_strategy *dks = (void *)addr; 2241 struct disk_strategy *dks = (void *)addr;
2247 2242
2248 s = splbio(); 2243 s = splbio();
2249 strlcpy(dks->dks_name, bufq_getstrategyname(ace->sc_q), 2244 strlcpy(dks->dks_name, bufq_getstrategyname(ace->sc_q),
2250 sizeof(dks->dks_name)); 2245 sizeof(dks->dks_name));
2251 splx(s); 2246 splx(s);
2252 dks->dks_paramlen = 0; 2247 dks->dks_paramlen = 0;
2253 2248
2254 return 0; 2249 return 0;
2255 } 2250 }
2256 2251
2257 case DIOCSSTRATEGY: 2252 case DIOCSSTRATEGY:
2258 { 2253 {
2259 struct disk_strategy *dks = (void *)addr; 2254 struct disk_strategy *dks = (void *)addr;
2260 struct bufq_state *new; 2255 struct bufq_state *new;
2261 struct bufq_state *old; 2256 struct bufq_state *old;
2262 2257
2263 if ((flag & FWRITE) == 0) { 2258 if ((flag & FWRITE) == 0) {
2264 return EBADF; 2259 return EBADF;
2265 } 2260 }
2266 if (dks->dks_param != NULL) { 2261 if (dks->dks_param != NULL) {
2267 return EINVAL; 2262 return EINVAL;
2268 } 2263 }
2269 dks->dks_name[sizeof(dks->dks_name) - 1] = 0; /* ensure term */ 2264 dks->dks_name[sizeof(dks->dks_name) - 1] = 0; /* ensure term */
2270 error = bufq_alloc(&new, dks->dks_name, 2265 error = bufq_alloc(&new, dks->dks_name,
2271 BUFQ_EXACT|BUFQ_SORT_RAWBLOCK); 2266 BUFQ_EXACT|BUFQ_SORT_RAWBLOCK);
2272 if (error) { 2267 if (error) {
2273 return error; 2268 return error;
2274 } 2269 }
2275 s = splbio(); 2270 s = splbio();
2276 old = ace->sc_q; 2271 old = ace->sc_q;
2277 bufq_move(new, old); 2272 bufq_move(new, old);
2278 ace->sc_q = new; 2273 ace->sc_q = new;
2279 splx(s); 2274 splx(s);
2280 bufq_free(old); 2275 bufq_free(old);
2281 2276
2282 return 0; 2277 return 0;
2283 } 2278 }
2284 2279
2285#ifdef USE_ACE_FOR_RECONFIG 2280#ifdef USE_ACE_FOR_RECONFIG
2286 /* 2281 /*
2287 * Ok, how do I get this standardized 2282 * Ok, how do I get this standardized
2288 * [nothing to do with disks either] 2283 * [nothing to do with disks either]
2289 */ 2284 */
2290#define DIOC_FPGA_RECONFIGURE _IOW('d',166, struct ioctl_pt) 2285#define DIOC_FPGA_RECONFIGURE _IOW('d',166, struct ioctl_pt)
2291 case DIOC_FPGA_RECONFIGURE: 2286 case DIOC_FPGA_RECONFIGURE:
2292 { 2287 {
2293 /* 2288 /*
2294 * BUGBUG This is totally wrong, we need to fault in 2289 * BUGBUG This is totally wrong, we need to fault in
2295 * all data in advance. 2290 * all data in advance.
2296 * Otherwise we get back here with the sysace in a bad state 2291 * Otherwise we get back here with the sysace in a bad state
2297 * (its NOT reentrant!) 2292 * (its NOT reentrant!)
2298 */ 2293 */
2299 struct ioctl_pt *pt = (struct ioctl_pt *)addr; 2294 struct ioctl_pt *pt = (struct ioctl_pt *)addr;
2300 return sysace_send_config(ace,(uint32_t*)pt->data,pt->com); 2295 return sysace_send_config(ace,(uint32_t*)pt->data,pt->com);
2301 } 2296 }
2302#endif /* USE_ACE_FOR_RECONFIG */ 2297#endif /* USE_ACE_FOR_RECONFIG */
2303 2298
2304 default: 2299 default:
2305 /* 2300 /*
2306 * NB: we get a DIOCGWEDGEINFO, but nobody else handles it 2301 * NB: we get a DIOCGWEDGEINFO, but nobody else handles it
2307 * either 2302 * either
2308 */ 2303 */
2309 DEBUG_PRINT(("aceioctl: unsup x%lx\n", xfer), DEBUG_FUNCS); 2304 DEBUG_PRINT(("aceioctl: unsup x%lx\n", xfer), DEBUG_FUNCS);
2310 return ENOTTY; 2305 return ENOTTY;
2311 } 2306 }
2312} 2307}
2313 2308
2314int 2309int
2315acesize(dev_t dev) 2310acesize(dev_t dev)
2316{ 2311{
2317 struct ace_softc *ace; 2312 struct ace_softc *ace;
2318 int part, omask; 2313 int part, omask;
2319 int size; 2314 int size;
2320 2315
2321 DEBUG_PRINT(("acesize\n"), DEBUG_FUNCS); 2316 DEBUG_PRINT(("acesize\n"), DEBUG_FUNCS);
2322 2317
2323 ace = device_lookup_private(&ace_cd, ACEUNIT(dev)); 2318 ace = device_lookup_private(&ace_cd, ACEUNIT(dev));
2324 if (ace == NULL) 2319 if (ace == NULL)
2325 return -1; 2320 return -1;
2326 2321
2327 part = ACEPART(dev); 2322 part = ACEPART(dev);
2328 omask = ace->sc_dk.dk_openmask & (1 << part); 2323 omask = ace->sc_dk.dk_openmask & (1 << part);
2329 2324
2330 if (omask == 0 && aceopen(dev, 0, S_IFBLK, NULL) != 0) 2325 if (omask == 0 && aceopen(dev, 0, S_IFBLK, NULL) != 0)
2331 return -1; 2326 return -1;
2332 if (ace->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP) 2327 if (ace->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
2333 size = -1; 2328 size = -1;
2334 else 2329 else
2335 size = ace->sc_dk.dk_label->d_partitions[part].p_size * 2330 size = ace->sc_dk.dk_label->d_partitions[part].p_size *
2336 (ace->sc_dk.dk_label->d_secsize / DEV_BSIZE); 2331 (ace->sc_dk.dk_label->d_secsize / DEV_BSIZE);
2337 if (omask == 0 && aceclose(dev, 0, S_IFBLK, NULL) != 0) 2332 if (omask == 0 && aceclose(dev, 0, S_IFBLK, NULL) != 0)
2338 return -1; 2333 return -1;
2339 return size; 2334 return size;
2340} 2335}
2341 2336
2342/* #define ACE_DUMP_NOT_TRUSTED if you just want to watch */ 2337/* #define ACE_DUMP_NOT_TRUSTED if you just want to watch */
2343#define ACE_DUMP_NOT_TRUSTED 2338#define ACE_DUMP_NOT_TRUSTED
2344static int acedoingadump = 0; 2339static int acedoingadump = 0;
2345 2340
2346/* 2341/*
2347 * Dump core after a system crash. 2342 * Dump core after a system crash.
2348 */ 2343 */
2349int 2344int
2350acedump(dev_t dev, daddr_t blkno, void *va, size_t size) 2345acedump(dev_t dev, daddr_t blkno, void *va, size_t size)
2351{ 2346{
2352 struct ace_softc *ace; /* disk unit to do the I/O */ 2347 struct ace_softc *ace; /* disk unit to do the I/O */
2353 struct disklabel *lp; /* disk's disklabel */ 2348 struct disklabel *lp; /* disk's disklabel */
2354 int part, err; 2349 int part, err;
2355 int nblks; /* total number of sectors left to write */ 2350 int nblks; /* total number of sectors left to write */
2356 2351
2357 /* Check if recursive dump; if so, punt. */ 2352 /* Check if recursive dump; if so, punt. */
2358 if (acedoingadump) 2353 if (acedoingadump)
2359 return EFAULT; 2354 return EFAULT;
2360 acedoingadump = 1; 2355 acedoingadump = 1;
2361 2356
2362 ace = device_lookup_private(&ace_cd, ACEUNIT(dev)); 2357 ace = device_lookup_private(&ace_cd, ACEUNIT(dev));
2363 if (ace == NULL) 2358 if (ace == NULL)
2364 return ENXIO; 2359 return ENXIO;
2365 2360
2366 part = ACEPART(dev); 2361 part = ACEPART(dev);
2367 2362
2368 /* Convert to disk sectors. Request must be a multiple of size. */ 2363 /* Convert to disk sectors. Request must be a multiple of size. */
2369 lp = ace->sc_dk.dk_label; 2364 lp = ace->sc_dk.dk_label;
2370 if ((size % lp->d_secsize) != 0) 2365 if ((size % lp->d_secsize) != 0)
2371 return EFAULT; 2366 return EFAULT;
2372 nblks = size / lp->d_secsize; 2367 nblks = size / lp->d_secsize;
2373 blkno = blkno / (lp->d_secsize / DEV_BSIZE); 2368 blkno = blkno / (lp->d_secsize / DEV_BSIZE);
2374 2369
2375 /* Check transfer bounds against partition size. */ 2370 /* Check transfer bounds against partition size. */
2376 if ((blkno < 0) || ((blkno + nblks) > lp->d_partitions[part].p_size)) 2371 if ((blkno < 0) || ((blkno + nblks) > lp->d_partitions[part].p_size))
2377 return EINVAL; 2372 return EINVAL;
2378 2373
2379 /* Offset block number to start of partition. */ 2374 /* Offset block number to start of partition. */
2380 blkno += lp->d_partitions[part].p_offset; 2375 blkno += lp->d_partitions[part].p_offset;
2381 2376
2382 ace->sc_bp = NULL; 2377 ace->sc_bp = NULL;
2383 ace->sc_bio.blkno = blkno; 2378 ace->sc_bio.blkno = blkno;
2384 ace->sc_bio.flags = ATA_POLL; 2379 ace->sc_bio.flags = ATA_POLL;
2385 ace->sc_bio.nbytes = nblks * lp->d_secsize; 2380 ace->sc_bio.nbytes = nblks * lp->d_secsize;
2386 ace->sc_bio.databuf = va; 2381 ace->sc_bio.databuf = va;
2387#ifndef ACE_DUMP_NOT_TRUSTED 2382#ifndef ACE_DUMP_NOT_TRUSTED
2388 ace->active_xfer = bp; 2383 ace->active_xfer = bp;
2389 wakeup(&ace->ch_thread); 2384 wakeup(&ace->ch_thread);
2390 2385
2391 switch(ace->sc_bio.error) { 2386 switch(ace->sc_bio.error) {
2392 case ETIMEDOUT: 2387 case ETIMEDOUT:
2393 printf("acedump: device timed out"); 2388 printf("acedump: device timed out");
2394 err = EIO; 2389 err = EIO;
2395 break; 2390 break;
2396 case 0: 2391 case 0:
2397 err = 0; 2392 err = 0;
2398 break; 2393 break;
2399 default: 2394 default:
2400 panic("acedump: unknown error type"); 2395 panic("acedump: unknown error type");
2401 } 2396 }
2402 if (err != 0) { 2397 if (err != 0) {
2403 printf("\n"); 2398 printf("\n");
2404 return err; 2399 return err;
2405 } 2400 }
2406#else /* ACE_DUMP_NOT_TRUSTED */ 2401#else /* ACE_DUMP_NOT_TRUSTED */
2407 /* Let's just talk about this first... */ 2402 /* Let's just talk about this first... */
2408 device_printf(ace->sc_dev, ": dump addr 0x%p, size %zu blkno %llx\n", 2403 device_printf(ace->sc_dev, ": dump addr 0x%p, size %zu blkno %llx\n",
2409 va, size, blkno); 2404 va, size, blkno);
2410 DELAY(500 * 1000); /* half a second */ 2405 DELAY(500 * 1000); /* half a second */
2411 err = 0; 2406 err = 0;
2412 __USE(err); 2407 __USE(err);
2413#endif 2408#endif
2414 2409
2415 acedoingadump = 0; 2410 acedoingadump = 0;
2416 return 0; 2411 return 0;
2417} 2412}
2418 2413
2419#ifdef HAS_BAD144_HANDLING 2414#ifdef HAS_BAD144_HANDLING
2420/* 2415/*
2421 * Internalize the bad sector table. 2416 * Internalize the bad sector table.
2422 */ 2417 */
2423void 2418void
2424bad144intern(struct ace_softc *ace) 2419bad144intern(struct ace_softc *ace)
2425{ 2420{
2426 struct dkbad *bt = &ace->sc_dk.dk_cpulabel->bad; 2421 struct dkbad *bt = &ace->sc_dk.dk_cpulabel->bad;
2427 struct disklabel *lp = ace->sc_dk.dk_label; 2422 struct disklabel *lp = ace->sc_dk.dk_label;
2428 int i = 0; 2423 int i = 0;
2429 2424
2430 DEBUG_PRINT(("bad144intern\n"), DEBUG_XFERS); 2425 DEBUG_PRINT(("bad144intern\n"), DEBUG_XFERS);
2431 2426
2432 for (; i < NBT_BAD; i++) { 2427 for (; i < NBT_BAD; i++) {
2433 if (bt->bt_bad[i].bt_cyl == 0xffff) 2428 if (bt->bt_bad[i].bt_cyl == 0xffff)
2434 break; 2429 break;
2435 ace->sc_bio.badsect[i] = 2430 ace->sc_bio.badsect[i] =
2436 bt->bt_bad[i].bt_cyl * lp->d_secpercyl + 2431 bt->bt_bad[i].bt_cyl * lp->d_secpercyl +
2437 (bt->bt_bad[i].bt_trksec >> 8) * lp->d_nsectors + 2432 (bt->bt_bad[i].bt_trksec >> 8) * lp->d_nsectors +
2438 (bt->bt_bad[i].bt_trksec & 0xff); 2433 (bt->bt_bad[i].bt_trksec & 0xff);
2439 } 2434 }
2440 for (; i < NBT_BAD+1; i++) 2435 for (; i < NBT_BAD+1; i++)
2441 ace->sc_bio.badsect[i] = -1; 2436 ace->sc_bio.badsect[i] = -1;
2442} 2437}
2443#endif 2438#endif
2444 2439
2445static void 2440static void
2446ace_set_geometry(struct ace_softc *ace) 2441ace_set_geometry(struct ace_softc *ace)
2447{ 2442{
2448 struct disk_geom *dg = &ace->sc_dk.dk_geom; 2443 struct disk_geom *dg = &ace->sc_dk.dk_geom;
2449 2444
2450 memset(dg, 0, sizeof(*dg)); 2445 memset(dg, 0, sizeof(*dg));
2451 2446
2452 dg->dg_secperunit = ace->sc_capacity; 2447 dg->dg_secperunit = ace->sc_capacity;
2453 dg->dg_secsize = DEV_BSIZE /* XXX 512? */; 2448 dg->dg_secsize = DEV_BSIZE /* XXX 512? */;
2454 dg->dg_nsectors = ace->sc_params.CurrentSectorsPerTrack; 2449 dg->dg_nsectors = ace->sc_params.CurrentSectorsPerTrack;
2455 dg->dg_ntracks = ace->sc_params.CurrentNumberOfHeads; 2450 dg->dg_ntracks = ace->sc_params.CurrentNumberOfHeads;
2456 2451
2457 disk_set_info(ace->sc_dev, &ace->sc_dk, ST506); 2452 disk_set_info(ace->sc_dev, &ace->sc_dk, ST506);
2458} 2453}

cvs diff -r1.20 -r1.20.8.1 src/sys/arch/emips/ebus/flash_ebus.c (switch to unified diff)

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