Annotation of src/sys/dev/scsipi/atapi_wdc.c, Revision 1.138.4.1
1.138.4.1! thorpej 1: /* $NetBSD: atapi_wdc.c,v 1.138 2020/04/13 10:49:34 jdolecek Exp $ */
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: *
1.35 bouyer 15: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1.92 perry 18: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1.35 bouyer 19: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.2 bouyer 25: */
1.44 lukem 26:
27: #include <sys/cdefs.h>
1.138.4.1! thorpej 28: __KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.138 2020/04/13 10:49:34 jdolecek Exp $");
1.2 bouyer 29:
1.86 thorpej 30: #ifndef ATADEBUG
31: #define ATADEBUG
32: #endif /* ATADEBUG */
1.2 bouyer 33:
34: #include <sys/param.h>
35: #include <sys/systm.h>
36: #include <sys/kernel.h>
37: #include <sys/file.h>
38: #include <sys/stat.h>
39: #include <sys/buf.h>
40: #include <sys/malloc.h>
41: #include <sys/device.h>
42: #include <sys/syslog.h>
43: #include <sys/proc.h>
1.39 mycroft 44: #include <sys/dvdio.h>
1.2 bouyer 45:
1.105 ad 46: #include <sys/intr.h>
47: #include <sys/bus.h>
1.2 bouyer 48:
49: #ifndef __BUS_SPACE_HAS_STREAM_METHODS
1.65 thorpej 50: #define bus_space_write_multi_stream_2 bus_space_write_multi_2
51: #define bus_space_write_multi_stream_4 bus_space_write_multi_4
52: #define bus_space_read_multi_stream_2 bus_space_read_multi_2
53: #define bus_space_read_multi_stream_4 bus_space_read_multi_4
1.2 bouyer 54: #endif /* __BUS_SPACE_HAS_STREAM_METHODS */
55:
1.101 itohy 56: #include <dev/ata/ataconf.h>
1.2 bouyer 57: #include <dev/ata/atareg.h>
58: #include <dev/ata/atavar.h>
59: #include <dev/ic/wdcreg.h>
60: #include <dev/ic/wdcvar.h>
61:
1.40 bouyer 62: #include <dev/scsipi/scsi_all.h> /* for SCSI status */
63:
1.2 bouyer 64: #define DEBUG_INTR 0x01
65: #define DEBUG_XFERS 0x02
66: #define DEBUG_STATUS 0x04
67: #define DEBUG_FUNCS 0x08
68: #define DEBUG_PROBE 0x10
1.86 thorpej 69: #ifdef ATADEBUG
1.130 mlelstv 70: #ifndef ATADEBUG_ATAPI_MASK
71: #define ATADEBUG_ATAPI_MASK 0x0
72: #endif
73: int wdcdebug_atapi_mask = ATADEBUG_ATAPI_MASK;
1.86 thorpej 74: #define ATADEBUG_PRINT(args, level) \
1.2 bouyer 75: if (wdcdebug_atapi_mask & (level)) \
76: printf args
77: #else
1.86 thorpej 78: #define ATADEBUG_PRINT(args, level)
1.2 bouyer 79: #endif
80:
81: #define ATAPI_DELAY 10 /* 10 ms, this is used only before sending a cmd */
1.59 bouyer 82: #define ATAPI_MODE_DELAY 1000 /* 1s, timeout for SET_FEATYRE cmds */
1.65 thorpej 83:
84: static int wdc_atapi_get_params(struct scsipi_channel *, int,
85: struct ataparams *);
86: static void wdc_atapi_probe_device(struct atapibus_softc *, int);
87: static void wdc_atapi_minphys (struct buf *bp);
1.124 jdolecek 88: static int wdc_atapi_start(struct ata_channel *,struct ata_xfer *);
1.87 thorpej 89: static int wdc_atapi_intr(struct ata_channel *, struct ata_xfer *, int);
90: static void wdc_atapi_kill_xfer(struct ata_channel *,
1.71 bouyer 91: struct ata_xfer *, int);
1.133 jdolecek 92: static void wdc_atapi_phase_complete(struct ata_xfer *, int);
1.124 jdolecek 93: static void wdc_atapi_poll(struct ata_channel *, 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.136 riastrad 104: .bustype_type = SCSIPI_BUSTYPE_ATAPI,
105: .bustype_cmd = atapi_scsipi_cmd,
106: .bustype_interpret_sense = atapi_interpret_sense,
107: .bustype_printaddr = atapi_print_addr,
108: .bustype_kill_pending = wdc_atapi_kill_pending,
109: .bustype_async_event_xfer_mode = NULL,
1.40 bouyer 110: };
111:
1.2 bouyer 112: void
1.65 thorpej 113: wdc_atapibus_attach(struct atabus_softc *ata_sc)
1.2 bouyer 114: {
1.87 thorpej 115: struct ata_channel *chp = ata_sc->sc_chan;
1.88 thorpej 116: struct atac_softc *atac = chp->ch_atac;
117: struct scsipi_adapter *adapt = &atac->atac_atapi_adapter._generic;
1.40 bouyer 118: struct scsipi_channel *chan = &chp->ch_atapi_channel;
1.2 bouyer 119:
1.9 thorpej 120: /*
1.40 bouyer 121: * Fill in the scsipi_adapter.
1.9 thorpej 122: */
1.106 cube 123: adapt->adapt_dev = atac->atac_dev;
1.88 thorpej 124: adapt->adapt_nchannels = atac->atac_nchannels;
1.40 bouyer 125: adapt->adapt_request = wdc_atapi_scsipi_request;
126: adapt->adapt_minphys = wdc_atapi_minphys;
1.88 thorpej 127: if (atac->atac_cap & ATAC_CAP_NOIRQ)
1.42 bjh21 128: adapt->adapt_flags |= SCSIPI_ADAPT_POLL_ONLY;
1.88 thorpej 129: atac->atac_atapi_adapter.atapi_probe_device = wdc_atapi_probe_device;
1.40 bouyer 130:
131: /*
132: * Fill in the scsipi_channel.
133: */
134: memset(chan, 0, sizeof(*chan));
135: chan->chan_adapter = adapt;
136: chan->chan_bustype = &wdc_atapi_bustype;
1.67 thorpej 137: chan->chan_channel = chp->ch_channel;
1.40 bouyer 138: chan->chan_flags = SCSIPI_CHAN_OPENINGS;
139: chan->chan_openings = 1;
140: chan->chan_max_periph = 1;
1.135 chs 141: chan->chan_ntargets = chp->ch_ndrives;
1.40 bouyer 142: chan->chan_nluns = 1;
143:
1.138.4.1! thorpej 144: chp->atapibus = config_found(ata_sc->sc_dev, chan, atapiprint,
! 145: CFARG_IATTR, "atapi",
! 146: CFARG_EOL);
1.2 bouyer 147: }
148:
1.65 thorpej 149: static void
150: wdc_atapi_minphys(struct buf *bp)
1.2 bouyer 151: {
1.40 bouyer 152:
153: if (bp->b_bcount > MAX_SIZE)
1.2 bouyer 154: bp->b_bcount = MAX_SIZE;
155: minphys(bp);
156: }
157:
1.28 enami 158: /*
1.40 bouyer 159: * Kill off all pending xfers for a periph.
1.28 enami 160: *
1.123 mlelstv 161: * Must be called with adapter lock held
1.28 enami 162: */
1.65 thorpej 163: static void
164: wdc_atapi_kill_pending(struct scsipi_periph *periph)
1.28 enami 165: {
1.88 thorpej 166: struct atac_softc *atac =
1.106 cube 167: device_private(periph->periph_channel->chan_adapter->adapt_dev);
1.87 thorpej 168: struct ata_channel *chp =
1.88 thorpej 169: atac->atac_channels[periph->periph_channel->chan_channel];
1.28 enami 170:
1.82 thorpej 171: ata_kill_pending(&chp->ch_drive[periph->periph_target]);
1.28 enami 172: }
173:
1.65 thorpej 174: static void
1.87 thorpej 175: wdc_atapi_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, int reason)
1.28 enami 176: {
1.124 jdolecek 177: struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
178: bool deactivate = true;
1.28 enami 179:
180: /* remove this command from xfer queue */
1.71 bouyer 181: switch (reason) {
1.124 jdolecek 182: case KILL_GONE_INACTIVE:
183: deactivate = false;
184: /* FALLTHROUGH */
1.71 bouyer 185: case KILL_GONE:
186: sc_xfer->error = XS_DRIVER_STUFFUP;
187: break;
188: case KILL_RESET:
189: sc_xfer->error = XS_RESET;
190: break;
191: default:
192: printf("wdc_ata_bio_kill_xfer: unknown reason %d\n",
193: reason);
194: panic("wdc_ata_bio_kill_xfer");
195: }
1.124 jdolecek 196:
197: if (deactivate)
198: ata_deactivate_xfer(chp, xfer);
199:
1.81 thorpej 200: ata_free_xfer(chp, xfer);
1.73 bouyer 201: scsipi_done(sc_xfer);
1.28 enami 202: }
203:
1.65 thorpej 204: static int
205: wdc_atapi_get_params(struct scsipi_channel *chan, int drive,
206: struct ataparams *id)
1.2 bouyer 207: {
1.106 cube 208: struct wdc_softc *wdc = device_private(chan->chan_adapter->adapt_dev);
1.88 thorpej 209: struct atac_softc *atac = &wdc->sc_atac;
1.87 thorpej 210: struct wdc_regs *wdr = &wdc->regs[chan->chan_channel];
1.88 thorpej 211: struct ata_channel *chp = atac->atac_channels[chan->chan_channel];
1.124 jdolecek 212: struct ata_xfer *xfer;
213: int rv;
214:
1.131 jdolecek 215: xfer = ata_get_xfer(chp, false);
1.124 jdolecek 216: if (xfer == NULL) {
217: printf("wdc_atapi_get_params: no xfer\n");
218: return EBUSY;
219: }
1.2 bouyer 220:
1.124 jdolecek 221: xfer->c_ata_c.r_command = ATAPI_SOFT_RESET;
222: xfer->c_ata_c.r_st_bmask = 0;
223: xfer->c_ata_c.r_st_pmask = 0;
224: xfer->c_ata_c.flags = AT_WAIT | AT_POLL;
225: xfer->c_ata_c.timeout = WDC_RESET_WAIT;
1.138 jdolecek 226:
227: wdc_exec_command(&chp->ch_drive[drive], xfer);
228: ata_wait_cmd(chp, xfer);
229:
1.124 jdolecek 230: if (xfer->c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
1.86 thorpej 231: ATADEBUG_PRINT(("wdc_atapi_get_params: ATAPI_SOFT_RESET "
1.59 bouyer 232: "failed for drive %s:%d:%d: error 0x%x\n",
1.106 cube 233: device_xname(atac->atac_dev), chp->ch_channel, drive,
1.124 jdolecek 234: xfer->c_ata_c.r_error), DEBUG_PROBE);
235: rv = -1;
236: goto out_xfer;
1.2 bouyer 237: }
1.59 bouyer 238: chp->ch_drive[drive].state = 0;
1.2 bouyer 239:
1.124 jdolecek 240: ata_free_xfer(chp, xfer);
241:
1.99 christos 242: (void)bus_space_read_1(wdr->cmd_iot, wdr->cmd_iohs[wd_status], 0);
1.92 perry 243:
1.2 bouyer 244: /* Some ATAPI devices need a bit more time after software reset. */
245: delay(5000);
1.57 mycroft 246: if (ata_get_params(&chp->ch_drive[drive], AT_WAIT, id) != 0) {
1.86 thorpej 247: ATADEBUG_PRINT(("wdc_atapi_get_params: ATAPI_IDENTIFY_DEVICE "
1.124 jdolecek 248: "failed for drive %s:%d:%d\n",
249: device_xname(atac->atac_dev), chp->ch_channel, drive),
250: DEBUG_PROBE);
251: rv = -1;
252: goto out;
253: }
254: rv = 0;
255: out:
256: return rv;
257:
258: out_xfer:
259: ata_free_xfer(chp, xfer);
260: return rv;
1.2 bouyer 261: }
262:
1.65 thorpej 263: static void
264: wdc_atapi_probe_device(struct atapibus_softc *sc, int target)
1.33 bouyer 265: {
1.40 bouyer 266: struct scsipi_channel *chan = sc->sc_channel;
267: struct scsipi_periph *periph;
1.33 bouyer 268: struct ataparams ids;
269: struct ataparams *id = &ids;
1.106 cube 270: struct wdc_softc *wdc = device_private(chan->chan_adapter->adapt_dev);
1.88 thorpej 271: struct atac_softc *atac = &wdc->sc_atac;
272: struct ata_channel *chp = atac->atac_channels[chan->chan_channel];
1.46 bouyer 273: struct ata_drive_datas *drvp = &chp->ch_drive[target];
1.40 bouyer 274: struct scsipibus_attach_args sa;
1.33 bouyer 275: char serial_number[21], model[41], firmware_revision[9];
1.89 thorpej 276: int s;
1.33 bouyer 277:
1.40 bouyer 278: /* skip if already attached */
279: if (scsipi_lookup_periph(chan, target, 0) != NULL)
1.33 bouyer 280: return;
1.40 bouyer 281:
1.119 bouyer 282: /* if no ATAPI device detected at wdc attach time, skip */
283: if (drvp->drive_type != ATA_DRIVET_ATAPI) {
284: ATADEBUG_PRINT(("wdc_atapi_probe_device: "
285: "drive %d not present\n", target), DEBUG_PROBE);
286: return;
287: }
288:
1.57 mycroft 289: if (wdc_atapi_get_params(chan, target, id) == 0) {
1.33 bouyer 290: #ifdef ATAPI_DEBUG_PROBE
291: printf("%s drive %d: cmdsz 0x%x drqtype 0x%x\n",
1.107 cube 292: device_xname(sc->sc_dev), target,
1.33 bouyer 293: id->atap_config & ATAPI_CFG_CMD_MASK,
294: id->atap_config & ATAPI_CFG_DRQ_MASK);
295: #endif
1.134 chs 296: periph = scsipi_alloc_periph(M_WAITOK);
1.40 bouyer 297: periph->periph_dev = NULL;
298: periph->periph_channel = chan;
299: periph->periph_switch = &atapi_probe_periphsw;
300: periph->periph_target = target;
301: periph->periph_lun = 0;
1.56 mycroft 302: periph->periph_quirks = PQUIRK_ONLYBIG;
1.40 bouyer 303:
304: #ifdef SCSIPI_DEBUG
305: if (SCSIPI_DEBUG_TYPE == SCSIPI_BUSTYPE_ATAPI &&
306: SCSIPI_DEBUG_TARGET == target)
307: periph->periph_dbflags |= SCSIPI_DEBUG_FLAGS;
308: #endif
309: periph->periph_type = ATAPI_CFG_TYPE(id->atap_config);
310: if (id->atap_config & ATAPI_CFG_REMOV)
311: periph->periph_flags |= PERIPH_REMOVABLE;
1.89 thorpej 312: if (periph->periph_type == T_SEQUENTIAL) {
313: s = splbio();
1.118 bouyer 314: drvp->drive_flags |= ATA_DRIVE_ATAPIDSCW;
1.89 thorpej 315: splx(s);
316: }
1.40 bouyer 317:
318: sa.sa_periph = periph;
319: sa.sa_inqbuf.type = ATAPI_CFG_TYPE(id->atap_config);
320: sa.sa_inqbuf.removable = id->atap_config & ATAPI_CFG_REMOV ?
321: T_REMOV : T_FIXED;
1.122 christos 322: strnvisx(model, sizeof(model), id->atap_model,
323: sizeof(id->atap_model), VIS_TRIM|VIS_SAFE|VIS_OCTAL);
324: strnvisx(serial_number, sizeof(serial_number),
325: id->atap_serial, sizeof(id->atap_serial),
326: VIS_TRIM|VIS_SAFE|VIS_OCTAL);
327: strnvisx(firmware_revision, sizeof(firmware_revision),
328: id->atap_revision, sizeof(id->atap_revision),
329: VIS_TRIM|VIS_SAFE|VIS_OCTAL);
1.33 bouyer 330: sa.sa_inqbuf.vendor = model;
331: sa.sa_inqbuf.product = serial_number;
332: sa.sa_inqbuf.revision = firmware_revision;
1.40 bouyer 333:
334: /*
335: * Determine the operating mode capabilities of the device.
336: */
337: if ((id->atap_config & ATAPI_CFG_CMD_MASK) == ATAPI_CFG_CMD_16)
338: periph->periph_cap |= PERIPH_CAP_CMD16;
339: /* XXX This is gross. */
340: periph->periph_cap |= (id->atap_config & ATAPI_CFG_DRQ_MASK);
341:
342: drvp->drv_softc = atapi_probe_device(sc, target, periph, &sa);
343:
344: if (drvp->drv_softc)
1.80 thorpej 345: ata_probe_caps(drvp);
1.89 thorpej 346: else {
347: s = splbio();
1.118 bouyer 348: drvp->drive_type = ATA_DRIVET_NONE;
1.89 thorpej 349: splx(s);
350: }
1.69 bouyer 351: } else {
1.89 thorpej 352: s = splbio();
1.118 bouyer 353: drvp->drive_type = ATA_DRIVET_NONE;
1.89 thorpej 354: splx(s);
1.33 bouyer 355: }
356: }
357:
1.131 jdolecek 358: static const struct ata_xfer_ops wdc_atapi_xfer_ops = {
359: .c_start = wdc_atapi_start,
360: .c_intr = wdc_atapi_intr,
361: .c_poll = wdc_atapi_poll,
362: .c_abort = wdc_atapi_reset,
363: .c_kill_xfer = wdc_atapi_kill_xfer,
364: };
365:
1.65 thorpej 366: static void
367: wdc_atapi_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,
368: void *arg)
1.40 bouyer 369: {
370: struct scsipi_adapter *adapt = chan->chan_adapter;
371: struct scsipi_periph *periph;
1.2 bouyer 372: struct scsipi_xfer *sc_xfer;
1.106 cube 373: struct wdc_softc *wdc = device_private(adapt->adapt_dev);
1.88 thorpej 374: struct atac_softc *atac = &wdc->sc_atac;
1.63 thorpej 375: struct ata_xfer *xfer;
1.40 bouyer 376: int channel = chan->chan_channel;
377: int drive, s;
378:
379: switch (req) {
380: case ADAPTER_REQ_RUN_XFER:
381: sc_xfer = arg;
382: periph = sc_xfer->xs_periph;
383: drive = periph->periph_target;
384:
1.86 thorpej 385: ATADEBUG_PRINT(("wdc_atapi_scsipi_request %s:%d:%d\n",
1.106 cube 386: device_xname(atac->atac_dev), channel, drive),
387: DEBUG_XFERS);
388: if (!device_is_active(atac->atac_dev)) {
1.40 bouyer 389: sc_xfer->error = XS_DRIVER_STUFFUP;
390: scsipi_done(sc_xfer);
391: return;
392: }
393:
1.131 jdolecek 394: xfer = ata_get_xfer(atac->atac_channels[channel], false);
1.40 bouyer 395: if (xfer == NULL) {
396: sc_xfer->error = XS_RESOURCE_SHORTAGE;
397: scsipi_done(sc_xfer);
398: return;
399: }
400:
401: if (sc_xfer->xs_control & XS_CTL_POLL)
402: xfer->c_flags |= C_POLL;
1.102 itohy 403: #if NATA_DMA
1.88 thorpej 404: if ((atac->atac_channels[channel]->ch_drive[drive].drive_flags &
1.118 bouyer 405: (ATA_DRIVE_DMA | ATA_DRIVE_UDMA)) && sc_xfer->datalen > 0)
1.59 bouyer 406: xfer->c_flags |= C_DMA;
1.102 itohy 407: #endif
408: #if NATA_DMA && NATA_PIOBM
409: else
410: #endif
1.101 itohy 411: #if NATA_PIOBM
1.102 itohy 412: if ((atac->atac_cap & ATAC_CAP_PIOBM) &&
1.101 itohy 413: sc_xfer->datalen > 0)
414: xfer->c_flags |= C_PIOBM;
415: #endif
1.63 thorpej 416: xfer->c_drive = drive;
1.40 bouyer 417: xfer->c_flags |= C_ATAPI;
1.102 itohy 418: #if NATA_DMA
1.40 bouyer 419: if (sc_xfer->cmd->opcode == GPCMD_REPORT_KEY ||
420: sc_xfer->cmd->opcode == GPCMD_SEND_KEY ||
421: sc_xfer->cmd->opcode == GPCMD_READ_DVD_STRUCTURE) {
422: /*
423: * DVD authentication commands must always be done in
424: * PIO mode.
425: */
1.59 bouyer 426: xfer->c_flags &= ~C_DMA;
1.40 bouyer 427: }
1.104 reinoud 428:
1.52 bouyer 429: /*
1.104 reinoud 430: * DMA normally can't deal with transfers which are not a
431: * multiple of its databus width. It's a bug to request odd
432: * length transfers for ATAPI.
433: *
434: * Some devices also can't cope with unaligned DMA xfers
435: * either. Also some devices seem to not handle DMA xfers of
436: * less than 4 bytes.
437: *
438: * By enforcing at least 4 byte aligned offset and length for
439: * DMA, we might use PIO where DMA could be allowed but better
440: * safe than sorry as recent problems proved.
441: *
442: * Offending structures that are thus done by PIO instead of
443: * DMA are normally small structures since all bulkdata is
444: * aligned. But as the request may come from userland, we have
445: * to protect against it anyway.
446: *
447: * XXX check for the 32 bit wide flag?
1.52 bouyer 448: */
1.104 reinoud 449:
450: if (((uintptr_t) sc_xfer->data) & 0x03)
1.103 reinoud 451: xfer->c_flags &= ~C_DMA;
1.104 reinoud 452: if ((sc_xfer->datalen < 4) || (sc_xfer->datalen & 0x03))
1.59 bouyer 453: xfer->c_flags &= ~C_DMA;
1.102 itohy 454: #endif /* NATA_DMA */
1.52 bouyer 455:
1.63 thorpej 456: xfer->c_databuf = sc_xfer->data;
1.40 bouyer 457: xfer->c_bcount = sc_xfer->datalen;
1.131 jdolecek 458: xfer->ops = &wdc_atapi_xfer_ops;
459: xfer->c_scsipi = sc_xfer;
460: xfer->c_atapi.c_dscpoll = 0;
1.40 bouyer 461: s = splbio();
1.88 thorpej 462: ata_exec_xfer(atac->atac_channels[channel], xfer);
1.2 bouyer 463: #ifdef DIAGNOSTIC
1.40 bouyer 464: if ((sc_xfer->xs_control & XS_CTL_POLL) != 0 &&
465: (sc_xfer->xs_status & XS_STS_DONE) == 0)
466: panic("wdc_atapi_scsipi_request: polled command "
467: "not done");
1.2 bouyer 468: #endif
1.40 bouyer 469: splx(s);
470: return;
471:
472: default:
473: /* Not supported, nothing to do. */
1.41 lukem 474: ;
1.40 bouyer 475: }
1.2 bouyer 476: }
477:
1.124 jdolecek 478: static int
1.87 thorpej 479: wdc_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer)
1.2 bouyer 480: {
1.88 thorpej 481: struct atac_softc *atac = chp->ch_atac;
482: struct wdc_softc *wdc = CHAN_TO_WDC(chp);
1.87 thorpej 483: struct wdc_regs *wdr = &wdc->regs[chp->ch_channel];
1.124 jdolecek 484: struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
1.63 thorpej 485: struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
1.59 bouyer 486: int wait_flags = (sc_xfer->xs_control & XS_CTL_POLL) ? AT_POLL : 0;
1.124 jdolecek 487: int tfd;
1.93 christos 488: const char *errstring;
1.2 bouyer 489:
1.86 thorpej 490: ATADEBUG_PRINT(("wdc_atapi_start %s:%d:%d, scsi flags 0x%x \n",
1.106 cube 491: device_xname(atac->atac_dev), chp->ch_channel, drvp->drive,
1.27 thorpej 492: sc_xfer->xs_control), DEBUG_XFERS);
1.124 jdolecek 493:
494: ata_channel_lock_owned(chp);
495:
1.102 itohy 496: #if NATA_DMA
1.59 bouyer 497: if ((xfer->c_flags & C_DMA) && (drvp->n_xfers <= NXFER))
498: drvp->n_xfers++;
1.102 itohy 499: #endif
1.59 bouyer 500: /* Do control operations specially. */
501: if (__predict_false(drvp->state < READY)) {
1.94 peter 502: /* If it's not a polled command, we need the kernel thread */
1.137 jdolecek 503: if ((sc_xfer->xs_control & XS_CTL_POLL) == 0
504: && !ata_is_thread_run(chp))
1.124 jdolecek 505: return ATASTART_TH;
1.59 bouyer 506: /*
507: * disable interrupts, all commands here should be quick
1.111 snj 508: * enough to be able to poll, and we don't go here that often
1.59 bouyer 509: */
1.120 tsutsui 510: bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr,
1.59 bouyer 511: WDCTL_4BIT | WDCTL_IDS);
1.85 thorpej 512: if (wdc->select)
1.67 thorpej 513: wdc->select(chp, xfer->c_drive);
1.87 thorpej 514: bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
1.63 thorpej 515: WDSD_IBM | (xfer->c_drive << 4));
1.59 bouyer 516: /* Don't try to set mode if controller can't be adjusted */
1.88 thorpej 517: if (atac->atac_set_modes == NULL)
1.59 bouyer 518: goto ready;
519: /* Also don't try if the drive didn't report its mode */
1.118 bouyer 520: if ((drvp->drive_flags & ATA_DRIVE_MODE) == 0)
1.59 bouyer 521: goto ready;
522: errstring = "unbusy";
1.124 jdolecek 523: if (wdc_wait_for_unbusy(chp, ATAPI_DELAY, wait_flags, &tfd))
1.59 bouyer 524: goto timeout;
525: wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
526: 0x08 | drvp->PIO_mode, WDSF_SET_MODE);
527: errstring = "piomode";
1.124 jdolecek 528: if (wdc_wait_for_unbusy(chp, ATAPI_MODE_DELAY, wait_flags,
529: &tfd))
1.59 bouyer 530: goto timeout;
1.124 jdolecek 531: if (ATACH_ST(tfd) & WDCS_ERR) {
532: if (ATACH_ST(tfd) == WDCE_ABRT) {
1.59 bouyer 533: /*
1.76 mycroft 534: * Some ATAPI drives reject PIO settings.
535: * Fall back to PIO mode 3 since that's the
536: * minimum for ATAPI.
1.59 bouyer 537: */
1.76 mycroft 538: printf("%s:%d:%d: PIO mode %d rejected, "
539: "falling back to PIO mode 3\n",
1.106 cube 540: device_xname(atac->atac_dev),
1.76 mycroft 541: chp->ch_channel, xfer->c_drive,
542: drvp->PIO_mode);
543: if (drvp->PIO_mode > 3)
544: drvp->PIO_mode = 3;
545: } else
546: goto error;
1.59 bouyer 547: }
1.102 itohy 548: #if NATA_DMA
549: #if NATA_UDMA
1.118 bouyer 550: if (drvp->drive_flags & ATA_DRIVE_UDMA) {
1.59 bouyer 551: wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
552: 0x40 | drvp->UDMA_mode, WDSF_SET_MODE);
1.102 itohy 553: } else
554: #endif
1.118 bouyer 555: if (drvp->drive_flags & ATA_DRIVE_DMA) {
1.59 bouyer 556: wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
557: 0x20 | drvp->DMA_mode, WDSF_SET_MODE);
558: } else {
559: goto ready;
560: }
561: errstring = "dmamode";
1.124 jdolecek 562: if (wdc_wait_for_unbusy(chp, ATAPI_MODE_DELAY, wait_flags,
563: &tfd))
1.59 bouyer 564: goto timeout;
1.124 jdolecek 565: if (ATACH_ST(tfd) & WDCS_ERR) {
566: if (ATACH_ERR(tfd) == WDCE_ABRT) {
1.102 itohy 567: #if NATA_UDMA
1.118 bouyer 568: if (drvp->drive_flags & ATA_DRIVE_UDMA)
1.76 mycroft 569: goto error;
1.102 itohy 570: else
571: #endif
572: {
1.76 mycroft 573: /*
574: * The drive rejected our DMA setting.
575: * Fall back to mode 1.
576: */
577: printf("%s:%d:%d: DMA mode %d rejected, "
578: "falling back to DMA mode 0\n",
1.106 cube 579: device_xname(atac->atac_dev),
1.76 mycroft 580: chp->ch_channel, xfer->c_drive,
581: drvp->DMA_mode);
582: if (drvp->DMA_mode > 0)
583: drvp->DMA_mode = 0;
584: }
585: } else
586: goto error;
587: }
1.102 itohy 588: #endif /* NATA_DMA */
1.59 bouyer 589: ready:
590: drvp->state = READY;
1.87 thorpej 591: bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr,
1.59 bouyer 592: WDCTL_4BIT);
1.70 bouyer 593: delay(10); /* some drives need a little delay here */
1.30 bouyer 594: }
1.24 bouyer 595: /* start timeout machinery */
1.27 thorpej 596: if ((sc_xfer->xs_control & XS_CTL_POLL) == 0)
1.131 jdolecek 597: callout_reset(&chp->c_timo_callout, mstohz(sc_xfer->timeout),
598: wdctimeout, chp);
1.59 bouyer 599:
1.85 thorpej 600: if (wdc->select)
1.67 thorpej 601: wdc->select(chp, xfer->c_drive);
1.87 thorpej 602: bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
1.63 thorpej 603: WDSD_IBM | (xfer->c_drive << 4));
1.124 jdolecek 604: switch (wdc_wait_for_unbusy(chp, ATAPI_DELAY, wait_flags, &tfd)) {
1.59 bouyer 605: case WDCWAIT_OK:
606: break;
607: case WDCWAIT_TOUT:
1.2 bouyer 608: printf("wdc_atapi_start: not ready, st = %02x\n",
1.124 jdolecek 609: ATACH_ST(tfd));
1.3 bouyer 610: sc_xfer->error = XS_TIMEOUT;
1.124 jdolecek 611: return ATASTART_ABORT;
1.59 bouyer 612: case WDCWAIT_THR:
1.124 jdolecek 613: return ATASTART_TH;
1.2 bouyer 614: }
615:
616: /*
617: * Even with WDCS_ERR, the device should accept a command packet
618: * Limit length to what can be stuffed into the cylinder register
619: * (16 bits). Some CD-ROMs seem to interpret '0' as 65536,
620: * but not all devices do that and it's not obvious from the
621: * ATAPI spec that that behaviour should be expected. If more
622: * data is necessary, multiple data transfer phases will be done.
623: */
1.5 bouyer 624:
1.92 perry 625: wdccommand(chp, xfer->c_drive, ATAPI_PKT_CMD,
1.29 bouyer 626: xfer->c_bcount <= 0xffff ? xfer->c_bcount : 0xffff,
1.92 perry 627: 0, 0, 0,
1.102 itohy 628: #if NATA_DMA
629: (xfer->c_flags & C_DMA) ? ATAPI_PKT_CMD_FTRE_DMA :
630: #endif
631: 0
632: );
1.92 perry 633:
1.101 itohy 634: #if NATA_PIOBM
635: if (xfer->c_flags & C_PIOBM) {
636: int error;
637: int dma_flags = (sc_xfer->xs_control & XS_CTL_DATA_IN)
638: ? WDC_DMA_READ : 0;
639: if (xfer->c_flags & C_POLL) {
640: /* XXX not supported yet --- fall back to PIO */
641: xfer->c_flags &= ~C_PIOBM;
642: } else {
643: /* Init the DMA channel. */
644: error = (*wdc->dma_init)(wdc->dma_arg,
645: chp->ch_channel, xfer->c_drive,
646: (char *)xfer->c_databuf,
647: xfer->c_bcount,
648: dma_flags | WDC_DMA_PIOBM_ATAPI);
649: if (error) {
650: if (error == EINVAL) {
651: /*
652: * We can't do DMA on this transfer
653: * for some reason. Fall back to
654: * PIO.
655: */
656: xfer->c_flags &= ~C_PIOBM;
657: error = 0;
658: } else {
659: sc_xfer->error = XS_DRIVER_STUFFUP;
660: errstring = "piobm";
661: goto error;
662: }
663: }
664: }
665: }
666: #endif
1.2 bouyer 667: /*
1.92 perry 668: * If there is no interrupt for CMD input, busy-wait for it (done in
1.124 jdolecek 669: * the interrupt routine. Poll routine will exit early in this case.
1.2 bouyer 670: */
1.40 bouyer 671: if ((sc_xfer->xs_periph->periph_cap & ATAPI_CFG_DRQ_MASK) !=
1.124 jdolecek 672: ATAPI_CFG_IRQ_DRQ || (sc_xfer->xs_control & XS_CTL_POLL))
673: return ATASTART_POLL;
1.129 jdolecek 674: else {
675: chp->ch_flags |= ATACH_IRQ_WAIT;
1.124 jdolecek 676: return ATASTART_STARTED;
1.129 jdolecek 677: }
1.124 jdolecek 678:
1.59 bouyer 679: timeout:
680: printf("%s:%d:%d: %s timed out\n",
1.106 cube 681: device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive,
1.67 thorpej 682: errstring);
1.59 bouyer 683: sc_xfer->error = XS_TIMEOUT;
1.87 thorpej 684: bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
1.70 bouyer 685: delay(10); /* some drives need a little delay here */
1.124 jdolecek 686: return ATASTART_ABORT;
687:
1.59 bouyer 688: error:
689: printf("%s:%d:%d: %s ",
1.106 cube 690: device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive,
1.59 bouyer 691: errstring);
1.124 jdolecek 692: printf("error (0x%x)\n", ATACH_ERR(tfd));
1.59 bouyer 693: sc_xfer->error = XS_SHORTSENSE;
1.124 jdolecek 694: sc_xfer->sense.atapi_sense = ATACH_ERR(tfd);
1.87 thorpej 695: bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
1.70 bouyer 696: delay(10); /* some drives need a little delay here */
1.124 jdolecek 697: return ATASTART_ABORT;
698: }
699:
700: static void
701: wdc_atapi_poll(struct ata_channel *chp, struct ata_xfer *xfer)
702: {
703: /*
704: * If there is no interrupt for CMD input, busy-wait for it (done in
705: * the interrupt routine. If it is a polled command, call the interrupt
706: * routine until command is done.
707: */
708: const bool poll = ((xfer->c_scsipi->xs_control & XS_CTL_POLL) != 0);
709:
710: /* Wait for at last 400ns for status bit to be valid */
711: DELAY(1);
712: wdc_atapi_intr(chp, xfer, 0);
713:
714: if (!poll)
715: return;
716:
717: #if NATA_DMA
718: if (chp->ch_flags & ATACH_DMA_WAIT) {
719: wdc_dmawait(chp, xfer, xfer->c_scsipi->timeout);
720: chp->ch_flags &= ~ATACH_DMA_WAIT;
721: }
722: #endif
723: while ((xfer->c_scsipi->xs_status & XS_STS_DONE) == 0) {
724: /* Wait for at last 400ns for status bit to be valid */
725: DELAY(1);
726: wdc_atapi_intr(chp, xfer, 0);
727: }
1.2 bouyer 728: }
729:
1.65 thorpej 730: static int
1.128 jdolecek 731: wdc_atapi_intr(struct ata_channel *chp, struct ata_xfer *xfer, int irq)
1.2 bouyer 732: {
1.88 thorpej 733: struct atac_softc *atac = chp->ch_atac;
734: struct wdc_softc *wdc = CHAN_TO_WDC(chp);
1.87 thorpej 735: struct wdc_regs *wdr = &wdc->regs[chp->ch_channel];
1.124 jdolecek 736: struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
1.63 thorpej 737: struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
1.2 bouyer 738: int len, phase, i, retries=0;
1.124 jdolecek 739: int ire, tfd;
1.102 itohy 740: #if NATA_DMA
741: int error;
742: #endif
743: #if NATA_DMA || NATA_PIOBM
1.2 bouyer 744: int dma_flags = 0;
1.102 itohy 745: #endif
1.8 bouyer 746: void *cmd;
1.2 bouyer 747:
1.86 thorpej 748: ATADEBUG_PRINT(("wdc_atapi_intr %s:%d:%d\n",
1.106 cube 749: device_xname(atac->atac_dev), chp->ch_channel, drvp->drive),
1.67 thorpej 750: DEBUG_INTR);
1.2 bouyer 751:
1.124 jdolecek 752: ata_channel_lock(chp);
753:
1.2 bouyer 754: /* Is it not a transfer, but a control operation? */
755: if (drvp->state < READY) {
756: printf("%s:%d:%d: bad state %d in wdc_atapi_intr\n",
1.106 cube 757: device_xname(atac->atac_dev), chp->ch_channel,
758: xfer->c_drive, drvp->state);
1.55 provos 759: panic("wdc_atapi_intr: bad state");
1.2 bouyer 760: }
1.24 bouyer 761: /*
762: * If we missed an interrupt in a PIO transfer, reset and restart.
763: * Don't try to continue transfer, we may have missed cycles.
764: */
765: if ((xfer->c_flags & (C_TIMEOU | C_DMA)) == C_TIMEOU) {
1.124 jdolecek 766: ata_channel_unlock(chp);
1.24 bouyer 767: sc_xfer->error = XS_TIMEOUT;
768: wdc_atapi_reset(chp, xfer);
1.25 bouyer 769: return 1;
1.92 perry 770: }
1.24 bouyer 771:
1.101 itohy 772: #if NATA_PIOBM
773: /* Transfer-done interrupt for busmastering PIO operation */
774: if ((xfer->c_flags & C_PIOBM) && (chp->ch_flags & ATACH_PIOBM_WAIT)) {
775: chp->ch_flags &= ~ATACH_PIOBM_WAIT;
776:
777: /* restore transfer length */
778: len = xfer->c_bcount;
1.131 jdolecek 779: if (xfer->c_atapi.c_lenoff < 0)
780: len += xfer->c_atapi.c_lenoff;
1.101 itohy 781:
782: if (sc_xfer->xs_control & XS_CTL_DATA_IN)
783: goto end_piobm_datain;
784: else
785: goto end_piobm_dataout;
786: }
787: #endif
788:
1.64 thorpej 789: /* Ack interrupt done in wdc_wait_for_unbusy */
1.85 thorpej 790: if (wdc->select)
1.67 thorpej 791: wdc->select(chp, xfer->c_drive);
1.87 thorpej 792: bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
1.63 thorpej 793: WDSD_IBM | (xfer->c_drive << 4));
1.64 thorpej 794: if (wdc_wait_for_unbusy(chp,
1.128 jdolecek 795: (irq == 0) ? sc_xfer->timeout : 0, AT_POLL, &tfd) == WDCWAIT_TOUT) {
796: if (irq && (xfer->c_flags & C_TIMEOU) == 0) {
1.124 jdolecek 797: ata_channel_unlock(chp);
1.19 bouyer 798: return 0; /* IRQ was not for us */
1.124 jdolecek 799: }
1.16 bouyer 800: printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip=%d\n",
1.106 cube 801: device_xname(atac->atac_dev), chp->ch_channel,
802: xfer->c_drive, xfer->c_bcount, xfer->c_skip);
1.102 itohy 803: #if NATA_DMA
1.33 bouyer 804: if (xfer->c_flags & C_DMA) {
1.59 bouyer 805: ata_dmaerr(drvp,
806: (xfer->c_flags & C_POLL) ? AT_POLL : 0);
1.33 bouyer 807: }
1.102 itohy 808: #endif
1.3 bouyer 809: sc_xfer->error = XS_TIMEOUT;
1.132 jdolecek 810: ata_channel_unlock(chp);
1.2 bouyer 811: wdc_atapi_reset(chp, xfer);
812: return 1;
813: }
1.85 thorpej 814: if (wdc->irqack)
1.67 thorpej 815: wdc->irqack(chp);
1.36 bouyer 816:
1.102 itohy 817: #if NATA_DMA
1.48 bouyer 818: /*
819: * If we missed an IRQ and were using DMA, flag it as a DMA error
820: * and reset device.
821: */
1.33 bouyer 822: if ((xfer->c_flags & C_TIMEOU) && (xfer->c_flags & C_DMA)) {
1.59 bouyer 823: ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0);
1.48 bouyer 824: sc_xfer->error = XS_RESET;
1.132 jdolecek 825: ata_channel_unlock(chp);
1.48 bouyer 826: wdc_atapi_reset(chp, xfer);
827: return (1);
1.33 bouyer 828: }
1.102 itohy 829: #endif
1.92 perry 830: /*
1.8 bouyer 831: * if the request sense command was aborted, report the short sense
832: * previously recorded, else continue normal processing
833: */
834:
1.102 itohy 835: #if NATA_DMA || NATA_PIOBM
1.101 itohy 836: if (xfer->c_flags & (C_DMA | C_PIOBM))
1.40 bouyer 837: dma_flags = (sc_xfer->xs_control & XS_CTL_DATA_IN)
838: ? WDC_DMA_READ : 0;
1.102 itohy 839: #endif
1.2 bouyer 840: again:
1.87 thorpej 841: len = bus_space_read_1(wdr->cmd_iot, wdr->cmd_iohs[wd_cyl_lo], 0) +
842: 256 * bus_space_read_1(wdr->cmd_iot, wdr->cmd_iohs[wd_cyl_hi], 0);
843: ire = bus_space_read_1(wdr->cmd_iot, wdr->cmd_iohs[wd_ireason], 0);
1.124 jdolecek 844: phase = (ire & (WDCI_CMD | WDCI_IN)) | (ATACH_ST(tfd) & WDCS_DRQ);
1.86 thorpej 845: ATADEBUG_PRINT(("wdc_atapi_intr: c_bcount %d len %d st 0x%x err 0x%x "
1.2 bouyer 846: "ire 0x%x :", xfer->c_bcount,
1.124 jdolecek 847: len, ATACH_ST(tfd), ATACH_ERR(tfd), ire), DEBUG_INTR);
1.2 bouyer 848:
849: switch (phase) {
850: case PHASE_CMDOUT:
1.57 mycroft 851: cmd = sc_xfer->cmd;
1.86 thorpej 852: ATADEBUG_PRINT(("PHASE_CMDOUT\n"), DEBUG_INTR);
1.102 itohy 853: #if NATA_DMA
1.2 bouyer 854: /* Init the DMA channel if necessary */
855: if (xfer->c_flags & C_DMA) {
1.95 thorpej 856: error = (*wdc->dma_init)(wdc->dma_arg,
1.67 thorpej 857: chp->ch_channel, xfer->c_drive,
1.95 thorpej 858: xfer->c_databuf, xfer->c_bcount, dma_flags);
859: if (error) {
860: if (error == EINVAL) {
861: /*
862: * We can't do DMA on this transfer
863: * for some reason. Fall back to
864: * PIO.
865: */
866: xfer->c_flags &= ~C_DMA;
867: error = 0;
868: } else {
869: sc_xfer->error = XS_DRIVER_STUFFUP;
870: break;
871: }
1.2 bouyer 872: }
873: }
1.102 itohy 874: #endif
1.75 mycroft 875:
1.2 bouyer 876: /* send packet command */
877: /* Commands are 12 or 16 bytes long. It's 32-bit aligned */
1.77 mycroft 878: wdc->dataout_pio(chp, drvp->drive_flags, cmd, sc_xfer->cmdlen);
1.75 mycroft 879:
1.102 itohy 880: #if NATA_DMA
1.2 bouyer 881: /* Start the DMA channel if necessary */
882: if (xfer->c_flags & C_DMA) {
1.67 thorpej 883: (*wdc->dma_start)(wdc->dma_arg,
884: chp->ch_channel, xfer->c_drive);
1.87 thorpej 885: chp->ch_flags |= ATACH_DMA_WAIT;
1.2 bouyer 886: }
1.102 itohy 887: #endif
1.129 jdolecek 888:
889: if ((sc_xfer->xs_control & XS_CTL_POLL) == 0) {
890: chp->ch_flags |= ATACH_IRQ_WAIT;
891: }
892:
1.124 jdolecek 893: ata_channel_unlock(chp);
1.2 bouyer 894: return 1;
895:
896: case PHASE_DATAOUT:
897: /* write data */
1.86 thorpej 898: ATADEBUG_PRINT(("PHASE_DATAOUT\n"), DEBUG_INTR);
1.102 itohy 899: #if NATA_DMA
1.27 thorpej 900: if ((sc_xfer->xs_control & XS_CTL_DATA_OUT) == 0 ||
1.2 bouyer 901: (xfer->c_flags & C_DMA) != 0) {
1.15 bouyer 902: printf("wdc_atapi_intr: bad data phase DATAOUT\n");
1.2 bouyer 903: if (xfer->c_flags & C_DMA) {
1.59 bouyer 904: ata_dmaerr(drvp,
905: (xfer->c_flags & C_POLL) ? AT_POLL : 0);
1.2 bouyer 906: }
1.3 bouyer 907: sc_xfer->error = XS_TIMEOUT;
1.132 jdolecek 908: ata_channel_unlock(chp);
1.2 bouyer 909: wdc_atapi_reset(chp, xfer);
910: return 1;
911: }
1.102 itohy 912: #endif
1.131 jdolecek 913: xfer->c_atapi.c_lenoff = len - xfer->c_bcount;
1.2 bouyer 914: if (xfer->c_bcount < len) {
915: printf("wdc_atapi_intr: warning: write only "
916: "%d of %d requested bytes\n", xfer->c_bcount, len);
1.101 itohy 917: len = xfer->c_bcount;
918: }
919:
920: #if NATA_PIOBM
921: if (xfer->c_flags & C_PIOBM) {
922: /* start the busmastering PIO */
923: (*wdc->piobm_start)(wdc->dma_arg,
924: chp->ch_channel, xfer->c_drive,
925: xfer->c_skip, len, WDC_PIOBM_XFER_IRQ);
1.129 jdolecek 926: chp->ch_flags |= ATACH_DMA_WAIT | ATACH_IRQ_WAIT |
927: ATACH_PIOBM_WAIT;
1.124 jdolecek 928: ata_channel_unlock(chp);
1.101 itohy 929: return 1;
1.2 bouyer 930: }
1.101 itohy 931: #endif
932: wdc->dataout_pio(chp, drvp->drive_flags,
1.120 tsutsui 933: (char *)xfer->c_databuf + xfer->c_skip, len);
1.101 itohy 934:
935: #if NATA_PIOBM
936: end_piobm_dataout:
937: #endif
1.131 jdolecek 938: for (i = xfer->c_atapi.c_lenoff; i > 0; i -= 2)
1.101 itohy 939: bus_space_write_2(wdr->cmd_iot,
940: wdr->cmd_iohs[wd_data], 0, 0);
941:
942: xfer->c_skip += len;
943: xfer->c_bcount -= len;
1.129 jdolecek 944: if ((sc_xfer->xs_control & XS_CTL_POLL) == 0) {
945: chp->ch_flags |= ATACH_IRQ_WAIT;
946: }
1.124 jdolecek 947: ata_channel_unlock(chp);
1.2 bouyer 948: return 1;
949:
950: case PHASE_DATAIN:
951: /* Read data */
1.86 thorpej 952: ATADEBUG_PRINT(("PHASE_DATAIN\n"), DEBUG_INTR);
1.102 itohy 953: #if NATA_DMA
1.92 perry 954: if ((sc_xfer->xs_control & XS_CTL_DATA_IN) == 0 ||
1.2 bouyer 955: (xfer->c_flags & C_DMA) != 0) {
1.15 bouyer 956: printf("wdc_atapi_intr: bad data phase DATAIN\n");
1.2 bouyer 957: if (xfer->c_flags & C_DMA) {
1.59 bouyer 958: ata_dmaerr(drvp,
959: (xfer->c_flags & C_POLL) ? AT_POLL : 0);
1.2 bouyer 960: }
1.3 bouyer 961: sc_xfer->error = XS_TIMEOUT;
1.132 jdolecek 962: ata_channel_unlock(chp);
1.2 bouyer 963: wdc_atapi_reset(chp, xfer);
964: return 1;
965: }
1.102 itohy 966: #endif
1.131 jdolecek 967: xfer->c_atapi.c_lenoff = len - xfer->c_bcount;
1.2 bouyer 968: if (xfer->c_bcount < len) {
969: printf("wdc_atapi_intr: warning: reading only "
970: "%d of %d bytes\n", xfer->c_bcount, len);
1.101 itohy 971: len = xfer->c_bcount;
972: }
973:
974: #if NATA_PIOBM
975: if (xfer->c_flags & C_PIOBM) {
976: /* start the busmastering PIO */
977: (*wdc->piobm_start)(wdc->dma_arg,
978: chp->ch_channel, xfer->c_drive,
979: xfer->c_skip, len, WDC_PIOBM_XFER_IRQ);
1.129 jdolecek 980: chp->ch_flags |= ATACH_DMA_WAIT | ATACH_IRQ_WAIT |
981: ATACH_PIOBM_WAIT;
1.124 jdolecek 982: ata_channel_unlock(chp);
1.101 itohy 983: return 1;
984: }
985: #endif
986: wdc->datain_pio(chp, drvp->drive_flags,
987: (char *)xfer->c_databuf + xfer->c_skip, len);
988:
989: #if NATA_PIOBM
990: end_piobm_datain:
991: #endif
1.131 jdolecek 992: if (xfer->c_atapi.c_lenoff > 0)
993: wdcbit_bucket(chp, xfer->c_atapi.c_lenoff);
1.101 itohy 994:
995: xfer->c_skip += len;
996: xfer->c_bcount -= len;
1.129 jdolecek 997: if ((sc_xfer->xs_control & XS_CTL_POLL) == 0) {
998: chp->ch_flags |= ATACH_IRQ_WAIT;
999: }
1.124 jdolecek 1000: ata_channel_unlock(chp);
1.2 bouyer 1001: return 1;
1002:
1003: case PHASE_ABORTED:
1004: case PHASE_COMPLETED:
1.86 thorpej 1005: ATADEBUG_PRINT(("PHASE_COMPLETED\n"), DEBUG_INTR);
1.102 itohy 1006: #if NATA_DMA
1.2 bouyer 1007: if (xfer->c_flags & C_DMA) {
1.40 bouyer 1008: xfer->c_bcount -= sc_xfer->datalen;
1009: }
1.102 itohy 1010: #endif
1.40 bouyer 1011: sc_xfer->resid = xfer->c_bcount;
1.124 jdolecek 1012: /* this will unlock channel lock too */
1.133 jdolecek 1013: wdc_atapi_phase_complete(xfer, tfd);
1.45 bouyer 1014: return(1);
1.2 bouyer 1015:
1016: default:
1017: if (++retries<500) {
1018: DELAY(100);
1.124 jdolecek 1019: tfd = ATACH_ERR_ST(
1020: bus_space_read_1(wdr->cmd_iot,
1021: wdr->cmd_iohs[wd_error], 0),
1022: bus_space_read_1(wdr->cmd_iot,
1023: wdr->cmd_iohs[wd_status], 0)
1024: );
1.2 bouyer 1025: goto again;
1026: }
1027: printf("wdc_atapi_intr: unknown phase 0x%x\n", phase);
1.124 jdolecek 1028: if (ATACH_ST(tfd) & WDCS_ERR) {
1.8 bouyer 1029: sc_xfer->error = XS_SHORTSENSE;
1.124 jdolecek 1030: sc_xfer->sense.atapi_sense = ATACH_ERR(tfd);
1.2 bouyer 1031: } else {
1.102 itohy 1032: #if NATA_DMA
1.33 bouyer 1033: if (xfer->c_flags & C_DMA) {
1.59 bouyer 1034: ata_dmaerr(drvp,
1035: (xfer->c_flags & C_POLL) ? AT_POLL : 0);
1.33 bouyer 1036: }
1.102 itohy 1037: #endif
1.16 bouyer 1038: sc_xfer->error = XS_RESET;
1.132 jdolecek 1039: ata_channel_unlock(chp);
1.16 bouyer 1040: wdc_atapi_reset(chp, xfer);
1041: return (1);
1.2 bouyer 1042: }
1043: }
1.86 thorpej 1044: ATADEBUG_PRINT(("wdc_atapi_intr: wdc_atapi_done() (end), error 0x%x "
1.2 bouyer 1045: "sense 0x%x\n", sc_xfer->error, sc_xfer->sense.atapi_sense),
1046: DEBUG_INTR);
1.124 jdolecek 1047: ata_channel_unlock(chp);
1.2 bouyer 1048: wdc_atapi_done(chp, xfer);
1049: return (1);
1050: }
1051:
1.65 thorpej 1052: static void
1.133 jdolecek 1053: wdc_atapi_phase_complete(struct ata_xfer *xfer, int tfd)
1.45 bouyer 1054: {
1.87 thorpej 1055: struct ata_channel *chp = xfer->c_chp;
1.88 thorpej 1056: struct atac_softc *atac = chp->ch_atac;
1.102 itohy 1057: #if NATA_DMA || NATA_PIOBM
1.88 thorpej 1058: struct wdc_softc *wdc = CHAN_TO_WDC(chp);
1.102 itohy 1059: #endif
1.124 jdolecek 1060: struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
1.63 thorpej 1061: struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
1.124 jdolecek 1062:
1063: ata_channel_lock_owned(chp);
1.45 bouyer 1064:
1065: /* wait for DSC if needed */
1.118 bouyer 1066: if (drvp->drive_flags & ATA_DRIVE_ATAPIDSCW) {
1.86 thorpej 1067: ATADEBUG_PRINT(("wdc_atapi_phase_complete(%s:%d:%d) "
1.106 cube 1068: "polldsc %d\n", device_xname(atac->atac_dev),
1069: chp->ch_channel,
1.131 jdolecek 1070: xfer->c_drive, xfer->c_atapi.c_dscpoll), DEBUG_XFERS);
1.57 mycroft 1071: #if 1
1072: if (cold)
1073: panic("wdc_atapi_phase_complete: cold");
1074: #endif
1.59 bouyer 1075: if (wdcwait(chp, WDCS_DSC, WDCS_DSC, 10,
1.124 jdolecek 1076: AT_POLL, &tfd) == WDCWAIT_TOUT) {
1.57 mycroft 1077: /* 10ms not enough, try again in 1 tick */
1.131 jdolecek 1078: if (xfer->c_atapi.c_dscpoll++ >
1.57 mycroft 1079: mstohz(sc_xfer->timeout)) {
1.59 bouyer 1080: printf("%s:%d:%d: wait_for_dsc "
1081: "failed\n",
1.106 cube 1082: device_xname(atac->atac_dev),
1.67 thorpej 1083: chp->ch_channel, xfer->c_drive);
1.124 jdolecek 1084: ata_channel_unlock(chp);
1.45 bouyer 1085: sc_xfer->error = XS_TIMEOUT;
1086: wdc_atapi_reset(chp, xfer);
1.124 jdolecek 1087: } else {
1.131 jdolecek 1088: callout_reset(&chp->c_timo_callout, 1,
1089: wdc_atapi_polldsc, chp);
1.124 jdolecek 1090: ata_channel_unlock(chp);
1091: }
1.57 mycroft 1092: return;
1.45 bouyer 1093: }
1.127 christos 1094: }
1095:
1.45 bouyer 1096: /*
1.92 perry 1097: * Some drive occasionally set WDCS_ERR with
1.45 bouyer 1098: * "ATA illegal length indication" in the error
1099: * register. If we read some data the sense is valid
1100: * anyway, so don't report the error.
1101: */
1.124 jdolecek 1102: if (ATACH_ST(tfd) & WDCS_ERR &&
1.45 bouyer 1103: ((sc_xfer->xs_control & XS_CTL_REQSENSE) == 0 ||
1104: sc_xfer->resid == sc_xfer->datalen)) {
1105: /* save the short sense */
1106: sc_xfer->error = XS_SHORTSENSE;
1.124 jdolecek 1107: sc_xfer->sense.atapi_sense = ATACH_ERR(tfd);
1.45 bouyer 1108: if ((sc_xfer->xs_periph->periph_quirks &
1109: PQUIRK_NOSENSE) == 0) {
1110: /* ask scsipi to send a REQUEST_SENSE */
1111: sc_xfer->error = XS_BUSY;
1112: sc_xfer->status = SCSI_CHECK;
1.102 itohy 1113: }
1114: #if NATA_DMA || NATA_PIOBM
1115: else if (wdc->dma_status &
1.45 bouyer 1116: (WDC_DMAST_NOIRQ | WDC_DMAST_ERR)) {
1.102 itohy 1117: #if NATA_DMA
1.59 bouyer 1118: ata_dmaerr(drvp,
1119: (xfer->c_flags & C_POLL) ? AT_POLL : 0);
1.102 itohy 1120: #endif
1.45 bouyer 1121: sc_xfer->error = XS_RESET;
1.132 jdolecek 1122: ata_channel_unlock(chp);
1.45 bouyer 1123: wdc_atapi_reset(chp, xfer);
1124: return;
1125: }
1.102 itohy 1126: #endif
1.45 bouyer 1127: }
1128: if (xfer->c_bcount != 0) {
1.86 thorpej 1129: ATADEBUG_PRINT(("wdc_atapi_intr: bcount value is "
1.45 bouyer 1130: "%d after io\n", xfer->c_bcount), DEBUG_XFERS);
1131: }
1132: #ifdef DIAGNOSTIC
1133: if (xfer->c_bcount < 0) {
1134: printf("wdc_atapi_intr warning: bcount value "
1135: "is %d after io\n", xfer->c_bcount);
1136: }
1137: #endif
1.86 thorpej 1138: ATADEBUG_PRINT(("wdc_atapi_phase_complete: wdc_atapi_done(), "
1.45 bouyer 1139: "error 0x%x sense 0x%x\n", sc_xfer->error,
1140: sc_xfer->sense.atapi_sense), DEBUG_INTR);
1.124 jdolecek 1141: ata_channel_unlock(chp);
1.45 bouyer 1142: wdc_atapi_done(chp, xfer);
1143: }
1144:
1.65 thorpej 1145: static void
1.87 thorpej 1146: wdc_atapi_done(struct ata_channel *chp, struct ata_xfer *xfer)
1.2 bouyer 1147: {
1.88 thorpej 1148: struct atac_softc *atac = chp->ch_atac;
1.124 jdolecek 1149: struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
1.2 bouyer 1150:
1.86 thorpej 1151: ATADEBUG_PRINT(("wdc_atapi_done %s:%d:%d: flags 0x%x\n",
1.106 cube 1152: device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive,
1.91 reinoud 1153: (u_int)xfer->c_flags), DEBUG_XFERS);
1.124 jdolecek 1154:
1155: if (ata_waitdrain_xfer_check(chp, xfer))
1156: return;
1157:
1158: ata_deactivate_xfer(chp, xfer);
1.81 thorpej 1159: ata_free_xfer(chp, xfer);
1.40 bouyer 1160:
1.86 thorpej 1161: ATADEBUG_PRINT(("wdc_atapi_done: scsipi_done\n"), DEBUG_XFERS);
1.25 bouyer 1162: scsipi_done(sc_xfer);
1.86 thorpej 1163: ATADEBUG_PRINT(("atastart from wdc_atapi_done, flags 0x%x\n",
1.4 bouyer 1164: chp->ch_flags), DEBUG_XFERS);
1.84 thorpej 1165: atastart(chp);
1.2 bouyer 1166: }
1167:
1.65 thorpej 1168: static void
1.87 thorpej 1169: wdc_atapi_reset(struct ata_channel *chp, struct ata_xfer *xfer)
1.2 bouyer 1170: {
1.88 thorpej 1171: struct atac_softc *atac = chp->ch_atac;
1.63 thorpej 1172: struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
1.124 jdolecek 1173: struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
1174: int tfd;
1.2 bouyer 1175:
1.124 jdolecek 1176: ata_channel_lock(chp);
1.63 thorpej 1177: wdccommandshort(chp, xfer->c_drive, ATAPI_SOFT_RESET);
1.2 bouyer 1178: drvp->state = 0;
1.124 jdolecek 1179: if (wdc_wait_for_unbusy(chp, WDC_RESET_WAIT, AT_POLL, &tfd) != 0) {
1.2 bouyer 1180: printf("%s:%d:%d: reset failed\n",
1.106 cube 1181: device_xname(atac->atac_dev), chp->ch_channel,
1.63 thorpej 1182: xfer->c_drive);
1.2 bouyer 1183: sc_xfer->error = XS_SELTIMEOUT;
1184: }
1.124 jdolecek 1185: ata_channel_unlock(chp);
1.2 bouyer 1186: wdc_atapi_done(chp, xfer);
1187: return;
1.45 bouyer 1188: }
1189:
1.59 bouyer 1190: static void
1.65 thorpej 1191: wdc_atapi_polldsc(void *arg)
1.45 bouyer 1192: {
1.131 jdolecek 1193: struct ata_channel *chp = arg;
1194: struct ata_xfer *xfer = ata_queue_get_active_xfer(chp);
1195:
1196: KASSERT(xfer != NULL);
1.124 jdolecek 1197:
1198: ata_channel_lock(chp);
1.65 thorpej 1199:
1.124 jdolecek 1200: /* this will unlock channel lock too */
1.133 jdolecek 1201: wdc_atapi_phase_complete(xfer, 0);
1.2 bouyer 1202: }
CVSweb <webmaster@jp.NetBSD.org>