Annotation of sys/dev/atapiscsi/atapiscsi.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: atapiscsi.c,v 1.78 2007/08/06 08:28:09 tom 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: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed by Manuel Bouyer.
21: * 4. Neither the name of the University nor the names of its contributors
22: * may be used to endorse or promote products derived from this software
23: * without specific prior written permission.
24: *
25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35: * SUCH DAMAGE.
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: /* drive states stored in ata_drive_datas */
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 /* Debug error handling code */
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: /* 10 ms, this is used only before sending a cmd. */
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: /* When polling, let the exponential backoff max out at 1 second's interval. */
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: /* Inital version shares bus_link structure so it can easily
190: be "attached to current" wdc driver */
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: /* Initialize shared data. */
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: /* Tape drives do funny DSC stuff */
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: /* 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: 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: /* 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: 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: * Returns 1 if we experienced an ATA-level abort command
464: * (ABRT bit set but no additional sense)
465: * 0 if normal command processing
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: /* Media change requested */
499: /* Let's ignore these in version 1 */
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: /* XXX we should consider an alternate signaling regime here */
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: /* Don't go through more than 50 state machine steps
659: before yielding. This tries to limit the amount of time
660: spent at high SPL */
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: * Add 1 tick to compensate for the fact that we
671: * can be just microseconds before the tick changes.
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: * Only set the DMA flag if the transfer is reasonably large.
744: * At least one older drive failed to complete a 4 byte DMA transfer.
745: */
746:
747: /* Turn off DMA flag on REQUEST SENSE */
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: /* Do control operations specially. */
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: * Even with WDCS_ERR, the device should accept a command packet
821: * Limit length to what can be stuffed into the cylinder register
822: * (16 bits). Some CD-ROMs seem to interpret '0' as 65536,
823: * but not all devices do that and it's not obvious from the
824: * ATAPI spec that this behaviour should be expected. If more
825: * data is necessary, multiple data transfer phases will be done.
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: /* We expect an IRQ to tell us of the next state */
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: /* Init the DMA channel if necessary */
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: /* Start the DMA channel if necessary */
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: /* If we read/write to a tape we will get into buffer
928: availability mode. */
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: /* Clause 3.2.4 of QIC-157 D.
937:
938: Any media access command other than read or
939: write will switch DSC back to completion
940: mode */
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: /* Make sure polarities match */
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: /* The drive has dropped BSY before setting up the
1031: registers correctly for DATA phase. This drive is
1032: not compliant with ATA/ATAPI-4.
1033:
1034: Give the drive 100ms to get its house in order
1035: before we try again. */
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: /* Common case */
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: /* Exceptional case - drive want to transfer more
1067: data than we have buffer for */
1068: if (!tohost) {
1069: /* Wouldn't it be better to just abort here rather
1070: than to write random stuff to drive? */
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: * request sense failed ! it's not supposed
1159: * to be possible
1160: */
1161: sc_xfer->error = XS_SHORTSENSE;
1162: } else if (xfer->c_bcount < sizeof(sc_xfer->sense)) {
1163: /* use the sense we just read */
1164: sc_xfer->error = XS_SENSE;
1165: } else {
1166: /*
1167: * command completed, but no data was read.
1168: * use the short sense we saved previously.
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: * let the driver issue a
1180: * 'request sense'
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: /* My ATAPI slave device likes to assert DASP-/PDIAG- until
1407: it is DEVICE RESET. This causes the LED to stay on.
1408:
1409: There is a trade-off here. This drive will cause any
1410: play-back or seeks happening to be interrupted.
1411:
1412: Note that the bus reset that triggered this state
1413: (which may have been caused by the other drive on
1414: the chain) need not interrupt this playback. It happens
1415: to on my Smart & Friendly CD burner.
1416:
1417: - csapuntz@
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: /* FALLTHROUGH */
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: * Note, we can't go directly to set PIO mode
1455: * because the drive is free to assert BSY
1456: * after the transfer
1457: */
1458: break;
1459: }
1460:
1461: case ATAPI_PIOMODE_STATE:
1462: /* Don't try to set mode if controller can't be adjusted */
1463: if ((chp->wdc->cap & WDC_CAPABILITY_MODE) == 0)
1464: goto ready;
1465: /* Also don't try if the drive didn't report its mode */
1466: if ((drvp->drive_flags & DRIVE_MODE) == 0)
1467: goto ready;
1468: /* SET FEATURES 0x08 is only for PIO mode > 2 */
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: /* Downgrade straight to PIO mode 3 */
1482: drvp->PIO_mode = 3;
1483: chp->wdc->set_modes(chp);
1484: }
1485: /* FALLTHROUGH */
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: /* FALLTHROUGH */
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: /* Some ATAPI devices need extra time to find their
1602: brains after a reset
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: }
CVSweb