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