| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: siisata.c,v 1.30.4.14 2017/04/24 21:19:21 jakllsch Exp $ */ | | 1 | /* $NetBSD: siisata.c,v 1.30.4.15 2017/06/13 00:02:19 jakllsch Exp $ */ |
2 | | | 2 | |
3 | /* from ahcisata_core.c */ | | 3 | /* from ahcisata_core.c */ |
4 | | | 4 | |
5 | /* | | 5 | /* |
6 | * Copyright (c) 2006 Manuel Bouyer. | | 6 | * Copyright (c) 2006 Manuel Bouyer. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -69,27 +69,27 @@ | | | @@ -69,27 +69,27 @@ |
69 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 69 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
70 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 70 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
71 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 71 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
72 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 72 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
73 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 73 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
74 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 74 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
75 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 75 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
76 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 76 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
77 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 77 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
78 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 78 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
79 | */ | | 79 | */ |
80 | | | 80 | |
81 | #include <sys/cdefs.h> | | 81 | #include <sys/cdefs.h> |
82 | __KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.14 2017/04/24 21:19:21 jakllsch Exp $"); | | 82 | __KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.15 2017/06/13 00:02:19 jakllsch Exp $"); |
83 | | | 83 | |
84 | #include <sys/types.h> | | 84 | #include <sys/types.h> |
85 | #include <sys/param.h> | | 85 | #include <sys/param.h> |
86 | #include <sys/kernel.h> | | 86 | #include <sys/kernel.h> |
87 | #include <sys/malloc.h> | | 87 | #include <sys/malloc.h> |
88 | #include <sys/systm.h> | | 88 | #include <sys/systm.h> |
89 | #include <sys/syslog.h> | | 89 | #include <sys/syslog.h> |
90 | #include <sys/disklabel.h> | | 90 | #include <sys/disklabel.h> |
91 | #include <sys/buf.h> | | 91 | #include <sys/buf.h> |
92 | #include <sys/proc.h> | | 92 | #include <sys/proc.h> |
93 | | | 93 | |
94 | #include <dev/ata/atareg.h> | | 94 | #include <dev/ata/atareg.h> |
95 | #include <dev/ata/satavar.h> | | 95 | #include <dev/ata/satavar.h> |
| @@ -138,27 +138,27 @@ static void siisata_intr_port(struct sii | | | @@ -138,27 +138,27 @@ static void siisata_intr_port(struct sii |
138 | | | 138 | |
139 | void siisata_probe_drive(struct ata_channel *); | | 139 | void siisata_probe_drive(struct ata_channel *); |
140 | void siisata_setup_channel(struct ata_channel *); | | 140 | void siisata_setup_channel(struct ata_channel *); |
141 | | | 141 | |
142 | int siisata_ata_bio(struct ata_drive_datas *, struct ata_xfer *); | | 142 | int siisata_ata_bio(struct ata_drive_datas *, struct ata_xfer *); |
143 | void siisata_reset_drive(struct ata_drive_datas *, int, uint32_t *); | | 143 | void siisata_reset_drive(struct ata_drive_datas *, int, uint32_t *); |
144 | void siisata_reset_channel(struct ata_channel *, int); | | 144 | void siisata_reset_channel(struct ata_channel *, int); |
145 | int siisata_ata_addref(struct ata_drive_datas *); | | 145 | int siisata_ata_addref(struct ata_drive_datas *); |
146 | void siisata_ata_delref(struct ata_drive_datas *); | | 146 | void siisata_ata_delref(struct ata_drive_datas *); |
147 | void siisata_killpending(struct ata_drive_datas *); | | 147 | void siisata_killpending(struct ata_drive_datas *); |
148 | | | 148 | |
149 | void siisata_cmd_start(struct ata_channel *, struct ata_xfer *); | | 149 | void siisata_cmd_start(struct ata_channel *, struct ata_xfer *); |
150 | int siisata_cmd_complete(struct ata_channel *, struct ata_xfer *, int); | | 150 | int siisata_cmd_complete(struct ata_channel *, struct ata_xfer *, int); |
151 | void siisata_cmd_done(struct ata_channel *, struct ata_xfer *, int); | | 151 | void siisata_cmd_done(struct ata_channel *, struct ata_xfer *); |
152 | void siisata_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int); | | 152 | void siisata_cmd_kill_xfer(struct ata_channel *, struct ata_xfer *, int); |
153 | | | 153 | |
154 | void siisata_bio_start(struct ata_channel *, struct ata_xfer *); | | 154 | void siisata_bio_start(struct ata_channel *, struct ata_xfer *); |
155 | int siisata_bio_complete(struct ata_channel *, struct ata_xfer *, int); | | 155 | int siisata_bio_complete(struct ata_channel *, struct ata_xfer *, int); |
156 | void siisata_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int); | | 156 | void siisata_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int); |
157 | int siisata_exec_command(struct ata_drive_datas *, struct ata_xfer *); | | 157 | int siisata_exec_command(struct ata_drive_datas *, struct ata_xfer *); |
158 | | | 158 | |
159 | void siisata_timeout(void *); | | 159 | void siisata_timeout(void *); |
160 | | | 160 | |
161 | static void siisata_reinit_port(struct ata_channel *); | | 161 | static void siisata_reinit_port(struct ata_channel *); |
162 | static void siisata_device_reset(struct ata_channel *); | | 162 | static void siisata_device_reset(struct ata_channel *); |
163 | static void siisata_activate_prb(struct siisata_channel *, int); | | 163 | static void siisata_activate_prb(struct siisata_channel *, int); |
164 | static void siisata_deactivate_prb(struct siisata_channel *, int); | | 164 | static void siisata_deactivate_prb(struct siisata_channel *, int); |
| @@ -199,27 +199,27 @@ static const struct scsipi_bustype siisa | | | @@ -199,27 +199,27 @@ static const struct scsipi_bustype siisa |
199 | NULL, | | 199 | NULL, |
200 | }; | | 200 | }; |
201 | #endif /* NATAPIBUS */ | | 201 | #endif /* NATAPIBUS */ |
202 | | | 202 | |
203 | | | 203 | |
204 | void | | 204 | void |
205 | siisata_attach(struct siisata_softc *sc) | | 205 | siisata_attach(struct siisata_softc *sc) |
206 | { | | 206 | { |
207 | int i; | | 207 | int i; |
208 | | | 208 | |
209 | SIISATA_DEBUG_PRINT(("%s: %s: GR_GC: 0x%08x\n", | | 209 | SIISATA_DEBUG_PRINT(("%s: %s: GR_GC: 0x%08x\n", |
210 | SIISATANAME(sc), __func__, GRREAD(sc, GR_GC)), DEBUG_FUNCS); | | 210 | SIISATANAME(sc), __func__, GRREAD(sc, GR_GC)), DEBUG_FUNCS); |
211 | | | 211 | |
212 | sc->sc_atac.atac_cap = ATAC_CAP_DMA | ATAC_CAP_UDMA; | | 212 | sc->sc_atac.atac_cap = ATAC_CAP_DMA | ATAC_CAP_UDMA | ATAC_CAP_NCQ; |
213 | sc->sc_atac.atac_pio_cap = 4; | | 213 | sc->sc_atac.atac_pio_cap = 4; |
214 | sc->sc_atac.atac_dma_cap = 2; | | 214 | sc->sc_atac.atac_dma_cap = 2; |
215 | sc->sc_atac.atac_udma_cap = 6; | | 215 | sc->sc_atac.atac_udma_cap = 6; |
216 | sc->sc_atac.atac_channels = sc->sc_chanarray; | | 216 | sc->sc_atac.atac_channels = sc->sc_chanarray; |
217 | sc->sc_atac.atac_probe = siisata_probe_drive; | | 217 | sc->sc_atac.atac_probe = siisata_probe_drive; |
218 | sc->sc_atac.atac_bustype_ata = &siisata_ata_bustype; | | 218 | sc->sc_atac.atac_bustype_ata = &siisata_ata_bustype; |
219 | sc->sc_atac.atac_set_modes = siisata_setup_channel; | | 219 | sc->sc_atac.atac_set_modes = siisata_setup_channel; |
220 | #if NATAPIBUS > 0 | | 220 | #if NATAPIBUS > 0 |
221 | sc->sc_atac.atac_atapibus_attach = siisata_atapibus_attach; | | 221 | sc->sc_atac.atac_atapibus_attach = siisata_atapibus_attach; |
222 | #endif | | 222 | #endif |
223 | | | 223 | |
224 | /* come out of reset state */ | | 224 | /* come out of reset state */ |
225 | GRWRITE(sc, GR_GC, 0); | | 225 | GRWRITE(sc, GR_GC, 0); |
| @@ -236,46 +236,46 @@ siisata_attach(struct siisata_softc *sc) | | | @@ -236,46 +236,46 @@ siisata_attach(struct siisata_softc *sc) |
236 | static void | | 236 | static void |
237 | siisata_disable_port_interrupt(struct ata_channel *chp) | | 237 | siisata_disable_port_interrupt(struct ata_channel *chp) |
238 | { | | 238 | { |
239 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; | | 239 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; |
240 | | | 240 | |
241 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PIEC), 0xffffffff); | | 241 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PIEC), 0xffffffff); |
242 | } | | 242 | } |
243 | | | 243 | |
244 | static void | | 244 | static void |
245 | siisata_enable_port_interrupt(struct ata_channel *chp) | | 245 | siisata_enable_port_interrupt(struct ata_channel *chp) |
246 | { | | 246 | { |
247 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; | | 247 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; |
248 | | | 248 | |
249 | /* clear any interrupts */ | | 249 | /* enable CmdErrr+CmdCmpl interrupting */ |
250 | (void)PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)); | | | |
251 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), 0xffffffff); | | | |
252 | /* and enable CmdErrr+CmdCmpl interrupting */ | | | |
253 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PIES), | | 250 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PIES), |
254 | PR_PIS_CMDERRR | PR_PIS_CMDCMPL); | | 251 | PR_PIS_CMDERRR | PR_PIS_CMDCMPL); |
255 | } | | 252 | } |
256 | | | 253 | |
257 | static void | | 254 | static void |
258 | siisata_init_port(struct siisata_softc *sc, int port) | | 255 | siisata_init_port(struct siisata_softc *sc, int port) |
259 | { | | 256 | { |
260 | struct siisata_channel *schp; | | 257 | struct siisata_channel *schp; |
261 | struct ata_channel *chp; | | 258 | struct ata_channel *chp; |
262 | | | 259 | |
263 | schp = &sc->sc_channels[port]; | | 260 | schp = &sc->sc_channels[port]; |
264 | chp = (struct ata_channel *)schp; | | 261 | chp = (struct ata_channel *)schp; |
265 | | | 262 | |
266 | /* come out of reset, 64-bit activation */ | | 263 | /* |
| | | 264 | * Come out of reset. Disable no clearing of PR_PIS_CMDCMPL on read |
| | | 265 | * of PR_PSS. Disable 32-bit PRB activation, we use 64-bit activation. |
| | | 266 | */ |
267 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PCC), | | 267 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PCC), |
268 | PR_PC_32BA | PR_PC_PORT_RESET); | | 268 | PR_PC_32BA | PR_PC_INCOR | PR_PC_PORT_RESET); |
269 | /* initialize port */ | | 269 | /* initialize port */ |
270 | siisata_reinit_port(chp); | | 270 | siisata_reinit_port(chp); |
271 | /* enable CmdErrr+CmdCmpl interrupting */ | | 271 | /* enable CmdErrr+CmdCmpl interrupting */ |
272 | siisata_enable_port_interrupt(chp); | | 272 | siisata_enable_port_interrupt(chp); |
273 | /* enable port interrupt */ | | 273 | /* enable port interrupt */ |
274 | GRWRITE(sc, GR_GC, GRREAD(sc, GR_GC) | GR_GC_PXIE(chp->ch_channel)); | | 274 | GRWRITE(sc, GR_GC, GRREAD(sc, GR_GC) | GR_GC_PXIE(chp->ch_channel)); |
275 | } | | 275 | } |
276 | | | 276 | |
277 | static void | | 277 | static void |
278 | siisata_attach_port(struct siisata_softc *sc, int port) | | 278 | siisata_attach_port(struct siisata_softc *sc, int port) |
279 | { | | 279 | { |
280 | int j; | | 280 | int j; |
281 | int dmasize; | | 281 | int dmasize; |
| @@ -463,145 +463,201 @@ siisata_intr(void *v) | | | @@ -463,145 +463,201 @@ siisata_intr(void *v) |
463 | for (i = 0; i < sc->sc_atac.atac_nchannels; i++) | | 463 | for (i = 0; i < sc->sc_atac.atac_nchannels; i++) |
464 | if (is & GR_GIS_PXIS(i)) | | 464 | if (is & GR_GIS_PXIS(i)) |
465 | siisata_intr_port(&sc->sc_channels[i]); | | 465 | siisata_intr_port(&sc->sc_channels[i]); |
466 | } | | 466 | } |
467 | return r; | | 467 | return r; |
468 | } | | 468 | } |
469 | | | 469 | |
470 | static void | | 470 | static void |
471 | siisata_intr_port(struct siisata_channel *schp) | | 471 | siisata_intr_port(struct siisata_channel *schp) |
472 | { | | 472 | { |
473 | struct siisata_softc *sc; | | 473 | struct siisata_softc *sc; |
474 | struct ata_channel *chp; | | 474 | struct ata_channel *chp; |
475 | struct ata_xfer *xfer; | | 475 | struct ata_xfer *xfer; |
476 | int slot; | | 476 | u_int slot; |
477 | uint32_t pss, pis; | | 477 | uint32_t pss, pis; |
478 | uint32_t prbfis; | | 478 | uint32_t prbfis; |
479 | | | 479 | |
480 | sc = (struct siisata_softc *)schp->ata_channel.ch_atac; | | 480 | sc = (struct siisata_softc *)schp->ata_channel.ch_atac; |
481 | chp = &schp->ata_channel; | | 481 | chp = &schp->ata_channel; |
482 | xfer = ata_queue_hwslot_to_xfer(chp->ch_queue, 0); /* XXX slot */ | | 482 | |
483 | slot = SIISATA_NON_NCQ_SLOT; | | 483 | /* get slot status, clearing completion interrupt (PR_PIS_CMDCMPL) */ |
| | | 484 | pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)); |
| | | 485 | SIISATA_DEBUG_PRINT(("%s: %s port %d, pss 0x%x\n", |
| | | 486 | SIISATANAME(sc), __func__, chp->ch_channel, pss), DEBUG_INTR); |
| | | 487 | |
| | | 488 | for (slot = 0; slot < SIISATA_MAX_SLOTS; slot++) { |
| | | 489 | if (((schp->sch_active_slots >> slot) & 1) == 0) |
| | | 490 | /* there's nothing executing here, skip */ |
| | | 491 | continue; |
| | | 492 | if (((pss >> slot) & 1) != 0) |
| | | 493 | /* execution is incomplete or unsuccessful, skip for now */ |
| | | 494 | continue; |
| | | 495 | xfer = ata_queue_hwslot_to_xfer(chp->ch_queue, slot); |
| | | 496 | if (xfer->c_intr == NULL) { |
| | | 497 | wakeup(schp); |
| | | 498 | continue; |
| | | 499 | } |
| | | 500 | KASSERT(xfer != NULL); |
| | | 501 | KASSERT(xfer->c_intr != NULL); |
| | | 502 | xfer->c_intr(chp, xfer, 0); |
| | | 503 | } |
| | | 504 | /* if no errors, we're done now */ |
| | | 505 | if ((pss & PR_PSS_ATTENTION) == 0) { |
| | | 506 | pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS)); |
| | | 507 | pis &= 0xffff; |
| | | 508 | if (pis) { |
| | | 509 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), |
| | | 510 | pis & 0xfffcfffc); |
| | | 511 | } |
| | | 512 | return; |
| | | 513 | } |
484 | | | 514 | |
485 | pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS)); | | 515 | pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS)); |
486 | | | 516 | |
487 | SIISATA_DEBUG_PRINT(("%s: %s port %d, pis 0x%x ", SIISATANAME(sc), | | 517 | SIISATA_DEBUG_PRINT(("%s: %s port %d, pis 0x%x ", SIISATANAME(sc), |
488 | __func__, chp->ch_channel, pis), DEBUG_INTR); | | 518 | __func__, chp->ch_channel, pis), DEBUG_INTR); |
489 | | | 519 | |
490 | if (pis & PR_PIS_CMDCMPL) { | | 520 | if (pis & PR_PIS_CMDERRR) { |
491 | /* get slot status, clearing completion interrupt */ | | | |
492 | pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)); | | | |
493 | SIISATA_DEBUG_PRINT(("pss 0x%x\n", pss), DEBUG_INTR); | | | |
494 | /* is this expected? */ | | | |
495 | /* XXX improve */ | | | |
496 | if ((schp->sch_active_slots & __BIT(slot)) == 0) { | | | |
497 | aprint_error( "%s: unexpected command " | | | |
498 | "completion on port %d\n", | | | |
499 | SIISATANAME(sc), chp->ch_channel); | | | |
500 | return; | | | |
501 | } | | | |
502 | if ((~pss & __BIT(slot)) == 0) { | | | |
503 | aprint_error( "%s: unknown slot " | | | |
504 | "completion on port %d, pss 0x%x\n", | | | |
505 | SIISATANAME(sc), chp->ch_channel, pss); | | | |
506 | return; | | | |
507 | } | | | |
508 | } else if (pis & PR_PIS_CMDERRR) { | | | |
509 | uint32_t ec; | | 521 | uint32_t ec; |
| | | 522 | uint32_t ps; |
| | | 523 | |
| | | 524 | ps = PRREAD(sc, PRX(chp->ch_channel, PRO_PS)); |
| | | 525 | ec = PRREAD(sc, PRX(chp->ch_channel, PRO_PCE)); |
| | | 526 | SIISATA_DEBUG_PRINT(("ec %d\n", ec), DEBUG_INTR); |
| | | 527 | |
| | | 528 | slot = PR_PS_ACTIVE_SLOT(ps); /* XXX invalid for NCQ? */ |
510 | | | 529 | |
511 | /* emulate a CRC error by default */ | | 530 | /* emulate a CRC error by default */ |
512 | chp->ch_status = WDCS_ERR; | | 531 | chp->ch_status = WDCS_ERR; |
513 | chp->ch_error = WDCE_CRC; | | 532 | chp->ch_error = WDCE_CRC; |
514 | | | 533 | |
515 | ec = PRREAD(sc, PRX(chp->ch_channel, PRO_PCE)); | | | |
516 | SIISATA_DEBUG_PRINT(("ec %d\n", ec), DEBUG_INTR); | | | |
517 | if (ec <= PR_PCE_DATAFISERROR) { | | 534 | if (ec <= PR_PCE_DATAFISERROR) { |
518 | if (ec == PR_PCE_DEVICEERROR && xfer != NULL) { | | 535 | if (ec == PR_PCE_DEVICEERROR) { |
519 | /* read in specific information about error */ | | 536 | /* read in specific information about error */ |
520 | prbfis = bus_space_read_stream_4( | | 537 | prbfis = bus_space_read_stream_4( |
521 | sc->sc_prt, sc->sc_prh, | | 538 | sc->sc_prt, sc->sc_prh, |
522 | PRSX(chp->ch_channel, slot, PRSO_FIS)); | | 539 | PRSX(chp->ch_channel, slot, |
| | | 540 | PRSO_FIS)); |
523 | /* set ch_status and ch_error */ | | 541 | /* set ch_status and ch_error */ |
524 | satafis_rdh_parse(chp, (uint8_t *)&prbfis); | | 542 | satafis_rdh_parse(chp, (uint8_t *)&prbfis); |
525 | } | | 543 | } |
526 | siisata_reinit_port(chp); | | 544 | siisata_reinit_port(chp); |
527 | } else { | | 545 | } else { |
528 | aprint_error_dev(sc->sc_atac.atac_dev, "fatal error %d" | | 546 | aprint_error_dev(sc->sc_atac.atac_dev, "fatal error %d" |
529 | " on channel %d (ctx 0x%x), resetting\n", | | 547 | " on channel %d (ctx 0x%x), resetting\n", |
530 | ec, chp->ch_channel, | | 548 | ec, chp->ch_channel, |
531 | PRREAD(sc, PRX(chp->ch_channel, PRO_PCR))); | | 549 | PRREAD(sc, PRX(chp->ch_channel, PRO_PCR))); |
532 | /* okay, we have a "Fatal Error" */ | | 550 | /* okay, we have a "Fatal Error" */ |
533 | siisata_device_reset(chp); | | 551 | siisata_device_reset(chp); |
534 | } | | 552 | } |
| | | 553 | for (slot = 0; slot < SIISATA_MAX_SLOTS; slot++) { |
| | | 554 | /* there's nothing executing here, skip */ |
| | | 555 | if (((schp->sch_active_slots >> slot) & 1) == 0) |
| | | 556 | continue; |
| | | 557 | xfer = ata_queue_hwslot_to_xfer(chp->ch_queue, slot); |
| | | 558 | if (xfer == NULL) |
| | | 559 | continue; |
| | | 560 | xfer->c_intr(chp, xfer, 0); |
| | | 561 | } |
535 | } | | 562 | } |
536 | | | 563 | |
537 | /* clear some (ok, all) ints */ | | 564 | /* clear */ |
538 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), 0xffffffff); | | 565 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), pis); |
539 | if (xfer && xfer->c_intr) | | | |
540 | xfer->c_intr(chp, xfer, 0); | | | |
541 | | | 566 | |
542 | return; | | 567 | return; |
543 | } | | 568 | } |
544 | | | 569 | |
545 | void | | 570 | void |
546 | siisata_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp) | | 571 | siisata_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp) |
547 | { | | 572 | { |
548 | struct ata_channel *chp = drvp->chnl_softc; | | 573 | struct ata_channel *chp = drvp->chnl_softc; |
549 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; | | 574 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; |
550 | struct siisata_channel *schp = (struct siisata_channel *)chp; | | 575 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
551 | struct siisata_prb *prb; | | 576 | struct siisata_prb *prb; |
552 | int slot = SIISATA_NON_NCQ_SLOT; | | 577 | struct ata_xfer *xfer; |
| | | 578 | uint32_t pss, pis; |
553 | int i; | | 579 | int i; |
554 | | | 580 | |
555 | /* wait for ready */ | | 581 | /* wait for ready */ |
556 | while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) & PR_PS_PORT_READY)) | | 582 | while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) & PR_PS_PORT_READY)) |
557 | DELAY(10); | | 583 | DELAY(10); |
558 | | | 584 | |
559 | prb = schp->sch_prb[slot]; | | 585 | xfer = ata_get_xfer(chp); /* Is this right? What if the slots are full? */ |
| | | 586 | if (xfer == NULL) |
| | | 587 | return; |
| | | 588 | |
| | | 589 | prb = schp->sch_prb[xfer->c_slot]; |
560 | memset(prb, 0, SIISATA_CMD_SIZE); | | 590 | memset(prb, 0, SIISATA_CMD_SIZE); |
561 | prb->prb_control = | | 591 | prb->prb_control = |
562 | htole16(PRB_CF_SOFT_RESET | PRB_CF_INTERRUPT_MASK); | | 592 | htole16(PRB_CF_SOFT_RESET /* | PRB_CF_INTERRUPT_MASK */); |
563 | KASSERT(drvp->drive <= PMP_PORT_CTL); | | 593 | KASSERT(drvp->drive <= PMP_PORT_CTL); |
564 | prb->prb_fis[rhd_c] = drvp->drive; | | 594 | prb->prb_fis[rhd_c] = drvp->drive; |
565 | | | 595 | |
566 | siisata_activate_prb(schp, slot); | | 596 | ata_activate_xfer(chp, xfer); |
| | | 597 | siisata_activate_prb(schp, xfer->c_slot); |
567 | | | 598 | |
568 | for(i = 0; i < 3100; i++) { | | 599 | for(i = 0; i < 3100; i++) { |
569 | if ((PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) & | | 600 | #if 0 /* XXX-jak-jd-ncq this block needs re-work... XXX */ |
570 | PR_PXSS(slot)) == 0) | | 601 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PCS), PR_PC_INCOR); |
| | | 602 | pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)); |
| | | 603 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PCC), PR_PC_INCOR); |
| | | 604 | if ((pss & PR_PXSS(xfer->c_slot)) == 0) |
| | | 605 | break; |
| | | 606 | if (pss & PR_PSS_ATTENTION) |
571 | break; | | 607 | break; |
572 | if (flags & AT_WAIT) | | 608 | #else |
| | | 609 | pss = PR_PXSS(xfer->c_slot); |
| | | 610 | /* XXX DO NOT MERGE UNTIL THIS IS FIXED XXX */ |
| | | 611 | #endif |
| | | 612 | if ((flags & AT_POLL) == 0) |
573 | tsleep(schp, PRIBIO, "siiprb", mstohz(10)); | | 613 | tsleep(schp, PRIBIO, "siiprb", mstohz(10)); |
574 | else | | 614 | else |
575 | DELAY(10000); | | 615 | DELAY(10000); |
576 | } | | 616 | } |
577 | | | 617 | |
578 | siisata_deactivate_prb(schp, slot); | | 618 | siisata_deactivate_prb(schp, xfer->c_slot); |
| | | 619 | |
| | | 620 | if ((pss & PR_PSS_ATTENTION) != 0) { |
| | | 621 | pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS)); |
| | | 622 | const uint32_t ps = PRREAD(sc, PRX(chp->ch_channel, PRO_PS)); |
| | | 623 | const u_int slot = PR_PS_ACTIVE_SLOT(ps); |
| | | 624 | if (slot != xfer->c_slot) |
| | | 625 | device_printf(sc->sc_atac.atac_dev, "%s port %d " |
| | | 626 | "drive %d slot %d c_slot %d", __func__, |
| | | 627 | chp->ch_channel, drvp->drive, slot, xfer->c_slot); |
| | | 628 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), pis & |
| | | 629 | PR_PIS_CMDERRR); |
| | | 630 | } |
| | | 631 | |
579 | if (i == 3100) { | | 632 | if (i == 3100) { |
580 | /* timeout */ | | 633 | /* timeout */ |
581 | siisata_device_reset(chp); | | 634 | siisata_device_reset(chp); /* XXX is this right? */ |
582 | if (sigp) | | 635 | if (sigp) |
583 | *sigp = 0xffffffff; | | 636 | *sigp = 0xffffffff; |
584 | } else { | | 637 | } else { |
585 | /* read the signature out of the FIS */ | | 638 | /* read the signature out of the FIS */ |
586 | if (sigp) { | | 639 | if (sigp) { |
587 | *sigp = 0; | | 640 | *sigp = 0; |
588 | *sigp |= (PRREAD(sc, PRSX(chp->ch_channel, slot, | | 641 | *sigp |= (PRREAD(sc, PRSX(chp->ch_channel, xfer->c_slot, |
589 | PRSO_FIS+0x4)) & 0x00ffffff) << 8; | | 642 | PRSO_FIS+0x4)) & 0x00ffffff) << 8; |
590 | *sigp |= PRREAD(sc, PRSX(chp->ch_channel, slot, | | 643 | *sigp |= PRREAD(sc, PRSX(chp->ch_channel, xfer->c_slot, |
591 | PRSO_FIS+0xc)) & 0xff; | | 644 | PRSO_FIS+0xc)) & 0xff; |
592 | } | | 645 | } |
593 | } | | 646 | } |
594 | | | 647 | |
| | | 648 | ata_deactivate_xfer(chp, xfer); |
| | | 649 | ata_free_xfer(chp, xfer); |
| | | 650 | |
595 | #if 1 | | 651 | #if 1 |
596 | /* attempt to downgrade signaling in event of CRC error */ | | 652 | /* attempt to downgrade signaling in event of CRC error */ |
597 | /* XXX should be part of the MI (S)ATA subsystem */ | | 653 | /* XXX should be part of the MI (S)ATA subsystem */ |
598 | if (chp->ch_status == 0x51 && chp->ch_error == 0x84) { | | 654 | if (chp->ch_status == 0x51 && chp->ch_error == 0x84) { |
599 | bus_space_write_4(sc->sc_prt, schp->sch_scontrol, 0, | | 655 | bus_space_write_4(sc->sc_prt, schp->sch_scontrol, 0, |
600 | SControl_IPM_NONE | SControl_SPD_G1 | SControl_DET_INIT); | | 656 | SControl_IPM_NONE | SControl_SPD_G1 | SControl_DET_INIT); |
601 | DELAY(10); | | 657 | DELAY(10); |
602 | bus_space_write_4(sc->sc_prt, schp->sch_scontrol, 0, | | 658 | bus_space_write_4(sc->sc_prt, schp->sch_scontrol, 0, |
603 | SControl_IPM_NONE | SControl_SPD_G1); | | 659 | SControl_IPM_NONE | SControl_SPD_G1); |
604 | DELAY(10); | | 660 | DELAY(10); |
605 | for (;;) { | | 661 | for (;;) { |
606 | if ((bus_space_read_4(sc->sc_prt, schp->sch_sstatus, 0) | | 662 | if ((bus_space_read_4(sc->sc_prt, schp->sch_sstatus, 0) |
607 | & SStatus_DET_mask) == SStatus_DET_DEV) | | 663 | & SStatus_DET_mask) == SStatus_DET_DEV) |
| @@ -614,28 +670,28 @@ siisata_reset_drive(struct ata_drive_dat | | | @@ -614,28 +670,28 @@ siisata_reset_drive(struct ata_drive_dat |
614 | #if 1 | | 670 | #if 1 |
615 | chp->ch_status = 0; | | 671 | chp->ch_status = 0; |
616 | chp->ch_error = 0; | | 672 | chp->ch_error = 0; |
617 | #endif | | 673 | #endif |
618 | return; | | 674 | return; |
619 | } | | 675 | } |
620 | | | 676 | |
621 | void | | 677 | void |
622 | siisata_reset_channel(struct ata_channel *chp, int flags) | | 678 | siisata_reset_channel(struct ata_channel *chp, int flags) |
623 | { | | 679 | { |
624 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; | | 680 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; |
625 | struct siisata_channel *schp = (struct siisata_channel *)chp; | | 681 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
626 | | | 682 | |
627 | SIISATA_DEBUG_PRINT(("%s: %s\n", SIISATANAME(sc), __func__), | | 683 | SIISATA_DEBUG_PRINT(("%s: %s channel %d\n", SIISATANAME(sc), __func__, |
628 | DEBUG_FUNCS); | | 684 | chp->ch_channel), DEBUG_FUNCS); |
629 | | | 685 | |
630 | if (sata_reset_interface(chp, sc->sc_prt, schp->sch_scontrol, | | 686 | if (sata_reset_interface(chp, sc->sc_prt, schp->sch_scontrol, |
631 | schp->sch_sstatus, flags) != SStatus_DET_DEV) { | | 687 | schp->sch_sstatus, flags) != SStatus_DET_DEV) { |
632 | aprint_error("%s port %d: reset failed\n", | | 688 | aprint_error("%s port %d: reset failed\n", |
633 | SIISATANAME(sc), chp->ch_channel); | | 689 | SIISATANAME(sc), chp->ch_channel); |
634 | /* XXX and then ? */ | | 690 | /* XXX and then ? */ |
635 | } | | 691 | } |
636 | /* wait for ready */ | | 692 | /* wait for ready */ |
637 | while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) & PR_PS_PORT_READY)) | | 693 | while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) & PR_PS_PORT_READY)) |
638 | DELAY(10); | | 694 | DELAY(10); |
639 | PRWRITE(sc, PRX(chp->ch_channel, PRO_SERROR), | | 695 | PRWRITE(sc, PRX(chp->ch_channel, PRO_SERROR), |
640 | PRREAD(sc, PRX(chp->ch_channel, PRO_SERROR))); | | 696 | PRREAD(sc, PRX(chp->ch_channel, PRO_SERROR))); |
641 | ata_kill_active(chp, KILL_RESET); | | 697 | ata_kill_active(chp, KILL_RESET); |
| @@ -658,89 +714,92 @@ siisata_ata_delref(struct ata_drive_data | | | @@ -658,89 +714,92 @@ siisata_ata_delref(struct ata_drive_data |
658 | void | | 714 | void |
659 | siisata_killpending(struct ata_drive_datas *drvp) | | 715 | siisata_killpending(struct ata_drive_datas *drvp) |
660 | { | | 716 | { |
661 | return; | | 717 | return; |
662 | } | | 718 | } |
663 | | | 719 | |
664 | void | | 720 | void |
665 | siisata_probe_drive(struct ata_channel *chp) | | 721 | siisata_probe_drive(struct ata_channel *chp) |
666 | { | | 722 | { |
667 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; | | 723 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; |
668 | struct siisata_channel *schp = (struct siisata_channel *)chp; | | 724 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
669 | int i; | | 725 | int i; |
670 | uint32_t sig; | | 726 | uint32_t sig; |
671 | int slot = SIISATA_NON_NCQ_SLOT; | | | |
672 | struct siisata_prb *prb; | | 727 | struct siisata_prb *prb; |
673 | bool timed_out; | | 728 | bool timed_out; |
| | | 729 | const u_int slot0 = 0; /* XXX this is a problem */ |
674 | | | 730 | |
675 | SIISATA_DEBUG_PRINT(("%s: %s: port %d start\n", SIISATANAME(sc), | | 731 | SIISATA_DEBUG_PRINT(("%s: %s: port %d start\n", SIISATANAME(sc), |
676 | __func__, chp->ch_channel), DEBUG_FUNCS); | | 732 | __func__, chp->ch_channel), DEBUG_FUNCS); |
677 | | | 733 | |
678 | /* | | 734 | /* |
679 | * disable port interrupt as we're polling for PHY up and | | 735 | * disable port interrupt as we're polling for PHY up and |
680 | * prb completion | | 736 | * prb completion |
681 | */ | | 737 | */ |
682 | siisata_disable_port_interrupt(chp); | | 738 | siisata_disable_port_interrupt(chp); |
683 | | | 739 | |
684 | switch(sata_reset_interface(chp, sc->sc_prt, schp->sch_scontrol, | | 740 | switch(sata_reset_interface(chp, sc->sc_prt, schp->sch_scontrol, |
685 | schp->sch_sstatus, AT_WAIT)) { | | 741 | schp->sch_sstatus, AT_WAIT)) { |
686 | case SStatus_DET_DEV: | | 742 | case SStatus_DET_DEV: |
| | | 743 | #if 0 /* XXX Including this seems to cause problems. */ |
| | | 744 | /* XXX DO NOT MERGE UNTIL THIS IS ADDRESSED PROPERLY XXX */ |
687 | /* clear any interrupts */ | | 745 | /* clear any interrupts */ |
688 | (void)PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)); | | 746 | (void)PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)); |
689 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), 0xffffffff); | | 747 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), 0xffffffff); |
| | | 748 | #endif |
690 | /* wait for ready */ | | 749 | /* wait for ready */ |
691 | while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) | | 750 | while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) |
692 | & PR_PS_PORT_READY)) | | 751 | & PR_PS_PORT_READY)) |
693 | DELAY(10); | | 752 | DELAY(10); |
694 | prb = schp->sch_prb[slot]; | | 753 | prb = schp->sch_prb[slot0]; |
695 | memset(prb, 0, SIISATA_CMD_SIZE); | | 754 | memset(prb, 0, SIISATA_CMD_SIZE); |
696 | prb->prb_control = htole16(PRB_CF_SOFT_RESET); | | 755 | prb->prb_control = htole16(PRB_CF_SOFT_RESET); |
697 | prb->prb_fis[rhd_c] = PMP_PORT_CTL; | | 756 | prb->prb_fis[rhd_c] = PMP_PORT_CTL; |
698 | | | 757 | |
699 | siisata_activate_prb(schp, slot); | | 758 | siisata_activate_prb(schp, slot0); |
700 | | | 759 | |
701 | timed_out = 1; | | 760 | timed_out = 1; |
702 | for(i = 0; i < 3100; i++) { | | 761 | for(i = 0; i < 3100; i++) { |
703 | if ((PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) & | | 762 | if ((PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) & |
704 | PR_PXSS(slot)) == 0) { | | 763 | PR_PXSS(slot0)) == 0) { |
705 | /* prb completed */ | | 764 | /* prb completed */ |
706 | timed_out = 0; | | 765 | timed_out = 0; |
707 | break; | | 766 | break; |
708 | } | | 767 | } |
709 | if (PRREAD(sc, PRX(chp->ch_channel, PRO_PIS)) & | | 768 | if (PRREAD(sc, PRX(chp->ch_channel, PRO_PIS)) & |
710 | (PR_PIS_CMDERRR << 16)) { | | 769 | (PR_PIS_CMDERRR << 16)) { |
711 | /* we got an error; handle as timeout */ | | 770 | /* we got an error; handle as timeout */ |
712 | break; | | 771 | break; |
713 | } | | 772 | } |
714 | | | 773 | |
715 | tsleep(schp, PRIBIO, "siiprb", mstohz(10)); | | 774 | tsleep(schp, PRIBIO, "siiprb", mstohz(10)); |
716 | } | | 775 | } |
717 | | | 776 | |
718 | siisata_deactivate_prb(schp, slot); | | 777 | siisata_deactivate_prb(schp, slot0); |
719 | if (timed_out) { | | 778 | if (timed_out) { |
720 | aprint_error_dev(sc->sc_atac.atac_dev, | | 779 | aprint_error_dev(sc->sc_atac.atac_dev, |
721 | "SOFT_RESET failed on port %d (error %d PSS 0x%x), " | | 780 | "SOFT_RESET failed on port %d (error %d PSS 0x%x), " |
722 | "resetting\n", chp->ch_channel, | | 781 | "resetting\n", chp->ch_channel, |
723 | PRREAD(sc, PRX(chp->ch_channel, PRO_PCE)), | | 782 | PRREAD(sc, PRX(chp->ch_channel, PRO_PCE)), |
724 | PRREAD(sc, PRX(chp->ch_channel, PRO_PSS))); | | 783 | PRREAD(sc, PRX(chp->ch_channel, PRO_PSS))); |
725 | siisata_reinit_port(chp); | | 784 | siisata_reinit_port(chp); |
726 | break; | | 785 | break; |
727 | } | | 786 | } |
728 | | | 787 | |
729 | /* read the signature out of the FIS */ | | 788 | /* read the signature out of the FIS */ |
730 | sig = 0; | | 789 | sig = 0; |
731 | sig |= (PRREAD(sc, PRSX(chp->ch_channel, slot, | | 790 | sig |= (PRREAD(sc, PRSX(chp->ch_channel, slot0, |
732 | PRSO_FIS+0x4)) & 0x00ffffff) << 8; | | 791 | PRSO_FIS+0x4)) & 0x00ffffff) << 8; |
733 | sig |= PRREAD(sc, PRSX(chp->ch_channel, slot, | | 792 | sig |= PRREAD(sc, PRSX(chp->ch_channel, slot0, |
734 | PRSO_FIS+0xc)) & 0xff; | | 793 | PRSO_FIS+0xc)) & 0xff; |
735 | | | 794 | |
736 | SIISATA_DEBUG_PRINT(("%s: %s: sig=0x%08x\n", SIISATANAME(sc), | | 795 | SIISATA_DEBUG_PRINT(("%s: %s: sig=0x%08x\n", SIISATANAME(sc), |
737 | __func__, sig), DEBUG_PROBE); | | 796 | __func__, sig), DEBUG_PROBE); |
738 | | | 797 | |
739 | if (sig == 0x96690101) | | 798 | if (sig == 0x96690101) |
740 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PCS), | | 799 | PRWRITE(sc, PRX(chp->ch_channel, PRO_PCS), |
741 | PR_PC_PMP_ENABLE); | | 800 | PR_PC_PMP_ENABLE); |
742 | sata_interpret_sig(chp, 0, sig); | | 801 | sata_interpret_sig(chp, 0, sig); |
743 | break; | | 802 | break; |
744 | default: | | 803 | default: |
745 | break; | | 804 | break; |
746 | } | | 805 | } |
| @@ -804,67 +863,66 @@ siisata_exec_command(struct ata_drive_da | | | @@ -804,67 +863,66 @@ siisata_exec_command(struct ata_drive_da |
804 | } | | 863 | } |
805 | splx(s); | | 864 | splx(s); |
806 | SIISATA_DEBUG_PRINT( ("%s: %s ends\n", | | 865 | SIISATA_DEBUG_PRINT( ("%s: %s ends\n", |
807 | SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__), | | 866 | SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__), |
808 | DEBUG_FUNCS); | | 867 | DEBUG_FUNCS); |
809 | return ret; | | 868 | return ret; |
810 | } | | 869 | } |
811 | | | 870 | |
812 | void | | 871 | void |
813 | siisata_cmd_start(struct ata_channel *chp, struct ata_xfer *xfer) | | 872 | siisata_cmd_start(struct ata_channel *chp, struct ata_xfer *xfer) |
814 | { | | 873 | { |
815 | struct siisata_channel *schp = (struct siisata_channel *)chp; | | 874 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
816 | struct ata_command *ata_c = &xfer->c_ata_c; | | 875 | struct ata_command *ata_c = &xfer->c_ata_c; |
817 | int slot = SIISATA_NON_NCQ_SLOT; | | | |
818 | struct siisata_prb *prb; | | 876 | struct siisata_prb *prb; |
819 | int i; | | 877 | int i; |
820 | | | 878 | |
821 | SIISATA_DEBUG_PRINT(("%s: %s port %d drive %d command 0x%x, slot %d\n", | | 879 | SIISATA_DEBUG_PRINT(("%s: %s port %d drive %d command 0x%x, slot %d\n", |
822 | SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__, | | 880 | SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__, |
823 | chp->ch_channel, xfer->c_drive, ata_c->r_command, slot), | | 881 | chp->ch_channel, xfer->c_drive, ata_c->r_command, xfer->c_slot), |
824 | DEBUG_FUNCS|DEBUG_XFERS); | | 882 | DEBUG_FUNCS|DEBUG_XFERS); |
825 | | | 883 | |
826 | chp->ch_status = 0; | | 884 | chp->ch_status = 0; |
827 | chp->ch_error = 0; | | 885 | chp->ch_error = 0; |
828 | | | 886 | |
829 | prb = schp->sch_prb[slot]; | | 887 | prb = schp->sch_prb[xfer->c_slot]; |
830 | memset(prb, 0, SIISATA_CMD_SIZE); | | 888 | memset(prb, 0, SIISATA_CMD_SIZE); |
831 | | | 889 | |
832 | satafis_rhd_construct_cmd(ata_c, prb->prb_fis); | | 890 | satafis_rhd_construct_cmd(ata_c, prb->prb_fis); |
833 | KASSERT(xfer->c_drive <= PMP_PORT_CTL); | | 891 | KASSERT(xfer->c_drive <= PMP_PORT_CTL); |
834 | prb->prb_fis[rhd_c] |= xfer->c_drive; | | 892 | prb->prb_fis[rhd_c] |= xfer->c_drive; |
835 | | | 893 | |
836 | if (ata_c->r_command == ATA_DATA_SET_MANAGEMENT) { | | 894 | if (ata_c->r_command == ATA_DATA_SET_MANAGEMENT) { |
837 | prb->prb_control |= htole16(PRB_CF_PROTOCOL_OVERRIDE); | | 895 | prb->prb_control |= htole16(PRB_CF_PROTOCOL_OVERRIDE); |
838 | prb->prb_protocol_override |= htole16(PRB_PO_WRITE); | | 896 | prb->prb_protocol_override |= htole16(PRB_PO_WRITE); |
839 | } | | 897 | } |
840 | | | 898 | |
841 | if (siisata_dma_setup(chp, slot, | | 899 | if (siisata_dma_setup(chp, xfer->c_slot, |
842 | (ata_c->flags & (AT_READ | AT_WRITE)) ? ata_c->data : NULL, | | 900 | (ata_c->flags & (AT_READ | AT_WRITE)) ? ata_c->data : NULL, |
843 | ata_c->bcount, | | 901 | ata_c->bcount, |
844 | (ata_c->flags & AT_READ) ? BUS_DMA_READ : BUS_DMA_WRITE)) { | | 902 | (ata_c->flags & AT_READ) ? BUS_DMA_READ : BUS_DMA_WRITE)) { |
845 | ata_c->flags |= AT_DF; | | 903 | ata_c->flags |= AT_DF; |
846 | siisata_cmd_complete(chp, xfer, 0); | | 904 | siisata_cmd_complete(chp, xfer, 0); |
847 | return; | | 905 | return; |
848 | } | | 906 | } |
849 | | | 907 | |
850 | if (xfer->c_flags & C_POLL) { | | 908 | if (xfer->c_flags & C_POLL) { |
851 | /* polled command, disable interrupts */ | | 909 | /* polled command, disable interrupts */ |
852 | prb->prb_control = htole16(PRB_CF_INTERRUPT_MASK); | | 910 | prb->prb_control = htole16(PRB_CF_INTERRUPT_MASK); |
853 | siisata_disable_port_interrupt(chp); | | 911 | siisata_disable_port_interrupt(chp); |
854 | } | | 912 | } |
855 | | | 913 | |
856 | /* go for it */ | | 914 | /* go for it */ |
857 | siisata_activate_prb(schp, slot); | | 915 | siisata_activate_prb(schp, xfer->c_slot); |
858 | | | 916 | |
859 | if ((ata_c->flags & AT_POLL) == 0) { | | 917 | if ((ata_c->flags & AT_POLL) == 0) { |
860 | chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */ | | 918 | chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */ |
861 | callout_reset(&xfer->c_timo_callout, mstohz(ata_c->timeout), | | 919 | callout_reset(&xfer->c_timo_callout, mstohz(ata_c->timeout), |
862 | siisata_timeout, xfer); | | 920 | siisata_timeout, xfer); |
863 | goto out; | | 921 | goto out; |
864 | } | | 922 | } |
865 | | | 923 | |
866 | /* | | 924 | /* |
867 | * polled command | | 925 | * polled command |
868 | */ | | 926 | */ |
869 | for (i = 0; i < ata_c->timeout / 10; i++) { | | 927 | for (i = 0; i < ata_c->timeout / 10; i++) { |
870 | if (ata_c->flags & AT_DONE) | | 928 | if (ata_c->flags & AT_DONE) |
| @@ -880,118 +938,122 @@ siisata_cmd_start(struct ata_channel *ch | | | @@ -880,118 +938,122 @@ siisata_cmd_start(struct ata_channel *ch |
880 | /* reenable interrupts */ | | 938 | /* reenable interrupts */ |
881 | siisata_enable_port_interrupt(chp); | | 939 | siisata_enable_port_interrupt(chp); |
882 | out: | | 940 | out: |
883 | SIISATA_DEBUG_PRINT(("%s: %s: done\n", | | 941 | SIISATA_DEBUG_PRINT(("%s: %s: done\n", |
884 | SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__), | | 942 | SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__), |
885 | DEBUG_FUNCS); | | 943 | DEBUG_FUNCS); |
886 | return; | | 944 | return; |
887 | } | | 945 | } |
888 | | | 946 | |
889 | void | | 947 | void |
890 | siisata_cmd_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, | | 948 | siisata_cmd_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, |
891 | int reason) | | 949 | int reason) |
892 | { | | 950 | { |
893 | int slot = SIISATA_NON_NCQ_SLOT; | | | |
894 | | | | |
895 | struct ata_command *ata_c = &xfer->c_ata_c; | | 951 | struct ata_command *ata_c = &xfer->c_ata_c; |
| | | 952 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
| | | 953 | |
| | | 954 | siisata_deactivate_prb(schp, xfer->c_slot); |
| | | 955 | |
896 | switch (reason) { | | 956 | switch (reason) { |
897 | case KILL_GONE: | | 957 | case KILL_GONE: |
898 | ata_c->flags |= AT_GONE; | | 958 | ata_c->flags |= AT_GONE; |
899 | break; | | 959 | break; |
900 | case KILL_RESET: | | 960 | case KILL_RESET: |
901 | ata_c->flags |= AT_RESET; | | 961 | ata_c->flags |= AT_RESET; |
902 | break; | | 962 | break; |
903 | default: | | 963 | default: |
904 | panic("%s: port %d: unknown reason %d", | | 964 | panic("%s: port %d: unknown reason %d", |
905 | __func__, chp->ch_channel, reason); | | 965 | __func__, chp->ch_channel, reason); |
906 | } | | 966 | } |
907 | siisata_cmd_done(chp, xfer, slot); | | 967 | siisata_cmd_done(chp, xfer); |
908 | } | | 968 | } |
909 | | | 969 | |
910 | int | | 970 | int |
911 | siisata_cmd_complete(struct ata_channel *chp, struct ata_xfer *xfer, int is) | | 971 | siisata_cmd_complete(struct ata_channel *chp, struct ata_xfer *xfer, int is) |
912 | { | | 972 | { |
| | | 973 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
913 | struct ata_command *ata_c = &xfer->c_ata_c; | | 974 | struct ata_command *ata_c = &xfer->c_ata_c; |
914 | #ifdef SIISATA_DEBUG | | 975 | #ifdef SIISATA_DEBUG |
915 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; | | 976 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; |
916 | #endif | | 977 | #endif |
917 | int slot = SIISATA_NON_NCQ_SLOT; | | | |
918 | | | 978 | |
| | | 979 | SIISATA_DEBUG_PRINT(("%s: %s: port %d slot %d\n", |
| | | 980 | SIISATANAME(sc), __func__, |
| | | 981 | chp->ch_channel, xfer->c_slot), DEBUG_FUNCS); |
919 | SIISATA_DEBUG_PRINT(("%s: %s\n", SIISATANAME(sc), __func__), | | 982 | SIISATA_DEBUG_PRINT(("%s: %s\n", SIISATANAME(sc), __func__), |
920 | DEBUG_FUNCS|DEBUG_XFERS); | | 983 | DEBUG_FUNCS|DEBUG_XFERS); |
921 | | | 984 | |
| | | 985 | siisata_deactivate_prb(schp, xfer->c_slot); |
922 | chp->ch_flags &= ~ATACH_IRQ_WAIT; | | 986 | chp->ch_flags &= ~ATACH_IRQ_WAIT; |
923 | if (xfer->c_flags & C_TIMEOU) | | 987 | if (xfer->c_flags & C_TIMEOU) |
924 | ata_c->flags |= AT_TIMEOU; | | 988 | ata_c->flags |= AT_TIMEOU; |
925 | else | | 989 | else |
926 | callout_stop(&xfer->c_timo_callout); | | 990 | callout_stop(&xfer->c_timo_callout); |
927 | | | 991 | |
928 | if (chp->ch_status & WDCS_BSY) { | | 992 | if (chp->ch_status & WDCS_BSY) { |
929 | ata_c->flags |= AT_TIMEOU; | | 993 | ata_c->flags |= AT_TIMEOU; |
930 | } else if (chp->ch_status & WDCS_ERR) { | | 994 | } else if (chp->ch_status & WDCS_ERR) { |
931 | ata_c->r_error = chp->ch_error; | | 995 | ata_c->r_error = chp->ch_error; |
932 | ata_c->flags |= AT_ERROR; | | 996 | ata_c->flags |= AT_ERROR; |
933 | } | | 997 | } |
934 | | | 998 | |
935 | ata_deactivate_xfer(chp, xfer); | | 999 | ata_deactivate_xfer(chp, xfer); |
936 | | | 1000 | |
937 | if (!ata_waitdrain_xfer_check(chp, xfer)) { | | 1001 | if (!ata_waitdrain_xfer_check(chp, xfer)) { |
938 | siisata_cmd_done(chp, xfer, slot); | | 1002 | siisata_cmd_done(chp, xfer); |
939 | } | | 1003 | } |
940 | | | 1004 | |
941 | return 0; | | 1005 | return 0; |
942 | } | | 1006 | } |
943 | | | 1007 | |
944 | void | | 1008 | void |
945 | siisata_cmd_done(struct ata_channel *chp, struct ata_xfer *xfer, int slot) | | 1009 | siisata_cmd_done(struct ata_channel *chp, struct ata_xfer *xfer) |
946 | { | | 1010 | { |
947 | uint32_t fis[howmany(RDH_FISLEN,sizeof(uint32_t))]; | | 1011 | uint32_t fis[howmany(RDH_FISLEN,sizeof(uint32_t))]; |
948 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; | | 1012 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; |
949 | struct siisata_channel *schp = (struct siisata_channel *)chp; | | 1013 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
950 | struct ata_command *ata_c = &xfer->c_ata_c; | | 1014 | struct ata_command *ata_c = &xfer->c_ata_c; |
951 | uint16_t *idwordbuf; | | 1015 | uint16_t *idwordbuf; |
952 | int i; | | 1016 | int i; |
953 | | | 1017 | |
954 | SIISATA_DEBUG_PRINT(("%s: %s flags 0x%x error 0x%x\n", SIISATANAME(sc), | | 1018 | SIISATA_DEBUG_PRINT(("%s: %s flags 0x%x error 0x%x\n", SIISATANAME(sc), |
955 | __func__, ata_c->flags, ata_c->r_error), DEBUG_FUNCS|DEBUG_XFERS); | | 1019 | __func__, ata_c->flags, ata_c->r_error), DEBUG_FUNCS|DEBUG_XFERS); |
956 | | | 1020 | |
957 | siisata_deactivate_prb(schp, slot); | | | |
958 | | | | |
959 | if (ata_c->flags & (AT_READ | AT_WRITE)) { | | 1021 | if (ata_c->flags & (AT_READ | AT_WRITE)) { |
960 | bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[slot], 0, | | 1022 | bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[xfer->c_slot], 0, |
961 | schp->sch_datad[slot]->dm_mapsize, | | 1023 | schp->sch_datad[xfer->c_slot]->dm_mapsize, |
962 | (ata_c->flags & AT_READ) ? BUS_DMASYNC_POSTREAD : | | 1024 | (ata_c->flags & AT_READ) ? BUS_DMASYNC_POSTREAD : |
963 | BUS_DMASYNC_POSTWRITE); | | 1025 | BUS_DMASYNC_POSTWRITE); |
964 | bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[slot]); | | 1026 | bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[xfer->c_slot]); |
965 | } | | 1027 | } |
966 | | | 1028 | |
967 | if (ata_c->flags & AT_READREG) { | | 1029 | if (ata_c->flags & AT_READREG) { |
968 | bus_space_read_region_stream_4(sc->sc_prt, sc->sc_prh, | | 1030 | bus_space_read_region_stream_4(sc->sc_prt, sc->sc_prh, |
969 | PRSX(chp->ch_channel, slot, PRSO_FIS), | | 1031 | PRSX(chp->ch_channel, xfer->c_slot, PRSO_FIS), |
970 | fis, __arraycount(fis)); | | 1032 | fis, __arraycount(fis)); |
971 | satafis_rdh_cmd_readreg(ata_c, (uint8_t *)fis); | | 1033 | satafis_rdh_cmd_readreg(ata_c, (uint8_t *)fis); |
972 | } | | 1034 | } |
973 | | | 1035 | |
974 | /* correct the endianess of IDENTIFY data */ | | 1036 | /* correct the endianess of IDENTIFY data */ |
975 | if (ata_c->r_command == WDCC_IDENTIFY || | | 1037 | if (ata_c->r_command == WDCC_IDENTIFY || |
976 | ata_c->r_command == ATAPI_IDENTIFY_DEVICE) { | | 1038 | ata_c->r_command == ATAPI_IDENTIFY_DEVICE) { |
977 | idwordbuf = xfer->c_databuf; | | 1039 | idwordbuf = xfer->c_databuf; |
978 | for (i = 0; i < (xfer->c_bcount / sizeof(*idwordbuf)); i++) { | | 1040 | for (i = 0; i < (xfer->c_bcount / sizeof(*idwordbuf)); i++) { |
979 | idwordbuf[i] = le16toh(idwordbuf[i]); | | 1041 | idwordbuf[i] = le16toh(idwordbuf[i]); |
980 | } | | 1042 | } |
981 | } | | 1043 | } |
982 | | | 1044 | |
983 | ata_c->flags |= AT_DONE; | | 1045 | ata_c->flags |= AT_DONE; |
984 | if (PRREAD(sc, PRSX(chp->ch_channel, slot, PRSO_RTC))) | | 1046 | if (PRREAD(sc, PRSX(chp->ch_channel, xfer->c_slot, PRSO_RTC))) |
985 | ata_c->flags |= AT_XFDONE; | | 1047 | ata_c->flags |= AT_XFDONE; |
986 | | | 1048 | |
987 | if (ata_c->flags & AT_WAIT) | | 1049 | if (ata_c->flags & AT_WAIT) |
988 | wakeup(ata_c); | | 1050 | wakeup(ata_c); |
989 | else if (ata_c->callback) | | 1051 | else if (ata_c->callback) |
990 | ata_c->callback(ata_c->callback_arg); | | 1052 | ata_c->callback(ata_c->callback_arg); |
991 | atastart(chp); | | 1053 | atastart(chp); |
992 | return; | | 1054 | return; |
993 | } | | 1055 | } |
994 | | | 1056 | |
995 | int | | 1057 | int |
996 | siisata_ata_bio(struct ata_drive_datas *drvp, struct ata_xfer *xfer) | | 1058 | siisata_ata_bio(struct ata_drive_datas *drvp, struct ata_xfer *xfer) |
997 | { | | 1059 | { |
| @@ -1013,58 +1075,57 @@ siisata_ata_bio(struct ata_drive_datas * | | | @@ -1013,58 +1075,57 @@ siisata_ata_bio(struct ata_drive_datas * |
1013 | xfer->c_intr = siisata_bio_complete; | | 1075 | xfer->c_intr = siisata_bio_complete; |
1014 | xfer->c_kill_xfer = siisata_bio_kill_xfer; | | 1076 | xfer->c_kill_xfer = siisata_bio_kill_xfer; |
1015 | ata_exec_xfer(chp, xfer); | | 1077 | ata_exec_xfer(chp, xfer); |
1016 | return (ata_bio->flags & ATA_ITSDONE) ? | | 1078 | return (ata_bio->flags & ATA_ITSDONE) ? |
1017 | ATACMD_COMPLETE : ATACMD_QUEUED; | | 1079 | ATACMD_COMPLETE : ATACMD_QUEUED; |
1018 | } | | 1080 | } |
1019 | | | 1081 | |
1020 | void | | 1082 | void |
1021 | siisata_bio_start(struct ata_channel *chp, struct ata_xfer *xfer) | | 1083 | siisata_bio_start(struct ata_channel *chp, struct ata_xfer *xfer) |
1022 | { | | 1084 | { |
1023 | struct siisata_channel *schp = (struct siisata_channel *)chp; | | 1085 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
1024 | struct siisata_prb *prb; | | 1086 | struct siisata_prb *prb; |
1025 | struct ata_bio *ata_bio = &xfer->c_bio; | | 1087 | struct ata_bio *ata_bio = &xfer->c_bio; |
1026 | int slot = SIISATA_NON_NCQ_SLOT; | | | |
1027 | int i; | | 1088 | int i; |
1028 | | | 1089 | |
1029 | SIISATA_DEBUG_PRINT(("%s: %s port %d, slot %d\n", | | 1090 | SIISATA_DEBUG_PRINT(("%s: %s port %d slot %d drive %d\n", |
1030 | SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__, | | 1091 | SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__, |
1031 | chp->ch_channel, slot), DEBUG_FUNCS); | | 1092 | chp->ch_channel, xfer->c_slot, xfer->c_drive), DEBUG_FUNCS); |
1032 | | | 1093 | |
1033 | chp->ch_status = 0; | | 1094 | chp->ch_status = 0; |
1034 | chp->ch_error = 0; | | 1095 | chp->ch_error = 0; |
1035 | | | 1096 | |
1036 | prb = schp->sch_prb[slot]; | | 1097 | prb = schp->sch_prb[xfer->c_slot]; |
1037 | memset(prb, 0, SIISATA_CMD_SIZE); | | 1098 | memset(prb, 0, SIISATA_CMD_SIZE); |
1038 | | | 1099 | |
1039 | satafis_rhd_construct_bio(xfer, prb->prb_fis); | | 1100 | satafis_rhd_construct_bio(xfer, prb->prb_fis); |
1040 | KASSERT(xfer->c_drive <= PMP_PORT_CTL); | | 1101 | KASSERT(xfer->c_drive <= PMP_PORT_CTL); |
1041 | prb->prb_fis[rhd_c] |= xfer->c_drive; | | 1102 | prb->prb_fis[rhd_c] |= xfer->c_drive; |
1042 | | | 1103 | |
1043 | if (siisata_dma_setup(chp, slot, ata_bio->databuf, ata_bio->bcount, | | 1104 | if (siisata_dma_setup(chp, xfer->c_slot, ata_bio->databuf, ata_bio->bcount, |
1044 | (ata_bio->flags & ATA_READ) ? BUS_DMA_READ : BUS_DMA_WRITE)) { | | 1105 | (ata_bio->flags & ATA_READ) ? BUS_DMA_READ : BUS_DMA_WRITE)) { |
1045 | ata_bio->error = ERR_DMA; | | 1106 | ata_bio->error = ERR_DMA; |
1046 | ata_bio->r_error = 0; | | 1107 | ata_bio->r_error = 0; |
1047 | siisata_bio_complete(chp, xfer, 0); | | 1108 | siisata_bio_complete(chp, xfer, 0); |
1048 | return; | | 1109 | return; |
1049 | } | | 1110 | } |
1050 | | | 1111 | |
1051 | if (xfer->c_flags & C_POLL) { | | 1112 | if (xfer->c_flags & C_POLL) { |
1052 | /* polled command, disable interrupts */ | | 1113 | /* polled command, disable interrupts */ |
1053 | prb->prb_control = htole16(PRB_CF_INTERRUPT_MASK); | | 1114 | prb->prb_control = htole16(PRB_CF_INTERRUPT_MASK); |
1054 | siisata_disable_port_interrupt(chp); | | 1115 | siisata_disable_port_interrupt(chp); |
1055 | } | | 1116 | } |
1056 | | | 1117 | |
1057 | siisata_activate_prb(schp, slot); | | 1118 | siisata_activate_prb(schp, xfer->c_slot); |
1058 | | | 1119 | |
1059 | if ((ata_bio->flags & ATA_POLL) == 0) { | | 1120 | if ((ata_bio->flags & ATA_POLL) == 0) { |
1060 | chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */ | | 1121 | chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */ |
1061 | callout_reset(&xfer->c_timo_callout, mstohz(ATA_DELAY), | | 1122 | callout_reset(&xfer->c_timo_callout, mstohz(ATA_DELAY), |
1062 | siisata_timeout, xfer); | | 1123 | siisata_timeout, xfer); |
1063 | goto out; | | 1124 | goto out; |
1064 | } | | 1125 | } |
1065 | | | 1126 | |
1066 | /* | | 1127 | /* |
1067 | * polled command | | 1128 | * polled command |
1068 | */ | | 1129 | */ |
1069 | for (i = 0; i < ATA_DELAY / 10; i++) { | | 1130 | for (i = 0; i < ATA_DELAY / 10; i++) { |
1070 | if (ata_bio->flags & ATA_ITSDONE) | | 1131 | if (ata_bio->flags & ATA_ITSDONE) |
| @@ -1078,95 +1139,97 @@ out: | | | @@ -1078,95 +1139,97 @@ out: |
1078 | SIISATA_DEBUG_PRINT(("%s: %s: done\n", | | 1139 | SIISATA_DEBUG_PRINT(("%s: %s: done\n", |
1079 | SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__), | | 1140 | SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__), |
1080 | DEBUG_FUNCS); | | 1141 | DEBUG_FUNCS); |
1081 | return; | | 1142 | return; |
1082 | } | | 1143 | } |
1083 | | | 1144 | |
1084 | void | | 1145 | void |
1085 | siisata_bio_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, | | 1146 | siisata_bio_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, |
1086 | int reason) | | 1147 | int reason) |
1087 | { | | 1148 | { |
1088 | struct siisata_channel *schp = (struct siisata_channel *)chp; | | 1149 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
1089 | struct ata_bio *ata_bio = &xfer->c_bio; | | 1150 | struct ata_bio *ata_bio = &xfer->c_bio; |
1090 | int drive = xfer->c_drive; | | 1151 | int drive = xfer->c_drive; |
1091 | int slot = SIISATA_NON_NCQ_SLOT; | | | |
1092 | | | 1152 | |
1093 | SIISATA_DEBUG_PRINT(("%s: %s: port %d\n", | | 1153 | SIISATA_DEBUG_PRINT(("%s: %s: port %d slot %d\n", |
1094 | SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__, | | 1154 | SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__, |
1095 | chp->ch_channel), DEBUG_FUNCS); | | 1155 | chp->ch_channel, xfer->c_slot), DEBUG_FUNCS); |
1096 | | | 1156 | |
1097 | siisata_deactivate_prb(schp, slot); | | 1157 | siisata_deactivate_prb(schp, xfer->c_slot); |
1098 | | | 1158 | |
1099 | ata_bio->flags |= ATA_ITSDONE; | | 1159 | ata_bio->flags |= ATA_ITSDONE; |
1100 | switch (reason) { | | 1160 | switch (reason) { |
1101 | case KILL_GONE: | | 1161 | case KILL_GONE: |
1102 | ata_bio->error = ERR_NODEV; | | 1162 | ata_bio->error = ERR_NODEV; |
1103 | break; | | 1163 | break; |
1104 | case KILL_RESET: | | 1164 | case KILL_RESET: |
1105 | ata_bio->error = ERR_RESET; | | 1165 | ata_bio->error = ERR_RESET; |
1106 | break; | | 1166 | break; |
1107 | default: | | 1167 | default: |
1108 | panic("%s: port %d: unknown reason %d", | | 1168 | panic("%s: port %d: unknown reason %d", |
1109 | __func__, chp->ch_channel, reason); | | 1169 | __func__, chp->ch_channel, reason); |
1110 | } | | 1170 | } |
1111 | ata_bio->r_error = WDCE_ABRT; | | 1171 | ata_bio->r_error = WDCE_ABRT; |
1112 | (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc, xfer); | | 1172 | (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc, xfer); |
1113 | } | | 1173 | } |
1114 | | | 1174 | |
1115 | int | | 1175 | int |
1116 | siisata_bio_complete(struct ata_channel *chp, struct ata_xfer *xfer, int is) | | 1176 | siisata_bio_complete(struct ata_channel *chp, struct ata_xfer *xfer, int is) |
1117 | { | | 1177 | { |
1118 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; | | 1178 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; |
1119 | struct siisata_channel *schp = (struct siisata_channel *)chp; | | 1179 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
1120 | struct ata_bio *ata_bio = &xfer->c_bio; | | 1180 | struct ata_bio *ata_bio = &xfer->c_bio; |
1121 | int drive = xfer->c_drive; | | 1181 | int drive = xfer->c_drive; |
1122 | int slot = SIISATA_NON_NCQ_SLOT; | | | |
1123 | | | 1182 | |
1124 | schp->sch_active_slots &= ~__BIT(slot); | | 1183 | SIISATA_DEBUG_PRINT(("%s: %s: port %d slot %d drive %d\n", |
| | | 1184 | SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__, |
| | | 1185 | chp->ch_channel, xfer->c_slot, xfer->c_drive), DEBUG_FUNCS); |
| | | 1186 | |
| | | 1187 | siisata_deactivate_prb(schp, xfer->c_slot); |
1125 | chp->ch_flags &= ~ATACH_IRQ_WAIT; | | 1188 | chp->ch_flags &= ~ATACH_IRQ_WAIT; |
1126 | if (xfer->c_flags & C_TIMEOU) { | | 1189 | if (xfer->c_flags & C_TIMEOU) { |
1127 | ata_bio->error = TIMEOUT; | | 1190 | ata_bio->error = TIMEOUT; |
1128 | } else { | | 1191 | } else { |
1129 | callout_stop(&xfer->c_timo_callout); | | 1192 | callout_stop(&xfer->c_timo_callout); |
1130 | ata_bio->error = NOERROR; | | 1193 | ata_bio->error = NOERROR; |
1131 | } | | 1194 | } |
1132 | | | 1195 | |
1133 | bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[slot], 0, | | 1196 | bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[xfer->c_slot], 0, |
1134 | schp->sch_datad[slot]->dm_mapsize, | | 1197 | schp->sch_datad[xfer->c_slot]->dm_mapsize, |
1135 | (ata_bio->flags & ATA_READ) ? BUS_DMASYNC_POSTREAD : | | 1198 | (ata_bio->flags & ATA_READ) ? BUS_DMASYNC_POSTREAD : |
1136 | BUS_DMASYNC_POSTWRITE); | | 1199 | BUS_DMASYNC_POSTWRITE); |
1137 | bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[slot]); | | 1200 | bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[xfer->c_slot]); |
1138 | | | 1201 | |
1139 | ata_deactivate_xfer(chp, xfer); | | 1202 | ata_deactivate_xfer(chp, xfer); |
1140 | | | 1203 | |
1141 | if (ata_waitdrain_xfer_check(chp, xfer)) { | | 1204 | if (ata_waitdrain_xfer_check(chp, xfer)) { |
1142 | return 0; | | 1205 | return 0; |
1143 | } | | 1206 | } |
1144 | | | 1207 | |
1145 | ata_bio->flags |= ATA_ITSDONE; | | 1208 | ata_bio->flags |= ATA_ITSDONE; |
1146 | if (chp->ch_status & WDCS_DWF) { | | 1209 | if (chp->ch_status & WDCS_DWF) { |
1147 | ata_bio->error = ERR_DF; | | 1210 | ata_bio->error = ERR_DF; |
1148 | } else if (chp->ch_status & WDCS_ERR) { | | 1211 | } else if (chp->ch_status & WDCS_ERR) { |
1149 | ata_bio->error = ERROR; | | 1212 | ata_bio->error = ERROR; |
1150 | ata_bio->r_error = chp->ch_error; | | 1213 | ata_bio->r_error = chp->ch_error; |
1151 | } else if (chp->ch_status & WDCS_CORR) | | 1214 | } else if (chp->ch_status & WDCS_CORR) |
1152 | ata_bio->flags |= ATA_CORR; | | 1215 | ata_bio->flags |= ATA_CORR; |
1153 | | | 1216 | |
1154 | SIISATA_DEBUG_PRINT(("%s: %s bcount: %ld", SIISATANAME(sc), __func__, | | 1217 | SIISATA_DEBUG_PRINT(("%s: %s bcount: %ld", SIISATANAME(sc), __func__, |
1155 | ata_bio->bcount), DEBUG_XFERS); | | 1218 | ata_bio->bcount), DEBUG_XFERS); |
1156 | if (ata_bio->error == NOERROR) { | | 1219 | if (ata_bio->error == NOERROR) { |
1157 | if (ata_bio->flags & ATA_READ) | | 1220 | if (ata_bio->flags & ATA_READ) |
1158 | ata_bio->bcount -= | | 1221 | ata_bio->bcount -= |
1159 | PRREAD(sc, PRSX(chp->ch_channel, slot, PRSO_RTC)); | | 1222 | PRREAD(sc, PRSX(chp->ch_channel, xfer->c_slot, PRSO_RTC)); |
1160 | else | | 1223 | else |
1161 | ata_bio->bcount = 0; | | 1224 | ata_bio->bcount = 0; |
1162 | } | | 1225 | } |
1163 | SIISATA_DEBUG_PRINT((" now %ld\n", ata_bio->bcount), DEBUG_XFERS); | | 1226 | SIISATA_DEBUG_PRINT((" now %ld\n", ata_bio->bcount), DEBUG_XFERS); |
1164 | if (ata_bio->flags & ATA_POLL) | | 1227 | if (ata_bio->flags & ATA_POLL) |
1165 | return 1; | | 1228 | return 1; |
1166 | (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc, xfer); | | 1229 | (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc, xfer); |
1167 | atastart(chp); | | 1230 | atastart(chp); |
1168 | return 0; | | 1231 | return 0; |
1169 | } | | 1232 | } |
1170 | | | 1233 | |
1171 | void | | 1234 | void |
1172 | siisata_timeout(void *v) | | 1235 | siisata_timeout(void *v) |
| @@ -1346,26 +1409,29 @@ siisata_atapi_kill_pending(struct scsipi | | | @@ -1346,26 +1409,29 @@ siisata_atapi_kill_pending(struct scsipi |
1346 | struct atac_softc *atac = | | 1409 | struct atac_softc *atac = |
1347 | device_private(periph->periph_channel->chan_adapter->adapt_dev); | | 1410 | device_private(periph->periph_channel->chan_adapter->adapt_dev); |
1348 | struct ata_channel *chp = | | 1411 | struct ata_channel *chp = |
1349 | atac->atac_channels[periph->periph_channel->chan_channel]; | | 1412 | atac->atac_channels[periph->periph_channel->chan_channel]; |
1350 | | | 1413 | |
1351 | ata_kill_pending(&chp->ch_drive[periph->periph_target]); | | 1414 | ata_kill_pending(&chp->ch_drive[periph->periph_target]); |
1352 | } | | 1415 | } |
1353 | | | 1416 | |
1354 | void | | 1417 | void |
1355 | siisata_atapi_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, | | 1418 | siisata_atapi_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, |
1356 | int reason) | | 1419 | int reason) |
1357 | { | | 1420 | { |
1358 | struct scsipi_xfer *sc_xfer = xfer->c_scsipi; | | 1421 | struct scsipi_xfer *sc_xfer = xfer->c_scsipi; |
| | | 1422 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
| | | 1423 | |
| | | 1424 | siisata_deactivate_prb(schp, xfer->c_slot); |
1359 | | | 1425 | |
1360 | /* remove this command from xfer queue */ | | 1426 | /* remove this command from xfer queue */ |
1361 | switch (reason) { | | 1427 | switch (reason) { |
1362 | case KILL_GONE: | | 1428 | case KILL_GONE: |
1363 | sc_xfer->error = XS_DRIVER_STUFFUP; | | 1429 | sc_xfer->error = XS_DRIVER_STUFFUP; |
1364 | break; | | 1430 | break; |
1365 | case KILL_RESET: | | 1431 | case KILL_RESET: |
1366 | sc_xfer->error = XS_RESET; | | 1432 | sc_xfer->error = XS_RESET; |
1367 | break; | | 1433 | break; |
1368 | default: | | 1434 | default: |
1369 | panic("%s: port %d: unknown reason %d", | | 1435 | panic("%s: port %d: unknown reason %d", |
1370 | __func__, chp->ch_channel, reason); | | 1436 | __func__, chp->ch_channel, reason); |
1371 | } | | 1437 | } |
| @@ -1543,70 +1609,68 @@ siisata_atapi_scsipi_request(struct scsi | | | @@ -1543,70 +1609,68 @@ siisata_atapi_scsipi_request(struct scsi |
1543 | default: | | 1609 | default: |
1544 | /* Not supported, nothing to do. */ | | 1610 | /* Not supported, nothing to do. */ |
1545 | ; | | 1611 | ; |
1546 | } | | 1612 | } |
1547 | } | | 1613 | } |
1548 | | | 1614 | |
1549 | void | | 1615 | void |
1550 | siisata_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer) | | 1616 | siisata_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer) |
1551 | { | | 1617 | { |
1552 | struct siisata_channel *schp = (struct siisata_channel *)chp; | | 1618 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
1553 | struct siisata_prb *prbp; | | 1619 | struct siisata_prb *prbp; |
1554 | | | 1620 | |
1555 | struct scsipi_xfer *sc_xfer = xfer->c_scsipi; | | 1621 | struct scsipi_xfer *sc_xfer = xfer->c_scsipi; |
1556 | | | | |
1557 | int slot = SIISATA_NON_NCQ_SLOT; | | | |
1558 | int i; | | 1622 | int i; |
1559 | | | 1623 | |
1560 | SIISATA_DEBUG_PRINT( ("%s: %s:%d:%d, scsi flags 0x%x\n", __func__, | | 1624 | SIISATA_DEBUG_PRINT( ("%s: %s:%d:%d, scsi flags 0x%x\n", __func__, |
1561 | SIISATANAME((struct siisata_softc *)chp->ch_atac), chp->ch_channel, | | 1625 | SIISATANAME((struct siisata_softc *)chp->ch_atac), chp->ch_channel, |
1562 | chp->ch_drive[xfer->c_drive].drive, sc_xfer->xs_control), | | 1626 | chp->ch_drive[xfer->c_drive].drive, sc_xfer->xs_control), |
1563 | DEBUG_XFERS); | | 1627 | DEBUG_XFERS); |
1564 | | | 1628 | |
1565 | chp->ch_status = 0; | | 1629 | chp->ch_status = 0; |
1566 | chp->ch_error = 0; | | 1630 | chp->ch_error = 0; |
1567 | | | 1631 | |
1568 | prbp = schp->sch_prb[slot]; | | 1632 | prbp = schp->sch_prb[xfer->c_slot]; |
1569 | memset(prbp, 0, SIISATA_CMD_SIZE); | | 1633 | memset(prbp, 0, SIISATA_CMD_SIZE); |
1570 | | | 1634 | |
1571 | /* fill in direction for ATAPI command */ | | 1635 | /* fill in direction for ATAPI command */ |
1572 | if ((sc_xfer->xs_control & XS_CTL_DATA_IN)) | | 1636 | if ((sc_xfer->xs_control & XS_CTL_DATA_IN)) |
1573 | prbp->prb_control |= htole16(PRB_CF_PACKET_READ); | | 1637 | prbp->prb_control |= htole16(PRB_CF_PACKET_READ); |
1574 | if ((sc_xfer->xs_control & XS_CTL_DATA_OUT)) | | 1638 | if ((sc_xfer->xs_control & XS_CTL_DATA_OUT)) |
1575 | prbp->prb_control |= htole16(PRB_CF_PACKET_WRITE); | | 1639 | prbp->prb_control |= htole16(PRB_CF_PACKET_WRITE); |
1576 | | | 1640 | |
1577 | satafis_rhd_construct_atapi(xfer, prbp->prb_fis); | | 1641 | satafis_rhd_construct_atapi(xfer, prbp->prb_fis); |
1578 | KASSERT(xfer->c_drive <= PMP_PORT_CTL); | | 1642 | KASSERT(xfer->c_drive <= PMP_PORT_CTL); |
1579 | prbp->prb_fis[rhd_c] |= xfer->c_drive; | | 1643 | prbp->prb_fis[rhd_c] |= xfer->c_drive; |
1580 | | | 1644 | |
1581 | /* copy over ATAPI command */ | | 1645 | /* copy over ATAPI command */ |
1582 | memcpy(prbp->prb_atapi, sc_xfer->cmd, sc_xfer->cmdlen); | | 1646 | memcpy(prbp->prb_atapi, sc_xfer->cmd, sc_xfer->cmdlen); |
1583 | | | 1647 | |
1584 | if (siisata_dma_setup(chp, slot, | | 1648 | if (siisata_dma_setup(chp, xfer->c_slot, |
1585 | (sc_xfer->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) ? | | 1649 | (sc_xfer->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) ? |
1586 | xfer->c_databuf : NULL, | | 1650 | xfer->c_databuf : NULL, |
1587 | xfer->c_bcount, | | 1651 | xfer->c_bcount, |
1588 | (sc_xfer->xs_control & XS_CTL_DATA_IN) ? | | 1652 | (sc_xfer->xs_control & XS_CTL_DATA_IN) ? |
1589 | BUS_DMA_READ : BUS_DMA_WRITE) | | 1653 | BUS_DMA_READ : BUS_DMA_WRITE) |
1590 | ) | | 1654 | ) |
1591 | panic("%s", __func__); | | 1655 | panic("%s", __func__); |
1592 | | | 1656 | |
1593 | if (xfer->c_flags & C_POLL) { | | 1657 | if (xfer->c_flags & C_POLL) { |
1594 | /* polled command, disable interrupts */ | | 1658 | /* polled command, disable interrupts */ |
1595 | prbp->prb_control = htole16(PRB_CF_INTERRUPT_MASK); | | 1659 | prbp->prb_control = htole16(PRB_CF_INTERRUPT_MASK); |
1596 | siisata_disable_port_interrupt(chp); | | 1660 | siisata_disable_port_interrupt(chp); |
1597 | } | | 1661 | } |
1598 | | | 1662 | |
1599 | siisata_activate_prb(schp, slot); | | 1663 | siisata_activate_prb(schp, xfer->c_slot); |
1600 | | | 1664 | |
1601 | if ((xfer->c_flags & C_POLL) == 0) { | | 1665 | if ((xfer->c_flags & C_POLL) == 0) { |
1602 | chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */ | | 1666 | chp->ch_flags |= ATACH_IRQ_WAIT; /* wait for interrupt */ |
1603 | callout_reset(&xfer->c_timo_callout, mstohz(sc_xfer->timeout), | | 1667 | callout_reset(&xfer->c_timo_callout, mstohz(sc_xfer->timeout), |
1604 | siisata_timeout, xfer); | | 1668 | siisata_timeout, xfer); |
1605 | goto out; | | 1669 | goto out; |
1606 | } | | 1670 | } |
1607 | | | 1671 | |
1608 | /* | | 1672 | /* |
1609 | * polled command | | 1673 | * polled command |
1610 | */ | | 1674 | */ |
1611 | for (i = 0; i < ATA_DELAY / 10; i++) { | | 1675 | for (i = 0; i < ATA_DELAY / 10; i++) { |
1612 | if (sc_xfer->xs_status & XS_STS_DONE) | | 1676 | if (sc_xfer->xs_status & XS_STS_DONE) |
| @@ -1623,57 +1687,57 @@ out: | | | @@ -1623,57 +1687,57 @@ out: |
1623 | SIISATA_DEBUG_PRINT(("%s: %s: done\n", | | 1687 | SIISATA_DEBUG_PRINT(("%s: %s: done\n", |
1624 | SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__), | | 1688 | SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__), |
1625 | DEBUG_FUNCS); | | 1689 | DEBUG_FUNCS); |
1626 | return; | | 1690 | return; |
1627 | } | | 1691 | } |
1628 | | | 1692 | |
1629 | int | | 1693 | int |
1630 | siisata_atapi_complete(struct ata_channel *chp, struct ata_xfer *xfer, | | 1694 | siisata_atapi_complete(struct ata_channel *chp, struct ata_xfer *xfer, |
1631 | int is) | | 1695 | int is) |
1632 | { | | 1696 | { |
1633 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; | | 1697 | struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; |
1634 | struct siisata_channel *schp = (struct siisata_channel *)chp; | | 1698 | struct siisata_channel *schp = (struct siisata_channel *)chp; |
1635 | struct scsipi_xfer *sc_xfer = xfer->c_scsipi; | | 1699 | struct scsipi_xfer *sc_xfer = xfer->c_scsipi; |
1636 | int slot = SIISATA_NON_NCQ_SLOT; | | | |
1637 | | | 1700 | |
1638 | SIISATA_DEBUG_PRINT(("%s: %s()\n", SIISATANAME(sc), __func__), | | 1701 | SIISATA_DEBUG_PRINT(("%s: %s()\n", SIISATANAME(sc), __func__), |
1639 | DEBUG_INTR); | | 1702 | DEBUG_INTR); |
1640 | | | 1703 | |
1641 | /* this command is not active any more */ | | 1704 | /* this command is not active any more */ |
1642 | schp->sch_active_slots &= ~__BIT(slot); | | 1705 | siisata_deactivate_prb(schp, xfer->c_slot); |
1643 | chp->ch_flags &= ~ATACH_IRQ_WAIT; | | 1706 | chp->ch_flags &= ~ATACH_IRQ_WAIT; |
1644 | if (xfer->c_flags & C_TIMEOU) { | | 1707 | if (xfer->c_flags & C_TIMEOU) { |
1645 | sc_xfer->error = XS_TIMEOUT; | | 1708 | sc_xfer->error = XS_TIMEOUT; |
1646 | } else { | | 1709 | } else { |
1647 | callout_stop(&xfer->c_timo_callout); | | 1710 | callout_stop(&xfer->c_timo_callout); |
1648 | sc_xfer->error = XS_NOERROR; | | 1711 | sc_xfer->error = XS_NOERROR; |
1649 | } | | 1712 | } |
1650 | | | 1713 | |
1651 | bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[slot], 0, | | 1714 | bus_dmamap_sync(sc->sc_dmat, schp->sch_datad[xfer->c_slot], 0, |
1652 | schp->sch_datad[slot]->dm_mapsize, | | 1715 | schp->sch_datad[xfer->c_slot]->dm_mapsize, |
1653 | (sc_xfer->xs_control & XS_CTL_DATA_IN) ? | | 1716 | (sc_xfer->xs_control & XS_CTL_DATA_IN) ? |
1654 | BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); | | 1717 | BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); |
1655 | bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[slot]); | | 1718 | bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[xfer->c_slot]); |
1656 | | | 1719 | |
1657 | ata_deactivate_xfer(chp, xfer); | | 1720 | ata_deactivate_xfer(chp, xfer); |
1658 | | | 1721 | |
1659 | if (ata_waitdrain_xfer_check(chp, xfer)) { | | 1722 | if (ata_waitdrain_xfer_check(chp, xfer)) { |
1660 | sc_xfer->error = XS_DRIVER_STUFFUP; | | 1723 | sc_xfer->error = XS_DRIVER_STUFFUP; |
1661 | return 0; /* XXX verify */ | | 1724 | return 0; /* XXX verify */ |
1662 | } | | 1725 | } |
1663 | | | 1726 | |
1664 | ata_free_xfer(chp, xfer); | | 1727 | ata_free_xfer(chp, xfer); |
1665 | sc_xfer->resid = sc_xfer->datalen; | | 1728 | sc_xfer->resid = sc_xfer->datalen; |
1666 | sc_xfer->resid -= PRREAD(sc, PRSX(chp->ch_channel, slot, PRSO_RTC)); | | 1729 | sc_xfer->resid -= PRREAD(sc, PRSX(chp->ch_channel, xfer->c_slot, |
| | | 1730 | PRSO_RTC)); |
1667 | SIISATA_DEBUG_PRINT(("%s: %s datalen %d resid %d\n", SIISATANAME(sc), | | 1731 | SIISATA_DEBUG_PRINT(("%s: %s datalen %d resid %d\n", SIISATANAME(sc), |
1668 | __func__, sc_xfer->datalen, sc_xfer->resid), DEBUG_XFERS); | | 1732 | __func__, sc_xfer->datalen, sc_xfer->resid), DEBUG_XFERS); |
1669 | if ((chp->ch_status & WDCS_ERR) && | | 1733 | if ((chp->ch_status & WDCS_ERR) && |
1670 | ((sc_xfer->xs_control & XS_CTL_REQSENSE) == 0 || | | 1734 | ((sc_xfer->xs_control & XS_CTL_REQSENSE) == 0 || |
1671 | sc_xfer->resid == sc_xfer->datalen)) { | | 1735 | sc_xfer->resid == sc_xfer->datalen)) { |
1672 | sc_xfer->error = XS_SHORTSENSE; | | 1736 | sc_xfer->error = XS_SHORTSENSE; |
1673 | sc_xfer->sense.atapi_sense = chp->ch_error; | | 1737 | sc_xfer->sense.atapi_sense = chp->ch_error; |
1674 | if ((sc_xfer->xs_periph->periph_quirks & | | 1738 | if ((sc_xfer->xs_periph->periph_quirks & |
1675 | PQUIRK_NOSENSE) == 0) { | | 1739 | PQUIRK_NOSENSE) == 0) { |
1676 | /* request sense */ | | 1740 | /* request sense */ |
1677 | sc_xfer->error = XS_BUSY; | | 1741 | sc_xfer->error = XS_BUSY; |
1678 | sc_xfer->status = SCSI_CHECK; | | 1742 | sc_xfer->status = SCSI_CHECK; |
1679 | } | | 1743 | } |