Bug Summary

File:dev/atapiscsi/atapiscsi.c
Warning:line 974, column 7
Although the value stored to 'message' is used in the enclosing expression, the value is never actually read from 'message'

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 atapiscsi.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/atapiscsi/atapiscsi.c
1/* $OpenBSD: atapiscsi.c,v 1.118 2022/01/09 05:42:37 jsg Exp $ */
2
3/*
4 * This code is derived from code with the copyright below.
5 */
6
7/*
8 * Copyright (c) 1996, 1998 Manuel Bouyer.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 */
32
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/kernel.h>
37#include <sys/device.h>
38#include <sys/buf.h>
39#include <sys/disklabel.h>
40#include <sys/malloc.h>
41#include <sys/reboot.h>
42#include <sys/ioctl.h>
43#include <sys/timeout.h>
44#include <scsi/scsi_all.h>
45#include <scsi/scsi_disk.h>
46#include <scsi/scsi_tape.h>
47#include <scsi/scsiconf.h>
48
49#include <machine/bus.h>
50#include <machine/cpu.h>
51#include <machine/intr.h>
52
53#include <dev/ata/atareg.h>
54#include <dev/ata/atavar.h>
55#include <dev/ic/wdcreg.h>
56#include <dev/ic/wdcvar.h>
57#include <dev/ic/wdcevent.h>
58
59/* drive states stored in ata_drive_datas */
60enum atapi_drive_states {
61 ATAPI_RESET_BASE_STATE = 0,
62 ATAPI_DEVICE_RESET_WAIT_STATE = 1,
63 ATAPI_IDENTIFY_STATE = 2,
64 ATAPI_IDENTIFY_WAIT_STATE = 3,
65 ATAPI_PIOMODE_STATE = 4,
66 ATAPI_PIOMODE_WAIT_STATE = 5,
67 ATAPI_DMAMODE_STATE = 6,
68 ATAPI_DMAMODE_WAIT_STATE = 7,
69 ATAPI_READY_STATE = 8
70};
71
72#define DEBUG_INTR0x01 0x01
73#define DEBUG_XFERS0x02 0x02
74#define DEBUG_STATUS0x04 0x04
75#define DEBUG_FUNCS0x08 0x08
76#define DEBUG_PROBE0x10 0x10
77#define DEBUG_DSC0x20 0x20
78#define DEBUG_POLL0x40 0x40
79#define DEBUG_ERRORS0x80 0x80 /* Debug error handling code */
80
81#if defined(WDCDEBUG)
82#ifndef WDCDEBUG_ATAPI_MASK
83#define WDCDEBUG_ATAPI_MASK 0x00
84#endif
85int wdcdebug_atapi_mask = WDCDEBUG_ATAPI_MASK;
86#define WDCDEBUG_PRINT(args, level) do { \
87 if ((wdcdebug_atapi_mask & (level)) != 0) \
88 printf args; \
89} while (0)
90#else
91#define WDCDEBUG_PRINT(args, level)
92#endif
93
94/* 10 ms, this is used only before sending a cmd. */
95#define ATAPI_DELAY10 10
96#define ATAPI_RESET_DELAY1000 1000
97#define ATAPI_RESET_WAIT2000 2000
98#define ATAPI_CTRL_WAIT4000 4000
99
100/* When polling, let the exponential backoff max out at 1 second's interval. */
101#define ATAPI_POLL_MAXTIC(hz) (hz)
102
103void wdc_atapi_start(struct channel_softc *,struct wdc_xfer *);
104
105void wdc_atapi_timer_handler(void *);
106
107void wdc_atapi_real_start(struct channel_softc *, struct wdc_xfer *,
108 int, struct atapi_return_args *);
109void wdc_atapi_real_start_2(struct channel_softc *, struct wdc_xfer *,
110 int, struct atapi_return_args *);
111void wdc_atapi_intr_command(struct channel_softc *, struct wdc_xfer *,
112 int, struct atapi_return_args *);
113void wdc_atapi_intr_data(struct channel_softc *, struct wdc_xfer *,
114 int, struct atapi_return_args *);
115void wdc_atapi_intr_complete(struct channel_softc *, struct wdc_xfer *,
116 int, struct atapi_return_args *);
117void wdc_atapi_pio_intr(struct channel_softc *, struct wdc_xfer *,
118 int, struct atapi_return_args *);
119void wdc_atapi_send_packet(struct channel_softc *, struct wdc_xfer *,
120 int, struct atapi_return_args *);
121void wdc_atapi_ctrl(struct channel_softc *, struct wdc_xfer *,
122 int, struct atapi_return_args *);
123
124char *wdc_atapi_in_data_phase(struct wdc_xfer *, int, int);
125
126int wdc_atapi_intr(struct channel_softc *, struct wdc_xfer *, int);
127void wdc_atapi_done(struct channel_softc *, struct wdc_xfer *,
128 int, struct atapi_return_args *);
129void wdc_atapi_reset(struct channel_softc *, struct wdc_xfer *,
130 int, struct atapi_return_args *);
131void wdc_atapi_reset_2(struct channel_softc *, struct wdc_xfer *,
132 int, struct atapi_return_args *);
133
134void wdc_atapi_tape_done(struct channel_softc *, struct wdc_xfer *,
135 int, struct atapi_return_args *);
136
137struct atapiscsi_softc;
138struct atapiscsi_xfer;
139
140int atapiscsi_match(struct device *, void *, void *);
141void atapiscsi_attach(struct device *, struct device *, void *);
142int atapiscsi_activate(struct device *, int);
143int atapiscsi_detach(struct device *, int);
144int atapi_to_scsi_sense(struct scsi_xfer *, u_int8_t);
145
146enum atapi_state { as_none, as_data, as_completed };
147
148struct atapiscsi_softc {
149 struct device sc_dev;
150 struct channel_softc *chp;
151 enum atapi_state protocol_phase;
152
153 int drive;
154};
155
156int wdc_atapi_ioctl(struct scsi_link *, u_long, caddr_t, int);
157void wdc_atapi_send_cmd(struct scsi_xfer *sc_xfer);
158
159static struct scsi_adapter atapiscsi_switch = {
160 wdc_atapi_send_cmd, NULL((void *)0), NULL((void *)0), NULL((void *)0), wdc_atapi_ioctl
161};
162
163/* Initial version shares bus_link structure so it can easily
164 be "attached to current" wdc driver */
165
166struct cfattach atapiscsi_ca = {
167 sizeof(struct atapiscsi_softc), atapiscsi_match, atapiscsi_attach,
168 atapiscsi_detach, atapiscsi_activate
169};
170
171struct cfdriver atapiscsi_cd = {
172 NULL((void *)0), "atapiscsi", DV_DULL
173};
174
175
176int
177atapiscsi_match(struct device *parent, void *match, void *aux)
178{
179 struct ata_atapi_attach *aa_link = aux;
180 struct cfdata *cf = match;
181
182 if (aa_link == NULL((void *)0))
183 return (0);
184
185 if (aa_link->aa_type != T_ATAPI1)
186 return (0);
187
188 if (cf->cf_loc[0] != aa_link->aa_channel &&
189 cf->cf_loc[0] != -1)
190 return (0);
191
192 return (1);
193}
194
195void
196atapiscsi_attach(struct device *parent, struct device *self, void *aux)
197{
198 struct atapiscsi_softc *as = (struct atapiscsi_softc *)self;
199 struct ata_atapi_attach *aa_link = aux;
200 struct scsibus_attach_args saa;
201 struct ata_drive_datas *drvp = aa_link->aa_drv_data;
202 struct channel_softc *chp = drvp->chnl_softc;
203 struct ataparams *id = &drvp->id;
204 struct device *child;
205
206 extern struct scsi_iopool wdc_xfer_iopool;
207
208 printf("\n");
209
210 /* Initialize shared data. */
211 scsi_init();
212
213#ifdef WDCDEBUG
214 if (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE0x10000)
215 wdcdebug_atapi_mask |= DEBUG_PROBE0x10;
216#endif
217
218 as->chp = chp;
219 as->drive = drvp->drive;
220
221 strlcpy(drvp->drive_name, as->sc_dev.dv_xname,
222 sizeof(drvp->drive_name));
223 drvp->cf_flags = as->sc_dev.dv_cfdata->cf_flags;
224
225 wdc_probe_caps(drvp, id);
226
227 WDCDEBUG_PRINT(
228 ("general config %04x capabilities %04x ",
229 id->atap_config, id->atap_capabilities1),
230 DEBUG_PROBE);
231
232 if ((NERRS_MAX4 - 2) > 0)
233 drvp->n_dmaerrs = NERRS_MAX4 - 2;
234 else
235 drvp->n_dmaerrs = 0;
236 drvp->drive_flags |= DRIVE_DEVICE_RESET0x0800;
237
238 /* Tape drives do funny DSC stuff */
239 if (ATAPI_CFG_TYPE(id->atap_config)(((id->atap_config) & 0x1f00) >> 8) ==
240 ATAPI_CFG_TYPE_SEQUENTIAL0x01)
241 drvp->atapi_cap |= ACAP_DSC0x02;
242
243 if ((id->atap_config & ATAPI_CFG_CMD_MASK0x0003) ==
244 ATAPI_CFG_CMD_160x0001)
245 drvp->atapi_cap |= ACAP_LEN0x01;
246
247 drvp->atapi_cap |=
248 (id->atap_config & ATAPI_CFG_DRQ_MASK0x0060);
249
250 WDCDEBUG_PRINT(("driver caps %04x\n", drvp->atapi_cap),
251 DEBUG_PROBE);
252
253
254 saa.saa_adapter_softc = as;
255 saa.saa_adapter_target = SDEV_NO_ADAPTER_TARGET0xffff;
256 saa.saa_adapter_buswidth = 2;
257 saa.saa_adapter = &atapiscsi_switch;
258 saa.saa_luns = 1;
259 saa.saa_openings = 1;
260 saa.saa_flags = SDEV_ATAPI0x0200;
261 saa.saa_pool = &wdc_xfer_iopool;
262 saa.saa_quirks = 0;
263 saa.saa_wwpn = saa.saa_wwnn = 0;
264
265 child = config_found((struct device *)as, &saa, scsiprint)config_found_sm(((struct device *)as), (&saa), (scsiprint
), ((void *)0))
;
266
267 if (child != NULL((void *)0)) {
268 struct scsibus_softc *scsi = (struct scsibus_softc *)child;
269 struct scsi_link *link = scsi_get_link(scsi, 0, 0);
270
271 if (link) {
272 strlcpy(drvp->drive_name,
273 ((struct device *)(link->device_softc))->dv_xname,
274 sizeof(drvp->drive_name));
275
276 wdc_print_caps(drvp);
277 }
278 }
279
280#ifdef WDCDEBUG
281 if (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE0x10000)
282 wdcdebug_atapi_mask &= ~DEBUG_PROBE0x10;
283#endif
284}
285
286int
287atapiscsi_activate(struct device *self, int act)
288{
289 struct atapiscsi_softc *as = (void *)self;
290 struct channel_softc *chp = as->chp;
291 struct ata_drive_datas *drvp = &chp->ch_drive[as->drive];
292
293 switch (act) {
294 case DVACT_SUSPEND3:
295 break;
296 case DVACT_RESUME4:
297 /*
298 * Do two resets separated by a small delay. The
299 * first wakes the controller, the second resets
300 * the channel
301 */
302 wdc_disable_intr(chp);
303 wdc_reset_channel(drvp, 1);
304 delay(10000)(*delay_func)(10000);
305 wdc_reset_channel(drvp, 0);
306 wdc_enable_intr(chp);
307 break;
308 }
309 return (0);
310}
311
312int
313atapiscsi_detach(struct device *dev, int flags)
314{
315 return (config_detach_children(dev, flags));
316}
317
318void
319wdc_atapi_send_cmd(struct scsi_xfer *sc_xfer)
320{
321 struct atapiscsi_softc *as = sc_xfer->sc_link->bus->sb_adapter_softc;
322 struct channel_softc *chp = as->chp;
323 struct ata_drive_datas *drvp = &chp->ch_drive[as->drive];
324 struct wdc_xfer *xfer;
325 int s;
326 int idx;
327
328 WDCDEBUG_PRINT(("wdc_atapi_send_cmd %s:%d:%d start\n",
329 chp->wdc->sc_dev.dv_xname, chp->channel, as->drive), DEBUG_XFERS);
330
331 if (sc_xfer->sc_link->target != 0) {
332 sc_xfer->error = XS_DRIVER_STUFFUP2;
333 scsi_done(sc_xfer);
334 return;
335 }
336
337 xfer = sc_xfer->io;
338 wdc_scrub_xfer(xfer);
339 if (sc_xfer->flags & SCSI_POLL0x00002)
340 xfer->c_flags |= C_POLL0x0020;
341 xfer->drive = as->drive;
342 xfer->c_flags |= C_ATAPI0x0002;
343 xfer->cmd = sc_xfer;
344 xfer->databuf = sc_xfer->data;
345 xfer->c_bcount = sc_xfer->datalen;
346 xfer->c_start = wdc_atapi_start;
347 xfer->c_intr = wdc_atapi_intr;
348
349 timeout_set(&xfer->atapi_poll_to, wdc_atapi_timer_handler, chp);
350
351 WDCDEBUG_PRINT(("wdc_atapi_send_cmd %s:%d:%d ",
352 chp->wdc->sc_dev.dv_xname, chp->channel, as->drive),
353 DEBUG_XFERS | DEBUG_ERRORS);
354
355 for (idx = 0; idx < sc_xfer->cmdlen; idx++) {
356 WDCDEBUG_PRINT((" %02x",
357 ((unsigned char *)&sc_xfer->cmd)[idx]),
358 DEBUG_XFERS | DEBUG_ERRORS);
359 }
360 WDCDEBUG_PRINT(("\n"), DEBUG_XFERS | DEBUG_ERRORS);
361
362 s = splbio()splraise(0x6);
363
364 if (drvp->atapi_cap & ACAP_DSC0x02) {
365 WDCDEBUG_PRINT(("about to send cmd 0x%x ",
366 sc_xfer->cmd.opcode), DEBUG_DSC);
367 switch (sc_xfer->cmd.opcode) {
368 case READ0x08:
369 case WRITE0x0a:
370 xfer->c_flags |= C_MEDIA_ACCESS0x0100;
371
372 /* If we are not in buffer availability mode,
373 we limit the first request to 0 bytes, which
374 gets us into buffer availability mode without
375 holding the bus. */
376 if (!(drvp->drive_flags & DRIVE_DSCBA0x0200)) {
377 xfer->c_bcount = 0;
378 xfer->transfer_len =
379 _3btol(((struct scsi_rw_tape *)
380 &sc_xfer->cmd)->len);
381 _lto3b(0,
382 ((struct scsi_rw_tape *)
383 &sc_xfer->cmd)->len);
384 xfer->c_done = wdc_atapi_tape_done;
385 WDCDEBUG_PRINT(
386 ("R/W in completion mode, do 0 blocks\n"),
387 DEBUG_DSC);
388 } else
389 WDCDEBUG_PRINT(("R/W %d blocks %d bytes\n",
390 _3btol(((struct scsi_rw_tape *)
391 &sc_xfer->cmd)->len),
392 sc_xfer->datalen),
393 DEBUG_DSC);
394
395 /* DSC will change to buffer availability mode.
396 We reflect this in wdc_atapi_intr. */
397 break;
398
399 case ERASE0x19: /* Media access commands */
400 case LOAD0x1b:
401 case REWIND0x01:
402 case SPACE0x11:
403 case WRITE_FILEMARKS0x10:
404#if 0
405 case LOCATE:
406 case READ_POSITION:
407#endif
408
409 xfer->c_flags |= C_MEDIA_ACCESS0x0100;
410 break;
411
412 default:
413 WDCDEBUG_PRINT(("no media access\n"), DEBUG_DSC);
414 }
415 }
416
417 wdc_exec_xfer(chp, xfer);
418 splx(s)spllower(s);
419}
420
421int
422wdc_atapi_ioctl (struct scsi_link *sc_link, u_long cmd, caddr_t addr, int flag)
423{
424 struct atapiscsi_softc *as = sc_link->bus->sb_adapter_softc;
425 struct channel_softc *chp = as->chp;
426 struct ata_drive_datas *drvp = &chp->ch_drive[as->drive];
427
428 if (sc_link->target != 0)
429 return ENOTTY25;
430
431 return (wdc_ioctl(drvp, cmd, addr, flag, curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc
));
432}
433
434
435/*
436 * Returns 1 if we experienced an ATA-level abort command
437 * (ABRT bit set but no additional sense)
438 * 0 if normal command processing
439 */
440int
441atapi_to_scsi_sense(struct scsi_xfer *xfer, u_int8_t flags)
442{
443 struct scsi_sense_data *sense = &xfer->sense;
444 int ret = 0;
445
446 xfer->error = XS_SHORTSENSE6;
447
448 sense->error_code = SSD_ERRCODE_VALID0x80 | SSD_ERRCODE_CURRENT0x70;
449 sense->flags = (flags >> 4);
450
451 WDCDEBUG_PRINT(("Atapi error: %d ", (flags >> 4)), DEBUG_ERRORS);
452
453 if ((flags & 4) && (sense->flags == 0)) {
454 sense->flags = SKEY_ABORTED_COMMAND0x0B;
455 WDCDEBUG_PRINT(("ABRT "), DEBUG_ERRORS);
456 ret = 1;
457 }
458
459 if (flags & 0x1) {
460 sense->flags |= SSD_ILI0x20;
461 WDCDEBUG_PRINT(("ILI "), DEBUG_ERRORS);
462 }
463
464 if (flags & 0x2) {
465 sense->flags |= SSD_EOM0x40;
466 WDCDEBUG_PRINT(("EOM "), DEBUG_ERRORS);
467 }
468
469 /* Media change requested */
470 /* Let's ignore these in version 1 */
471 if (flags & 0x8) {
472 WDCDEBUG_PRINT(("MCR "), DEBUG_ERRORS);
473 if (sense->flags == 0)
474 xfer->error = XS_NOERROR0;
475 }
476
477 WDCDEBUG_PRINT(("\n"), DEBUG_ERRORS);
478 return (ret);
479}
480
481int wdc_atapi_drive_selected(struct channel_softc *, int);
482
483int
484wdc_atapi_drive_selected(struct channel_softc *chp, int drive)
485{
486 u_int8_t reg = CHP_READ_REG(chp, wdr_sdh)((chp)->_vtbl->read_reg)(chp, wdr_sdh);
487
488 WDC_LOG_REG(chp, wdr_sdh, reg);
489
490 return ((reg & 0x10) == (drive << 4));
491}
492
493enum atapi_context {
494 ctxt_process = 0,
495 ctxt_timer = 1,
496 ctxt_interrupt = 2
497};
498
499void wdc_atapi_the_machine(struct channel_softc *, struct wdc_xfer *,
500 enum atapi_context);
501
502void wdc_atapi_the_poll_machine(struct channel_softc *, struct wdc_xfer *);
503
504void
505wdc_atapi_start(struct channel_softc *chp, struct wdc_xfer *xfer)
506{
507 xfer->next = wdc_atapi_real_start;
508
509 wdc_atapi_the_machine(chp, xfer, ctxt_process);
510}
511
512
513void
514wdc_atapi_timer_handler(void *arg)
515{
516 struct channel_softc *chp = arg;
517 struct wdc_xfer *xfer;
518 int s;
519
520 s = splbio()splraise(0x6);
521 xfer = TAILQ_FIRST(&chp->ch_queue->sc_xfer)((&chp->ch_queue->sc_xfer)->tqh_first);
522 if (xfer == NULL((void *)0) ||
523 !timeout_triggered(&xfer->atapi_poll_to)((&xfer->atapi_poll_to)->to_flags & 0x08)) {
524 splx(s)spllower(s);
525 return;
526 }
527 xfer->c_flags &= ~C_POLL_MACHINE0x0200;
528 timeout_del(&xfer->atapi_poll_to);
529 chp->ch_flags &= ~WDCF_IRQ_WAIT0x10;
530 wdc_atapi_the_machine(chp, xfer, ctxt_timer);
531 splx(s)spllower(s);
532}
533
534
535int
536wdc_atapi_intr(struct channel_softc *chp, struct wdc_xfer *xfer, int irq)
537{
538 timeout_del(&chp->ch_timo);
539
540 /* XXX we should consider an alternate signaling regime here */
541 if (xfer->c_flags & C_TIMEOU0x0004) {
542 xfer->c_flags &= ~C_TIMEOU0x0004;
543 wdc_atapi_the_machine(chp, xfer, ctxt_timer);
544 return (0);
545 }
546
547 wdc_atapi_the_machine(chp, xfer, ctxt_interrupt);
548
549 return (-1);
550}
551
552struct atapi_return_args {
553 int timeout;
554 int delay;
555 int expect_irq;
556};
557
558#define ARGS_INIT{-1, 0, 0} {-1, 0, 0}
559
560void
561wdc_atapi_the_poll_machine(struct channel_softc *chp, struct wdc_xfer *xfer)
562{
563 int idx = 0;
564 int current_timeout = 10;
565
566
567 while (1) {
568 struct atapi_return_args retargs = ARGS_INIT{-1, 0, 0};
569 idx++;
570
571 (xfer->next)(chp, xfer, (current_timeout * 1000 <= idx),
572 &retargs);
573
574 if (xfer->next == NULL((void *)0)) {
575 wdc_free_xfer(chp, xfer);
576 wdcstart(chp);
577 return;
578 }
579
580 if (retargs.timeout != -1) {
581 current_timeout = retargs.timeout;
582 idx = 0;
583 }
584
585 if (retargs.delay != 0) {
586 delay (1000 * retargs.delay)(*delay_func)(1000 * retargs.delay);
587 idx += 1000 * retargs.delay;
588 }
589
590 DELAY(1)(*delay_func)(1);
591 }
592}
593
594
595void
596wdc_atapi_the_machine(struct channel_softc *chp, struct wdc_xfer *xfer,
597 enum atapi_context ctxt)
598{
599 int idx = 0;
600 extern int ticks;
601 int timeout_delay = hz / 10;
602
603 if (xfer->c_flags & C_POLL0x0020) {
604 wdc_disable_intr(chp);
605
606 if (ctxt != ctxt_process) {
607 if (ctxt == ctxt_interrupt)
608 xfer->endticks = 1;
609
610 return;
611 }
612
613 wdc_atapi_the_poll_machine(chp, xfer);
614 return;
615 }
616
617 /* Don't go through more than 50 state machine steps
618 before yielding. This tries to limit the amount of time
619 spent at high SPL */
620 for (idx = 0; idx < 50; idx++) {
621 struct atapi_return_args retargs = ARGS_INIT{-1, 0, 0};
622
623 (xfer->next)(chp, xfer,
624 xfer->endticks && (ticks - xfer->endticks >= 0),
625 &retargs);
626
627 if (retargs.timeout != -1)
628 /*
629 * Add 1 tick to compensate for the fact that we
630 * can be just microseconds before the tick changes.
631 */
632 xfer->endticks =
633 max((retargs.timeout * hz) / 1000, 1) + 1 + ticks;
634
635 if (xfer->next == NULL((void *)0)) {
636 if (xfer->c_flags & C_POLL_MACHINE0x0200)
637 timeout_del(&xfer->atapi_poll_to);
638
639 wdc_free_xfer(chp, xfer);
640 wdcstart(chp);
641
642 return;
643 }
644
645 if (retargs.expect_irq) {
646 int timeout_period;
647 chp->ch_flags |= WDCF_IRQ_WAIT0x10;
648 timeout_period = xfer->endticks - ticks;
649 if (timeout_period < 1)
650 timeout_period = 1;
651 timeout_add(&chp->ch_timo, timeout_period);
652 return;
653 }
654
655 if (retargs.delay != 0) {
656 timeout_delay = max(retargs.delay * hz / 1000, 1);
657 break;
658 }
659
660 DELAY(1)(*delay_func)(1);
661 }
662
663 timeout_add(&xfer->atapi_poll_to, timeout_delay);
664 xfer->c_flags |= C_POLL_MACHINE0x0200;
665
666 return;
667}
668
669
670void wdc_atapi_update_status(struct channel_softc *);
671
672void
673wdc_atapi_update_status(struct channel_softc *chp)
674{
675 chp->ch_status = CHP_READ_REG(chp, wdr_status)((chp)->_vtbl->read_reg)(chp, wdr_status);
676
677 WDC_LOG_STATUS(chp, chp->ch_status);
678
679 if (chp->ch_status == 0xff && (chp->ch_flags & WDCF_ONESLAVE0x02)) {
680 wdc_set_drive(chp, 1);
681
682 chp->ch_status = CHP_READ_REG(chp, wdr_status)((chp)->_vtbl->read_reg)(chp, wdr_status);
683 WDC_LOG_STATUS(chp, chp->ch_status);
684 }
685
686 if ((chp->ch_status & (WDCS_BSY0x80 | WDCS_ERR0x01)) == WDCS_ERR0x01) {
687 chp->ch_error = CHP_READ_REG(chp, wdr_error)((chp)->_vtbl->read_reg)(chp, wdr_error);
688 WDC_LOG_ERROR(chp, chp->ch_error);
689 }
690}
691
692void
693wdc_atapi_real_start(struct channel_softc *chp, struct wdc_xfer *xfer,
694 int timeout, struct atapi_return_args *ret)
695{
696#ifdef WDCDEBUG
697 struct scsi_xfer *sc_xfer = xfer->cmd;
698#endif
699 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
700
701 /*
702 * Only set the DMA flag if the transfer is reasonably large.
703 * At least one older drive failed to complete a 4 byte DMA transfer.
704 */
705
706 /* Turn off DMA flag on REQUEST SENSE */
707
708 if (!(xfer->c_flags & (C_POLL0x0020 | C_SENSE0x0080 | C_MEDIA_ACCESS0x0100)) &&
709 (drvp->drive_flags & (DRIVE_DMA0x0010 | DRIVE_UDMA0x0020)) &&
710 (xfer->c_bcount > 100))
711 xfer->c_flags |= C_DMA0x0040;
712 else
713 xfer->c_flags &= ~C_DMA0x0040;
714
715
716 wdc_set_drive(chp, xfer->drive);
717
718 DELAY(1)(*delay_func)(1);
719
720 xfer->next = wdc_atapi_real_start_2;
721 ret->timeout = ATAPI_DELAY10;
722
723 WDCDEBUG_PRINT(("wdc_atapi_start %s:%d:%d, scsi flags 0x%x, "
724 "ATA flags 0x%x\n",
725 chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive,
726 sc_xfer->flags, xfer->c_flags), DEBUG_XFERS);
727
728
729 return;
730}
731
732
733void
734wdc_atapi_real_start_2(struct channel_softc *chp, struct wdc_xfer *xfer,
735 int timeout, struct atapi_return_args *ret)
736{
737 struct scsi_xfer *sc_xfer = xfer->cmd;
738 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
739
740 if (timeout) {
741 printf("wdc_atapi_start: not ready, st = %02x\n",
742 chp->ch_status);
743
744 sc_xfer->error = XS_TIMEOUT4;
745 xfer->next = wdc_atapi_reset;
746 return;
747 } else {
748 wdc_atapi_update_status(chp);
749
750 if (chp->ch_status & (WDCS_BSY0x80 | WDCS_DRQ0x08))
751 return;
752 }
753
754 /* Do control operations specially. */
755 if (drvp->state < ATAPI_READY_STATE) {
756 xfer->next = wdc_atapi_ctrl;
757 return;
758 }
759
760 xfer->next = wdc_atapi_send_packet;
761 return;
762}
763
764
765void
766wdc_atapi_send_packet(struct channel_softc *chp, struct wdc_xfer *xfer,
767 int timeout, struct atapi_return_args *ret)
768{
769 struct scsi_xfer *sc_xfer = xfer->cmd;
770 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
771
772 /*
773 * Even with WDCS_ERR, the device should accept a command packet.
774 * Limit length to what can be stuffed into the cylinder register
775 * (16 bits). Some CD-ROMs seem to interpret '0' as 65536,
776 * but not all devices do that and it's not obvious from the
777 * ATAPI spec that this behaviour should be expected. If more
778 * data is necessary, multiple data transfer phases will be done.
779 */
780
781 wdccommand(chp, xfer->drive, ATAPI_PKT_CMD0xa0,
782 xfer->c_bcount <= 0xfffe ? xfer->c_bcount : 0xfffe,
783 0, 0, 0,
784 (xfer->c_flags & C_DMA0x0040) ? ATAPI_PKT_CMD_FTRE_DMA0x01 : 0);
785
786 if (xfer->c_flags & C_DMA0x0040)
787 drvp->n_xfers++;
788
789 DELAY(1)(*delay_func)(1);
790
791 xfer->next = wdc_atapi_intr_command;
792 ret->timeout = sc_xfer->timeout;
793
794 if ((drvp->atapi_cap & ATAPI_CFG_DRQ_MASK0x0060) == ATAPI_CFG_IRQ_DRQ0x0020) {
795 /* We expect an IRQ to tell us of the next state */
796 ret->expect_irq = 1;
797 }
798
799 WDCDEBUG_PRINT(("wdc_atapi_send_packet %s:%d:%d command sent\n",
800 chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive
801 ), DEBUG_XFERS);
802 return;
803}
804
805void
806wdc_atapi_intr_command(struct channel_softc *chp, struct wdc_xfer *xfer,
807 int timeout, struct atapi_return_args *ret)
808{
809 struct scsi_xfer *sc_xfer = xfer->cmd;
810 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
811 struct atapiscsi_softc *as = sc_xfer->sc_link->bus->sb_adapter_softc;
812 int i;
813 u_int8_t cmd[16];
814 struct scsi_sense *cmd_reqsense;
815 int cmdlen = (drvp->atapi_cap & ACAP_LEN0x01) ? 16 : 12;
816 int dma_flags = ((sc_xfer->flags & SCSI_DATA_IN0x00800) ||
817 (xfer->c_flags & C_SENSE0x0080)) ? WDC_DMA_READ0x01 : 0;
818
819 wdc_atapi_update_status(chp);
820
821 if ((chp->ch_status & WDCS_BSY0x80) || !(chp->ch_status & WDCS_DRQ0x08)) {
822 if (timeout)
823 goto timeout;
824
825 return;
826 }
827
828 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK0x0400)
829 chp->wdc->irqack(chp);
830
831 bzero(cmd, sizeof(cmd))__builtin_bzero((cmd), (sizeof(cmd)));
832
833 if (xfer->c_flags & C_SENSE0x0080) {
834 cmd_reqsense = (struct scsi_sense *)&cmd[0];
835 cmd_reqsense->opcode = REQUEST_SENSE0x03;
836 cmd_reqsense->length = xfer->c_bcount;
837 } else
838 bcopy(&sc_xfer->cmd, cmd, sc_xfer->cmdlen);
839
840 WDC_LOG_ATAPI_CMD(chp, xfer->drive, xfer->c_flags,
841 cmdlen, cmd);
842
843 for (i = 0; i < 12; i++)
844 WDCDEBUG_PRINT(("%02x ", cmd[i]), DEBUG_INTR);
845 WDCDEBUG_PRINT((": PHASE_CMDOUT\n"), DEBUG_INTR);
846
847 /* Init the DMA channel if necessary */
848 if (xfer->c_flags & C_DMA0x0040) {
849 if ((*chp->wdc->dma_init)(chp->wdc->dma_arg,
850 chp->channel, xfer->drive, xfer->databuf,
851 xfer->c_bcount, dma_flags) != 0) {
852 sc_xfer->error = XS_DRIVER_STUFFUP2;
853
854 xfer->next = wdc_atapi_reset;
855 return;
856 }
857 }
858
859 wdc_output_bytes(drvp, cmd, cmdlen);
860
861 /* Start the DMA channel if necessary */
862 if (xfer->c_flags & C_DMA0x0040) {
863 (*chp->wdc->dma_start)(chp->wdc->dma_arg,
864 chp->channel, xfer->drive);
865 xfer->next = wdc_atapi_intr_complete;
866 } else {
867 if (xfer->c_bcount == 0)
868 as->protocol_phase = as_completed;
869 else
870 as->protocol_phase = as_data;
871
872 xfer->next = wdc_atapi_pio_intr;
873 }
874
875 ret->expect_irq = 1;
876
877 /* If we read/write to a tape we will get into buffer
878 availability mode. */
879 if (drvp->atapi_cap & ACAP_DSC0x02) {
880 if ((sc_xfer->cmd.opcode == READ0x08 ||
881 sc_xfer->cmd.opcode == WRITE0x0a)) {
882 drvp->drive_flags |= DRIVE_DSCBA0x0200;
883 WDCDEBUG_PRINT(("set DSCBA\n"), DEBUG_DSC);
884 } else if ((xfer->c_flags & C_MEDIA_ACCESS0x0100) &&
885 (drvp->drive_flags & DRIVE_DSCBA0x0200)) {
886 /* Clause 3.2.4 of QIC-157 D.
887
888 Any media access command other than read or
889 write will switch DSC back to completion
890 mode */
891 drvp->drive_flags &= ~DRIVE_DSCBA0x0200;
892 WDCDEBUG_PRINT(("clear DCSBA\n"), DEBUG_DSC);
893 }
894 }
895
896 return;
897
898 timeout:
899 printf ("%s:%d:%d: device timeout waiting to send SCSI packet\n",
900 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive);
901
902 sc_xfer->error = XS_TIMEOUT4;
903 xfer->next = wdc_atapi_reset;
904 return;
905}
906
907
908char *
909wdc_atapi_in_data_phase(struct wdc_xfer *xfer, int len, int ire)
910{
911 struct scsi_xfer *sc_xfer = xfer->cmd;
912 struct atapiscsi_softc *as = sc_xfer->sc_link->bus->sb_adapter_softc;
913 char *message;
914
915 if (as->protocol_phase != as_data) {
916 message = "unexpected data phase";
917 goto unexpected_state;
918 }
919
920 if (ire & WDCI_CMD0x01) {
921 message = "unexpectedly in command phase";
922 goto unexpected_state;
923 }
924
925 if (!(xfer->c_flags & C_SENSE0x0080)) {
926 if (!(sc_xfer->flags & (SCSI_DATA_IN0x00800 | SCSI_DATA_OUT0x01000))) {
927 message = "data phase where none expected";
928 goto unexpected_state;
929 }
930
931 /* Make sure polarities match */
932 if (((ire & WDCI_IN0x02) == WDCI_IN0x02) ==
933 ((sc_xfer->flags & SCSI_DATA_OUT0x01000) == SCSI_DATA_OUT0x01000)) {
934 message = "data transfer direction disagreement";
935 goto unexpected_state;
936 }
937 } else {
938 if (!(ire & WDCI_IN0x02)) {
939 message = "data transfer direction disagreement during sense";
940 goto unexpected_state;
941 }
942 }
943
944 if (len == 0) {
945 message = "zero length transfer requested in data phase";
946 goto unexpected_state;
947 }
948
949
950 return (0);
951
952 unexpected_state:
953
954 return (message);
955}
956
957void
958wdc_atapi_intr_data(struct channel_softc *chp, struct wdc_xfer *xfer,
959 int timeout, struct atapi_return_args *ret)
960{
961 struct scsi_xfer *sc_xfer = xfer->cmd;
962 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
963 int len, ire;
964 char *message;
965 int tohost;
966
967 len = (CHP_READ_REG(chp, wdr_cyl_hi)((chp)->_vtbl->read_reg)(chp, wdr_cyl_hi) << 8) |
968 CHP_READ_REG(chp, wdr_cyl_lo)((chp)->_vtbl->read_reg)(chp, wdr_cyl_lo);
969 WDC_LOG_REG(chp, wdr_cyl_lo, len);
970
971 ire = CHP_READ_REG(chp, wdr_ireason)((chp)->_vtbl->read_reg)(chp, wdr_ireason);
972 WDC_LOG_REG(chp, wdr_ireason, ire);
973
974 if ((message = wdc_atapi_in_data_phase(xfer, len, ire))) {
Although the value stored to 'message' is used in the enclosing expression, the value is never actually read from 'message'
975 /* The drive has dropped BSY before setting up the
976 registers correctly for DATA phase. This drive is
977 not compliant with ATA/ATAPI-4.
978
979 Give the drive 100ms to get its house in order
980 before we try again. */
981 WDCDEBUG_PRINT(("wdc_atapi_intr: %s\n", message),
982 DEBUG_ERRORS);
983
984 if (!timeout) {
985 ret->delay = 100;
986 return;
987 }
988 }
989
990 tohost = ((sc_xfer->flags & SCSI_DATA_IN0x00800) != 0 ||
991 (xfer->c_flags & C_SENSE0x0080) != 0);
992
993 if (xfer->c_bcount >= len) {
994 WDCDEBUG_PRINT(("wdc_atapi_intr: c_bcount %d len %d "
995 "st 0x%b err 0x%x "
996 "ire 0x%x\n", xfer->c_bcount,
997 len, chp->ch_status, WDCS_BITS, chp->ch_error, ire),
998 DEBUG_INTR);
999
1000 /* Common case */
1001 if (!tohost)
1002 wdc_output_bytes(drvp, (u_int8_t *)xfer->databuf +
1003 xfer->c_skip, len);
1004 else
1005 wdc_input_bytes(drvp, (u_int8_t *)xfer->databuf +
1006 xfer->c_skip, len);
1007
1008 xfer->c_skip += len;
1009 xfer->c_bcount -= len;
1010 } else {
1011 /* Exceptional case - drive want to transfer more
1012 data than we have buffer for */
1013 if (!tohost) {
1014 /* Wouldn't it be better to just abort here rather
1015 than to write random stuff to drive? */
1016 printf("wdc_atapi_intr: warning: device requesting "
1017 "%d bytes, only %d left in buffer\n", len, xfer->c_bcount);
1018
1019 wdc_output_bytes(drvp, (u_int8_t *)xfer->databuf +
1020 xfer->c_skip, xfer->c_bcount);
1021
1022 CHP_WRITE_RAW_MULTI_2(chp, NULL,((chp)->_vtbl->write_raw_multi_2)(chp, ((void *)0), len
- xfer->c_bcount)
1023 len - xfer->c_bcount)((chp)->_vtbl->write_raw_multi_2)(chp, ((void *)0), len
- xfer->c_bcount)
;
1024 } else {
1025 printf("wdc_atapi_intr: warning: reading only "
1026 "%d of %d bytes\n", xfer->c_bcount, len);
1027
1028 wdc_input_bytes(drvp,
1029 (char *)xfer->databuf + xfer->c_skip,
1030 xfer->c_bcount);
1031 wdcbit_bucket(chp, len - xfer->c_bcount);
1032 }
1033
1034 xfer->c_skip += xfer->c_bcount;
1035 xfer->c_bcount = 0;
1036 }
1037
1038 ret->expect_irq = 1;
1039 xfer->next = wdc_atapi_pio_intr;
1040
1041 return;
1042}
1043
1044void
1045wdc_atapi_intr_complete(struct channel_softc *chp, struct wdc_xfer *xfer,
1046 int timeout, struct atapi_return_args *ret)
1047{
1048 struct scsi_xfer *sc_xfer = xfer->cmd;
1049 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
1050 struct atapiscsi_softc *as = sc_xfer->sc_link->bus->sb_adapter_softc;
1051
1052 WDCDEBUG_PRINT(("PHASE_COMPLETED\n"), DEBUG_INTR);
1053
1054 if (xfer->c_flags & C_DMA0x0040) {
1055 int retry;
1056
1057 if (timeout) {
1058 sc_xfer->error = XS_TIMEOUT4;
1059 ata_dmaerr(drvp);
1060
1061 xfer->next = wdc_atapi_reset;
1062 return;
1063 }
1064
1065 for (retry = 5; retry > 0; retry--) {
1066 wdc_atapi_update_status(chp);
1067 if ((chp->ch_status & (WDCS_BSY0x80 | WDCS_DRQ0x08)) == 0)
1068 break;
1069 DELAY(5)(*delay_func)(5);
1070 }
1071 if (retry == 0) {
1072 ret->expect_irq = 1;
1073 return;
1074 }
1075
1076 chp->wdc->dma_status =
1077 (*chp->wdc->dma_finish)
1078 (chp->wdc->dma_arg, chp->channel,
1079 xfer->drive, 1);
1080
1081 if (chp->wdc->dma_status & WDC_DMAST_UNDER0x04)
1082 xfer->c_bcount = 1;
1083 else
1084 xfer->c_bcount = 0;
1085 }
1086
1087 as->protocol_phase = as_none;
1088
1089 if (xfer->c_flags & C_SENSE0x0080) {
1090 if (chp->ch_status & WDCS_ERR0x01) {
1091 if (chp->ch_error & WDCE_ABRT0x04) {
1092 WDCDEBUG_PRINT(("wdc_atapi_intr: request_sense aborted, "
1093 "calling wdc_atapi_done()"
1094 ), DEBUG_INTR);
1095 xfer->next = wdc_atapi_done;
1096 return;
1097 }
1098
1099 /*
1100 * request sense failed ! it's not supposed
1101 * to be possible
1102 */
1103 sc_xfer->error = XS_SHORTSENSE6;
1104 } else if (xfer->c_bcount < sizeof(sc_xfer->sense)) {
1105 /* use the sense we just read */
1106 sc_xfer->error = XS_SENSE1;
1107 } else {
1108 /*
1109 * command completed, but no data was read.
1110 * use the short sense we saved previously.
1111 */
1112 sc_xfer->error = XS_SHORTSENSE6;
1113 }
1114 } else {
1115 sc_xfer->resid = xfer->c_bcount;
1116 if (chp->ch_status & WDCS_ERR0x01) {
1117 if (!atapi_to_scsi_sense(sc_xfer, chp->ch_error) &&
1118 (sc_xfer->sc_link->quirks &
1119 ADEV_NOSENSE0x0020) == 0) {
1120 /*
1121 * let the driver issue a
1122 * 'request sense'
1123 */
1124 xfer->databuf = &sc_xfer->sense;
1125 xfer->c_bcount = sizeof(sc_xfer->sense);
1126 xfer->c_skip = 0;
1127 xfer->c_done = NULL((void *)0);
1128 xfer->c_flags |= C_SENSE0x0080;
1129 xfer->next = wdc_atapi_real_start;
1130 return;
1131 }
1132 }
1133 }
1134
1135 if ((xfer->c_flags & C_DMA0x0040) &&
1136 (chp->wdc->dma_status & ~WDC_DMAST_UNDER0x04)) {
1137 ata_dmaerr(drvp);
1138 sc_xfer->error = XS_RESET8;
1139
1140 xfer->next = wdc_atapi_reset;
1141 return;
1142 }
1143
1144
1145 if (xfer->c_bcount != 0) {
1146 WDCDEBUG_PRINT(("wdc_atapi_intr: bcount value is "
1147 "%d after io\n", xfer->c_bcount), DEBUG_XFERS);
1148 }
1149#ifdef DIAGNOSTIC1
1150 if (xfer->c_bcount < 0) {
1151 printf("wdc_atapi_intr warning: bcount value "
1152 "is %d after io\n", xfer->c_bcount);
1153 }
1154#endif
1155
1156 WDCDEBUG_PRINT(("wdc_atapi_intr: wdc_atapi_done() (end), error 0x%x "
1157 "\n", sc_xfer->error),
1158 DEBUG_INTR);
1159
1160
1161 if (xfer->c_done)
1162 xfer->next = xfer->c_done;
1163 else
1164 xfer->next = wdc_atapi_done;
1165
1166 return;
1167}
1168
1169void
1170wdc_atapi_pio_intr(struct channel_softc *chp, struct wdc_xfer *xfer,
1171 int timeout, struct atapi_return_args *ret)
1172{
1173 struct scsi_xfer *sc_xfer = xfer->cmd;
1174 struct atapiscsi_softc *as = sc_xfer->sc_link->bus->sb_adapter_softc;
1175 u_int8_t ireason;
1176
1177 wdc_atapi_update_status(chp);
1178
1179 if (chp->ch_status & WDCS_BSY0x80) {
1180 if (timeout)
1181 goto timeout;
1182
1183 return;
1184 }
1185
1186 if (!wdc_atapi_drive_selected(chp, xfer->drive)) {
1187 WDCDEBUG_PRINT(("wdc_atapi_intr_for_us: wrong drive selected\n"), DEBUG_INTR);
1188 wdc_set_drive(chp, xfer->drive);
1189 delay (1)(*delay_func)(1);
1190
1191 if (!timeout)
1192 return;
1193 }
1194
1195 if ((xfer->c_flags & C_MEDIA_ACCESS0x0100) &&
1196 !(chp->ch_status & (WDCS_DSC0x10 | WDCS_DRQ0x08))) {
1197 if (timeout)
1198 goto timeout;
1199
1200 ret->delay = 100;
1201 return;
1202 }
1203
1204 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK0x0400)
1205 chp->wdc->irqack(chp);
1206
1207 ireason = CHP_READ_REG(chp, wdr_ireason)((chp)->_vtbl->read_reg)(chp, wdr_ireason);
1208 WDC_LOG_REG(chp, wdr_ireason, ireason);
1209
1210 WDCDEBUG_PRINT(("Phase %d, (0x%b, 0x%x) ", as->protocol_phase,
1211 chp->ch_status, WDCS_BITS, ireason), DEBUG_INTR );
1212
1213 switch (as->protocol_phase) {
1214 case as_data:
1215 if ((chp->ch_status & WDCS_DRQ0x08) ||
1216 (ireason & 3) != 3) {
1217 if (timeout)
1218 goto timeout;
1219
1220 wdc_atapi_intr_data(chp, xfer, timeout, ret);
1221 return;
1222 }
1223
1224 wdc_atapi_intr_complete(chp, xfer, timeout, ret);
1225 return;
1226
1227 case as_completed:
1228 if ((chp->ch_status & WDCS_DRQ0x08) ||
1229 (ireason & 3) != 3) {
1230 if (timeout)
1231 goto timeout;
1232
1233 ret->delay = 100;
1234 return;
1235 }
1236
1237 wdc_atapi_intr_complete(chp, xfer, timeout, ret);
1238 return;
1239
1240 default:
1241 printf ("atapiscsi: Shouldn't get here\n");
1242 sc_xfer->error = XS_DRIVER_STUFFUP2;
1243 xfer->next = wdc_atapi_reset;
1244 return;
1245 }
1246
1247 return;
1248timeout:
1249 ireason = CHP_READ_REG(chp, wdr_ireason)((chp)->_vtbl->read_reg)(chp, wdr_ireason);
1250 WDC_LOG_REG(chp, wdr_ireason, ireason);
1251
1252 printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip=%d, "
1253 "status=0x%b, ireason=0x%x\n",
1254 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
1255 xfer->c_bcount, xfer->c_skip, chp->ch_status, WDCS_BITS"\020\010BSY\007DRDY\006DWF\005DSC\004DRQ\003CORR\002IDX\001ERR", ireason);
1256
1257 sc_xfer->error = XS_TIMEOUT4;
1258 xfer->next = wdc_atapi_reset;
1259 return;
1260}
1261
1262void
1263wdc_atapi_ctrl(struct channel_softc *chp, struct wdc_xfer *xfer,
1264 int timeout, struct atapi_return_args *ret)
1265{
1266 struct scsi_xfer *sc_xfer = xfer->cmd;
1267 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
1268 char *errstring = NULL((void *)0);
1269
1270 wdc_atapi_update_status(chp);
1271
1272 if (!timeout) {
1273 switch (drvp->state) {
1274 case ATAPI_IDENTIFY_WAIT_STATE:
1275 if (chp->ch_status & WDCS_BSY0x80)
1276 return;
1277 break;
1278 default:
1279 if (chp->ch_status & (WDCS_BSY0x80 | WDCS_DRQ0x08))
1280 return;
1281 break;
1282 }
1283 }
1284
1285 if (!wdc_atapi_drive_selected(chp, xfer->drive))
1286 {
1287 wdc_set_drive(chp, xfer->drive);
1288 delay (1)(*delay_func)(1);
1289 }
1290
1291 if (timeout) {
1292 int trigger_timeout = 1;
1293
1294 switch (drvp->state) {
1295 case ATAPI_DEVICE_RESET_WAIT_STATE:
1296 errstring = "Device Reset Wait";
1297 drvp->drive_flags &= ~DRIVE_DEVICE_RESET0x0800;
1298 break;
1299
1300 case ATAPI_IDENTIFY_WAIT_STATE:
1301 errstring = "Identify";
1302 if (!(chp->ch_status & WDCS_BSY0x80) &&
1303 (chp->ch_status & (WDCS_DRQ0x08 | WDCS_ERR0x01)))
1304 trigger_timeout = 0;
1305
1306 break;
1307
1308 case ATAPI_PIOMODE_STATE:
1309 errstring = "Post-Identify";
1310 if (!(chp->ch_status & (WDCS_BSY0x80 | WDCS_DRQ0x08)))
1311 trigger_timeout = 0;
1312 break;
1313
1314 case ATAPI_PIOMODE_WAIT_STATE:
1315 errstring = "PIOMODE";
1316 if (chp->ch_status & (WDCS_BSY0x80 | WDCS_DRQ0x08))
1317 drvp->drive_flags &= ~DRIVE_MODE0x0040;
1318 else
1319 trigger_timeout = 0;
1320 break;
1321 case ATAPI_DMAMODE_WAIT_STATE:
1322 errstring = "dmamode";
1323 if (chp->ch_status & (WDCS_BSY0x80 | WDCS_DRQ0x08))
1324 drvp->drive_flags &= ~(DRIVE_DMA0x0010 | DRIVE_UDMA0x0020);
1325 else
1326 trigger_timeout = 0;
1327 break;
1328
1329 default:
1330 errstring = "unknown state";
1331 break;
1332 }
1333
1334 if (trigger_timeout)
1335 goto timeout;
1336 }
1337
1338 WDCDEBUG_PRINT(("wdc_atapi_ctrl %s:%d:%d state %d\n",
1339 chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive, drvp->state),
1340 DEBUG_INTR | DEBUG_FUNCS);
1341
1342 switch (drvp->state) {
1343 /* My ATAPI slave device likes to assert DASP-/PDIAG- until
1344 it is DEVICE RESET. This causes the LED to stay on.
1345
1346 There is a trade-off here. This drive will cause any
1347 play-back or seeks happening to be interrupted.
1348
1349 Note that the bus reset that triggered this state
1350 (which may have been caused by the other drive on
1351 the chain) need not interrupt this playback. It happens
1352 to on my Smart & Friendly CD burner.
1353
1354 - csapuntz@
1355 */
1356 case ATAPI_RESET_BASE_STATE:
1357 if ((drvp->drive_flags & DRIVE_DEVICE_RESET0x0800) == 0) {
1358 drvp->state = ATAPI_IDENTIFY_STATE;
1359 break;
1360 }
1361
1362 wdccommandshort(chp, drvp->drive, ATAPI_DEVICE_RESET0x08);
1363 drvp->state = ATAPI_DEVICE_RESET_WAIT_STATE;
1364 ret->delay = ATAPI_RESET_DELAY1000;
1365 ret->timeout = ATAPI_RESET_WAIT2000;
1366 break;
1367
1368 case ATAPI_DEVICE_RESET_WAIT_STATE:
1369 /* FALLTHROUGH */
1370
1371 case ATAPI_IDENTIFY_STATE:
1372 wdccommandshort(chp, drvp->drive, ATAPI_IDENTIFY_DEVICE0xa1);
1373 drvp->state = ATAPI_IDENTIFY_WAIT_STATE;
1374 ret->delay = 10;
1375 ret->timeout = ATAPI_RESET_WAIT2000;
1376 break;
1377
1378 case ATAPI_IDENTIFY_WAIT_STATE: {
1379 int idx = 0;
1380
1381 while ((chp->ch_status & WDCS_DRQ0x08) &&
1382 idx++ < 20) {
1383 wdcbit_bucket(chp, 512);
1384
1385 DELAY(1)(*delay_func)(1);
1386 wdc_atapi_update_status(chp);
1387 }
1388
1389 drvp->state = ATAPI_PIOMODE_STATE;
1390 /*
1391 * Note, we can't go directly to set PIO mode
1392 * because the drive is free to assert BSY
1393 * after the transfer
1394 */
1395 break;
1396 }
1397
1398 case ATAPI_PIOMODE_STATE:
1399 /* Don't try to set mode if controller can't be adjusted */
1400 if ((chp->wdc->cap & WDC_CAPABILITY_MODE0x0004) == 0)
1401 goto ready;
1402 /* Also don't try if the drive didn't report its mode */
1403 if ((drvp->drive_flags & DRIVE_MODE0x0040) == 0)
1404 goto ready;
1405 /* SET FEATURES 0x08 is only for PIO mode > 2 */
1406 if (drvp->PIO_mode <= 2)
1407 goto ready;
1408 wdccommand(chp, drvp->drive, SET_FEATURES0xef, 0, 0, 0,
1409 0x08 | drvp->PIO_mode, WDSF_SET_MODE0x03);
1410 drvp->state = ATAPI_PIOMODE_WAIT_STATE;
1411 ret->timeout = ATAPI_CTRL_WAIT4000;
1412 ret->expect_irq = 1;
1413 break;
1414 case ATAPI_PIOMODE_WAIT_STATE:
1415 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK0x0400)
1416 chp->wdc->irqack(chp);
1417 if (chp->ch_status & WDCS_ERR0x01) {
1418 /* Downgrade straight to PIO mode 3 */
1419 drvp->PIO_mode = 3;
1420 chp->wdc->set_modes(chp);
1421 }
1422 /* FALLTHROUGH */
1423
1424 case ATAPI_DMAMODE_STATE:
1425 if (drvp->drive_flags & DRIVE_UDMA0x0020) {
1426 wdccommand(chp, drvp->drive, SET_FEATURES0xef, 0, 0, 0,
1427 0x40 | drvp->UDMA_mode, WDSF_SET_MODE0x03);
1428 } else if (drvp->drive_flags & DRIVE_DMA0x0010) {
1429 wdccommand(chp, drvp->drive, SET_FEATURES0xef, 0, 0, 0,
1430 0x20 | drvp->DMA_mode, WDSF_SET_MODE0x03);
1431 } else {
1432 goto ready;
1433 }
1434 drvp->state = ATAPI_DMAMODE_WAIT_STATE;
1435
1436 ret->timeout = ATAPI_CTRL_WAIT4000;
1437 ret->expect_irq = 1;
1438 break;
1439
1440 case ATAPI_DMAMODE_WAIT_STATE:
1441 if (chp->wdc->cap & WDC_CAPABILITY_IRQACK0x0400)
1442 chp->wdc->irqack(chp);
1443 if (chp->ch_status & WDCS_ERR0x01)
1444 drvp->drive_flags &= ~(DRIVE_DMA0x0010 | DRIVE_UDMA0x0020);
1445 /* FALLTHROUGH */
1446
1447 case ATAPI_READY_STATE:
1448 ready:
1449 drvp->state = ATAPI_READY_STATE;
1450 xfer->next = wdc_atapi_real_start;
1451 break;
1452 }
1453 return;
1454
1455timeout:
1456 printf("%s:%d:%d: %s timed out\n",
1457 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, errstring);
1458 sc_xfer->error = XS_TIMEOUT4;
1459 xfer->next = wdc_atapi_reset;
1460 return;
1461
1462}
1463
1464void
1465wdc_atapi_tape_done(struct channel_softc *chp, struct wdc_xfer *xfer,
1466 int timeout, struct atapi_return_args *ret)
1467{
1468 struct scsi_xfer *sc_xfer = xfer->cmd;
1469
1470 if (sc_xfer->error != XS_NOERROR0) {
1471 xfer->next = wdc_atapi_done;
1472 return;
1473 }
1474
1475 _lto3b(xfer->transfer_len,
1476 ((struct scsi_rw_tape *)
1477 &sc_xfer->cmd)->len);
1478
1479 xfer->c_bcount = sc_xfer->datalen;
1480 xfer->c_done = NULL((void *)0);
1481 xfer->c_skip = 0;
1482
1483 xfer->next = wdc_atapi_real_start;
1484 return;
1485}
1486
1487
1488void
1489wdc_atapi_done(struct channel_softc *chp, struct wdc_xfer *xfer,
1490 int timeout, struct atapi_return_args *ret)
1491{
1492 struct scsi_xfer *sc_xfer = xfer->cmd;
1493
1494 WDCDEBUG_PRINT(("wdc_atapi_done %s:%d:%d: flags 0x%x error 0x%x\n",
1495 chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
1496 (u_int)xfer->c_flags, sc_xfer->error), DEBUG_XFERS);
1497 WDC_LOG_ATAPI_DONE(chp, xfer->drive, xfer->c_flags, sc_xfer->error);
1498
1499 if (xfer->c_flags & C_POLL0x0020)
1500 wdc_enable_intr(chp);
1501
1502 scsi_done(sc_xfer);
1503
1504 xfer->next = NULL((void *)0);
1505 return;
1506}
1507
1508
1509void
1510wdc_atapi_reset(struct channel_softc *chp, struct wdc_xfer *xfer,
1511 int timeout, struct atapi_return_args *ret)
1512{
1513 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
1514
1515 if (drvp->state == 0) {
1516 xfer->next = wdc_atapi_done;
1517 return;
1518 }
1519
1520 WDCDEBUG_PRINT(("wdc_atapi_reset\n"), DEBUG_XFERS);
1521 wdccommandshort(chp, xfer->drive, ATAPI_SOFT_RESET0x08);
1522 drvp->state = ATAPI_IDENTIFY_STATE;
1523
1524 drvp->n_resets++;
1525 /* Some ATAPI devices need extra time to find their
1526 brains after a reset
1527 */
1528 xfer->next = wdc_atapi_reset_2;
1529 ret->delay = ATAPI_RESET_DELAY1000;
1530 ret->timeout = ATAPI_RESET_WAIT2000;
1531 return;
1532}
1533
1534void
1535wdc_atapi_reset_2(struct channel_softc *chp, struct wdc_xfer *xfer,
1536 int timeout, struct atapi_return_args *ret)
1537{
1538 struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
1539 struct scsi_xfer *sc_xfer = xfer->cmd;
1540
1541 if (timeout) {
1542 printf("%s:%d:%d: soft reset failed\n",
1543 chp->wdc->sc_dev.dv_xname, chp->channel,
1544 xfer->drive);
1545 sc_xfer->error = XS_SELTIMEOUT3;
1546 wdc_reset_channel(drvp, 0);
1547
1548 xfer->next = wdc_atapi_done;
1549 return;
1550 }
1551
1552 wdc_atapi_update_status(chp);
1553
1554 if (chp->ch_status & (WDCS_BSY0x80 | WDCS_DRQ0x08)) {
1555 return;
1556 }
1557
1558 xfer->next = wdc_atapi_done;
1559 return;
1560}