Annotation of src/sys/dev/scsipi/atapi_wdc.c, Revision 1.98.6.1
1.98.6.1! tron 1: /* $NetBSD$ */
1.2 bouyer 2:
3: /*
1.47 bouyer 4: * Copyright (c) 1998, 2001 Manuel Bouyer.
1.2 bouyer 5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: * 3. All advertising materials mentioning features or use of this software
15: * must display the following acknowledgement:
1.51 bouyer 16: * This product includes software developed by Manuel Bouyer.
1.58 bouyer 17: * 4. The name of the author may not be used to endorse or promote products
18: * derived from this software without specific prior written permission.
1.2 bouyer 19: *
1.35 bouyer 20: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1.92 perry 23: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1.35 bouyer 24: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.2 bouyer 30: */
1.44 lukem 31:
32: #include <sys/cdefs.h>
1.98.6.1! tron 33: __KERNEL_RCSID(0, "$NetBSD$");
1.2 bouyer 34:
1.86 thorpej 35: #ifndef ATADEBUG
36: #define ATADEBUG
37: #endif /* ATADEBUG */
1.2 bouyer 38:
39: #include <sys/param.h>
40: #include <sys/systm.h>
41: #include <sys/kernel.h>
42: #include <sys/file.h>
43: #include <sys/stat.h>
44: #include <sys/buf.h>
45: #include <sys/malloc.h>
46: #include <sys/device.h>
47: #include <sys/syslog.h>
48: #include <sys/proc.h>
1.39 mycroft 49: #include <sys/dvdio.h>
1.2 bouyer 50:
51: #include <machine/intr.h>
52: #include <machine/bus.h>
53:
54: #ifndef __BUS_SPACE_HAS_STREAM_METHODS
1.65 thorpej 55: #define bus_space_write_multi_stream_2 bus_space_write_multi_2
56: #define bus_space_write_multi_stream_4 bus_space_write_multi_4
57: #define bus_space_read_multi_stream_2 bus_space_read_multi_2
58: #define bus_space_read_multi_stream_4 bus_space_read_multi_4
1.2 bouyer 59: #endif /* __BUS_SPACE_HAS_STREAM_METHODS */
60:
61: #include <dev/ata/atareg.h>
62: #include <dev/ata/atavar.h>
63: #include <dev/ic/wdcreg.h>
64: #include <dev/ic/wdcvar.h>
65:
1.40 bouyer 66: #include <dev/scsipi/scsi_all.h> /* for SCSI status */
67:
1.2 bouyer 68: #define DEBUG_INTR 0x01
69: #define DEBUG_XFERS 0x02
70: #define DEBUG_STATUS 0x04
71: #define DEBUG_FUNCS 0x08
72: #define DEBUG_PROBE 0x10
1.86 thorpej 73: #ifdef ATADEBUG
1.3 bouyer 74: int wdcdebug_atapi_mask = 0;
1.86 thorpej 75: #define ATADEBUG_PRINT(args, level) \
1.2 bouyer 76: if (wdcdebug_atapi_mask & (level)) \
77: printf args
78: #else
1.86 thorpej 79: #define ATADEBUG_PRINT(args, level)
1.2 bouyer 80: #endif
81:
82: #define ATAPI_DELAY 10 /* 10 ms, this is used only before sending a cmd */
1.59 bouyer 83: #define ATAPI_MODE_DELAY 1000 /* 1s, timeout for SET_FEATYRE cmds */
1.65 thorpej 84:
85: static int wdc_atapi_get_params(struct scsipi_channel *, int,
86: struct ataparams *);
87: static void wdc_atapi_probe_device(struct atapibus_softc *, int);
88: static void wdc_atapi_minphys (struct buf *bp);
1.87 thorpej 89: static void wdc_atapi_start(struct ata_channel *,struct ata_xfer *);
90: static int wdc_atapi_intr(struct ata_channel *, struct ata_xfer *, int);
91: static void wdc_atapi_kill_xfer(struct ata_channel *,
1.71 bouyer 92: struct ata_xfer *, int);
1.65 thorpej 93: static void wdc_atapi_phase_complete(struct ata_xfer *);
1.87 thorpej 94: static void wdc_atapi_done(struct ata_channel *, struct ata_xfer *);
95: static void wdc_atapi_reset(struct ata_channel *, struct ata_xfer *);
1.65 thorpej 96: static void wdc_atapi_scsipi_request(struct scsipi_channel *,
97: scsipi_adapter_req_t, void *);
98: static void wdc_atapi_kill_pending(struct scsipi_periph *);
99: static void wdc_atapi_polldsc(void *arg);
1.2 bouyer 100:
101: #define MAX_SIZE MAXPHYS
102:
1.65 thorpej 103: static const struct scsipi_bustype wdc_atapi_bustype = {
1.40 bouyer 104: SCSIPI_BUSTYPE_ATAPI,
105: atapi_scsipi_cmd,
106: atapi_interpret_sense,
107: atapi_print_addr,
108: wdc_atapi_kill_pending,
109: };
110:
1.2 bouyer 111: void
1.65 thorpej 112: wdc_atapibus_attach(struct atabus_softc *ata_sc)
1.2 bouyer 113: {
1.87 thorpej 114: struct ata_channel *chp = ata_sc->sc_chan;
1.88 thorpej 115: struct atac_softc *atac = chp->ch_atac;
116: struct scsipi_adapter *adapt = &atac->atac_atapi_adapter._generic;
1.40 bouyer 117: struct scsipi_channel *chan = &chp->ch_atapi_channel;
1.2 bouyer 118:
1.9 thorpej 119: /*
1.40 bouyer 120: * Fill in the scsipi_adapter.
1.9 thorpej 121: */
1.88 thorpej 122: adapt->adapt_dev = &atac->atac_dev;
123: adapt->adapt_nchannels = atac->atac_nchannels;
1.40 bouyer 124: adapt->adapt_request = wdc_atapi_scsipi_request;
125: adapt->adapt_minphys = wdc_atapi_minphys;
1.88 thorpej 126: if (atac->atac_cap & ATAC_CAP_NOIRQ)
1.42 bjh21 127: adapt->adapt_flags |= SCSIPI_ADAPT_POLL_ONLY;
1.88 thorpej 128: atac->atac_atapi_adapter.atapi_probe_device = wdc_atapi_probe_device;
1.40 bouyer 129:
130: /*
131: * Fill in the scsipi_channel.
132: */
133: memset(chan, 0, sizeof(*chan));
134: chan->chan_adapter = adapt;
135: chan->chan_bustype = &wdc_atapi_bustype;
1.67 thorpej 136: chan->chan_channel = chp->ch_channel;
1.40 bouyer 137: chan->chan_flags = SCSIPI_CHAN_OPENINGS;
138: chan->chan_openings = 1;
139: chan->chan_max_periph = 1;
140: chan->chan_ntargets = 2;
141: chan->chan_nluns = 1;
142:
1.96 drochner 143: chp->atapibus = config_found_ia(&ata_sc->sc_dev, "atapi", chan,
144: atapiprint);
1.2 bouyer 145: }
146:
1.65 thorpej 147: static void
148: wdc_atapi_minphys(struct buf *bp)
1.2 bouyer 149: {
1.40 bouyer 150:
151: if (bp->b_bcount > MAX_SIZE)
1.2 bouyer 152: bp->b_bcount = MAX_SIZE;
153: minphys(bp);
154: }
155:
1.28 enami 156: /*
1.40 bouyer 157: * Kill off all pending xfers for a periph.
1.28 enami 158: *
159: * Must be called at splbio().
160: */
1.65 thorpej 161: static void
162: wdc_atapi_kill_pending(struct scsipi_periph *periph)
1.28 enami 163: {
1.88 thorpej 164: struct atac_softc *atac =
1.40 bouyer 165: (void *)periph->periph_channel->chan_adapter->adapt_dev;
1.87 thorpej 166: struct ata_channel *chp =
1.88 thorpej 167: atac->atac_channels[periph->periph_channel->chan_channel];
1.28 enami 168:
1.82 thorpej 169: ata_kill_pending(&chp->ch_drive[periph->periph_target]);
1.28 enami 170: }
171:
1.65 thorpej 172: static void
1.87 thorpej 173: wdc_atapi_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, int reason)
1.28 enami 174: {
1.63 thorpej 175: struct scsipi_xfer *sc_xfer = xfer->c_cmd;
1.28 enami 176:
177: /* remove this command from xfer queue */
1.71 bouyer 178: switch (reason) {
179: case KILL_GONE:
180: sc_xfer->error = XS_DRIVER_STUFFUP;
181: break;
182: case KILL_RESET:
183: sc_xfer->error = XS_RESET;
184: break;
185: default:
186: printf("wdc_ata_bio_kill_xfer: unknown reason %d\n",
187: reason);
188: panic("wdc_ata_bio_kill_xfer");
189: }
1.81 thorpej 190: ata_free_xfer(chp, xfer);
1.73 bouyer 191: scsipi_done(sc_xfer);
1.28 enami 192: }
193:
1.65 thorpej 194: static int
195: wdc_atapi_get_params(struct scsipi_channel *chan, int drive,
196: struct ataparams *id)
1.2 bouyer 197: {
1.40 bouyer 198: struct wdc_softc *wdc = (void *)chan->chan_adapter->adapt_dev;
1.88 thorpej 199: struct atac_softc *atac = &wdc->sc_atac;
1.87 thorpej 200: struct wdc_regs *wdr = &wdc->regs[chan->chan_channel];
1.88 thorpej 201: struct ata_channel *chp = atac->atac_channels[chan->chan_channel];
1.78 thorpej 202: struct ata_command ata_c;
1.2 bouyer 203:
204: /* if no ATAPI device detected at wdc attach time, skip */
205: if ((chp->ch_drive[drive].drive_flags & DRIVE_ATAPI) == 0) {
1.86 thorpej 206: ATADEBUG_PRINT(("wdc_atapi_get_params: drive %d not present\n",
1.2 bouyer 207: drive), DEBUG_PROBE);
208: return -1;
209: }
1.59 bouyer 210:
1.78 thorpej 211: memset(&ata_c, 0, sizeof(struct ata_command));
212: ata_c.r_command = ATAPI_SOFT_RESET;
213: ata_c.r_st_bmask = 0;
214: ata_c.r_st_pmask = 0;
215: ata_c.flags = AT_WAIT | AT_POLL;
216: ata_c.timeout = WDC_RESET_WAIT;
1.79 thorpej 217: if (wdc_exec_command(&chp->ch_drive[drive], &ata_c) != ATACMD_COMPLETE) {
1.59 bouyer 218: printf("wdc_atapi_get_params: ATAPI_SOFT_RESET failed for"
219: " drive %s:%d:%d: driver failed\n",
1.88 thorpej 220: atac->atac_dev.dv_xname, chp->ch_channel, drive);
1.59 bouyer 221: panic("wdc_atapi_get_params");
222: }
1.78 thorpej 223: if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
1.86 thorpej 224: ATADEBUG_PRINT(("wdc_atapi_get_params: ATAPI_SOFT_RESET "
1.59 bouyer 225: "failed for drive %s:%d:%d: error 0x%x\n",
1.92 perry 226: atac->atac_dev.dv_xname, chp->ch_channel, drive,
1.78 thorpej 227: ata_c.r_error), DEBUG_PROBE);
1.2 bouyer 228: return -1;
229: }
1.59 bouyer 230: chp->ch_drive[drive].state = 0;
1.2 bouyer 231:
1.98.6.1! tron 232: (void)bus_space_read_1(wdr->cmd_iot, wdr->cmd_iohs[wd_status], 0);
1.92 perry 233:
1.2 bouyer 234: /* Some ATAPI devices need a bit more time after software reset. */
235: delay(5000);
1.57 mycroft 236: if (ata_get_params(&chp->ch_drive[drive], AT_WAIT, id) != 0) {
1.86 thorpej 237: ATADEBUG_PRINT(("wdc_atapi_get_params: ATAPI_IDENTIFY_DEVICE "
1.2 bouyer 238: "failed for drive %s:%d:%d: error 0x%x\n",
1.92 perry 239: atac->atac_dev.dv_xname, chp->ch_channel, drive,
1.78 thorpej 240: ata_c.r_error), DEBUG_PROBE);
1.2 bouyer 241: return -1;
242: }
1.40 bouyer 243: return 0;
1.2 bouyer 244: }
245:
1.65 thorpej 246: static void
247: wdc_atapi_probe_device(struct atapibus_softc *sc, int target)
1.33 bouyer 248: {
1.40 bouyer 249: struct scsipi_channel *chan = sc->sc_channel;
250: struct scsipi_periph *periph;
1.33 bouyer 251: struct ataparams ids;
252: struct ataparams *id = &ids;
1.46 bouyer 253: struct wdc_softc *wdc = (void *)chan->chan_adapter->adapt_dev;
1.88 thorpej 254: struct atac_softc *atac = &wdc->sc_atac;
255: struct ata_channel *chp = atac->atac_channels[chan->chan_channel];
1.46 bouyer 256: struct ata_drive_datas *drvp = &chp->ch_drive[target];
1.40 bouyer 257: struct scsipibus_attach_args sa;
1.33 bouyer 258: char serial_number[21], model[41], firmware_revision[9];
1.89 thorpej 259: int s;
1.33 bouyer 260:
1.40 bouyer 261: /* skip if already attached */
262: if (scsipi_lookup_periph(chan, target, 0) != NULL)
1.33 bouyer 263: return;
1.40 bouyer 264:
1.57 mycroft 265: if (wdc_atapi_get_params(chan, target, id) == 0) {
1.33 bouyer 266: #ifdef ATAPI_DEBUG_PROBE
267: printf("%s drive %d: cmdsz 0x%x drqtype 0x%x\n",
1.40 bouyer 268: sc->sc_dev.dv_xname, target,
1.33 bouyer 269: id->atap_config & ATAPI_CFG_CMD_MASK,
270: id->atap_config & ATAPI_CFG_DRQ_MASK);
271: #endif
1.40 bouyer 272: periph = scsipi_alloc_periph(M_NOWAIT);
273: if (periph == NULL) {
274: printf("%s: unable to allocate periph for drive %d\n",
275: sc->sc_dev.dv_xname, target);
276: return;
1.33 bouyer 277: }
1.40 bouyer 278: periph->periph_dev = NULL;
279: periph->periph_channel = chan;
280: periph->periph_switch = &atapi_probe_periphsw;
281: periph->periph_target = target;
282: periph->periph_lun = 0;
1.56 mycroft 283: periph->periph_quirks = PQUIRK_ONLYBIG;
1.40 bouyer 284:
285: #ifdef SCSIPI_DEBUG
286: if (SCSIPI_DEBUG_TYPE == SCSIPI_BUSTYPE_ATAPI &&
287: SCSIPI_DEBUG_TARGET == target)
288: periph->periph_dbflags |= SCSIPI_DEBUG_FLAGS;
289: #endif
290: periph->periph_type = ATAPI_CFG_TYPE(id->atap_config);
291: if (id->atap_config & ATAPI_CFG_REMOV)
292: periph->periph_flags |= PERIPH_REMOVABLE;
1.89 thorpej 293: if (periph->periph_type == T_SEQUENTIAL) {
294: s = splbio();
1.45 bouyer 295: drvp->drive_flags |= DRIVE_ATAPIST;
1.89 thorpej 296: splx(s);
297: }
1.40 bouyer 298:
299: sa.sa_periph = periph;
300: sa.sa_inqbuf.type = ATAPI_CFG_TYPE(id->atap_config);
301: sa.sa_inqbuf.removable = id->atap_config & ATAPI_CFG_REMOV ?
302: T_REMOV : T_FIXED;
1.33 bouyer 303: scsipi_strvis(model, 40, id->atap_model, 40);
1.40 bouyer 304: scsipi_strvis(serial_number, 20, id->atap_serial, 20);
1.33 bouyer 305: scsipi_strvis(firmware_revision, 8, id->atap_revision, 8);
306: sa.sa_inqbuf.vendor = model;
307: sa.sa_inqbuf.product = serial_number;
308: sa.sa_inqbuf.revision = firmware_revision;
1.40 bouyer 309:
310: /*
311: * Determine the operating mode capabilities of the device.
312: */
313: if ((id->atap_config & ATAPI_CFG_CMD_MASK) == ATAPI_CFG_CMD_16)
314: periph->periph_cap |= PERIPH_CAP_CMD16;
315: /* XXX This is gross. */
316: periph->periph_cap |= (id->atap_config & ATAPI_CFG_DRQ_MASK);
317:
318: drvp->drv_softc = atapi_probe_device(sc, target, periph, &sa);
319:
320: if (drvp->drv_softc)
1.80 thorpej 321: ata_probe_caps(drvp);
1.89 thorpej 322: else {
323: s = splbio();
1.60 bouyer 324: drvp->drive_flags &= ~DRIVE_ATAPI;
1.89 thorpej 325: splx(s);
326: }
1.69 bouyer 327: } else {
1.89 thorpej 328: s = splbio();
1.69 bouyer 329: drvp->drive_flags &= ~DRIVE_ATAPI;
1.89 thorpej 330: splx(s);
1.33 bouyer 331: }
332: }
333:
1.65 thorpej 334: static void
335: wdc_atapi_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,
336: void *arg)
1.40 bouyer 337: {
338: struct scsipi_adapter *adapt = chan->chan_adapter;
339: struct scsipi_periph *periph;
1.2 bouyer 340: struct scsipi_xfer *sc_xfer;
1.40 bouyer 341: struct wdc_softc *wdc = (void *)adapt->adapt_dev;
1.88 thorpej 342: struct atac_softc *atac = &wdc->sc_atac;
1.63 thorpej 343: struct ata_xfer *xfer;
1.40 bouyer 344: int channel = chan->chan_channel;
345: int drive, s;
346:
347: switch (req) {
348: case ADAPTER_REQ_RUN_XFER:
349: sc_xfer = arg;
350: periph = sc_xfer->xs_periph;
351: drive = periph->periph_target;
352:
1.86 thorpej 353: ATADEBUG_PRINT(("wdc_atapi_scsipi_request %s:%d:%d\n",
1.88 thorpej 354: atac->atac_dev.dv_xname, channel, drive), DEBUG_XFERS);
1.98 thorpej 355: if (!device_is_active(&atac->atac_dev)) {
1.40 bouyer 356: sc_xfer->error = XS_DRIVER_STUFFUP;
357: scsipi_done(sc_xfer);
358: return;
359: }
360:
1.81 thorpej 361: xfer = ata_get_xfer(ATAXF_NOSLEEP);
1.40 bouyer 362: if (xfer == NULL) {
363: sc_xfer->error = XS_RESOURCE_SHORTAGE;
364: scsipi_done(sc_xfer);
365: return;
366: }
367:
368: if (sc_xfer->xs_control & XS_CTL_POLL)
369: xfer->c_flags |= C_POLL;
1.88 thorpej 370: if ((atac->atac_channels[channel]->ch_drive[drive].drive_flags &
1.59 bouyer 371: (DRIVE_DMA | DRIVE_UDMA)) && sc_xfer->datalen > 0)
372: xfer->c_flags |= C_DMA;
1.63 thorpej 373: xfer->c_drive = drive;
1.40 bouyer 374: xfer->c_flags |= C_ATAPI;
375: if (sc_xfer->cmd->opcode == GPCMD_REPORT_KEY ||
376: sc_xfer->cmd->opcode == GPCMD_SEND_KEY ||
377: sc_xfer->cmd->opcode == GPCMD_READ_DVD_STRUCTURE) {
378: /*
379: * DVD authentication commands must always be done in
380: * PIO mode.
381: */
1.59 bouyer 382: xfer->c_flags &= ~C_DMA;
1.40 bouyer 383: }
1.52 bouyer 384: /*
385: * DMA can't deal with transfers which are not a multiple of
386: * 2 bytes. It's a bug to request such transfers for ATAPI
387: * but as the request can come from userland, we have to
388: * protect against it.
1.53 bouyer 389: * Also some devices seems to not handle DMA xfers of less than
390: * 4 bytes.
1.52 bouyer 391: */
1.53 bouyer 392: if (sc_xfer->datalen < 4 || (sc_xfer->datalen & 0x01))
1.59 bouyer 393: xfer->c_flags &= ~C_DMA;
1.52 bouyer 394:
1.63 thorpej 395: xfer->c_cmd = sc_xfer;
396: xfer->c_databuf = sc_xfer->data;
1.40 bouyer 397: xfer->c_bcount = sc_xfer->datalen;
398: xfer->c_start = wdc_atapi_start;
399: xfer->c_intr = wdc_atapi_intr;
400: xfer->c_kill_xfer = wdc_atapi_kill_xfer;
1.45 bouyer 401: xfer->c_dscpoll = 0;
1.40 bouyer 402: s = splbio();
1.88 thorpej 403: ata_exec_xfer(atac->atac_channels[channel], xfer);
1.2 bouyer 404: #ifdef DIAGNOSTIC
1.40 bouyer 405: if ((sc_xfer->xs_control & XS_CTL_POLL) != 0 &&
406: (sc_xfer->xs_status & XS_STS_DONE) == 0)
407: panic("wdc_atapi_scsipi_request: polled command "
408: "not done");
1.2 bouyer 409: #endif
1.40 bouyer 410: splx(s);
411: return;
412:
413: default:
414: /* Not supported, nothing to do. */
1.41 lukem 415: ;
1.40 bouyer 416: }
1.2 bouyer 417: }
418:
1.65 thorpej 419: static void
1.87 thorpej 420: wdc_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer)
1.2 bouyer 421: {
1.88 thorpej 422: struct atac_softc *atac = chp->ch_atac;
423: struct wdc_softc *wdc = CHAN_TO_WDC(chp);
1.87 thorpej 424: struct wdc_regs *wdr = &wdc->regs[chp->ch_channel];
1.63 thorpej 425: struct scsipi_xfer *sc_xfer = xfer->c_cmd;
426: struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
1.59 bouyer 427: int wait_flags = (sc_xfer->xs_control & XS_CTL_POLL) ? AT_POLL : 0;
1.93 christos 428: const char *errstring;
1.2 bouyer 429:
1.86 thorpej 430: ATADEBUG_PRINT(("wdc_atapi_start %s:%d:%d, scsi flags 0x%x \n",
1.88 thorpej 431: atac->atac_dev.dv_xname, chp->ch_channel, drvp->drive,
1.27 thorpej 432: sc_xfer->xs_control), DEBUG_XFERS);
1.59 bouyer 433: if ((xfer->c_flags & C_DMA) && (drvp->n_xfers <= NXFER))
434: drvp->n_xfers++;
435: /* Do control operations specially. */
436: if (__predict_false(drvp->state < READY)) {
1.94 peter 437: /* If it's not a polled command, we need the kernel thread */
1.59 bouyer 438: if ((sc_xfer->xs_control & XS_CTL_POLL) == 0 &&
1.87 thorpej 439: (chp->ch_flags & ATACH_TH_RUN) == 0) {
1.61 bouyer 440: chp->ch_queue->queue_freeze++;
1.68 thorpej 441: wakeup(&chp->ch_thread);
1.59 bouyer 442: return;
443: }
444: /*
445: * disable interrupts, all commands here should be quick
446: * enouth to be able to poll, and we don't go here that often
447: */
1.87 thorpej 448: bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr,
1.59 bouyer 449: WDCTL_4BIT | WDCTL_IDS);
1.85 thorpej 450: if (wdc->select)
1.67 thorpej 451: wdc->select(chp, xfer->c_drive);
1.87 thorpej 452: bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
1.63 thorpej 453: WDSD_IBM | (xfer->c_drive << 4));
1.59 bouyer 454: /* Don't try to set mode if controller can't be adjusted */
1.88 thorpej 455: if (atac->atac_set_modes == NULL)
1.59 bouyer 456: goto ready;
457: /* Also don't try if the drive didn't report its mode */
458: if ((drvp->drive_flags & DRIVE_MODE) == 0)
459: goto ready;
460: errstring = "unbusy";
1.64 thorpej 461: if (wdc_wait_for_unbusy(chp, ATAPI_DELAY, wait_flags))
1.59 bouyer 462: goto timeout;
463: wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
464: 0x08 | drvp->PIO_mode, WDSF_SET_MODE);
465: errstring = "piomode";
1.64 thorpej 466: if (wdc_wait_for_unbusy(chp, ATAPI_MODE_DELAY, wait_flags))
1.59 bouyer 467: goto timeout;
468: if (chp->ch_status & WDCS_ERR) {
469: if (chp->ch_error == WDCE_ABRT) {
470: /*
1.76 mycroft 471: * Some ATAPI drives reject PIO settings.
472: * Fall back to PIO mode 3 since that's the
473: * minimum for ATAPI.
1.59 bouyer 474: */
1.76 mycroft 475: printf("%s:%d:%d: PIO mode %d rejected, "
476: "falling back to PIO mode 3\n",
1.88 thorpej 477: atac->atac_dev.dv_xname,
1.76 mycroft 478: chp->ch_channel, xfer->c_drive,
479: drvp->PIO_mode);
480: if (drvp->PIO_mode > 3)
481: drvp->PIO_mode = 3;
482: } else
483: goto error;
1.59 bouyer 484: }
485: if (drvp->drive_flags & DRIVE_UDMA) {
486: wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
487: 0x40 | drvp->UDMA_mode, WDSF_SET_MODE);
488: } else if (drvp->drive_flags & DRIVE_DMA) {
489: wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
490: 0x20 | drvp->DMA_mode, WDSF_SET_MODE);
491: } else {
492: goto ready;
493: }
494: errstring = "dmamode";
1.64 thorpej 495: if (wdc_wait_for_unbusy(chp, ATAPI_MODE_DELAY, wait_flags))
1.59 bouyer 496: goto timeout;
1.76 mycroft 497: if (chp->ch_status & WDCS_ERR) {
498: if (chp->ch_error == WDCE_ABRT) {
499: if (drvp->drive_flags & DRIVE_UDMA)
500: goto error;
501: else {
502: /*
503: * The drive rejected our DMA setting.
504: * Fall back to mode 1.
505: */
506: printf("%s:%d:%d: DMA mode %d rejected, "
507: "falling back to DMA mode 0\n",
1.88 thorpej 508: atac->atac_dev.dv_xname,
1.76 mycroft 509: chp->ch_channel, xfer->c_drive,
510: drvp->DMA_mode);
511: if (drvp->DMA_mode > 0)
512: drvp->DMA_mode = 0;
513: }
514: } else
515: goto error;
516: }
1.59 bouyer 517: ready:
518: drvp->state = READY;
1.87 thorpej 519: bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr,
1.59 bouyer 520: WDCTL_4BIT);
1.70 bouyer 521: delay(10); /* some drives need a little delay here */
1.30 bouyer 522: }
1.24 bouyer 523: /* start timeout machinery */
1.27 thorpej 524: if ((sc_xfer->xs_control & XS_CTL_POLL) == 0)
1.50 bouyer 525: callout_reset(&chp->ch_callout, mstohz(sc_xfer->timeout),
1.32 thorpej 526: wdctimeout, chp);
1.59 bouyer 527:
1.85 thorpej 528: if (wdc->select)
1.67 thorpej 529: wdc->select(chp, xfer->c_drive);
1.87 thorpej 530: bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
1.63 thorpej 531: WDSD_IBM | (xfer->c_drive << 4));
1.64 thorpej 532: switch (wdc_wait_for_unbusy(chp, ATAPI_DELAY, wait_flags) < 0) {
1.59 bouyer 533: case WDCWAIT_OK:
534: break;
535: case WDCWAIT_TOUT:
1.2 bouyer 536: printf("wdc_atapi_start: not ready, st = %02x\n",
537: chp->ch_status);
1.3 bouyer 538: sc_xfer->error = XS_TIMEOUT;
1.2 bouyer 539: wdc_atapi_reset(chp, xfer);
540: return;
1.59 bouyer 541: case WDCWAIT_THR:
542: return;
1.2 bouyer 543: }
544:
545: /*
546: * Even with WDCS_ERR, the device should accept a command packet
547: * Limit length to what can be stuffed into the cylinder register
548: * (16 bits). Some CD-ROMs seem to interpret '0' as 65536,
549: * but not all devices do that and it's not obvious from the
550: * ATAPI spec that that behaviour should be expected. If more
551: * data is necessary, multiple data transfer phases will be done.
552: */
1.5 bouyer 553:
1.92 perry 554: wdccommand(chp, xfer->c_drive, ATAPI_PKT_CMD,
1.29 bouyer 555: xfer->c_bcount <= 0xffff ? xfer->c_bcount : 0xffff,
1.92 perry 556: 0, 0, 0,
1.2 bouyer 557: (xfer->c_flags & C_DMA) ? ATAPI_PKT_CMD_FTRE_DMA : 0);
1.92 perry 558:
1.2 bouyer 559: /*
1.92 perry 560: * If there is no interrupt for CMD input, busy-wait for it (done in
1.2 bouyer 561: * the interrupt routine. If it is a polled command, call the interrupt
562: * routine until command is done.
563: */
1.40 bouyer 564: if ((sc_xfer->xs_periph->periph_cap & ATAPI_CFG_DRQ_MASK) !=
1.27 thorpej 565: ATAPI_CFG_IRQ_DRQ || (sc_xfer->xs_control & XS_CTL_POLL)) {
1.2 bouyer 566: /* Wait for at last 400ns for status bit to be valid */
1.20 bouyer 567: DELAY(1);
568: wdc_atapi_intr(chp, xfer, 0);
1.21 bouyer 569: } else {
1.87 thorpej 570: chp->ch_flags |= ATACH_IRQ_WAIT;
1.2 bouyer 571: }
1.27 thorpej 572: if (sc_xfer->xs_control & XS_CTL_POLL) {
1.87 thorpej 573: if (chp->ch_flags & ATACH_DMA_WAIT) {
1.73 bouyer 574: wdc_dmawait(chp, xfer, sc_xfer->timeout);
1.87 thorpej 575: chp->ch_flags &= ~ATACH_DMA_WAIT;
1.73 bouyer 576: }
1.27 thorpej 577: while ((sc_xfer->xs_status & XS_STS_DONE) == 0) {
1.2 bouyer 578: /* Wait for at last 400ns for status bit to be valid */
1.20 bouyer 579: DELAY(1);
580: wdc_atapi_intr(chp, xfer, 0);
1.2 bouyer 581: }
582: }
1.59 bouyer 583: return;
584: timeout:
585: printf("%s:%d:%d: %s timed out\n",
1.88 thorpej 586: atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive,
1.67 thorpej 587: errstring);
1.59 bouyer 588: sc_xfer->error = XS_TIMEOUT;
1.87 thorpej 589: bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
1.70 bouyer 590: delay(10); /* some drives need a little delay here */
1.59 bouyer 591: wdc_atapi_reset(chp, xfer);
592: return;
593: error:
594: printf("%s:%d:%d: %s ",
1.88 thorpej 595: atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive,
1.59 bouyer 596: errstring);
597: printf("error (0x%x)\n", chp->ch_error);
598: sc_xfer->error = XS_SHORTSENSE;
599: sc_xfer->sense.atapi_sense = chp->ch_error;
1.87 thorpej 600: bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
1.70 bouyer 601: delay(10); /* some drives need a little delay here */
1.59 bouyer 602: wdc_atapi_reset(chp, xfer);
603: return;
1.2 bouyer 604: }
605:
1.65 thorpej 606: static int
1.87 thorpej 607: wdc_atapi_intr(struct ata_channel *chp, struct ata_xfer *xfer, int irq)
1.2 bouyer 608: {
1.88 thorpej 609: struct atac_softc *atac = chp->ch_atac;
610: struct wdc_softc *wdc = CHAN_TO_WDC(chp);
1.87 thorpej 611: struct wdc_regs *wdr = &wdc->regs[chp->ch_channel];
1.63 thorpej 612: struct scsipi_xfer *sc_xfer = xfer->c_cmd;
613: struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
1.2 bouyer 614: int len, phase, i, retries=0;
1.95 thorpej 615: int ire, error;
1.2 bouyer 616: int dma_flags = 0;
1.8 bouyer 617: void *cmd;
1.2 bouyer 618:
1.86 thorpej 619: ATADEBUG_PRINT(("wdc_atapi_intr %s:%d:%d\n",
1.88 thorpej 620: atac->atac_dev.dv_xname, chp->ch_channel, drvp->drive),
1.67 thorpej 621: DEBUG_INTR);
1.2 bouyer 622:
623: /* Is it not a transfer, but a control operation? */
624: if (drvp->state < READY) {
625: printf("%s:%d:%d: bad state %d in wdc_atapi_intr\n",
1.88 thorpej 626: atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive,
1.2 bouyer 627: drvp->state);
1.55 provos 628: panic("wdc_atapi_intr: bad state");
1.2 bouyer 629: }
1.24 bouyer 630: /*
631: * If we missed an interrupt in a PIO transfer, reset and restart.
632: * Don't try to continue transfer, we may have missed cycles.
633: */
634: if ((xfer->c_flags & (C_TIMEOU | C_DMA)) == C_TIMEOU) {
635: sc_xfer->error = XS_TIMEOUT;
636: wdc_atapi_reset(chp, xfer);
1.25 bouyer 637: return 1;
1.92 perry 638: }
1.24 bouyer 639:
1.64 thorpej 640: /* Ack interrupt done in wdc_wait_for_unbusy */
1.85 thorpej 641: if (wdc->select)
1.67 thorpej 642: wdc->select(chp, xfer->c_drive);
1.87 thorpej 643: bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
1.63 thorpej 644: WDSD_IBM | (xfer->c_drive << 4));
1.64 thorpej 645: if (wdc_wait_for_unbusy(chp,
1.59 bouyer 646: (irq == 0) ? sc_xfer->timeout : 0, AT_POLL) == WDCWAIT_TOUT) {
1.20 bouyer 647: if (irq && (xfer->c_flags & C_TIMEOU) == 0)
1.19 bouyer 648: return 0; /* IRQ was not for us */
1.16 bouyer 649: printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip=%d\n",
1.88 thorpej 650: atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive,
1.2 bouyer 651: xfer->c_bcount, xfer->c_skip);
1.33 bouyer 652: if (xfer->c_flags & C_DMA) {
1.59 bouyer 653: ata_dmaerr(drvp,
654: (xfer->c_flags & C_POLL) ? AT_POLL : 0);
1.33 bouyer 655: }
1.3 bouyer 656: sc_xfer->error = XS_TIMEOUT;
1.2 bouyer 657: wdc_atapi_reset(chp, xfer);
658: return 1;
659: }
1.85 thorpej 660: if (wdc->irqack)
1.67 thorpej 661: wdc->irqack(chp);
1.36 bouyer 662:
1.48 bouyer 663: /*
664: * If we missed an IRQ and were using DMA, flag it as a DMA error
665: * and reset device.
666: */
1.33 bouyer 667: if ((xfer->c_flags & C_TIMEOU) && (xfer->c_flags & C_DMA)) {
1.59 bouyer 668: ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0);
1.48 bouyer 669: sc_xfer->error = XS_RESET;
670: wdc_atapi_reset(chp, xfer);
671: return (1);
1.33 bouyer 672: }
1.92 perry 673: /*
1.8 bouyer 674: * if the request sense command was aborted, report the short sense
675: * previously recorded, else continue normal processing
676: */
677:
1.33 bouyer 678: if (xfer->c_flags & C_DMA)
1.40 bouyer 679: dma_flags = (sc_xfer->xs_control & XS_CTL_DATA_IN)
680: ? WDC_DMA_READ : 0;
1.2 bouyer 681: again:
1.87 thorpej 682: len = bus_space_read_1(wdr->cmd_iot, wdr->cmd_iohs[wd_cyl_lo], 0) +
683: 256 * bus_space_read_1(wdr->cmd_iot, wdr->cmd_iohs[wd_cyl_hi], 0);
684: ire = bus_space_read_1(wdr->cmd_iot, wdr->cmd_iohs[wd_ireason], 0);
1.2 bouyer 685: phase = (ire & (WDCI_CMD | WDCI_IN)) | (chp->ch_status & WDCS_DRQ);
1.86 thorpej 686: ATADEBUG_PRINT(("wdc_atapi_intr: c_bcount %d len %d st 0x%x err 0x%x "
1.2 bouyer 687: "ire 0x%x :", xfer->c_bcount,
688: len, chp->ch_status, chp->ch_error, ire), DEBUG_INTR);
689:
690: switch (phase) {
691: case PHASE_CMDOUT:
1.57 mycroft 692: cmd = sc_xfer->cmd;
1.86 thorpej 693: ATADEBUG_PRINT(("PHASE_CMDOUT\n"), DEBUG_INTR);
1.2 bouyer 694: /* Init the DMA channel if necessary */
695: if (xfer->c_flags & C_DMA) {
1.95 thorpej 696: error = (*wdc->dma_init)(wdc->dma_arg,
1.67 thorpej 697: chp->ch_channel, xfer->c_drive,
1.95 thorpej 698: xfer->c_databuf, xfer->c_bcount, dma_flags);
699: if (error) {
700: if (error == EINVAL) {
701: /*
702: * We can't do DMA on this transfer
703: * for some reason. Fall back to
704: * PIO.
705: */
706: xfer->c_flags &= ~C_DMA;
707: error = 0;
708: } else {
709: sc_xfer->error = XS_DRIVER_STUFFUP;
710: break;
711: }
1.2 bouyer 712: }
713: }
1.75 mycroft 714:
1.2 bouyer 715: /* send packet command */
716: /* Commands are 12 or 16 bytes long. It's 32-bit aligned */
1.77 mycroft 717: wdc->dataout_pio(chp, drvp->drive_flags, cmd, sc_xfer->cmdlen);
1.75 mycroft 718:
1.2 bouyer 719: /* Start the DMA channel if necessary */
720: if (xfer->c_flags & C_DMA) {
1.67 thorpej 721: (*wdc->dma_start)(wdc->dma_arg,
722: chp->ch_channel, xfer->c_drive);
1.87 thorpej 723: chp->ch_flags |= ATACH_DMA_WAIT;
1.2 bouyer 724: }
725:
1.27 thorpej 726: if ((sc_xfer->xs_control & XS_CTL_POLL) == 0) {
1.87 thorpej 727: chp->ch_flags |= ATACH_IRQ_WAIT;
1.2 bouyer 728: }
729: return 1;
730:
731: case PHASE_DATAOUT:
732: /* write data */
1.86 thorpej 733: ATADEBUG_PRINT(("PHASE_DATAOUT\n"), DEBUG_INTR);
1.27 thorpej 734: if ((sc_xfer->xs_control & XS_CTL_DATA_OUT) == 0 ||
1.2 bouyer 735: (xfer->c_flags & C_DMA) != 0) {
1.15 bouyer 736: printf("wdc_atapi_intr: bad data phase DATAOUT\n");
1.2 bouyer 737: if (xfer->c_flags & C_DMA) {
1.59 bouyer 738: ata_dmaerr(drvp,
739: (xfer->c_flags & C_POLL) ? AT_POLL : 0);
1.2 bouyer 740: }
1.3 bouyer 741: sc_xfer->error = XS_TIMEOUT;
1.2 bouyer 742: wdc_atapi_reset(chp, xfer);
743: return 1;
744: }
745: if (xfer->c_bcount < len) {
746: printf("wdc_atapi_intr: warning: write only "
747: "%d of %d requested bytes\n", xfer->c_bcount, len);
1.77 mycroft 748: wdc->dataout_pio(chp, drvp->drive_flags,
1.75 mycroft 749: (char *)xfer->c_databuf + xfer->c_skip,
750: xfer->c_bcount);
1.2 bouyer 751: for (i = xfer->c_bcount; i < len; i += 2)
1.87 thorpej 752: bus_space_write_2(wdr->cmd_iot,
753: wdr->cmd_iohs[wd_data], 0, 0);
1.2 bouyer 754: xfer->c_skip += xfer->c_bcount;
755: xfer->c_bcount = 0;
756: } else {
1.77 mycroft 757: wdc->dataout_pio(chp, drvp->drive_flags,
1.75 mycroft 758: (char *)xfer->c_databuf + xfer->c_skip, len);
759: xfer->c_skip += len;
760: xfer->c_bcount -= len;
1.2 bouyer 761: }
1.27 thorpej 762: if ((sc_xfer->xs_control & XS_CTL_POLL) == 0) {
1.87 thorpej 763: chp->ch_flags |= ATACH_IRQ_WAIT;
1.2 bouyer 764: }
765: return 1;
766:
767: case PHASE_DATAIN:
768: /* Read data */
1.86 thorpej 769: ATADEBUG_PRINT(("PHASE_DATAIN\n"), DEBUG_INTR);
1.92 perry 770: if ((sc_xfer->xs_control & XS_CTL_DATA_IN) == 0 ||
1.2 bouyer 771: (xfer->c_flags & C_DMA) != 0) {
1.15 bouyer 772: printf("wdc_atapi_intr: bad data phase DATAIN\n");
1.2 bouyer 773: if (xfer->c_flags & C_DMA) {
1.59 bouyer 774: ata_dmaerr(drvp,
775: (xfer->c_flags & C_POLL) ? AT_POLL : 0);
1.2 bouyer 776: }
1.3 bouyer 777: sc_xfer->error = XS_TIMEOUT;
1.2 bouyer 778: wdc_atapi_reset(chp, xfer);
779: return 1;
780: }
781: if (xfer->c_bcount < len) {
782: printf("wdc_atapi_intr: warning: reading only "
783: "%d of %d bytes\n", xfer->c_bcount, len);
1.77 mycroft 784: wdc->datain_pio(chp, drvp->drive_flags,
1.75 mycroft 785: (char *)xfer->c_databuf + xfer->c_skip,
786: xfer->c_bcount);
1.2 bouyer 787: wdcbit_bucket(chp, len - xfer->c_bcount);
788: xfer->c_skip += xfer->c_bcount;
789: xfer->c_bcount = 0;
790: } else {
1.77 mycroft 791: wdc->datain_pio(chp, drvp->drive_flags,
1.75 mycroft 792: (char *)xfer->c_databuf + xfer->c_skip, len);
793: xfer->c_skip += len;
794: xfer->c_bcount -=len;
1.2 bouyer 795: }
1.27 thorpej 796: if ((sc_xfer->xs_control & XS_CTL_POLL) == 0) {
1.87 thorpej 797: chp->ch_flags |= ATACH_IRQ_WAIT;
1.2 bouyer 798: }
799: return 1;
800:
801: case PHASE_ABORTED:
802: case PHASE_COMPLETED:
1.86 thorpej 803: ATADEBUG_PRINT(("PHASE_COMPLETED\n"), DEBUG_INTR);
1.2 bouyer 804: if (xfer->c_flags & C_DMA) {
1.40 bouyer 805: xfer->c_bcount -= sc_xfer->datalen;
806: }
807: sc_xfer->resid = xfer->c_bcount;
1.45 bouyer 808: wdc_atapi_phase_complete(xfer);
809: return(1);
1.2 bouyer 810:
811: default:
812: if (++retries<500) {
813: DELAY(100);
1.87 thorpej 814: chp->ch_status = bus_space_read_1(wdr->cmd_iot,
815: wdr->cmd_iohs[wd_status], 0);
816: chp->ch_error = bus_space_read_1(wdr->cmd_iot,
817: wdr->cmd_iohs[wd_error], 0);
1.2 bouyer 818: goto again;
819: }
820: printf("wdc_atapi_intr: unknown phase 0x%x\n", phase);
821: if (chp->ch_status & WDCS_ERR) {
1.8 bouyer 822: sc_xfer->error = XS_SHORTSENSE;
1.2 bouyer 823: sc_xfer->sense.atapi_sense = chp->ch_error;
824: } else {
1.33 bouyer 825: if (xfer->c_flags & C_DMA) {
1.59 bouyer 826: ata_dmaerr(drvp,
827: (xfer->c_flags & C_POLL) ? AT_POLL : 0);
1.33 bouyer 828: }
1.16 bouyer 829: sc_xfer->error = XS_RESET;
830: wdc_atapi_reset(chp, xfer);
831: return (1);
1.2 bouyer 832: }
833: }
1.86 thorpej 834: ATADEBUG_PRINT(("wdc_atapi_intr: wdc_atapi_done() (end), error 0x%x "
1.2 bouyer 835: "sense 0x%x\n", sc_xfer->error, sc_xfer->sense.atapi_sense),
836: DEBUG_INTR);
837: wdc_atapi_done(chp, xfer);
838: return (1);
839: }
840:
1.65 thorpej 841: static void
842: wdc_atapi_phase_complete(struct ata_xfer *xfer)
1.45 bouyer 843: {
1.87 thorpej 844: struct ata_channel *chp = xfer->c_chp;
1.88 thorpej 845: struct atac_softc *atac = chp->ch_atac;
846: struct wdc_softc *wdc = CHAN_TO_WDC(chp);
1.63 thorpej 847: struct scsipi_xfer *sc_xfer = xfer->c_cmd;
848: struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
1.45 bouyer 849:
850: /* wait for DSC if needed */
851: if (drvp->drive_flags & DRIVE_ATAPIST) {
1.86 thorpej 852: ATADEBUG_PRINT(("wdc_atapi_phase_complete(%s:%d:%d) "
1.88 thorpej 853: "polldsc %d\n", atac->atac_dev.dv_xname, chp->ch_channel,
1.63 thorpej 854: xfer->c_drive, xfer->c_dscpoll), DEBUG_XFERS);
1.57 mycroft 855: #if 1
856: if (cold)
857: panic("wdc_atapi_phase_complete: cold");
858: #endif
1.59 bouyer 859: if (wdcwait(chp, WDCS_DSC, WDCS_DSC, 10,
860: AT_POLL) == WDCWAIT_TOUT) {
1.57 mycroft 861: /* 10ms not enough, try again in 1 tick */
1.92 perry 862: if (xfer->c_dscpoll++ >
1.57 mycroft 863: mstohz(sc_xfer->timeout)) {
1.59 bouyer 864: printf("%s:%d:%d: wait_for_dsc "
865: "failed\n",
1.88 thorpej 866: atac->atac_dev.dv_xname,
1.67 thorpej 867: chp->ch_channel, xfer->c_drive);
1.45 bouyer 868: sc_xfer->error = XS_TIMEOUT;
869: wdc_atapi_reset(chp, xfer);
1.59 bouyer 870: return;
1.57 mycroft 871: } else
1.45 bouyer 872: callout_reset(&chp->ch_callout, 1,
873: wdc_atapi_polldsc, xfer);
1.57 mycroft 874: return;
1.45 bouyer 875: }
876: }
877:
878: /*
1.92 perry 879: * Some drive occasionally set WDCS_ERR with
1.45 bouyer 880: * "ATA illegal length indication" in the error
881: * register. If we read some data the sense is valid
882: * anyway, so don't report the error.
883: */
884: if (chp->ch_status & WDCS_ERR &&
885: ((sc_xfer->xs_control & XS_CTL_REQSENSE) == 0 ||
886: sc_xfer->resid == sc_xfer->datalen)) {
887: /* save the short sense */
888: sc_xfer->error = XS_SHORTSENSE;
889: sc_xfer->sense.atapi_sense = chp->ch_error;
890: if ((sc_xfer->xs_periph->periph_quirks &
891: PQUIRK_NOSENSE) == 0) {
892: /* ask scsipi to send a REQUEST_SENSE */
893: sc_xfer->error = XS_BUSY;
894: sc_xfer->status = SCSI_CHECK;
1.67 thorpej 895: } else if (wdc->dma_status &
1.45 bouyer 896: (WDC_DMAST_NOIRQ | WDC_DMAST_ERR)) {
1.59 bouyer 897: ata_dmaerr(drvp,
898: (xfer->c_flags & C_POLL) ? AT_POLL : 0);
1.45 bouyer 899: sc_xfer->error = XS_RESET;
900: wdc_atapi_reset(chp, xfer);
901: return;
902: }
903: }
904: if (xfer->c_bcount != 0) {
1.86 thorpej 905: ATADEBUG_PRINT(("wdc_atapi_intr: bcount value is "
1.45 bouyer 906: "%d after io\n", xfer->c_bcount), DEBUG_XFERS);
907: }
908: #ifdef DIAGNOSTIC
909: if (xfer->c_bcount < 0) {
910: printf("wdc_atapi_intr warning: bcount value "
911: "is %d after io\n", xfer->c_bcount);
912: }
913: #endif
1.86 thorpej 914: ATADEBUG_PRINT(("wdc_atapi_phase_complete: wdc_atapi_done(), "
1.45 bouyer 915: "error 0x%x sense 0x%x\n", sc_xfer->error,
916: sc_xfer->sense.atapi_sense), DEBUG_INTR);
917: wdc_atapi_done(chp, xfer);
918: }
919:
1.65 thorpej 920: static void
1.87 thorpej 921: wdc_atapi_done(struct ata_channel *chp, struct ata_xfer *xfer)
1.2 bouyer 922: {
1.88 thorpej 923: struct atac_softc *atac = chp->ch_atac;
1.63 thorpej 924: struct scsipi_xfer *sc_xfer = xfer->c_cmd;
1.74 bouyer 925: int drive = xfer->c_drive;
1.2 bouyer 926:
1.86 thorpej 927: ATADEBUG_PRINT(("wdc_atapi_done %s:%d:%d: flags 0x%x\n",
1.88 thorpej 928: atac->atac_dev.dv_xname, chp->ch_channel, xfer->c_drive,
1.91 reinoud 929: (u_int)xfer->c_flags), DEBUG_XFERS);
1.32 thorpej 930: callout_stop(&chp->ch_callout);
1.73 bouyer 931: /* mark controller inactive and free the command */
932: chp->ch_queue->active_xfer = NULL;
1.81 thorpej 933: ata_free_xfer(chp, xfer);
1.40 bouyer 934:
1.74 bouyer 935: if (chp->ch_drive[drive].drive_flags & DRIVE_WAITDRAIN) {
936: sc_xfer->error = XS_DRIVER_STUFFUP;
937: chp->ch_drive[drive].drive_flags &= ~DRIVE_WAITDRAIN;
938: wakeup(&chp->ch_queue->active_xfer);
939: }
940:
1.86 thorpej 941: ATADEBUG_PRINT(("wdc_atapi_done: scsipi_done\n"), DEBUG_XFERS);
1.25 bouyer 942: scsipi_done(sc_xfer);
1.86 thorpej 943: ATADEBUG_PRINT(("atastart from wdc_atapi_done, flags 0x%x\n",
1.4 bouyer 944: chp->ch_flags), DEBUG_XFERS);
1.84 thorpej 945: atastart(chp);
1.2 bouyer 946: }
947:
1.65 thorpej 948: static void
1.87 thorpej 949: wdc_atapi_reset(struct ata_channel *chp, struct ata_xfer *xfer)
1.2 bouyer 950: {
1.88 thorpej 951: struct atac_softc *atac = chp->ch_atac;
1.63 thorpej 952: struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
953: struct scsipi_xfer *sc_xfer = xfer->c_cmd;
1.2 bouyer 954:
1.63 thorpej 955: wdccommandshort(chp, xfer->c_drive, ATAPI_SOFT_RESET);
1.2 bouyer 956: drvp->state = 0;
1.64 thorpej 957: if (wdc_wait_for_unbusy(chp, WDC_RESET_WAIT, AT_POLL) != 0) {
1.2 bouyer 958: printf("%s:%d:%d: reset failed\n",
1.88 thorpej 959: atac->atac_dev.dv_xname, chp->ch_channel,
1.63 thorpej 960: xfer->c_drive);
1.2 bouyer 961: sc_xfer->error = XS_SELTIMEOUT;
962: }
963: wdc_atapi_done(chp, xfer);
964: return;
1.45 bouyer 965: }
966:
1.59 bouyer 967: static void
1.65 thorpej 968: wdc_atapi_polldsc(void *arg)
1.45 bouyer 969: {
1.65 thorpej 970:
1.45 bouyer 971: wdc_atapi_phase_complete(arg);
1.2 bouyer 972: }
CVSweb <webmaster@jp.NetBSD.org>