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