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