1 1.120 rin /* $NetBSD: ata_wdc.c,v 1.120 2021/10/05 08:01:05 rin Exp $ */ 2 1.2 bouyer 3 1.2 bouyer /* 4 1.41 bouyer * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. 5 1.2 bouyer * 6 1.2 bouyer * Redistribution and use in source and binary forms, with or without 7 1.2 bouyer * modification, are permitted provided that the following conditions 8 1.2 bouyer * are met: 9 1.2 bouyer * 1. Redistributions of source code must retain the above copyright 10 1.2 bouyer * notice, this list of conditions and the following disclaimer. 11 1.2 bouyer * 2. Redistributions in binary form must reproduce the above copyright 12 1.2 bouyer * notice, this list of conditions and the following disclaimer in the 13 1.2 bouyer * documentation and/or other materials provided with the distribution. 14 1.2 bouyer * 15 1.27 bouyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 1.27 bouyer * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 1.27 bouyer * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 1.79 perry * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 1.27 bouyer * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 1.27 bouyer * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 1.27 bouyer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 1.27 bouyer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 1.27 bouyer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 1.27 bouyer * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 1.2 bouyer */ 26 1.2 bouyer 27 1.2 bouyer /*- 28 1.57 mycroft * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. 29 1.2 bouyer * All rights reserved. 30 1.2 bouyer * 31 1.2 bouyer * This code is derived from software contributed to The NetBSD Foundation 32 1.2 bouyer * by Charles M. Hannum, by Onno van der Linden and by Manuel Bouyer. 33 1.2 bouyer * 34 1.2 bouyer * Redistribution and use in source and binary forms, with or without 35 1.2 bouyer * modification, are permitted provided that the following conditions 36 1.2 bouyer * are met: 37 1.2 bouyer * 1. Redistributions of source code must retain the above copyright 38 1.2 bouyer * notice, this list of conditions and the following disclaimer. 39 1.2 bouyer * 2. Redistributions in binary form must reproduce the above copyright 40 1.2 bouyer * notice, this list of conditions and the following disclaimer in the 41 1.2 bouyer * documentation and/or other materials provided with the distribution. 42 1.2 bouyer * 43 1.2 bouyer * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 44 1.2 bouyer * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 45 1.2 bouyer * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 46 1.2 bouyer * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 47 1.2 bouyer * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 48 1.2 bouyer * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 49 1.2 bouyer * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 50 1.2 bouyer * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 51 1.2 bouyer * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 52 1.2 bouyer * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 53 1.2 bouyer * POSSIBILITY OF SUCH DAMAGE. 54 1.2 bouyer */ 55 1.31 lukem 56 1.31 lukem #include <sys/cdefs.h> 57 1.120 rin __KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.120 2021/10/05 08:01:05 rin Exp $"); 58 1.2 bouyer 59 1.86 dyoung #include "opt_ata.h" 60 1.94 bouyer #include "opt_wdc.h" 61 1.2 bouyer 62 1.2 bouyer #include <sys/param.h> 63 1.2 bouyer #include <sys/systm.h> 64 1.2 bouyer #include <sys/kernel.h> 65 1.2 bouyer #include <sys/file.h> 66 1.2 bouyer #include <sys/stat.h> 67 1.2 bouyer #include <sys/buf.h> 68 1.76 yamt #include <sys/bufq.h> 69 1.2 bouyer #include <sys/device.h> 70 1.2 bouyer #include <sys/disklabel.h> 71 1.2 bouyer #include <sys/syslog.h> 72 1.2 bouyer #include <sys/proc.h> 73 1.2 bouyer 74 1.87 ad #include <sys/intr.h> 75 1.87 ad #include <sys/bus.h> 76 1.2 bouyer #ifndef __BUS_SPACE_HAS_STREAM_METHODS 77 1.2 bouyer #define bus_space_write_multi_stream_2 bus_space_write_multi_2 78 1.2 bouyer #define bus_space_write_multi_stream_4 bus_space_write_multi_4 79 1.2 bouyer #define bus_space_read_multi_stream_2 bus_space_read_multi_2 80 1.2 bouyer #define bus_space_read_multi_stream_4 bus_space_read_multi_4 81 1.2 bouyer #endif /* __BUS_SPACE_HAS_STREAM_METHODS */ 82 1.2 bouyer 83 1.84 itohy #include <dev/ata/ataconf.h> 84 1.2 bouyer #include <dev/ata/atareg.h> 85 1.2 bouyer #include <dev/ata/atavar.h> 86 1.2 bouyer #include <dev/ic/wdcreg.h> 87 1.2 bouyer #include <dev/ic/wdcvar.h> 88 1.2 bouyer 89 1.2 bouyer #define DEBUG_INTR 0x01 90 1.2 bouyer #define DEBUG_XFERS 0x02 91 1.2 bouyer #define DEBUG_STATUS 0x04 92 1.2 bouyer #define DEBUG_FUNCS 0x08 93 1.2 bouyer #define DEBUG_PROBE 0x10 94 1.71 thorpej #ifdef ATADEBUG 95 1.41 bouyer extern int wdcdebug_wd_mask; /* inited in wd.c */ 96 1.71 thorpej #define ATADEBUG_PRINT(args, level) \ 97 1.2 bouyer if (wdcdebug_wd_mask & (level)) \ 98 1.2 bouyer printf args 99 1.2 bouyer #else 100 1.71 thorpej #define ATADEBUG_PRINT(args, level) 101 1.2 bouyer #endif 102 1.2 bouyer 103 1.17 bouyer #define ATA_DELAY 10000 /* 10s for a drive I/O */ 104 1.2 bouyer 105 1.115 jdolecek static void wdc_ata_bio(struct ata_drive_datas*, struct ata_xfer *); 106 1.106 jdolecek static int wdc_ata_bio_start(struct ata_channel *,struct ata_xfer *); 107 1.106 jdolecek static int _wdc_ata_bio_start(struct ata_channel *,struct ata_xfer *); 108 1.120 rin static int wdc_ata_bio_poll(struct ata_channel *,struct ata_xfer *); 109 1.72 thorpej static int wdc_ata_bio_intr(struct ata_channel *, struct ata_xfer *, 110 1.45 thorpej int); 111 1.72 thorpej static void wdc_ata_bio_kill_xfer(struct ata_channel *, 112 1.58 bouyer struct ata_xfer *, int); 113 1.79 perry static void wdc_ata_bio_done(struct ata_channel *, struct ata_xfer *); 114 1.106 jdolecek static int wdc_ata_err(struct ata_drive_datas *, struct ata_bio *, int); 115 1.2 bouyer #define WDC_ATA_NOERR 0x00 /* Drive doesn't report an error */ 116 1.2 bouyer #define WDC_ATA_RECOV 0x01 /* There was a recovered error */ 117 1.2 bouyer #define WDC_ATA_ERR 0x02 /* Drive reports an error */ 118 1.45 thorpej static int wdc_ata_addref(struct ata_drive_datas *); 119 1.45 thorpej static void wdc_ata_delref(struct ata_drive_datas *); 120 1.32 bouyer 121 1.32 bouyer const struct ata_bustype wdc_ata_bustype = { 122 1.119 skrll .bustype_type = SCSIPI_BUSTYPE_ATA, 123 1.119 skrll .ata_bio = wdc_ata_bio, 124 1.119 skrll .ata_reset_drive = wdc_reset_drive, 125 1.119 skrll .ata_reset_channel = wdc_reset_channel, 126 1.119 skrll .ata_exec_command = wdc_exec_command, 127 1.119 skrll .ata_get_params = ata_get_params, 128 1.119 skrll .ata_addref = wdc_ata_addref, 129 1.119 skrll .ata_delref = wdc_ata_delref, 130 1.119 skrll .ata_killpending = ata_kill_pending, 131 1.119 skrll .ata_recovery = NULL, 132 1.112 jdolecek }; 133 1.112 jdolecek 134 1.112 jdolecek static const struct ata_xfer_ops wdc_bio_xfer_ops = { 135 1.112 jdolecek .c_start = wdc_ata_bio_start, 136 1.112 jdolecek .c_poll = wdc_ata_bio_poll, 137 1.112 jdolecek .c_abort = wdc_ata_bio_done, 138 1.112 jdolecek .c_intr = wdc_ata_bio_intr, 139 1.112 jdolecek .c_kill_xfer = wdc_ata_bio_kill_xfer 140 1.32 bouyer }; 141 1.32 bouyer 142 1.2 bouyer /* 143 1.115 jdolecek * Handle block I/O operation. 144 1.2 bouyer */ 145 1.115 jdolecek static void 146 1.106 jdolecek wdc_ata_bio(struct ata_drive_datas *drvp, struct ata_xfer *xfer) 147 1.2 bouyer { 148 1.72 thorpej struct ata_channel *chp = drvp->chnl_softc; 149 1.73 thorpej struct atac_softc *atac = chp->ch_atac; 150 1.106 jdolecek struct ata_bio *ata_bio = &xfer->c_bio; 151 1.2 bouyer 152 1.73 thorpej if (atac->atac_cap & ATAC_CAP_NOIRQ) 153 1.30 bjh21 ata_bio->flags |= ATA_POLL; 154 1.2 bouyer if (ata_bio->flags & ATA_POLL) 155 1.2 bouyer xfer->c_flags |= C_POLL; 156 1.85 itohy #if NATA_DMA 157 1.101 bouyer if ((drvp->drive_flags & (ATA_DRIVE_DMA | ATA_DRIVE_UDMA)) && 158 1.2 bouyer (ata_bio->flags & ATA_SINGLE) == 0) 159 1.2 bouyer xfer->c_flags |= C_DMA; 160 1.85 itohy #endif 161 1.85 itohy #if NATA_DMA && NATA_PIOBM 162 1.85 itohy else 163 1.85 itohy #endif 164 1.84 itohy #if NATA_PIOBM 165 1.85 itohy if (atac->atac_cap & ATAC_CAP_PIOBM) 166 1.84 itohy xfer->c_flags |= C_PIOBM; 167 1.84 itohy #endif 168 1.48 thorpej xfer->c_drive = drvp->drive; 169 1.48 thorpej xfer->c_databuf = ata_bio->databuf; 170 1.2 bouyer xfer->c_bcount = ata_bio->bcount; 171 1.112 jdolecek xfer->ops = &wdc_bio_xfer_ops; 172 1.68 thorpej ata_exec_xfer(chp, xfer); 173 1.2 bouyer } 174 1.2 bouyer 175 1.106 jdolecek static int 176 1.72 thorpej wdc_ata_bio_start(struct ata_channel *chp, struct ata_xfer *xfer) 177 1.2 bouyer { 178 1.73 thorpej struct atac_softc *atac = chp->ch_atac; 179 1.73 thorpej struct wdc_softc *wdc = CHAN_TO_WDC(chp); 180 1.72 thorpej struct wdc_regs *wdr = &wdc->regs[chp->ch_channel]; 181 1.106 jdolecek struct ata_bio *ata_bio = &xfer->c_bio; 182 1.48 thorpej struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive]; 183 1.106 jdolecek int wait_flags, tfd; 184 1.80 christos const char *errstring; 185 1.94 bouyer #ifdef WDC_NO_IDS 186 1.94 bouyer wait_flags = AT_POLL; 187 1.94 bouyer #else 188 1.95 christos wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0; 189 1.94 bouyer #endif 190 1.41 bouyer 191 1.101 bouyer ATADEBUG_PRINT(("wdc_ata_bio_start %s:%d:%d state %d drive_flags 0x%x " 192 1.101 bouyer "c_flags 0x%x ch_flags 0x%x\n", 193 1.101 bouyer device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive, 194 1.101 bouyer drvp->state, drvp->drive_flags, xfer->c_flags, chp->ch_flags), 195 1.20 bouyer DEBUG_XFERS); 196 1.20 bouyer 197 1.106 jdolecek ata_channel_lock_owned(chp); 198 1.106 jdolecek 199 1.41 bouyer /* Do control operations specially. */ 200 1.41 bouyer if (__predict_false(drvp->state < READY)) { 201 1.41 bouyer /* 202 1.41 bouyer * Actually, we want to be careful not to mess with the control 203 1.41 bouyer * state if the device is currently busy, but we can assume 204 1.41 bouyer * that we never get to this point if that's the case. 205 1.41 bouyer */ 206 1.81 peter /* If it's not a polled command, we need the kernel thread */ 207 1.114 jdolecek if ((xfer->c_flags & C_POLL) == 0 && !ata_is_thread_run(chp)) 208 1.106 jdolecek return ATASTART_TH; 209 1.114 jdolecek 210 1.41 bouyer /* 211 1.41 bouyer * disable interrupts, all commands here should be quick 212 1.93 snj * enough to be able to poll, and we don't go here that often 213 1.41 bouyer */ 214 1.102 rkujawa if (! (wdc->cap & WDC_CAPABILITY_NO_AUXCTL)) 215 1.102 rkujawa bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, 216 1.102 rkujawa wd_aux_ctlr, WDCTL_4BIT | WDCTL_IDS); 217 1.70 thorpej if (wdc->select) 218 1.51 thorpej wdc->select(chp, xfer->c_drive); 219 1.72 thorpej bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0, 220 1.48 thorpej WDSD_IBM | (xfer->c_drive << 4)); 221 1.53 fvdl DELAY(10); 222 1.41 bouyer errstring = "wait"; 223 1.106 jdolecek if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags, 224 1.106 jdolecek &tfd)) 225 1.41 bouyer goto ctrltimeout; 226 1.48 thorpej wdccommandshort(chp, xfer->c_drive, WDCC_RECAL); 227 1.41 bouyer /* Wait for at last 400ns for status bit to be valid */ 228 1.41 bouyer DELAY(1); 229 1.41 bouyer errstring = "recal"; 230 1.106 jdolecek if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags, 231 1.106 jdolecek &tfd)) 232 1.41 bouyer goto ctrltimeout; 233 1.106 jdolecek if (ATACH_ST(tfd) & (WDCS_ERR | WDCS_DWF)) 234 1.41 bouyer goto ctrlerror; 235 1.41 bouyer /* Don't try to set modes if controller can't be adjusted */ 236 1.73 thorpej if (atac->atac_set_modes == NULL) 237 1.41 bouyer goto geometry; 238 1.41 bouyer /* Also don't try if the drive didn't report its mode */ 239 1.101 bouyer if ((drvp->drive_flags & ATA_DRIVE_MODE) == 0) 240 1.41 bouyer goto geometry; 241 1.41 bouyer wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 242 1.41 bouyer 0x08 | drvp->PIO_mode, WDSF_SET_MODE); 243 1.41 bouyer errstring = "piomode"; 244 1.106 jdolecek if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags, 245 1.106 jdolecek &tfd)) 246 1.41 bouyer goto ctrltimeout; 247 1.106 jdolecek if (ATACH_ST(tfd) & (WDCS_ERR | WDCS_DWF)) 248 1.41 bouyer goto ctrlerror; 249 1.85 itohy #if NATA_DMA 250 1.85 itohy #if NATA_UDMA 251 1.101 bouyer if (drvp->drive_flags & ATA_DRIVE_UDMA) { 252 1.41 bouyer wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 253 1.41 bouyer 0x40 | drvp->UDMA_mode, WDSF_SET_MODE); 254 1.85 itohy } else 255 1.85 itohy #endif 256 1.101 bouyer if (drvp->drive_flags & ATA_DRIVE_DMA) { 257 1.41 bouyer wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 258 1.41 bouyer 0x20 | drvp->DMA_mode, WDSF_SET_MODE); 259 1.41 bouyer } else { 260 1.41 bouyer goto geometry; 261 1.79 perry } 262 1.41 bouyer errstring = "dmamode"; 263 1.106 jdolecek if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags, 264 1.106 jdolecek &tfd)) 265 1.41 bouyer goto ctrltimeout; 266 1.106 jdolecek if (ATACH_ST(tfd) & (WDCS_ERR | WDCS_DWF)) 267 1.41 bouyer goto ctrlerror; 268 1.85 itohy #endif /* NATA_DMA */ 269 1.41 bouyer geometry: 270 1.41 bouyer if (ata_bio->flags & ATA_LBA) 271 1.41 bouyer goto multimode; 272 1.48 thorpej wdccommand(chp, xfer->c_drive, WDCC_IDP, 273 1.106 jdolecek drvp->lp->d_ncylinders, 274 1.106 jdolecek drvp->lp->d_ntracks - 1, 0, drvp->lp->d_nsectors, 275 1.106 jdolecek (drvp->lp->d_type == DKTYPE_ST506) ? 276 1.106 jdolecek drvp->lp->d_precompcyl / 4 : 0); 277 1.41 bouyer errstring = "geometry"; 278 1.106 jdolecek if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags, 279 1.106 jdolecek &tfd)) 280 1.41 bouyer goto ctrltimeout; 281 1.106 jdolecek if (ATACH_ST(tfd) & (WDCS_ERR | WDCS_DWF)) 282 1.41 bouyer goto ctrlerror; 283 1.41 bouyer multimode: 284 1.106 jdolecek if (drvp->multi == 1) 285 1.41 bouyer goto ready; 286 1.48 thorpej wdccommand(chp, xfer->c_drive, WDCC_SETMULTI, 0, 0, 0, 287 1.106 jdolecek drvp->multi, 0); 288 1.41 bouyer errstring = "setmulti"; 289 1.106 jdolecek if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags, 290 1.106 jdolecek &tfd)) 291 1.41 bouyer goto ctrltimeout; 292 1.106 jdolecek if (ATACH_ST(tfd) & (WDCS_ERR | WDCS_DWF)) 293 1.41 bouyer goto ctrlerror; 294 1.41 bouyer ready: 295 1.41 bouyer drvp->state = READY; 296 1.41 bouyer /* 297 1.41 bouyer * The drive is usable now 298 1.41 bouyer */ 299 1.102 rkujawa if (! (wdc->cap & WDC_CAPABILITY_NO_AUXCTL)) 300 1.102 rkujawa bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, 301 1.102 rkujawa wd_aux_ctlr, WDCTL_4BIT); 302 1.54 bouyer delay(10); /* some drives need a little delay here */ 303 1.41 bouyer } 304 1.41 bouyer 305 1.106 jdolecek return _wdc_ata_bio_start(chp, xfer); 306 1.41 bouyer ctrltimeout: 307 1.41 bouyer printf("%s:%d:%d: %s timed out\n", 308 1.88 cube device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive, 309 1.51 thorpej errstring); 310 1.41 bouyer ata_bio->error = TIMEOUT; 311 1.41 bouyer goto ctrldone; 312 1.41 bouyer ctrlerror: 313 1.41 bouyer printf("%s:%d:%d: %s ", 314 1.88 cube device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive, 315 1.41 bouyer errstring); 316 1.106 jdolecek if (ATACH_ST(tfd) & WDCS_DWF) { 317 1.41 bouyer printf("drive fault\n"); 318 1.41 bouyer ata_bio->error = ERR_DF; 319 1.41 bouyer } else { 320 1.106 jdolecek ata_bio->r_error = ATACH_ERR(tfd); 321 1.41 bouyer ata_bio->error = ERROR; 322 1.106 jdolecek printf("error (%x)\n", ata_bio->r_error); 323 1.41 bouyer } 324 1.41 bouyer ctrldone: 325 1.41 bouyer drvp->state = 0; 326 1.102 rkujawa 327 1.102 rkujawa if (! (wdc->cap & WDC_CAPABILITY_NO_AUXCTL)) 328 1.102 rkujawa bus_space_write_1(wdr->ctl_iot, wdr->ctl_ioh, wd_aux_ctlr, 329 1.102 rkujawa WDCTL_4BIT); 330 1.106 jdolecek return ATASTART_ABORT; 331 1.20 bouyer } 332 1.20 bouyer 333 1.106 jdolecek static int 334 1.72 thorpej _wdc_ata_bio_start(struct ata_channel *chp, struct ata_xfer *xfer) 335 1.20 bouyer { 336 1.73 thorpej struct atac_softc *atac = chp->ch_atac; 337 1.73 thorpej struct wdc_softc *wdc = CHAN_TO_WDC(chp); 338 1.72 thorpej struct wdc_regs *wdr = &wdc->regs[chp->ch_channel]; 339 1.106 jdolecek struct ata_bio *ata_bio = &xfer->c_bio; 340 1.48 thorpej struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive]; 341 1.51 thorpej int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0; 342 1.104 matt uint16_t cyl; 343 1.104 matt uint8_t head, sect, cmd = 0; 344 1.106 jdolecek int nblks, tfd; 345 1.85 itohy #if NATA_DMA || NATA_PIOBM 346 1.85 itohy int error, dma_flags = 0; 347 1.85 itohy #endif 348 1.2 bouyer 349 1.71 thorpej ATADEBUG_PRINT(("_wdc_ata_bio_start %s:%d:%d\n", 350 1.88 cube device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive), 351 1.20 bouyer DEBUG_INTR | DEBUG_XFERS); 352 1.2 bouyer 353 1.85 itohy #if NATA_DMA || NATA_PIOBM 354 1.84 itohy if (xfer->c_flags & (C_DMA | C_PIOBM)) { 355 1.85 itohy #if NATA_DMA 356 1.23 bouyer if (drvp->n_xfers <= NXFER) 357 1.23 bouyer drvp->n_xfers++; 358 1.85 itohy #endif 359 1.2 bouyer dma_flags = (ata_bio->flags & ATA_READ) ? WDC_DMA_READ : 0; 360 1.39 nakayama if (ata_bio->flags & ATA_LBA48) 361 1.39 nakayama dma_flags |= WDC_DMA_LBA48; 362 1.2 bouyer } 363 1.85 itohy #endif 364 1.2 bouyer /* 365 1.2 bouyer * 366 1.2 bouyer * When starting a multi-sector transfer, or doing single-sector 367 1.2 bouyer * transfers... 368 1.2 bouyer */ 369 1.2 bouyer if (xfer->c_skip == 0 || (ata_bio->flags & ATA_SINGLE) != 0) { 370 1.2 bouyer if (ata_bio->flags & ATA_SINGLE) 371 1.2 bouyer nblks = 1; 372 1.79 perry else 373 1.106 jdolecek nblks = xfer->c_bcount / drvp->lp->d_secsize; 374 1.2 bouyer /* Check for bad sectors and adjust transfer, if necessary. */ 375 1.106 jdolecek if ((drvp->lp->d_flags & D_BADSECT) != 0) { 376 1.2 bouyer long blkdiff; 377 1.2 bouyer int i; 378 1.106 jdolecek for (i = 0; (blkdiff = drvp->badsect[i]) != -1; 379 1.2 bouyer i++) { 380 1.2 bouyer blkdiff -= ata_bio->blkno; 381 1.2 bouyer if (blkdiff < 0) 382 1.2 bouyer continue; 383 1.2 bouyer if (blkdiff == 0) { 384 1.2 bouyer /* Replace current block of transfer. */ 385 1.2 bouyer ata_bio->blkno = 386 1.106 jdolecek drvp->lp->d_secperunit - 387 1.106 jdolecek drvp->lp->d_nsectors - i - 1; 388 1.2 bouyer } 389 1.2 bouyer if (blkdiff < nblks) { 390 1.2 bouyer /* Bad block inside transfer. */ 391 1.2 bouyer ata_bio->flags |= ATA_SINGLE; 392 1.2 bouyer nblks = 1; 393 1.2 bouyer } 394 1.2 bouyer break; 395 1.2 bouyer } 396 1.2 bouyer /* Transfer is okay now. */ 397 1.2 bouyer } 398 1.34 christos if (ata_bio->flags & ATA_LBA48) { 399 1.34 christos sect = 0; 400 1.34 christos cyl = 0; 401 1.34 christos head = 0; 402 1.34 christos } else if (ata_bio->flags & ATA_LBA) { 403 1.2 bouyer sect = (ata_bio->blkno >> 0) & 0xff; 404 1.2 bouyer cyl = (ata_bio->blkno >> 8) & 0xffff; 405 1.2 bouyer head = (ata_bio->blkno >> 24) & 0x0f; 406 1.2 bouyer head |= WDSD_LBA; 407 1.2 bouyer } else { 408 1.2 bouyer int blkno = ata_bio->blkno; 409 1.106 jdolecek sect = blkno % drvp->lp->d_nsectors; 410 1.2 bouyer sect++; /* Sectors begin with 1, not 0. */ 411 1.106 jdolecek blkno /= drvp->lp->d_nsectors; 412 1.106 jdolecek head = blkno % drvp->lp->d_ntracks; 413 1.106 jdolecek blkno /= drvp->lp->d_ntracks; 414 1.2 bouyer cyl = blkno; 415 1.2 bouyer head |= WDSD_CHS; 416 1.2 bouyer } 417 1.85 itohy #if NATA_DMA 418 1.2 bouyer if (xfer->c_flags & C_DMA) { 419 1.106 jdolecek uint16_t count = nblks, features = 0; 420 1.106 jdolecek 421 1.2 bouyer ata_bio->nblks = nblks; 422 1.2 bouyer ata_bio->nbytes = xfer->c_bcount; 423 1.2 bouyer cmd = (ata_bio->flags & ATA_READ) ? 424 1.2 bouyer WDCC_READDMA : WDCC_WRITEDMA; 425 1.2 bouyer /* Init the DMA channel. */ 426 1.82 thorpej error = (*wdc->dma_init)(wdc->dma_arg, 427 1.51 thorpej chp->ch_channel, xfer->c_drive, 428 1.79 perry (char *)xfer->c_databuf + xfer->c_skip, 429 1.82 thorpej ata_bio->nbytes, dma_flags); 430 1.82 thorpej if (error) { 431 1.82 thorpej if (error == EINVAL) { 432 1.82 thorpej /* 433 1.82 thorpej * We can't do DMA on this transfer 434 1.82 thorpej * for some reason. Fall back to 435 1.82 thorpej * PIO. 436 1.82 thorpej */ 437 1.82 thorpej xfer->c_flags &= ~C_DMA; 438 1.82 thorpej error = 0; 439 1.82 thorpej goto do_pio; 440 1.82 thorpej } 441 1.2 bouyer ata_bio->error = ERR_DMA; 442 1.2 bouyer ata_bio->r_error = 0; 443 1.106 jdolecek return ATASTART_ABORT; 444 1.2 bouyer } 445 1.2 bouyer /* Initiate command */ 446 1.70 thorpej if (wdc->select) 447 1.51 thorpej wdc->select(chp, xfer->c_drive); 448 1.72 thorpej bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 449 1.48 thorpej 0, WDSD_IBM | (xfer->c_drive << 4)); 450 1.106 jdolecek switch(wdc_wait_for_ready(chp, ATA_DELAY, wait_flags, 451 1.106 jdolecek &tfd)) { 452 1.41 bouyer case WDCWAIT_OK: 453 1.79 perry break; 454 1.41 bouyer case WDCWAIT_TOUT: 455 1.2 bouyer goto timeout; 456 1.41 bouyer case WDCWAIT_THR: 457 1.106 jdolecek return ATASTART_TH; 458 1.41 bouyer } 459 1.110 macallan /* start the DMA channel before */ 460 1.110 macallan if ((chp->ch_flags & ATACH_DMA_BEFORE_CMD) != 0) 461 1.110 macallan (*wdc->dma_start)(wdc->dma_arg, 462 1.110 macallan chp->ch_channel, xfer->c_drive); 463 1.34 christos if (ata_bio->flags & ATA_LBA48) { 464 1.106 jdolecek uint8_t device = WDSD_LBA; 465 1.106 jdolecek cmd = atacmd_to48(cmd); 466 1.106 jdolecek 467 1.106 jdolecek atacmd_toncq(xfer, &cmd, &count, &features, 468 1.106 jdolecek &device); 469 1.106 jdolecek 470 1.106 jdolecek wdccommandext(chp, xfer->c_drive, cmd, 471 1.106 jdolecek ata_bio->blkno, count, features, device); 472 1.34 christos } else { 473 1.48 thorpej wdccommand(chp, xfer->c_drive, cmd, cyl, 474 1.106 jdolecek head, sect, count, features); 475 1.34 christos } 476 1.110 macallan /* start the DMA channel after */ 477 1.110 macallan if ((chp->ch_flags & ATACH_DMA_BEFORE_CMD) == 0) 478 1.110 macallan (*wdc->dma_start)(wdc->dma_arg, 479 1.110 macallan chp->ch_channel, xfer->c_drive); 480 1.72 thorpej chp->ch_flags |= ATACH_DMA_WAIT; 481 1.2 bouyer /* wait for irq */ 482 1.2 bouyer goto intr; 483 1.2 bouyer } /* else not DMA */ 484 1.82 thorpej do_pio: 485 1.85 itohy #endif /* NATA_DMA */ 486 1.84 itohy #if NATA_PIOBM 487 1.84 itohy if ((xfer->c_flags & C_PIOBM) && xfer->c_skip == 0) { 488 1.84 itohy if (ata_bio->flags & ATA_POLL) { 489 1.84 itohy /* XXX not supported yet --- fall back to PIO */ 490 1.84 itohy xfer->c_flags &= ~C_PIOBM; 491 1.84 itohy } else { 492 1.84 itohy /* Init the DMA channel. */ 493 1.84 itohy error = (*wdc->dma_init)(wdc->dma_arg, 494 1.84 itohy chp->ch_channel, xfer->c_drive, 495 1.84 itohy (char *)xfer->c_databuf + xfer->c_skip, 496 1.84 itohy xfer->c_bcount, 497 1.84 itohy dma_flags | WDC_DMA_PIOBM_ATA); 498 1.84 itohy if (error) { 499 1.84 itohy if (error == EINVAL) { 500 1.84 itohy /* 501 1.84 itohy * We can't do DMA on this 502 1.84 itohy * transfer for some reason. 503 1.84 itohy * Fall back to PIO. 504 1.84 itohy */ 505 1.84 itohy xfer->c_flags &= ~C_PIOBM; 506 1.84 itohy error = 0; 507 1.84 itohy } else { 508 1.84 itohy ata_bio->error = ERR_DMA; 509 1.84 itohy ata_bio->r_error = 0; 510 1.106 jdolecek return ATASTART_ABORT; 511 1.84 itohy } 512 1.84 itohy } 513 1.84 itohy } 514 1.84 itohy } 515 1.84 itohy #endif 516 1.111 riastrad ata_bio->nblks = uimin(nblks, drvp->multi); 517 1.106 jdolecek ata_bio->nbytes = ata_bio->nblks * drvp->lp->d_secsize; 518 1.56 mycroft KASSERT(nblks == 1 || (ata_bio->flags & ATA_SINGLE) == 0); 519 1.56 mycroft if (ata_bio->nblks > 1) { 520 1.2 bouyer cmd = (ata_bio->flags & ATA_READ) ? 521 1.2 bouyer WDCC_READMULTI : WDCC_WRITEMULTI; 522 1.2 bouyer } else { 523 1.2 bouyer cmd = (ata_bio->flags & ATA_READ) ? 524 1.2 bouyer WDCC_READ : WDCC_WRITE; 525 1.2 bouyer } 526 1.2 bouyer /* Initiate command! */ 527 1.70 thorpej if (wdc->select) 528 1.51 thorpej wdc->select(chp, xfer->c_drive); 529 1.72 thorpej bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0, 530 1.48 thorpej WDSD_IBM | (xfer->c_drive << 4)); 531 1.106 jdolecek switch(wdc_wait_for_ready(chp, ATA_DELAY, wait_flags, &tfd)) { 532 1.41 bouyer case WDCWAIT_OK: 533 1.41 bouyer break; 534 1.41 bouyer case WDCWAIT_TOUT: 535 1.2 bouyer goto timeout; 536 1.41 bouyer case WDCWAIT_THR: 537 1.106 jdolecek return ATASTART_TH; 538 1.41 bouyer } 539 1.34 christos if (ata_bio->flags & ATA_LBA48) { 540 1.75 thorpej wdccommandext(chp, xfer->c_drive, atacmd_to48(cmd), 541 1.103 jakllsch ata_bio->blkno, nblks, 0, WDSD_LBA); 542 1.34 christos } else { 543 1.48 thorpej wdccommand(chp, xfer->c_drive, cmd, cyl, 544 1.34 christos head, sect, nblks, 545 1.106 jdolecek (drvp->lp->d_type == DKTYPE_ST506) ? 546 1.106 jdolecek drvp->lp->d_precompcyl / 4 : 0); 547 1.34 christos } 548 1.2 bouyer } else if (ata_bio->nblks > 1) { 549 1.2 bouyer /* The number of blocks in the last stretch may be smaller. */ 550 1.106 jdolecek nblks = xfer->c_bcount / drvp->lp->d_secsize; 551 1.2 bouyer if (ata_bio->nblks > nblks) { 552 1.116 jdolecek ata_bio->nblks = nblks; 553 1.116 jdolecek ata_bio->nbytes = xfer->c_bcount; 554 1.2 bouyer } 555 1.2 bouyer } 556 1.2 bouyer /* If this was a write and not using DMA, push the data. */ 557 1.2 bouyer if ((ata_bio->flags & ATA_READ) == 0) { 558 1.41 bouyer /* 559 1.41 bouyer * we have to busy-wait here, we can't rely on running in 560 1.41 bouyer * thread context. 561 1.41 bouyer */ 562 1.106 jdolecek if (wdc_wait_for_drq(chp, ATA_DELAY, AT_POLL, &tfd) != 0) { 563 1.2 bouyer printf("%s:%d:%d: timeout waiting for DRQ, " 564 1.2 bouyer "st=0x%02x, err=0x%02x\n", 565 1.88 cube device_xname(atac->atac_dev), chp->ch_channel, 566 1.106 jdolecek xfer->c_drive, 567 1.106 jdolecek ATACH_ST(tfd), ATACH_ERR(tfd)); 568 1.106 jdolecek if (wdc_ata_err(drvp, ata_bio, tfd) != WDC_ATA_ERR) 569 1.2 bouyer ata_bio->error = TIMEOUT; 570 1.106 jdolecek return ATASTART_ABORT; 571 1.2 bouyer } 572 1.106 jdolecek if (wdc_ata_err(drvp, ata_bio, tfd) == WDC_ATA_ERR) { 573 1.106 jdolecek return ATASTART_ABORT; 574 1.2 bouyer } 575 1.84 itohy #if NATA_PIOBM 576 1.84 itohy if (xfer->c_flags & C_PIOBM) { 577 1.84 itohy /* start the busmastering PIO */ 578 1.84 itohy (*wdc->piobm_start)(wdc->dma_arg, 579 1.84 itohy chp->ch_channel, xfer->c_drive, 580 1.84 itohy xfer->c_skip, ata_bio->nbytes, 0); 581 1.84 itohy chp->ch_flags |= ATACH_DMA_WAIT; 582 1.84 itohy } else 583 1.84 itohy #endif 584 1.84 itohy 585 1.63 mycroft wdc->dataout_pio(chp, drvp->drive_flags, 586 1.62 mycroft (char *)xfer->c_databuf + xfer->c_skip, ata_bio->nbytes); 587 1.2 bouyer } 588 1.2 bouyer 589 1.85 itohy #if NATA_DMA 590 1.85 itohy intr: 591 1.85 itohy #endif 592 1.85 itohy /* Wait for IRQ (either real or polled) */ 593 1.117 jdolecek if ((xfer->c_flags & C_POLL) == 0) { 594 1.117 jdolecek /* start timeout machinery */ 595 1.117 jdolecek callout_reset(&chp->c_timo_callout, 596 1.117 jdolecek ATA_DELAY / 1000 * hz, wdctimeout, chp); 597 1.109 jdolecek chp->ch_flags |= ATACH_IRQ_WAIT; 598 1.109 jdolecek return ATASTART_STARTED; 599 1.109 jdolecek } else { 600 1.109 jdolecek return ATASTART_POLL; 601 1.109 jdolecek } 602 1.106 jdolecek 603 1.2 bouyer timeout: 604 1.2 bouyer printf("%s:%d:%d: not ready, st=0x%02x, err=0x%02x\n", 605 1.88 cube device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive, 606 1.106 jdolecek ATACH_ST(tfd), ATACH_ERR(tfd)); 607 1.106 jdolecek if (wdc_ata_err(drvp, ata_bio, tfd) != WDC_ATA_ERR) 608 1.2 bouyer ata_bio->error = TIMEOUT; 609 1.106 jdolecek return ATASTART_ABORT; 610 1.106 jdolecek } 611 1.106 jdolecek 612 1.120 rin static int 613 1.106 jdolecek wdc_ata_bio_poll(struct ata_channel *chp, struct ata_xfer *xfer) 614 1.106 jdolecek { 615 1.106 jdolecek /* Wait for at last 400ns for status bit to be valid */ 616 1.106 jdolecek delay(1); 617 1.106 jdolecek #if NATA_DMA 618 1.106 jdolecek if (chp->ch_flags & ATACH_DMA_WAIT) { 619 1.106 jdolecek wdc_dmawait(chp, xfer, ATA_DELAY); 620 1.106 jdolecek chp->ch_flags &= ~ATACH_DMA_WAIT; 621 1.106 jdolecek } 622 1.106 jdolecek #endif 623 1.106 jdolecek wdc_ata_bio_intr(chp, xfer, 0); 624 1.120 rin return (xfer->c_bio.flags & ATA_ITSDONE) ? ATAPOLL_DONE : ATAPOLL_AGAIN; 625 1.2 bouyer } 626 1.2 bouyer 627 1.45 thorpej static int 628 1.108 jdolecek wdc_ata_bio_intr(struct ata_channel *chp, struct ata_xfer *xfer, int irq) 629 1.2 bouyer { 630 1.73 thorpej struct atac_softc *atac = chp->ch_atac; 631 1.73 thorpej struct wdc_softc *wdc = CHAN_TO_WDC(chp); 632 1.106 jdolecek struct ata_bio *ata_bio = &xfer->c_bio; 633 1.48 thorpej struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive]; 634 1.106 jdolecek int drv_err, tfd; 635 1.2 bouyer 636 1.71 thorpej ATADEBUG_PRINT(("wdc_ata_bio_intr %s:%d:%d\n", 637 1.88 cube device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive), 638 1.2 bouyer DEBUG_INTR | DEBUG_XFERS); 639 1.2 bouyer 640 1.106 jdolecek ata_channel_lock(chp); 641 1.2 bouyer 642 1.2 bouyer /* Is it not a transfer, but a control operation? */ 643 1.2 bouyer if (drvp->state < READY) { 644 1.2 bouyer printf("%s:%d:%d: bad state %d in wdc_ata_bio_intr\n", 645 1.88 cube device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive, 646 1.2 bouyer drvp->state); 647 1.38 provos panic("wdc_ata_bio_intr: bad state"); 648 1.2 bouyer } 649 1.2 bouyer 650 1.20 bouyer /* 651 1.20 bouyer * if we missed an interrupt in a PIO transfer, reset and restart. 652 1.20 bouyer * Don't try to continue transfer, we may have missed cycles. 653 1.20 bouyer */ 654 1.20 bouyer if ((xfer->c_flags & (C_TIMEOU | C_DMA)) == C_TIMEOU) { 655 1.20 bouyer ata_bio->error = TIMEOUT; 656 1.107 christos goto err; 657 1.20 bouyer } 658 1.20 bouyer 659 1.84 itohy #if NATA_PIOBM 660 1.84 itohy /* Transfer-done interrupt for busmastering PIO read */ 661 1.84 itohy if ((xfer->c_flags & C_PIOBM) && (chp->ch_flags & ATACH_PIOBM_WAIT)) { 662 1.84 itohy chp->ch_flags &= ~ATACH_PIOBM_WAIT; 663 1.84 itohy goto end; 664 1.84 itohy } 665 1.84 itohy #endif 666 1.84 itohy 667 1.49 thorpej /* Ack interrupt done by wdc_wait_for_unbusy */ 668 1.108 jdolecek if (wdc_wait_for_unbusy(chp, 669 1.108 jdolecek (irq == 0) ? ATA_DELAY : 0, AT_POLL, &tfd) < 0) { 670 1.108 jdolecek if (irq && (xfer->c_flags & C_TIMEOU) == 0) { 671 1.106 jdolecek ata_channel_unlock(chp); 672 1.18 bouyer return 0; /* IRQ was not for us */ 673 1.106 jdolecek } 674 1.2 bouyer printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip%d\n", 675 1.107 christos device_xname(atac->atac_dev), chp->ch_channel, 676 1.107 christos xfer->c_drive, xfer->c_bcount, xfer->c_skip); 677 1.2 bouyer ata_bio->error = TIMEOUT; 678 1.107 christos goto err; 679 1.2 bouyer } 680 1.70 thorpej if (wdc->irqack) 681 1.51 thorpej wdc->irqack(chp); 682 1.79 perry 683 1.106 jdolecek drv_err = wdc_ata_err(drvp, ata_bio, tfd); 684 1.2 bouyer 685 1.85 itohy #if NATA_DMA 686 1.2 bouyer /* If we were using DMA, Turn off the DMA channel and check for error */ 687 1.2 bouyer if (xfer->c_flags & C_DMA) { 688 1.2 bouyer if (ata_bio->flags & ATA_POLL) { 689 1.2 bouyer /* 690 1.13 bouyer * IDE drives deassert WDCS_BSY before transfer is 691 1.2 bouyer * complete when using DMA. Polling for DRQ to deassert 692 1.37 wiz * is not enough DRQ is not required to be 693 1.7 bouyer * asserted for DMA transfers, so poll for DRDY. 694 1.2 bouyer */ 695 1.2 bouyer if (wdcwait(chp, WDCS_DRDY | WDCS_DRQ, WDCS_DRDY, 696 1.106 jdolecek ATA_DELAY, ATA_POLL, &tfd) == WDCWAIT_TOUT) { 697 1.7 bouyer printf("%s:%d:%d: polled transfer timed out " 698 1.88 cube "(st=0x%x)\n", 699 1.88 cube device_xname(atac->atac_dev), 700 1.51 thorpej chp->ch_channel, xfer->c_drive, 701 1.106 jdolecek ATACH_ST(tfd)); 702 1.2 bouyer ata_bio->error = TIMEOUT; 703 1.10 bouyer drv_err = WDC_ATA_ERR; 704 1.10 bouyer } 705 1.10 bouyer } 706 1.51 thorpej if (wdc->dma_status != 0) { 707 1.10 bouyer if (drv_err != WDC_ATA_ERR) { 708 1.10 bouyer ata_bio->error = ERR_DMA; 709 1.10 bouyer drv_err = WDC_ATA_ERR; 710 1.2 bouyer } 711 1.2 bouyer } 712 1.106 jdolecek if (ATACH_ST(tfd) & WDCS_DRQ) { 713 1.2 bouyer if (drv_err != WDC_ATA_ERR) { 714 1.2 bouyer printf("%s:%d:%d: intr with DRQ (st=0x%x)\n", 715 1.88 cube device_xname(atac->atac_dev), 716 1.88 cube chp->ch_channel, 717 1.106 jdolecek xfer->c_drive, ATACH_ST(tfd)); 718 1.2 bouyer ata_bio->error = TIMEOUT; 719 1.2 bouyer drv_err = WDC_ATA_ERR; 720 1.2 bouyer } 721 1.2 bouyer } 722 1.77 bouyer if (drv_err != WDC_ATA_ERR) 723 1.77 bouyer goto end; 724 1.106 jdolecek if (ata_bio->r_error & WDCE_CRC || ata_bio->error == ERR_DMA) { 725 1.107 christos ata_dmaerr(drvp, 726 1.107 christos (xfer->c_flags & C_POLL) ? AT_POLL : 0); 727 1.106 jdolecek goto err; 728 1.106 jdolecek } 729 1.2 bouyer } 730 1.85 itohy #endif /* NATA_DMA */ 731 1.2 bouyer 732 1.2 bouyer /* if we had an error, end */ 733 1.107 christos if (drv_err == WDC_ATA_ERR) 734 1.107 christos goto err; 735 1.2 bouyer 736 1.2 bouyer /* If this was a read and not using DMA, fetch the data. */ 737 1.2 bouyer if ((ata_bio->flags & ATA_READ) != 0) { 738 1.106 jdolecek if ((ATACH_ST(tfd) & WDCS_DRQ) != WDCS_DRQ) { 739 1.2 bouyer printf("%s:%d:%d: read intr before drq\n", 740 1.88 cube device_xname(atac->atac_dev), chp->ch_channel, 741 1.48 thorpej xfer->c_drive); 742 1.2 bouyer ata_bio->error = TIMEOUT; 743 1.107 christos goto err; 744 1.2 bouyer } 745 1.84 itohy #if NATA_PIOBM 746 1.84 itohy if (xfer->c_flags & C_PIOBM) { 747 1.84 itohy /* start the busmastering PIO */ 748 1.84 itohy (*wdc->piobm_start)(wdc->dma_arg, 749 1.84 itohy chp->ch_channel, xfer->c_drive, 750 1.84 itohy xfer->c_skip, ata_bio->nbytes, 751 1.84 itohy WDC_PIOBM_XFER_IRQ); 752 1.106 jdolecek chp->ch_flags |= ATACH_DMA_WAIT | ATACH_PIOBM_WAIT; 753 1.106 jdolecek ata_channel_unlock(chp); 754 1.84 itohy return 1; 755 1.107 christos } 756 1.84 itohy #endif 757 1.63 mycroft wdc->datain_pio(chp, drvp->drive_flags, 758 1.62 mycroft (char *)xfer->c_databuf + xfer->c_skip, ata_bio->nbytes); 759 1.2 bouyer } 760 1.2 bouyer 761 1.85 itohy #if NATA_DMA || NATA_PIOBM 762 1.2 bouyer end: 763 1.85 itohy #endif 764 1.2 bouyer ata_bio->blkno += ata_bio->nblks; 765 1.2 bouyer ata_bio->blkdone += ata_bio->nblks; 766 1.2 bouyer xfer->c_skip += ata_bio->nbytes; 767 1.2 bouyer xfer->c_bcount -= ata_bio->nbytes; 768 1.106 jdolecek 769 1.2 bouyer /* See if this transfer is complete. */ 770 1.2 bouyer if (xfer->c_bcount > 0) { 771 1.2 bouyer if ((ata_bio->flags & ATA_POLL) == 0) { 772 1.2 bouyer /* Start the next operation */ 773 1.118 jdolecek KASSERT((chp->ch_flags & ATACH_IRQ_WAIT) == 0); 774 1.118 jdolecek callout_stop(&chp->c_timo_callout); 775 1.106 jdolecek ata_xfer_start(xfer); 776 1.2 bouyer } else { 777 1.120 rin /* 778 1.120 rin * Let ata_xfer_start() do the loop; 779 1.120 rin * see wdc_ata_bio_poll(). 780 1.120 rin */ 781 1.2 bouyer } 782 1.106 jdolecek ata_channel_unlock(chp); 783 1.107 christos return 1; 784 1.2 bouyer } 785 1.107 christos 786 1.107 christos /* Done with this transfer */ 787 1.107 christos ata_bio->error = NOERROR; 788 1.107 christos err: ata_channel_unlock(chp); 789 1.107 christos wdc_ata_bio_done(chp, xfer); 790 1.2 bouyer return 1; 791 1.22 enami } 792 1.22 enami 793 1.45 thorpej static void 794 1.72 thorpej wdc_ata_bio_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, 795 1.58 bouyer int reason) 796 1.22 enami { 797 1.106 jdolecek struct ata_bio *ata_bio = &xfer->c_bio; 798 1.48 thorpej int drive = xfer->c_drive; 799 1.106 jdolecek bool deactivate = true; 800 1.22 enami 801 1.22 enami ata_bio->flags |= ATA_ITSDONE; 802 1.58 bouyer switch (reason) { 803 1.106 jdolecek case KILL_GONE_INACTIVE: 804 1.106 jdolecek deactivate = false; 805 1.106 jdolecek /* FALLTHROUGH */ 806 1.58 bouyer case KILL_GONE: 807 1.58 bouyer ata_bio->error = ERR_NODEV; 808 1.58 bouyer break; 809 1.58 bouyer case KILL_RESET: 810 1.58 bouyer ata_bio->error = ERR_RESET; 811 1.58 bouyer break; 812 1.58 bouyer default: 813 1.58 bouyer printf("wdc_ata_bio_kill_xfer: unknown reason %d\n", 814 1.58 bouyer reason); 815 1.58 bouyer panic("wdc_ata_bio_kill_xfer"); 816 1.58 bouyer } 817 1.22 enami ata_bio->r_error = WDCE_ABRT; 818 1.106 jdolecek 819 1.106 jdolecek if (deactivate) 820 1.106 jdolecek ata_deactivate_xfer(chp, xfer); 821 1.106 jdolecek 822 1.101 bouyer ATADEBUG_PRINT(("wdc_ata_bio_kill_xfer: drv_done\n"), DEBUG_XFERS); 823 1.106 jdolecek (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc, xfer); 824 1.2 bouyer } 825 1.2 bouyer 826 1.45 thorpej static void 827 1.72 thorpej wdc_ata_bio_done(struct ata_channel *chp, struct ata_xfer *xfer) 828 1.2 bouyer { 829 1.106 jdolecek struct ata_bio *ata_bio = &xfer->c_bio; 830 1.48 thorpej int drive = xfer->c_drive; 831 1.2 bouyer 832 1.71 thorpej ATADEBUG_PRINT(("wdc_ata_bio_done %s:%d:%d: flags 0x%x\n", 833 1.88 cube device_xname(chp->ch_atac->atac_dev), chp->ch_channel, 834 1.88 cube xfer->c_drive, (u_int)xfer->c_flags), 835 1.4 bouyer DEBUG_XFERS); 836 1.10 bouyer 837 1.106 jdolecek if (ata_waitdrain_xfer_check(chp, xfer)) 838 1.106 jdolecek return; 839 1.2 bouyer 840 1.2 bouyer /* feed back residual bcount to our caller */ 841 1.2 bouyer ata_bio->bcount = xfer->c_bcount; 842 1.2 bouyer 843 1.60 bouyer /* mark controller inactive and free xfer */ 844 1.106 jdolecek ata_deactivate_xfer(chp, xfer); 845 1.2 bouyer 846 1.2 bouyer ata_bio->flags |= ATA_ITSDONE; 847 1.71 thorpej ATADEBUG_PRINT(("wdc_ata_done: drv_done\n"), DEBUG_XFERS); 848 1.106 jdolecek (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc, xfer); 849 1.71 thorpej ATADEBUG_PRINT(("atastart from wdc_ata_done, flags 0x%x\n", 850 1.4 bouyer chp->ch_flags), DEBUG_XFERS); 851 1.69 thorpej atastart(chp); 852 1.2 bouyer } 853 1.2 bouyer 854 1.45 thorpej static int 855 1.106 jdolecek wdc_ata_err(struct ata_drive_datas *drvp, struct ata_bio *ata_bio, int tfd) 856 1.2 bouyer { 857 1.2 bouyer ata_bio->error = 0; 858 1.106 jdolecek if (ATACH_ST(tfd) & WDCS_BSY) { 859 1.2 bouyer ata_bio->error = TIMEOUT; 860 1.2 bouyer return WDC_ATA_ERR; 861 1.2 bouyer } 862 1.2 bouyer 863 1.106 jdolecek if (ATACH_ST(tfd) & WDCS_DWF) { 864 1.2 bouyer ata_bio->error = ERR_DF; 865 1.2 bouyer return WDC_ATA_ERR; 866 1.2 bouyer } 867 1.2 bouyer 868 1.106 jdolecek if (ATACH_ST(tfd) & WDCS_ERR) { 869 1.2 bouyer ata_bio->error = ERROR; 870 1.106 jdolecek ata_bio->r_error = ATACH_ERR(tfd); 871 1.2 bouyer if (ata_bio->r_error & (WDCE_BBK | WDCE_UNC | WDCE_IDNF | 872 1.2 bouyer WDCE_ABRT | WDCE_TK0NF | WDCE_AMNF)) 873 1.2 bouyer return WDC_ATA_ERR; 874 1.2 bouyer return WDC_ATA_NOERR; 875 1.2 bouyer } 876 1.2 bouyer 877 1.106 jdolecek if (ATACH_ST(tfd) & WDCS_CORR) 878 1.2 bouyer ata_bio->flags |= ATA_CORR; 879 1.2 bouyer return WDC_ATA_NOERR; 880 1.8 thorpej } 881 1.8 thorpej 882 1.45 thorpej static int 883 1.44 thorpej wdc_ata_addref(struct ata_drive_datas *drvp) 884 1.8 thorpej { 885 1.72 thorpej struct ata_channel *chp = drvp->chnl_softc; 886 1.8 thorpej 887 1.67 thorpej return (ata_addref(chp)); 888 1.8 thorpej } 889 1.8 thorpej 890 1.45 thorpej static void 891 1.44 thorpej wdc_ata_delref(struct ata_drive_datas *drvp) 892 1.8 thorpej { 893 1.72 thorpej struct ata_channel *chp = drvp->chnl_softc; 894 1.8 thorpej 895 1.67 thorpej ata_delref(chp); 896 1.2 bouyer } 897