Bug Summary

File:dev/ata/ata_wdc.c
Warning:line 333, column 6
Value stored to 'error' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ata_wdc.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/ata/ata_wdc.c
1/* $OpenBSD: ata_wdc.c,v 1.52 2018/11/02 09:59:36 fcambus Exp $ */
2/* $NetBSD: ata_wdc.c,v 1.21 1999/08/09 09:43:11 bouyer Exp $ */
3
4/*
5 * Copyright (c) 1998, 2001 Manuel Bouyer.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29/*-
30 * Copyright (c) 1998 The NetBSD Foundation, Inc.
31 * All rights reserved.
32 *
33 * This code is derived from software contributed to The NetBSD Foundation
34 * by Charles M. Hannum, by Onno van der Linden and by Manuel Bouyer.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
46 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
47 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
49 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
50 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
51 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
52 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
53 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55 * POSSIBILITY OF SUCH DAMAGE.
56 */
57
58#include <sys/param.h>
59#include <sys/systm.h>
60#include <sys/kernel.h>
61#include <sys/stat.h>
62#include <sys/buf.h>
63#include <sys/malloc.h>
64#include <sys/device.h>
65#include <sys/disklabel.h>
66#include <sys/disk.h>
67#include <sys/syslog.h>
68
69#include <machine/intr.h>
70#include <machine/bus.h>
71
72#include <dev/ata/atavar.h>
73#include <dev/ic/wdcreg.h>
74#include <dev/ic/wdcvar.h>
75#include <dev/ata/wdvar.h>
76
77#ifdef HIBERNATE1
78#include <sys/hibernate.h>
79#endif
80
81#define DEBUG_INTR0x01 0x01
82#define DEBUG_XFERS0x02 0x02
83#define DEBUG_STATUS0x04 0x04
84#define DEBUG_FUNCS0x08 0x08
85#define DEBUG_PROBE0x10 0x10
86
87#ifdef WDCDEBUG
88#ifndef WDCDEBUG_WD_MASK
89#define WDCDEBUG_WD_MASK 0x00
90#endif
91int wdcdebug_wd_mask = WDCDEBUG_WD_MASK;
92#define WDCDEBUG_PRINT(args, level) do { \
93 if ((wdcdebug_wd_mask & (level)) != 0) \
94 printf args; \
95} while (0)
96#else
97#define WDCDEBUG_PRINT(args, level)
98#endif
99
100#define ATA_DELAY45000 45000 /* 45s for a drive I/O */
101
102void wdc_ata_bio_start(struct channel_softc *, struct wdc_xfer *);
103void _wdc_ata_bio_start(struct channel_softc *, struct wdc_xfer *);
104int wdc_ata_bio_intr(struct channel_softc *, struct wdc_xfer *, int);
105void wdc_ata_bio_kill_xfer(struct channel_softc *, struct wdc_xfer *);
106void wdc_ata_bio_done(struct channel_softc *, struct wdc_xfer *);
107int wdc_ata_ctrl_intr(struct channel_softc *, struct wdc_xfer *, int);
108int wdc_ata_err(struct ata_drive_datas *, struct ata_bio *);
109#define WDC_ATA_NOERR0x00 0x00 /* Drive doesn't report an error */
110#define WDC_ATA_RECOV0x01 0x01 /* There was a recovered error */
111#define WDC_ATA_ERR0x02 0x02 /* Drive reports an error */
112
113#ifdef HIBERNATE1
114int
115wd_hibernate_io(dev_t dev, daddr_t blkno, vaddr_t addr, size_t size, int op, void *page)
116{
117 struct {
118 struct wd_softc wd;
119 struct wdc_xfer xfer;
120 struct channel_softc chp;
121 daddr_t poffset;
122 size_t psize;
123 } *my = page;
124 struct wd_softc *real_wd, *wd = &my->wd;
125 struct wdc_xfer *xfer = &my->xfer;
126 struct channel_softc *chp = &my->chp;
127 struct ata_bio *ata_bio;
128 extern struct cfdriver wd_cd;
129
130 /* early call for initialization */
131 if (op == HIB_INIT-1) {
132 my->poffset = blkno;
133 my->psize = size;
134 return(0);
135 }
136
137 real_wd = (struct wd_softc *)disk_lookup(&wd_cd, DISKUNIT(dev)(((unsigned)((dev) & 0xff) | (((dev) & 0xffff0000) >>
8)) / 16)
);
138 if (real_wd == NULL((void *)0))
139 return (ENODEV19);
140
141 if (op == HIB_DONE-2) {
142 struct wdc_softc *wdc = chp->wdc;
143 config_suspend(&wdc->sc_dev, DVACT_RESUME4);
144 return (0);
145 }
146
147 if (blkno > my->psize)
148 return (E2BIG7);
149 blkno += my->poffset;
150
151 /*
152 * Craft a fake set of softc and related structures
153 * which we think the driver modifies. Some of these will
154 * have pointers which reach to unsafe places, but..
155 */
156 bcopy(real_wd->drvp->chnl_softc, &my->chp, sizeof my->chp);
157 chp->ch_drive[0].chnl_softc = chp;
158 chp->ch_drive[1].chnl_softc = chp;
159
160 bcopy(real_wd, &my->wd, sizeof my->wd);
161 ata_bio = &wd->sc_wdc_bio;
162 ata_bio->wd = wd; /* fixup ata_bio->wd */
163 wd->drvp = &chp->ch_drive[real_wd->drvp->drive];
164
165 /* Fill the request and submit it */
166 wd->sc_wdc_bio.blkno = blkno;
167 wd->sc_wdc_bio.flags = ATA_POLL0x0002 | ATA_LBA480x0080;
168 if (op == HIB_R0)
169 wd->sc_wdc_bio.flags |= ATA_READ0x0020;
170 wd->sc_wdc_bio.bcount = size;
171 wd->sc_wdc_bio.databuf = (caddr_t)addr;
172 wd->sc_wdc_bio.wd = wd;
173
174 bzero(&my->xfer, sizeof my->xfer)__builtin_bzero((&my->xfer), (sizeof my->xfer));
175 xfer->c_flags |= C_PRIVATEXFER0x0400; /* Our xfer is totally private */
176 xfer->c_flags |= C_POLL0x0020;
177 xfer->drive = wd->drvp->drive;
178 xfer->cmd = ata_bio;
179 xfer->databuf = ata_bio->databuf;
180 xfer->c_bcount = ata_bio->bcount;
181 xfer->c_start = wdc_ata_bio_start;
182 xfer->c_intr = wdc_ata_bio_intr;
183 xfer->c_kill_xfer = wdc_ata_bio_kill_xfer;
184 wdc_exec_xfer(chp, xfer);
185 return (ata_bio->flags & ATA_ITSDONE0x0004) ? 0 : EIO5;
186}
187#endif /* HIBERNATE */
188
189/*
190 * Handle block I/O operation. Return WDC_COMPLETE, WDC_QUEUED, or
191 * WDC_TRY_AGAIN. Must be called at splbio().
192 */
193int
194wdc_ata_bio(struct ata_drive_datas *drvp, struct ata_bio *ata_bio)
195{
196 struct wdc_xfer *xfer;
197 struct channel_softc *chp = drvp->chnl_softc;
198
199 xfer = wdc_get_xfer(WDC_NOSLEEP0x01);
200 if (xfer == NULL((void *)0))
201 return WDC_TRY_AGAIN0x03;
202 if (ata_bio->flags & ATA_POLL0x0002)
203 xfer->c_flags |= C_POLL0x0020;
204 if (!(ata_bio->flags & ATA_POLL0x0002) &&
205 (drvp->drive_flags & (DRIVE_DMA0x0010 | DRIVE_UDMA0x0020)) &&
206 (ata_bio->flags & ATA_SINGLE0x0008) == 0 &&
207 (ata_bio->bcount > 512 ||
208 (chp->wdc->quirks & WDC_QUIRK_NOSHORTDMA0x0001) == 0))
209 xfer->c_flags |= C_DMA0x0040;
210 xfer->drive = drvp->drive;
211 xfer->cmd = ata_bio;
212 xfer->databuf = ata_bio->databuf;
213 xfer->c_bcount = ata_bio->bcount;
214 xfer->c_start = wdc_ata_bio_start;
215 xfer->c_intr = wdc_ata_bio_intr;
216 xfer->c_kill_xfer = wdc_ata_bio_kill_xfer;
217 wdc_exec_xfer(chp, xfer);
218 return (ata_bio->flags & ATA_ITSDONE0x0004) ? WDC_COMPLETE0x01 : WDC_QUEUED0x02;
219}
220
221void
222wdc_ata_bio_start(struct channel_softc *chp, struct wdc_xfer *xfer)
223{
224 struct ata_bio *ata_bio = xfer->cmd;
225 WDCDEBUG_PRINT(("wdc_ata_bio_start %s:%d:%d\n",
226 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
227 DEBUG_XFERS);
228
229 /* start timeout machinery */
230 if ((ata_bio->flags & ATA_POLL0x0002) == 0)
231 timeout_add_msec(&chp->ch_timo, ATA_DELAY45000);
232 _wdc_ata_bio_start(chp, xfer);
233}
234
235void
236_wdc_ata_bio_start(struct channel_softc *chp, struct wdc_xfer *xfer)
237{
238 struct ata_bio *ata_bio = xfer->cmd;
239 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
240 u_int16_t cyl;
241 u_int8_t head, sect, cmd = 0;
242 int nblks;
243 int error, dma_flags = 0;
244
245 WDCDEBUG_PRINT(("_wdc_ata_bio_start %s:%d:%d\n",
246 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
247 DEBUG_INTR | DEBUG_XFERS);
248 /* Do control operations specially. */
249 if (drvp->state < READY10) {
250 /*
251 * Actually, we want to be careful not to mess with the control
252 * state if the device is currently busy, but we can assume
253 * that we never get to this point if that's the case.
254 */
255 /* at this point, we should only be in RECAL state */
256 if (drvp->state != RECAL0) {
257 printf("%s:%d:%d: bad state %d in _wdc_ata_bio_start\n",
258 chp->wdc->sc_dev.dv_xname, chp->channel,
259 xfer->drive, drvp->state);
260 panic("_wdc_ata_bio_start: bad state");
261 }
262 xfer->c_intr = wdc_ata_ctrl_intr;
263 wdc_set_drive(chp, xfer->drive);
264 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY)((wdc_wait_for_status((chp), (0x40), (0x40), (45000)) >= 0
) ? 0 : -1)
!= 0)
265 goto timeout;
266 wdccommandshort(chp, xfer->drive, WDCC_RECAL0x10);
267 drvp->state = RECAL_WAIT1;
268 if ((ata_bio->flags & ATA_POLL0x0002) == 0) {
269 chp->ch_flags |= WDCF_IRQ_WAIT0x10;
270 } else {
271 /* Wait for at last 400ns for status bit to be valid */
272 DELAY(1)(*delay_func)(1);
273 wdc_ata_ctrl_intr(chp, xfer, 0);
274 }
275 return;
276 }
277
278 if (xfer->c_flags & C_DMA0x0040) {
279 if (drvp->n_xfers <= NXFER1000)
280 drvp->n_xfers++;
281 dma_flags = (ata_bio->flags & ATA_READ0x0020) ? WDC_DMA_READ0x01 : 0;
282 if (ata_bio->flags & ATA_LBA480x0080)
283 dma_flags |= WDC_DMA_LBA480x04;
284 }
285again:
286 /*
287 *
288 * When starting a multi-sector transfer, or doing single-sector
289 * transfers...
290 */
291 if (xfer->c_skip == 0 || (ata_bio->flags & ATA_SINGLE0x0008) != 0) {
292 if (ata_bio->flags & ATA_SINGLE0x0008)
293 nblks = 1;
294 else
295 nblks = xfer->c_bcount / ata_bio->lp->d_secsize;
296 if (ata_bio->flags & ATA_LBA0x0010) {
297 sect = (ata_bio->blkno >> 0) & 0xff;
298 cyl = (ata_bio->blkno >> 8) & 0xffff;
299 head = (ata_bio->blkno >> 24) & 0x0f;
300 head |= WDSD_LBA0x40;
301 } else {
302 int blkno = ata_bio->blkno;
303 sect = blkno % ata_bio->lp->d_nsectors;
304 sect++; /* Sectors begin with 1, not 0. */
305 blkno /= ata_bio->lp->d_nsectors;
306 head = blkno % ata_bio->lp->d_ntracks;
307 blkno /= ata_bio->lp->d_ntracks;
308 cyl = blkno;
309 head |= WDSD_CHS0x00;
310 }
311 if (xfer->c_flags & C_DMA0x0040) {
312 ata_bio->nblks = nblks;
313 ata_bio->nbytes = xfer->c_bcount;
314 if (ata_bio->flags & ATA_LBA480x0080)
315 cmd = (ata_bio->flags & ATA_READ0x0020) ?
316 WDCC_READDMA_EXT0x25 : WDCC_WRITEDMA_EXT0x35;
317 else
318 cmd = (ata_bio->flags & ATA_READ0x0020) ?
319 WDCC_READDMA0xc8 : WDCC_WRITEDMA0xca;
320 /* Init the DMA channel. */
321 error = (*chp->wdc->dma_init)(chp->wdc->dma_arg,
322 chp->channel, xfer->drive,
323 (char *)xfer->databuf + xfer->c_skip,
324 ata_bio->nbytes, dma_flags);
325 if (error) {
326 if (error == EINVAL22) {
327 /*
328 * We can't do DMA on this transfer
329 * for some reason. Fall back to
330 * PIO.
331 */
332 xfer->c_flags &= ~C_DMA0x0040;
333 error = 0;
Value stored to 'error' is never read
334 goto do_pio;
335 }
336 ata_bio->error = ERR_DMA3;
337 ata_bio->r_error = 0;
338 wdc_ata_bio_done(chp, xfer);
339 return;
340 }
341 /* Initiate command */
342 wdc_set_drive(chp, xfer->drive);
343 if (wait_for_ready(chp, ATA_DELAY)((wdc_wait_for_status(((chp)), (0x40), (0x40), ((45000))) >=
0) ? 0 : -1)
< 0)
344 goto timeout;
345
346 /* start the DMA channel (before) */
347 if (chp->ch_flags & WDCF_DMA_BEFORE_CMD0x80)
348 (*chp->wdc->dma_start)(chp->wdc->dma_arg,
349 chp->channel, xfer->drive);
350
351 if (ata_bio->flags & ATA_LBA480x0080) {
352 wdccommandext(chp, xfer->drive, cmd,
353 (u_int64_t)ata_bio->blkno, nblks);
354 } else {
355 wdccommand(chp, xfer->drive, cmd, cyl,
356 head, sect, nblks, 0);
357 }
358
359 /* start the DMA channel (after) */
360 if ((chp->ch_flags & WDCF_DMA_BEFORE_CMD0x80) == 0)
361 (*chp->wdc->dma_start)(chp->wdc->dma_arg,
362 chp->channel, xfer->drive);
363
364 chp->ch_flags |= WDCF_DMA_WAIT0x20;
365 /* wait for irq */
366 goto intr;
367 } /* else not DMA */
368 do_pio:
369 ata_bio->nblks = min(nblks, ata_bio->multi);
370 ata_bio->nbytes = ata_bio->nblks * ata_bio->lp->d_secsize;
371 KASSERT(nblks == 1 || (ata_bio->flags & ATA_SINGLE) == 0)((nblks == 1 || (ata_bio->flags & 0x0008) == 0) ? (void
)0 : __assert("diagnostic ", "/usr/src/sys/dev/ata/ata_wdc.c"
, 371, "nblks == 1 || (ata_bio->flags & ATA_SINGLE) == 0"
))
;
372 if (ata_bio->nblks > 1) {
373 if (ata_bio->flags & ATA_LBA480x0080)
374 cmd = (ata_bio->flags & ATA_READ0x0020) ?
375 WDCC_READMULTI_EXT0x29 : WDCC_WRITEMULTI_EXT0x39;
376 else
377 cmd = (ata_bio->flags & ATA_READ0x0020) ?
378 WDCC_READMULTI0xc4 : WDCC_WRITEMULTI0xc5;
379 } else {
380 if (ata_bio->flags & ATA_LBA480x0080)
381 cmd = (ata_bio->flags & ATA_READ0x0020) ?
382 WDCC_READ_EXT0x24 : WDCC_WRITE_EXT0x34;
383 else
384 cmd = (ata_bio->flags & ATA_READ0x0020) ?
385 WDCC_READ0x20 : WDCC_WRITE0x30;
386 }
387 /* Initiate command! */
388 wdc_set_drive(chp, xfer->drive);
389 if (wait_for_ready(chp, ATA_DELAY)((wdc_wait_for_status(((chp)), (0x40), (0x40), ((45000))) >=
0) ? 0 : -1)
< 0)
390 goto timeout;
391 if (ata_bio->flags & ATA_LBA480x0080) {
392 wdccommandext(chp, xfer->drive, cmd,
393 (u_int64_t)ata_bio->blkno, nblks);
394 } else {
395 wdccommand(chp, xfer->drive, cmd, cyl,
396 head, sect, nblks, 0);
397 }
398 } else if (ata_bio->nblks > 1) {
399 /* The number of blocks in the last stretch may be smaller. */
400 nblks = xfer->c_bcount / ata_bio->lp->d_secsize;
401 if (ata_bio->nblks > nblks) {
402 ata_bio->nblks = nblks;
403 ata_bio->nbytes = xfer->c_bcount;
404 }
405 }
406 /* If this was a write and not using DMA, push the data. */
407 if ((ata_bio->flags & ATA_READ0x0020) == 0) {
408 if (wait_for_drq(chp, ATA_DELAY)((wdc_wait_for_status(((chp)), (0x08), (0x08), ((45000))) >=
0) ? 0 : -1)
!= 0) {
409 printf("%s:%d:%d: timeout waiting for DRQ, "
410 "st=0x%b, err=0x%02x\n",
411 chp->wdc->sc_dev.dv_xname, chp->channel,
412 xfer->drive, chp->ch_status, WDCS_BITS"\020\010BSY\007DRDY\006DWF\005DSC\004DRQ\003CORR\002IDX\001ERR",
413 chp->ch_error);
414 if (wdc_ata_err(drvp, ata_bio) != WDC_ATA_ERR0x02)
415 ata_bio->error = TIMEOUT4;
416 wdc_ata_bio_done(chp, xfer);
417 return;
418 }
419 if (wdc_ata_err(drvp, ata_bio) == WDC_ATA_ERR0x02) {
420 wdc_ata_bio_done(chp, xfer);
421 return;
422 }
423 wdc_output_bytes(drvp, (char *)xfer->databuf + xfer->c_skip,
424 ata_bio->nbytes);
425 }
426
427intr: /* Wait for IRQ (either real or polled) */
428 if ((ata_bio->flags & ATA_POLL0x0002) == 0) {
429 chp->ch_flags |= WDCF_IRQ_WAIT0x10;
430 } else {
431 /* Wait for at last 400ns for status bit to be valid */
432 delay(1)(*delay_func)(1);
433 if (chp->ch_flags & WDCF_DMA_WAIT0x20) {
434 wdc_dmawait(chp, xfer, ATA_DELAY45000);
435 chp->ch_flags &= ~WDCF_DMA_WAIT0x20;
436 }
437 wdc_ata_bio_intr(chp, xfer, 0);
438 if ((ata_bio->flags & ATA_ITSDONE0x0004) == 0)
439 goto again;
440 }
441 return;
442timeout:
443 if (chp->ch_status == 0xff)
444 return;
445 printf("%s:%d:%d: not ready, st=0x%b, err=0x%02x\n",
446 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
447 chp->ch_status, WDCS_BITS"\020\010BSY\007DRDY\006DWF\005DSC\004DRQ\003CORR\002IDX\001ERR", chp->ch_error);
448 if (wdc_ata_err(drvp, ata_bio) != WDC_ATA_ERR0x02)
449 ata_bio->error = TIMEOUT4;
450 wdc_ata_bio_done(chp, xfer);
451 return;
452}
453
454int
455wdc_ata_bio_intr(struct channel_softc *chp, struct wdc_xfer *xfer, int irq)
456{
457 struct ata_bio *ata_bio = xfer->cmd;
458 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
459 int drv_err;
460
461 WDCDEBUG_PRINT(("wdc_ata_bio_intr %s:%d:%d\n",
462 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
463 DEBUG_INTR | DEBUG_XFERS);
464
465
466 /* Is it not a transfer, but a control operation? */
467 if (drvp->state < READY10) {
468 printf("%s:%d:%d: bad state %d in wdc_ata_bio_intr\n",
469 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
470 drvp->state);
471 panic("wdc_ata_bio_intr: bad state");
472 }
473
474 /*
475 * reset on timeout. This will cause extra resets in the case
476 * of occasional lost interrupts
477 */
478 if (xfer->c_flags & C_TIMEOU0x0004)
479 goto timeout;
480
481 /* Ack interrupt done by wait_for_unbusy */
482 if (wait_for_unbusy(chp,((wdc_wait_for_status(((chp)), (0), (0), (((irq == 0) ? 45000
: 0))) >= 0) ? 0 : -1)
483 (irq == 0) ? ATA_DELAY : 0)((wdc_wait_for_status(((chp)), (0), (0), (((irq == 0) ? 45000
: 0))) >= 0) ? 0 : -1)
< 0) {
484 if (irq)
485 return 0; /* IRQ was not for us */
486 printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip%d\n",
487 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
488 xfer->c_bcount, xfer->c_skip);
489
490 goto timeout;
491 }
492 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK0x0400)
493 chp->wdc->irqack(chp);
494
495 drv_err = wdc_ata_err(drvp, ata_bio);
496
497 if (xfer->c_flags & C_DMA0x0040) {
498 if (chp->wdc->dma_status != 0) {
499 if (drv_err != WDC_ATA_ERR0x02) {
500 ata_bio->error = ERR_DMA3;
501 drv_err = WDC_ATA_ERR0x02;
502 }
503 }
504 if (chp->ch_status & WDCS_DRQ0x08) {
505 if (drv_err != WDC_ATA_ERR0x02) {
506 printf("%s:%d:%d: intr with DRQ (st=0x%b)\n",
507 chp->wdc->sc_dev.dv_xname, chp->channel,
508 xfer->drive, chp->ch_status, WDCS_BITS"\020\010BSY\007DRDY\006DWF\005DSC\004DRQ\003CORR\002IDX\001ERR");
509 ata_bio->error = TIMEOUT4;
510 drv_err = WDC_ATA_ERR0x02;
511 }
512 }
513 if (drv_err != WDC_ATA_ERR0x02)
514 goto end;
515 ata_dmaerr(drvp);
516 }
517
518 /* if we had an error, end */
519 if (drv_err == WDC_ATA_ERR0x02) {
520 wdc_ata_bio_done(chp, xfer);
521 return 1;
522 }
523
524 /* If this was a read and not using DMA, fetch the data. */
525 if ((ata_bio->flags & ATA_READ0x0020) != 0) {
526 if ((chp->ch_status & WDCS_DRQ0x08) != WDCS_DRQ0x08) {
527 printf("%s:%d:%d: read intr before drq\n",
528 chp->wdc->sc_dev.dv_xname, chp->channel,
529 xfer->drive);
530 ata_bio->error = TIMEOUT4;
531 wdc_ata_bio_done(chp, xfer);
532 return 1;
533 }
534 wdc_input_bytes(drvp, (char *)xfer->databuf + xfer->c_skip,
535 ata_bio->nbytes);
536 }
537end:
538 ata_bio->blkno += ata_bio->nblks;
539 ata_bio->blkdone += ata_bio->nblks;
540 xfer->c_skip += ata_bio->nbytes;
541 xfer->c_bcount -= ata_bio->nbytes;
542 /* See if this transfer is complete. */
543 if (xfer->c_bcount > 0) {
544 if ((ata_bio->flags & ATA_POLL0x0002) == 0) {
545 /* Start the next operation */
546 _wdc_ata_bio_start(chp, xfer);
547 } else {
548 /* Let _wdc_ata_bio_start do the loop */
549 return 1;
550 }
551 } else { /* Done with this transfer */
552 ata_bio->error = NOERROR0;
553 wdc_ata_bio_done(chp, xfer);
554 }
555 return 1;
556
557timeout:
558 if (xfer->c_flags & C_DMA0x0040)
559 ata_dmaerr(drvp);
560
561 ata_bio->error = TIMEOUT4;
562 wdc_ata_bio_done(chp, xfer);
563 return 1;
564}
565
566void
567wdc_ata_bio_kill_xfer(struct channel_softc *chp, struct wdc_xfer *xfer)
568{
569 struct ata_bio *ata_bio = xfer->cmd;
570
571 timeout_del(&chp->ch_timo);
572 /* remove this command from xfer queue */
573 wdc_free_xfer(chp, xfer);
574
575 ata_bio->flags |= ATA_ITSDONE0x0004;
576 ata_bio->error = ERR_NODEV5;
577 ata_bio->r_error = WDCE_ABRT0x04;
578 if ((ata_bio->flags & ATA_POLL0x0002) == 0) {
579 WDCDEBUG_PRINT(("wdc_ata_done: wddone\n"), DEBUG_XFERS);
580 wddone(ata_bio->wd);
581 }
582}
583
584void
585wdc_ata_bio_done(struct channel_softc *chp, struct wdc_xfer *xfer)
586{
587 struct ata_bio *ata_bio = xfer->cmd;
588
589 WDCDEBUG_PRINT(("wdc_ata_bio_done %s:%d:%d: flags 0x%x\n",
590 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
591 (u_int)xfer->c_flags),
592 DEBUG_XFERS);
593
594 if ((xfer->c_flags & C_PRIVATEXFER0x0400) == 0)
595 timeout_del(&chp->ch_timo);
596
597 /* feed back residual bcount to our caller */
598 ata_bio->bcount = xfer->c_bcount;
599
600 /* remove this command from xfer queue */
601 wdc_free_xfer(chp, xfer);
602
603 ata_bio->flags |= ATA_ITSDONE0x0004;
604 if ((ata_bio->flags & ATA_POLL0x0002) == 0) {
605 WDCDEBUG_PRINT(("wdc_ata_done: wddone\n"), DEBUG_XFERS);
606 wddone(ata_bio->wd);
607 }
608 WDCDEBUG_PRINT(("wdcstart from wdc_ata_done, flags 0x%x\n",
609 chp->ch_flags), DEBUG_XFERS);
610 wdcstart(chp);
611}
612
613/*
614 * Implement operations needed before read/write.
615 */
616int
617wdc_ata_ctrl_intr(struct channel_softc *chp, struct wdc_xfer *xfer, int irq)
618{
619 struct ata_bio *ata_bio = xfer->cmd;
620 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
621 char *errstring = NULL((void *)0);
622 int delay = (irq == 0) ? ATA_DELAY45000 : 0;
623
624 WDCDEBUG_PRINT(("wdc_ata_ctrl_intr: state %d\n", drvp->state),
625 DEBUG_FUNCS);
626
627again:
628 switch (drvp->state) {
629 case RECAL0: /* Should not be in this state here */
630 panic("wdc_ata_ctrl_intr: state==RECAL");
631 break;
632
633 case RECAL_WAIT1:
634 errstring = "recal";
635 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay)((wdc_wait_for_status((chp), (0x40), (0x40), (delay)) >= 0
) ? 0 : -1)
)
636 goto timeout;
637 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK0x0400)
638 chp->wdc->irqack(chp);
639 if (chp->ch_status & (WDCS_ERR0x01 | WDCS_DWF0x20))
640 goto error;
641 /* FALLTHROUGH */
642
643 case PIOMODE2:
644 /* Don't try to set modes if controller can't be adjusted */
645 if ((chp->wdc->cap & WDC_CAPABILITY_MODE0x0004) == 0)
646 goto geometry;
647 /* Also don't try if the drive didn't report its mode */
648 if ((drvp->drive_flags & DRIVE_MODE0x0040) == 0)
649 goto geometry;
650 /* SET FEATURES 0x08 is only for PIO mode > 2 */
651 if (drvp->PIO_mode <= 2)
652 goto geometry;
653 wdccommand(chp, drvp->drive, SET_FEATURES0xef, 0, 0, 0,
654 0x08 | drvp->PIO_mode, WDSF_SET_MODE0x03);
655 drvp->state = PIOMODE_WAIT3;
656 break;
657
658 case PIOMODE_WAIT3:
659 errstring = "piomode";
660 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay)((wdc_wait_for_status((chp), (0x40), (0x40), (delay)) >= 0
) ? 0 : -1)
)
661 goto timeout;
662 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK0x0400)
663 chp->wdc->irqack(chp);
664 if (chp->ch_status & (WDCS_ERR0x01 | WDCS_DWF0x20))
665 goto error;
666 /* FALLTHROUGH */
667
668 case DMAMODE4:
669 if (drvp->drive_flags & DRIVE_UDMA0x0020) {
670 wdccommand(chp, drvp->drive, SET_FEATURES0xef, 0, 0, 0,
671 0x40 | drvp->UDMA_mode, WDSF_SET_MODE0x03);
672 } else if (drvp->drive_flags & DRIVE_DMA0x0010) {
673 wdccommand(chp, drvp->drive, SET_FEATURES0xef, 0, 0, 0,
674 0x20 | drvp->DMA_mode, WDSF_SET_MODE0x03);
675 } else {
676 goto geometry;
677 }
678 drvp->state = DMAMODE_WAIT5;
679 break;
680 case DMAMODE_WAIT5:
681 errstring = "dmamode";
682 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay)((wdc_wait_for_status((chp), (0x40), (0x40), (delay)) >= 0
) ? 0 : -1)
)
683 goto timeout;
684 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK0x0400)
685 chp->wdc->irqack(chp);
686 if (chp->ch_status & (WDCS_ERR0x01 | WDCS_DWF0x20))
687 goto error;
688 /* FALLTHROUGH */
689
690 case GEOMETRY6:
691 geometry:
692 if (ata_bio->flags & ATA_LBA0x0010)
693 goto multimode;
694 wdccommand(chp, xfer->drive, WDCC_IDP0x91,
695 ata_bio->lp->d_ncylinders,
696 ata_bio->lp->d_ntracks - 1, 0, ata_bio->lp->d_nsectors, 0);
697 drvp->state = GEOMETRY_WAIT7;
698 break;
699
700 case GEOMETRY_WAIT7:
701 errstring = "geometry";
702 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay)((wdc_wait_for_status((chp), (0x40), (0x40), (delay)) >= 0
) ? 0 : -1)
)
703 goto timeout;
704 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK0x0400)
705 chp->wdc->irqack(chp);
706 if (chp->ch_status & (WDCS_ERR0x01 | WDCS_DWF0x20))
707 goto error;
708 /* FALLTHROUGH */
709
710 case MULTIMODE8:
711 multimode:
712 if (ata_bio->multi == 1)
713 goto ready;
714 wdccommand(chp, xfer->drive, WDCC_SETMULTI0xc6, 0, 0, 0,
715 ata_bio->multi, 0);
716 drvp->state = MULTIMODE_WAIT9;
717 break;
718
719 case MULTIMODE_WAIT9:
720 errstring = "setmulti";
721 if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay)((wdc_wait_for_status((chp), (0x40), (0x40), (delay)) >= 0
) ? 0 : -1)
)
722 goto timeout;
723 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK0x0400)
724 chp->wdc->irqack(chp);
725 if (chp->ch_status & (WDCS_ERR0x01 | WDCS_DWF0x20))
726 goto error;
727 /* FALLTHROUGH */
728
729 case READY10:
730 ready:
731 drvp->state = READY10;
732 /*
733 * The drive is usable now
734 */
735 xfer->c_intr = wdc_ata_bio_intr;
736 _wdc_ata_bio_start(chp, xfer);
737 return 1;
738 }
739
740 if ((ata_bio->flags & ATA_POLL0x0002) == 0) {
741 chp->ch_flags |= WDCF_IRQ_WAIT0x10;
742 } else {
743 goto again;
744 }
745 return 1;
746
747timeout:
748 if (irq && (xfer->c_flags & C_TIMEOU0x0004) == 0) {
749 return 0; /* IRQ was not for us */
750 }
751 printf("%s:%d:%d: %s timed out\n",
752 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, errstring);
753 ata_bio->error = TIMEOUT4;
754 drvp->state = 0;
755 wdc_ata_bio_done(chp, xfer);
756 return 0;
757error:
758 printf("%s:%d:%d: %s ",
759 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
760 errstring);
761 if (chp->ch_status & WDCS_DWF0x20) {
762 printf("drive fault\n");
763 ata_bio->error = ERR_DF2;
764 } else {
765 printf("error (%x)\n", chp->ch_error);
766 ata_bio->r_error = chp->ch_error;
767 ata_bio->error = ERROR1;
768 }
769 drvp->state = 0;
770 wdc_ata_bio_done(chp, xfer);
771 return 1;
772}
773
774int
775wdc_ata_err(struct ata_drive_datas *drvp, struct ata_bio *ata_bio)
776{
777 struct channel_softc *chp = drvp->chnl_softc;
778 ata_bio->error = 0;
779
780 if (chp->ch_status == 0xff) {
781 ata_bio->error = ERR_NODEV5;
782 return WDC_ATA_ERR0x02;
783 }
784 if (chp->ch_status & WDCS_BSY0x80) {
785 ata_bio->error = TIMEOUT4;
786 return WDC_ATA_ERR0x02;
787 }
788
789 if (chp->ch_status & WDCS_DWF0x20) {
790 ata_bio->error = ERR_DF2;
791 return WDC_ATA_ERR0x02;
792 }
793
794 if (chp->ch_status & WDCS_ERR0x01) {
795 ata_bio->error = ERROR1;
796 ata_bio->r_error = chp->ch_error;
797 if (drvp->drive_flags & DRIVE_UDMA0x0020 &&
798 (ata_bio->r_error & WDCE_CRC0x80)) {
799 /*
800 * Record the CRC error, to avoid downgrading to
801 * multiword DMA
802 */
803 drvp->drive_flags |= DRIVE_DMAERR0x0100;
804 }
805 if (ata_bio->r_error & (WDCE_BBK0x80 | WDCE_UNC0x40 | WDCE_IDNF0x10 |
806 WDCE_ABRT0x04 | WDCE_TK0NF0x02 | WDCE_AMNF0x01))
807 return WDC_ATA_ERR0x02;
808 return WDC_ATA_NOERR0x00;
809 }
810
811 if (chp->ch_status & WDCS_CORR0x04)
812 ata_bio->flags |= ATA_CORR0x0040;
813 return WDC_ATA_NOERR0x00;
814}
815
816#if 0
817int
818wdc_ata_addref(drvp)
819 struct ata_drive_datas *drvp;
820{
821 struct channel_softc *chp = drvp->chnl_softc;
822
823 return (wdc_addref(chp));
824}
825
826void
827wdc_ata_delref(drvp)
828 struct ata_drive_datas *drvp;
829{
830 struct channel_softc *chp = drvp->chnl_softc;
831
832 wdc_delref(chp);
833}
834#endif