1 1.11 fvdl /* 2 1.11 fvdl * Adaptec 274x/284x/294x device driver firmware for Linux and FreeBSD. 3 1.2 mycroft * 4 1.14 fvdl * Copyright (c) 1994-2001 Justin T. Gibbs. 5 1.14 fvdl * Copyright (c) 2000-2001 Adaptec Inc. 6 1.11 fvdl * All rights reserved. 7 1.2 mycroft * 8 1.11 fvdl * Redistribution and use in source and binary forms, with or without 9 1.11 fvdl * modification, are permitted provided that the following conditions 10 1.11 fvdl * are met: 11 1.11 fvdl * 1. Redistributions of source code must retain the above copyright 12 1.11 fvdl * notice, this list of conditions, and the following disclaimer, 13 1.11 fvdl * without modification. 14 1.14 fvdl * 2. Redistributions in binary form must reproduce at minimum a disclaimer 15 1.14 fvdl * substantially similar to the "NO WARRANTY" disclaimer below 16 1.14 fvdl * ("Disclaimer") and any redistribution must be conditioned upon 17 1.14 fvdl * including a substantially similar Disclaimer requirement for further 18 1.14 fvdl * binary redistribution. 19 1.14 fvdl * 3. Neither the names of the above-listed copyright holders nor the names 20 1.14 fvdl * of any contributors may be used to endorse or promote products derived 21 1.14 fvdl * from this software without specific prior written permission. 22 1.2 mycroft * 23 1.11 fvdl * Alternatively, this software may be distributed under the terms of the 24 1.14 fvdl * GNU General Public License ("GPL") version 2 as published by the Free 25 1.14 fvdl * Software Foundation. 26 1.2 mycroft * 27 1.14 fvdl * NO WARRANTY 28 1.14 fvdl * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 1.14 fvdl * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 1.14 fvdl * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 31 1.14 fvdl * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 1.14 fvdl * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 1.11 fvdl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 1.11 fvdl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 1.14 fvdl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 36 1.14 fvdl * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 37 1.14 fvdl * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 1.14 fvdl * POSSIBILITY OF SUCH DAMAGES. 39 1.2 mycroft * 40 1.14 fvdl * $FreeBSD: /repoman/r/ncvs/src/sys/dev/aic7xxx/aic7xxx.seq,v 1.123 2003/01/20 20:44:55 gibbs Exp $ 41 1.11 fvdl */ 42 1.2 mycroft 43 1.24 andvar VERSION = "$NetBSD: aic7xxx.seq,v 1.24 2024/02/10 08:36:04 andvar Exp $" 44 1.14 fvdl PATCH_ARG_LIST = "struct ahc_softc *ahc" 45 1.14 fvdl PREFIX = "ahc_" 46 1.14 fvdl 47 1.11 fvdl #include <dev/microcode/aic7xxx/aic7xxx.reg> 48 1.11 fvdl #include <dev/scsipi/scsi_message.h> 49 1.2 mycroft 50 1.11 fvdl /* 51 1.11 fvdl * A few words on the waiting SCB list: 52 1.11 fvdl * After starting the selection hardware, we check for reconnecting targets 53 1.2 mycroft * as well as for our selection to complete just in case the reselection wins 54 1.2 mycroft * bus arbitration. The problem with this is that we must keep track of the 55 1.2 mycroft * SCB that we've already pulled from the QINFIFO and started the selection 56 1.2 mycroft * on just in case the reselection wins so that we can retry the selection at 57 1.2 mycroft * a later time. This problem cannot be resolved by holding a single entry 58 1.2 mycroft * in scratch ram since a reconnecting target can request sense and this will 59 1.16 perry * create yet another SCB waiting for selection. The solution used here is to 60 1.24 andvar * use byte 27 of the SCB as a pseudo-next pointer and to thread a list 61 1.16 perry * of SCBs that are awaiting selection. Since 0-0xfe are valid SCB indexes, 62 1.11 fvdl * SCB_LIST_NULL is 0xff which is out of range. An entry is also added to 63 1.11 fvdl * this list everytime a request sense occurs or after completing a non-tagged 64 1.11 fvdl * command for which a second SCB has been queued. The sequencer will 65 1.11 fvdl * automatically consume the entries. 66 1.2 mycroft */ 67 1.2 mycroft 68 1.14 fvdl bus_free_sel: 69 1.14 fvdl /* 70 1.14 fvdl * Turn off the selection hardware. We need to reset the 71 1.14 fvdl * selection request in order to perform a new selection. 72 1.14 fvdl */ 73 1.14 fvdl and SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP; 74 1.14 fvdl and SIMODE1, ~ENBUSFREE; 75 1.1 mycroft poll_for_work: 76 1.11 fvdl call clear_target_state; 77 1.11 fvdl and SXFRCTL0, ~SPIOEN; 78 1.14 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 79 1.14 fvdl clr SCSIBUSL; 80 1.14 fvdl } 81 1.14 fvdl test SCSISEQ, ENSELO jnz poll_for_selection; 82 1.14 fvdl if ((ahc->features & AHC_TWIN) != 0) { 83 1.14 fvdl xor SBLKCTL,SELBUSB; /* Toggle to the other bus */ 84 1.14 fvdl test SCSISEQ, ENSELO jnz poll_for_selection; 85 1.11 fvdl } 86 1.14 fvdl cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting; 87 1.11 fvdl poll_for_work_loop: 88 1.11 fvdl if ((ahc->features & AHC_TWIN) != 0) { 89 1.11 fvdl xor SBLKCTL,SELBUSB; /* Toggle to the other bus */ 90 1.11 fvdl } 91 1.14 fvdl test SSTAT0, SELDO|SELDI jnz selection; 92 1.11 fvdl test_queue: 93 1.11 fvdl /* Has the driver posted any work for us? */ 94 1.14 fvdl BEGIN_CRITICAL; 95 1.11 fvdl if ((ahc->features & AHC_QUEUE_REGS) != 0) { 96 1.11 fvdl test QOFF_CTLSTA, SCB_AVAIL jz poll_for_work_loop; 97 1.11 fvdl } else { 98 1.14 fvdl mov A, QINPOS; 99 1.11 fvdl cmp KERNEL_QINPOS, A je poll_for_work_loop; 100 1.11 fvdl } 101 1.14 fvdl mov ARG_1, NEXT_QUEUED_SCB; 102 1.2 mycroft 103 1.14 fvdl /* 104 1.16 perry * We have at least one queued SCB now and we don't have any 105 1.14 fvdl * SCBs in the list of SCBs awaiting selection. Allocate a 106 1.14 fvdl * card SCB for the host's SCB and get to work on it. 107 1.14 fvdl */ 108 1.11 fvdl if ((ahc->flags & AHC_PAGESCBS) != 0) { 109 1.11 fvdl mov ALLZEROS call get_free_or_disc_scb; 110 1.14 fvdl } else { 111 1.11 fvdl /* In the non-paging case, the SCBID == hardware SCB index */ 112 1.14 fvdl mov SCBPTR, ARG_1; 113 1.11 fvdl } 114 1.14 fvdl or SEQ_FLAGS2, SCB_DMA; 115 1.14 fvdl END_CRITICAL; 116 1.11 fvdl dma_queued_scb: 117 1.14 fvdl /* 118 1.14 fvdl * DMA the SCB from host ram into the current SCB location. 119 1.14 fvdl */ 120 1.11 fvdl mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 121 1.14 fvdl mov ARG_1 call dma_scb; 122 1.11 fvdl /* 123 1.14 fvdl * Check one last time to see if this SCB was canceled 124 1.14 fvdl * before we completed the DMA operation. If it was, 125 1.14 fvdl * the QINFIFO next pointer will not match our saved 126 1.14 fvdl * value. 127 1.11 fvdl */ 128 1.14 fvdl mov A, ARG_1; 129 1.14 fvdl BEGIN_CRITICAL; 130 1.14 fvdl cmp NEXT_QUEUED_SCB, A jne abort_qinscb; 131 1.14 fvdl if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { 132 1.14 fvdl cmp SCB_TAG, A je . + 2; 133 1.14 fvdl mvi SCB_MISMATCH call set_seqint; 134 1.14 fvdl } 135 1.14 fvdl mov NEXT_QUEUED_SCB, SCB_NEXT; 136 1.11 fvdl mov SCB_NEXT,WAITING_SCBH; 137 1.11 fvdl mov WAITING_SCBH, SCBPTR; 138 1.14 fvdl if ((ahc->features & AHC_QUEUE_REGS) != 0) { 139 1.14 fvdl mov NONE, SNSCB_QOFF; 140 1.14 fvdl } else { 141 1.14 fvdl inc QINPOS; 142 1.14 fvdl } 143 1.14 fvdl and SEQ_FLAGS2, ~SCB_DMA; 144 1.14 fvdl END_CRITICAL; 145 1.11 fvdl start_waiting: 146 1.11 fvdl /* 147 1.14 fvdl * Start the first entry on the waiting SCB list. 148 1.11 fvdl */ 149 1.11 fvdl mov SCBPTR, WAITING_SCBH; 150 1.11 fvdl call start_selection; 151 1.1 mycroft 152 1.14 fvdl poll_for_selection: 153 1.14 fvdl /* 154 1.14 fvdl * Twin channel devices cannot handle things like SELTO 155 1.14 fvdl * interrupts on the "background" channel. So, while 156 1.14 fvdl * selecting, keep polling the current channel until 157 1.14 fvdl * either a selection or reselection occurs. 158 1.14 fvdl */ 159 1.14 fvdl test SSTAT0, SELDO|SELDI jz poll_for_selection; 160 1.11 fvdl 161 1.14 fvdl selection: 162 1.14 fvdl /* 163 1.14 fvdl * We aren't expecting a bus free, so interrupt 164 1.14 fvdl * the kernel driver if it happens. 165 1.14 fvdl */ 166 1.14 fvdl mvi CLRSINT1,CLRBUSFREE; 167 1.14 fvdl if ((ahc->features & AHC_DT) == 0) { 168 1.14 fvdl or SIMODE1, ENBUSFREE; 169 1.11 fvdl } 170 1.11 fvdl 171 1.14 fvdl /* 172 1.14 fvdl * Guard against a bus free after (re)selection 173 1.14 fvdl * but prior to enabling the busfree interrupt. SELDI 174 1.14 fvdl * and SELDO will be cleared in that case. 175 1.14 fvdl */ 176 1.14 fvdl test SSTAT0, SELDI|SELDO jz bus_free_sel; 177 1.11 fvdl test SSTAT0,SELDO jnz select_out; 178 1.11 fvdl select_in: 179 1.14 fvdl if ((ahc->flags & AHC_TARGETROLE) != 0) { 180 1.14 fvdl if ((ahc->flags & AHC_INITIATORROLE) != 0) { 181 1.11 fvdl test SSTAT0, TARGET jz initiator_reselect; 182 1.11 fvdl } 183 1.14 fvdl mvi CLRSINT0, CLRSELDI; 184 1.11 fvdl 185 1.11 fvdl /* 186 1.11 fvdl * We've just been selected. Assert BSY and 187 1.11 fvdl * setup the phase for receiving messages 188 1.11 fvdl * from the target. 189 1.11 fvdl */ 190 1.11 fvdl mvi SCSISIGO, P_MESGOUT|BSYO; 191 1.11 fvdl 192 1.11 fvdl /* 193 1.11 fvdl * Setup the DMA for sending the identify and 194 1.11 fvdl * command information. 195 1.11 fvdl */ 196 1.14 fvdl mvi SEQ_FLAGS, CMDPHASE_PENDING; 197 1.11 fvdl 198 1.11 fvdl mov A, TQINPOS; 199 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 200 1.11 fvdl mvi DINDEX, CCHADDR; 201 1.14 fvdl mvi SHARED_DATA_ADDR call set_32byte_addr; 202 1.11 fvdl mvi CCSCBCTL, CCSCBRESET; 203 1.11 fvdl } else { 204 1.11 fvdl mvi DINDEX, HADDR; 205 1.14 fvdl mvi SHARED_DATA_ADDR call set_32byte_addr; 206 1.11 fvdl mvi DFCNTRL, FIFORESET; 207 1.11 fvdl } 208 1.11 fvdl 209 1.11 fvdl /* Initiator that selected us */ 210 1.14 fvdl and SAVED_SCSIID, SELID_MASK, SELID; 211 1.14 fvdl /* The Target ID we were selected at */ 212 1.14 fvdl if ((ahc->features & AHC_MULTI_TID) != 0) { 213 1.14 fvdl and A, OID, TARGIDIN; 214 1.14 fvdl } else if ((ahc->features & AHC_ULTRA2) != 0) { 215 1.14 fvdl and A, OID, SCSIID_ULTRA2; 216 1.11 fvdl } else { 217 1.14 fvdl and A, OID, SCSIID; 218 1.14 fvdl } 219 1.14 fvdl or SAVED_SCSIID, A; 220 1.14 fvdl if ((ahc->features & AHC_TWIN) != 0) { 221 1.14 fvdl test SBLKCTL, SELBUSB jz . + 2; 222 1.14 fvdl or SAVED_SCSIID, TWIN_CHNLB; 223 1.11 fvdl } 224 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 225 1.14 fvdl mov CCSCBRAM, SAVED_SCSIID; 226 1.11 fvdl } else { 227 1.14 fvdl mov DFDAT, SAVED_SCSIID; 228 1.11 fvdl } 229 1.11 fvdl 230 1.11 fvdl /* 231 1.11 fvdl * If ATN isn't asserted, the target isn't interested 232 1.11 fvdl * in talking to us. Go directly to bus free. 233 1.14 fvdl * XXX SCSI-1 may require us to assume lun 0 if 234 1.14 fvdl * ATN is false. 235 1.11 fvdl */ 236 1.11 fvdl test SCSISIGI, ATNI jz target_busfree; 237 1.11 fvdl 238 1.11 fvdl /* 239 1.11 fvdl * Watch ATN closely now as we pull in messages from the 240 1.11 fvdl * initiator. We follow the guidlines from section 6.5 241 1.11 fvdl * of the SCSI-2 spec for what messages are allowed when. 242 1.11 fvdl */ 243 1.11 fvdl call target_inb; 244 1.11 fvdl 245 1.11 fvdl /* 246 1.11 fvdl * Our first message must be one of IDENTIFY, ABORT, or 247 1.11 fvdl * BUS_DEVICE_RESET. 248 1.11 fvdl */ 249 1.11 fvdl test DINDEX, MSG_IDENTIFYFLAG jz host_target_message_loop; 250 1.11 fvdl /* Store for host */ 251 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 252 1.11 fvdl mov CCSCBRAM, DINDEX; 253 1.11 fvdl } else { 254 1.11 fvdl mov DFDAT, DINDEX; 255 1.11 fvdl } 256 1.14 fvdl and SAVED_LUN, MSG_IDENTIFY_LUNMASK, DINDEX; 257 1.11 fvdl 258 1.11 fvdl /* Remember for disconnection decision */ 259 1.11 fvdl test DINDEX, MSG_IDENTIFY_DISCFLAG jnz . + 2; 260 1.11 fvdl /* XXX Honor per target settings too */ 261 1.11 fvdl or SEQ_FLAGS, NO_DISCONNECT; 262 1.11 fvdl 263 1.11 fvdl test SCSISIGI, ATNI jz ident_messages_done; 264 1.11 fvdl call target_inb; 265 1.11 fvdl /* 266 1.11 fvdl * If this is a tagged request, the tagged message must 267 1.11 fvdl * immediately follow the identify. We test for a valid 268 1.11 fvdl * tag message by seeing if it is >= MSG_SIMPLE_Q_TAG and 269 1.11 fvdl * < MSG_IGN_WIDE_RESIDUE. 270 1.11 fvdl */ 271 1.11 fvdl add A, -MSG_SIMPLE_Q_TAG, DINDEX; 272 1.14 fvdl jnc ident_messages_done_msg_pending; 273 1.11 fvdl add A, -MSG_IGN_WIDE_RESIDUE, DINDEX; 274 1.14 fvdl jc ident_messages_done_msg_pending; 275 1.14 fvdl 276 1.11 fvdl /* Store for host */ 277 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 278 1.11 fvdl mov CCSCBRAM, DINDEX; 279 1.11 fvdl } else { 280 1.11 fvdl mov DFDAT, DINDEX; 281 1.11 fvdl } 282 1.16 perry 283 1.11 fvdl /* 284 1.11 fvdl * If the initiator doesn't feel like providing a tag number, 285 1.11 fvdl * we've got a failed selection and must transition to bus 286 1.11 fvdl * free. 287 1.11 fvdl */ 288 1.11 fvdl test SCSISIGI, ATNI jz target_busfree; 289 1.11 fvdl 290 1.11 fvdl /* 291 1.11 fvdl * Store the tag for the host. 292 1.11 fvdl */ 293 1.11 fvdl call target_inb; 294 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 295 1.11 fvdl mov CCSCBRAM, DINDEX; 296 1.11 fvdl } else { 297 1.11 fvdl mov DFDAT, DINDEX; 298 1.11 fvdl } 299 1.11 fvdl mov INITIATOR_TAG, DINDEX; 300 1.14 fvdl or SEQ_FLAGS, TARGET_CMD_IS_TAGGED; 301 1.11 fvdl 302 1.11 fvdl ident_messages_done: 303 1.11 fvdl /* Terminate the ident list */ 304 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 305 1.11 fvdl mvi CCSCBRAM, SCB_LIST_NULL; 306 1.11 fvdl } else { 307 1.11 fvdl mvi DFDAT, SCB_LIST_NULL; 308 1.11 fvdl } 309 1.14 fvdl or SEQ_FLAGS, TARG_CMD_PENDING; 310 1.14 fvdl test SEQ_FLAGS2, TARGET_MSG_PENDING 311 1.14 fvdl jnz target_mesgout_pending; 312 1.14 fvdl test SCSISIGI, ATNI jnz target_mesgout_continue; 313 1.11 fvdl jmp target_ITloop; 314 1.14 fvdl 315 1.14 fvdl 316 1.14 fvdl ident_messages_done_msg_pending: 317 1.14 fvdl or SEQ_FLAGS2, TARGET_MSG_PENDING; 318 1.14 fvdl jmp ident_messages_done; 319 1.14 fvdl 320 1.11 fvdl /* 321 1.14 fvdl * Pushed message loop to allow the kernel to 322 1.19 snj * run its own target mode message state engine. 323 1.11 fvdl */ 324 1.14 fvdl host_target_message_loop: 325 1.14 fvdl mvi HOST_MSG_LOOP call set_seqint; 326 1.14 fvdl cmp RETURN_1, EXIT_MSG_LOOP je target_ITloop; 327 1.11 fvdl test SSTAT0, SPIORDY jz .; 328 1.14 fvdl jmp host_target_message_loop; 329 1.11 fvdl } 330 1.2 mycroft 331 1.14 fvdl if ((ahc->flags & AHC_INITIATORROLE) != 0) { 332 1.2 mycroft /* 333 1.2 mycroft * Reselection has been initiated by a target. Make a note that we've been 334 1.11 fvdl * reselected, but haven't seen an IDENTIFY message from the target yet. 335 1.2 mycroft */ 336 1.11 fvdl initiator_reselect: 337 1.11 fvdl /* XXX test for and handle ONE BIT condition */ 338 1.14 fvdl or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN; 339 1.14 fvdl and SAVED_SCSIID, SELID_MASK, SELID; 340 1.14 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 341 1.14 fvdl and A, OID, SCSIID_ULTRA2; 342 1.14 fvdl } else { 343 1.14 fvdl and A, OID, SCSIID; 344 1.14 fvdl } 345 1.14 fvdl or SAVED_SCSIID, A; 346 1.11 fvdl if ((ahc->features & AHC_TWIN) != 0) { 347 1.11 fvdl test SBLKCTL, SELBUSB jz . + 2; 348 1.14 fvdl or SAVED_SCSIID, TWIN_CHNLB; 349 1.11 fvdl } 350 1.14 fvdl mvi CLRSINT0, CLRSELDI; 351 1.11 fvdl jmp ITloop; 352 1.11 fvdl } 353 1.1 mycroft 354 1.14 fvdl abort_qinscb: 355 1.14 fvdl call add_scb_to_free_list; 356 1.14 fvdl jmp poll_for_work_loop; 357 1.14 fvdl 358 1.14 fvdl start_selection: 359 1.14 fvdl /* 360 1.14 fvdl * If bus reset interrupts have been disabled (from a previous 361 1.14 fvdl * reset), re-enable them now. Resets are only of interest 362 1.14 fvdl * when we have outstanding transactions, so we can safely 363 1.14 fvdl * defer re-enabling the interrupt until, as an initiator, 364 1.14 fvdl * we start sending out transactions again. 365 1.14 fvdl */ 366 1.14 fvdl test SIMODE1, ENSCSIRST jnz . + 3; 367 1.14 fvdl mvi CLRSINT1, CLRSCSIRSTI; 368 1.14 fvdl or SIMODE1, ENSCSIRST; 369 1.14 fvdl if ((ahc->features & AHC_TWIN) != 0) { 370 1.14 fvdl and SINDEX,~SELBUSB,SBLKCTL;/* Clear channel select bit */ 371 1.14 fvdl test SCB_SCSIID, TWIN_CHNLB jz . + 2; 372 1.14 fvdl or SINDEX, SELBUSB; 373 1.14 fvdl mov SBLKCTL,SINDEX; /* select channel */ 374 1.14 fvdl } 375 1.14 fvdl initialize_scsiid: 376 1.14 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 377 1.14 fvdl mov SCSIID_ULTRA2, SCB_SCSIID; 378 1.14 fvdl } else if ((ahc->features & AHC_TWIN) != 0) { 379 1.14 fvdl and SCSIID, TWIN_TID|OID, SCB_SCSIID; 380 1.14 fvdl } else { 381 1.14 fvdl mov SCSIID, SCB_SCSIID; 382 1.14 fvdl } 383 1.14 fvdl if ((ahc->flags & AHC_TARGETROLE) != 0) { 384 1.14 fvdl mov SINDEX, SCSISEQ_TEMPLATE; 385 1.14 fvdl test SCB_CONTROL, TARGET_SCB jz . + 2; 386 1.14 fvdl or SINDEX, TEMODE; 387 1.14 fvdl mov SCSISEQ, SINDEX ret; 388 1.14 fvdl } else { 389 1.14 fvdl mov SCSISEQ, SCSISEQ_TEMPLATE ret; 390 1.14 fvdl } 391 1.14 fvdl 392 1.14 fvdl /* 393 1.14 fvdl * Initialize transfer settings with SCB provided settings. 394 1.14 fvdl */ 395 1.14 fvdl set_transfer_settings: 396 1.14 fvdl if ((ahc->features & AHC_ULTRA) != 0) { 397 1.14 fvdl test SCB_CONTROL, ULTRAENB jz . + 2; 398 1.14 fvdl or SXFRCTL0, FAST20; 399 1.16 perry } 400 1.14 fvdl /* 401 1.14 fvdl * Initialize SCSIRATE with the appropriate value for this target. 402 1.14 fvdl */ 403 1.14 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 404 1.14 fvdl bmov SCSIRATE, SCB_SCSIRATE, 2 ret; 405 1.14 fvdl } else { 406 1.14 fvdl mov SCSIRATE, SCB_SCSIRATE ret; 407 1.14 fvdl } 408 1.14 fvdl 409 1.14 fvdl if ((ahc->flags & AHC_TARGETROLE) != 0) { 410 1.14 fvdl /* 411 1.16 perry * We carefully toggle SPIOEN to allow us to return the 412 1.14 fvdl * message byte we receive so it can be checked prior to 413 1.14 fvdl * driving REQ on the bus for the next byte. 414 1.14 fvdl */ 415 1.14 fvdl target_inb: 416 1.14 fvdl /* 417 1.14 fvdl * Drive REQ on the bus by enabling SCSI PIO. 418 1.14 fvdl */ 419 1.14 fvdl or SXFRCTL0, SPIOEN; 420 1.14 fvdl /* Wait for the byte */ 421 1.14 fvdl test SSTAT0, SPIORDY jz .; 422 1.14 fvdl /* Prevent our read from triggering another REQ */ 423 1.14 fvdl and SXFRCTL0, ~SPIOEN; 424 1.14 fvdl /* Save latched contents */ 425 1.14 fvdl mov DINDEX, SCSIDATL ret; 426 1.14 fvdl } 427 1.14 fvdl 428 1.2 mycroft /* 429 1.11 fvdl * After the selection, remove this SCB from the "waiting SCB" 430 1.2 mycroft * list. This is achieved by simply moving our "next" pointer into 431 1.2 mycroft * WAITING_SCBH. Our next pointer will be set to null the next time this 432 1.2 mycroft * SCB is used, so don't bother with it now. 433 1.2 mycroft */ 434 1.11 fvdl select_out: 435 1.11 fvdl /* Turn off the selection hardware */ 436 1.14 fvdl and SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ; 437 1.11 fvdl mov SCBPTR, WAITING_SCBH; 438 1.11 fvdl mov WAITING_SCBH,SCB_NEXT; 439 1.14 fvdl mov SAVED_SCSIID, SCB_SCSIID; 440 1.14 fvdl mov SAVED_LUN, SCB_LUN; 441 1.14 fvdl call set_transfer_settings; 442 1.14 fvdl if ((ahc->flags & AHC_TARGETROLE) != 0) { 443 1.11 fvdl test SSTAT0, TARGET jz initiator_select; 444 1.11 fvdl 445 1.14 fvdl or SXFRCTL0, CLRSTCNT|CLRCHN; 446 1.14 fvdl 447 1.14 fvdl /* 448 1.14 fvdl * Put tag in connonical location since not 449 1.14 fvdl * all connections have an SCB. 450 1.14 fvdl */ 451 1.14 fvdl mov INITIATOR_TAG, SCB_TARGET_ITAG; 452 1.14 fvdl 453 1.11 fvdl /* 454 1.11 fvdl * We've just re-selected an initiator. 455 1.11 fvdl * Assert BSY and setup the phase for 456 1.11 fvdl * sending our identify messages. 457 1.11 fvdl */ 458 1.11 fvdl mvi P_MESGIN|BSYO call change_phase; 459 1.14 fvdl mvi CLRSINT0, CLRSELDO; 460 1.11 fvdl 461 1.11 fvdl /* 462 1.11 fvdl * Start out with a simple identify message. 463 1.11 fvdl */ 464 1.14 fvdl or SCB_LUN, MSG_IDENTIFYFLAG call target_outb; 465 1.11 fvdl 466 1.11 fvdl /* 467 1.11 fvdl * If we are the result of a tagged command, send 468 1.11 fvdl * a simple Q tag and the tag id. 469 1.11 fvdl */ 470 1.11 fvdl test SCB_CONTROL, TAG_ENB jz . + 3; 471 1.11 fvdl mvi MSG_SIMPLE_Q_TAG call target_outb; 472 1.14 fvdl mov SCB_TARGET_ITAG call target_outb; 473 1.11 fvdl target_synccmd: 474 1.11 fvdl /* 475 1.11 fvdl * Now determine what phases the host wants us 476 1.11 fvdl * to go through. 477 1.11 fvdl */ 478 1.11 fvdl mov SEQ_FLAGS, SCB_TARGET_PHASES; 479 1.16 perry 480 1.14 fvdl test SCB_CONTROL, MK_MESSAGE jz target_ITloop; 481 1.14 fvdl mvi P_MESGIN|BSYO call change_phase; 482 1.14 fvdl jmp host_target_message_loop; 483 1.11 fvdl target_ITloop: 484 1.11 fvdl /* 485 1.11 fvdl * Start honoring ATN signals now that 486 1.11 fvdl * we properly identified ourselves. 487 1.11 fvdl */ 488 1.11 fvdl test SCSISIGI, ATNI jnz target_mesgout; 489 1.11 fvdl test SEQ_FLAGS, CMDPHASE_PENDING jnz target_cmdphase; 490 1.11 fvdl test SEQ_FLAGS, DPHASE_PENDING jnz target_dphase; 491 1.11 fvdl test SEQ_FLAGS, SPHASE_PENDING jnz target_sphase; 492 1.11 fvdl 493 1.11 fvdl /* 494 1.11 fvdl * No more work to do. Either disconnect or not depending 495 1.11 fvdl * on the state of NO_DISCONNECT. 496 1.11 fvdl */ 497 1.16 perry test SEQ_FLAGS, NO_DISCONNECT jz target_disconnect; 498 1.14 fvdl mvi TARG_IMMEDIATE_SCB, SCB_LIST_NULL; 499 1.14 fvdl call complete_target_cmd; 500 1.11 fvdl if ((ahc->flags & AHC_PAGESCBS) != 0) { 501 1.11 fvdl mov ALLZEROS call get_free_or_disc_scb; 502 1.11 fvdl } 503 1.14 fvdl cmp TARG_IMMEDIATE_SCB, SCB_LIST_NULL je .; 504 1.11 fvdl mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 505 1.14 fvdl mov TARG_IMMEDIATE_SCB call dma_scb; 506 1.14 fvdl call set_transfer_settings; 507 1.14 fvdl or SXFRCTL0, CLRSTCNT|CLRCHN; 508 1.11 fvdl jmp target_synccmd; 509 1.11 fvdl 510 1.11 fvdl target_mesgout: 511 1.11 fvdl mvi SCSISIGO, P_MESGOUT|BSYO; 512 1.14 fvdl target_mesgout_continue: 513 1.11 fvdl call target_inb; 514 1.14 fvdl target_mesgout_pending: 515 1.14 fvdl and SEQ_FLAGS2, ~TARGET_MSG_PENDING; 516 1.11 fvdl /* Local Processing goes here... */ 517 1.11 fvdl jmp host_target_message_loop; 518 1.16 perry 519 1.11 fvdl target_disconnect: 520 1.11 fvdl mvi P_MESGIN|BSYO call change_phase; 521 1.11 fvdl test SEQ_FLAGS, DPHASE jz . + 2; 522 1.11 fvdl mvi MSG_SAVEDATAPOINTER call target_outb; 523 1.11 fvdl mvi MSG_DISCONNECT call target_outb; 524 1.11 fvdl 525 1.11 fvdl target_busfree_wait: 526 1.13 wiz /* Wait for preceding I/O session to complete. */ 527 1.11 fvdl test SCSISIGI, ACKI jnz .; 528 1.11 fvdl target_busfree: 529 1.14 fvdl and SIMODE1, ~ENBUSFREE; 530 1.14 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 531 1.14 fvdl clr SCSIBUSL; 532 1.14 fvdl } 533 1.11 fvdl clr SCSISIGO; 534 1.11 fvdl mvi LASTPHASE, P_BUSFREE; 535 1.11 fvdl call complete_target_cmd; 536 1.11 fvdl jmp poll_for_work; 537 1.11 fvdl 538 1.11 fvdl target_cmdphase: 539 1.14 fvdl /* 540 1.14 fvdl * The target has dropped ATN (doesn't want to abort or BDR) 541 1.14 fvdl * and we believe this selection to be valid. If the ring 542 1.14 fvdl * buffer for new commands is full, return busy or queue full. 543 1.14 fvdl */ 544 1.14 fvdl if ((ahc->features & AHC_HS_MAILBOX) != 0) { 545 1.14 fvdl and A, HOST_TQINPOS, HS_MAILBOX; 546 1.14 fvdl } else { 547 1.14 fvdl mov A, KERNEL_TQINPOS; 548 1.14 fvdl } 549 1.14 fvdl cmp TQINPOS, A jne tqinfifo_has_space; 550 1.14 fvdl mvi P_STATUS|BSYO call change_phase; 551 1.14 fvdl test SEQ_FLAGS, TARGET_CMD_IS_TAGGED jz . + 3; 552 1.14 fvdl mvi STATUS_QUEUE_FULL call target_outb; 553 1.14 fvdl jmp target_busfree_wait; 554 1.14 fvdl mvi STATUS_BUSY call target_outb; 555 1.14 fvdl jmp target_busfree_wait; 556 1.16 perry tqinfifo_has_space: 557 1.11 fvdl mvi P_COMMAND|BSYO call change_phase; 558 1.11 fvdl call target_inb; 559 1.11 fvdl mov A, DINDEX; 560 1.11 fvdl /* Store for host */ 561 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 562 1.11 fvdl mov CCSCBRAM, A; 563 1.11 fvdl } else { 564 1.11 fvdl mov DFDAT, A; 565 1.11 fvdl } 566 1.11 fvdl 567 1.11 fvdl /* 568 1.11 fvdl * Determine the number of bytes to read 569 1.11 fvdl * based on the command group code via table lookup. 570 1.11 fvdl * We reuse the first 8 bytes of the TARG_SCSIRATE 571 1.11 fvdl * BIOS array for this table. Count is one less than 572 1.11 fvdl * the total for the command since we've already fetched 573 1.11 fvdl * the first byte. 574 1.11 fvdl */ 575 1.11 fvdl shr A, CMD_GROUP_CODE_SHIFT; 576 1.14 fvdl add SINDEX, CMDSIZE_TABLE, A; 577 1.11 fvdl mov A, SINDIR; 578 1.11 fvdl 579 1.11 fvdl test A, 0xFF jz command_phase_done; 580 1.14 fvdl or SXFRCTL0, SPIOEN; 581 1.11 fvdl command_loop: 582 1.11 fvdl test SSTAT0, SPIORDY jz .; 583 1.11 fvdl cmp A, 1 jne . + 2; 584 1.11 fvdl and SXFRCTL0, ~SPIOEN; /* Last Byte */ 585 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 586 1.11 fvdl mov CCSCBRAM, SCSIDATL; 587 1.11 fvdl } else { 588 1.11 fvdl mov DFDAT, SCSIDATL; 589 1.11 fvdl } 590 1.11 fvdl dec A; 591 1.11 fvdl test A, 0xFF jnz command_loop; 592 1.11 fvdl 593 1.11 fvdl command_phase_done: 594 1.11 fvdl and SEQ_FLAGS, ~CMDPHASE_PENDING; 595 1.11 fvdl jmp target_ITloop; 596 1.11 fvdl 597 1.11 fvdl target_dphase: 598 1.11 fvdl /* 599 1.14 fvdl * Data phases on the bus are from the 600 1.15 wiz * perspective of the initiator. The DMA 601 1.14 fvdl * code looks at LASTPHASE to determine the 602 1.14 fvdl * data direction of the DMA. Toggle it for 603 1.14 fvdl * target transfers. 604 1.11 fvdl */ 605 1.14 fvdl xor LASTPHASE, IOI, SCB_TARGET_DATA_DIR; 606 1.14 fvdl or SCB_TARGET_DATA_DIR, BSYO call change_phase; 607 1.11 fvdl jmp p_data; 608 1.11 fvdl 609 1.11 fvdl target_sphase: 610 1.11 fvdl mvi P_STATUS|BSYO call change_phase; 611 1.11 fvdl mvi LASTPHASE, P_STATUS; 612 1.14 fvdl mov SCB_SCSI_STATUS call target_outb; 613 1.11 fvdl /* XXX Watch for ATN or parity errors??? */ 614 1.11 fvdl mvi SCSISIGO, P_MESGIN|BSYO; 615 1.11 fvdl /* MSG_CMDCMPLT is 0, but we can't do an immediate of 0 */ 616 1.11 fvdl mov ALLZEROS call target_outb; 617 1.11 fvdl jmp target_busfree_wait; 618 1.16 perry 619 1.11 fvdl complete_target_cmd: 620 1.11 fvdl test SEQ_FLAGS, TARG_CMD_PENDING jnz . + 2; 621 1.11 fvdl mov SCB_TAG jmp complete_post; 622 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 623 1.11 fvdl /* Set the valid byte */ 624 1.11 fvdl mvi CCSCBADDR, 24; 625 1.11 fvdl mov CCSCBRAM, ALLONES; 626 1.11 fvdl mvi CCHCNT, 28; 627 1.11 fvdl or CCSCBCTL, CCSCBEN|CCSCBRESET; 628 1.11 fvdl test CCSCBCTL, CCSCBDONE jz .; 629 1.11 fvdl clr CCSCBCTL; 630 1.11 fvdl } else { 631 1.11 fvdl /* Set the valid byte */ 632 1.11 fvdl or DFCNTRL, FIFORESET; 633 1.11 fvdl mvi DFWADDR, 3; /* Third 64bit word or byte 24 */ 634 1.11 fvdl mov DFDAT, ALLONES; 635 1.14 fvdl mvi 28 call set_hcnt; 636 1.11 fvdl or DFCNTRL, HDMAEN|FIFOFLUSH; 637 1.11 fvdl call dma_finish; 638 1.11 fvdl } 639 1.11 fvdl inc TQINPOS; 640 1.11 fvdl mvi INTSTAT,CMDCMPLT ret; 641 1.11 fvdl } 642 1.11 fvdl 643 1.14 fvdl if ((ahc->flags & AHC_INITIATORROLE) != 0) { 644 1.11 fvdl initiator_select: 645 1.14 fvdl or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN; 646 1.11 fvdl /* 647 1.11 fvdl * As soon as we get a successful selection, the target 648 1.11 fvdl * should go into the message out phase since we have ATN 649 1.11 fvdl * asserted. 650 1.11 fvdl */ 651 1.11 fvdl mvi MSG_OUT, MSG_IDENTIFYFLAG; 652 1.14 fvdl mvi SEQ_FLAGS, NO_CDB_SENT; 653 1.14 fvdl mvi CLRSINT0, CLRSELDO; 654 1.2 mycroft 655 1.11 fvdl /* 656 1.11 fvdl * Main loop for information transfer phases. Wait for the 657 1.11 fvdl * target to assert REQ before checking MSG, C/D and I/O for 658 1.11 fvdl * the bus phase. 659 1.11 fvdl */ 660 1.14 fvdl mesgin_phasemis: 661 1.1 mycroft ITloop: 662 1.11 fvdl call phase_lock; 663 1.11 fvdl 664 1.11 fvdl mov A, LASTPHASE; 665 1.11 fvdl 666 1.11 fvdl test A, ~P_DATAIN jz p_data; 667 1.11 fvdl cmp A,P_COMMAND je p_command; 668 1.11 fvdl cmp A,P_MESGOUT je p_mesgout; 669 1.11 fvdl cmp A,P_STATUS je p_status; 670 1.11 fvdl cmp A,P_MESGIN je p_mesgin; 671 1.11 fvdl 672 1.14 fvdl mvi BAD_PHASE call set_seqint; 673 1.11 fvdl jmp ITloop; /* Try reading the bus again. */ 674 1.11 fvdl 675 1.11 fvdl await_busfree: 676 1.11 fvdl and SIMODE1, ~ENBUSFREE; 677 1.11 fvdl mov NONE, SCSIDATL; /* Ack the last byte */ 678 1.14 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 679 1.14 fvdl clr SCSIBUSL; /* Prevent bit leakage durint SELTO */ 680 1.14 fvdl } 681 1.11 fvdl and SXFRCTL0, ~SPIOEN; 682 1.11 fvdl test SSTAT1,REQINIT|BUSFREE jz .; 683 1.11 fvdl test SSTAT1, BUSFREE jnz poll_for_work; 684 1.14 fvdl mvi MISSED_BUSFREE call set_seqint; 685 1.11 fvdl } 686 1.16 perry 687 1.11 fvdl clear_target_state: 688 1.11 fvdl /* 689 1.11 fvdl * We assume that the kernel driver may reset us 690 1.11 fvdl * at any time, even in the middle of a DMA, so 691 1.11 fvdl * clear DFCNTRL too. 692 1.11 fvdl */ 693 1.11 fvdl clr DFCNTRL; 694 1.14 fvdl or SXFRCTL0, CLRSTCNT|CLRCHN; 695 1.1 mycroft 696 1.11 fvdl /* 697 1.11 fvdl * We don't know the target we will connect to, 698 1.11 fvdl * so default to narrow transfers to avoid 699 1.11 fvdl * parity problems. 700 1.11 fvdl */ 701 1.11 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 702 1.11 fvdl bmov SCSIRATE, ALLZEROS, 2; 703 1.11 fvdl } else { 704 1.11 fvdl clr SCSIRATE; 705 1.14 fvdl if ((ahc->features & AHC_ULTRA) != 0) { 706 1.14 fvdl and SXFRCTL0, ~(FAST20); 707 1.14 fvdl } 708 1.11 fvdl } 709 1.11 fvdl mvi LASTPHASE, P_BUSFREE; 710 1.11 fvdl /* clear target specific flags */ 711 1.14 fvdl mvi SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT ret; 712 1.14 fvdl 713 1.14 fvdl sg_advance: 714 1.14 fvdl clr A; /* add sizeof(struct scatter) */ 715 1.14 fvdl add SCB_RESIDUAL_SGPTR[0],SG_SIZEOF; 716 1.14 fvdl adc SCB_RESIDUAL_SGPTR[1],A; 717 1.14 fvdl adc SCB_RESIDUAL_SGPTR[2],A; 718 1.14 fvdl adc SCB_RESIDUAL_SGPTR[3],A ret; 719 1.14 fvdl 720 1.14 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 721 1.14 fvdl disable_ccsgen: 722 1.14 fvdl test CCSGCTL, CCSGEN jz return; 723 1.14 fvdl test CCSGCTL, CCSGDONE jz .; 724 1.14 fvdl disable_ccsgen_fetch_done: 725 1.14 fvdl clr CCSGCTL; 726 1.14 fvdl test CCSGCTL, CCSGEN jnz .; 727 1.14 fvdl ret; 728 1.14 fvdl idle_loop: 729 1.14 fvdl /* 730 1.14 fvdl * Do we need any more segments for this transfer? 731 1.14 fvdl */ 732 1.14 fvdl test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jnz return; 733 1.14 fvdl 734 1.14 fvdl /* Did we just finish fetching segs? */ 735 1.14 fvdl cmp CCSGCTL, CCSGEN|CCSGDONE je idle_sgfetch_complete; 736 1.14 fvdl 737 1.14 fvdl /* Are we actively fetching segments? */ 738 1.14 fvdl test CCSGCTL, CCSGEN jnz return; 739 1.14 fvdl 740 1.14 fvdl /* 741 1.14 fvdl * Do we have any prefetch left??? 742 1.14 fvdl */ 743 1.14 fvdl cmp CCSGADDR, SG_PREFETCH_CNT jne idle_sg_avail; 744 1.14 fvdl 745 1.14 fvdl /* 746 1.14 fvdl * Need to fetch segments, but we can only do that 747 1.14 fvdl * if the command channel is completely idle. Make 748 1.14 fvdl * sure we don't have an SCB prefetch going on. 749 1.14 fvdl */ 750 1.14 fvdl test CCSCBCTL, CCSCBEN jnz return; 751 1.2 mycroft 752 1.14 fvdl /* 753 1.14 fvdl * We fetch a "cacheline aligned" and sized amount of data 754 1.21 andvar * so we don't end up referencing a non-existent page. 755 1.14 fvdl * Cacheline aligned is in quotes because the kernel will 756 1.14 fvdl * set the prefetch amount to a reasonable level if the 757 1.14 fvdl * cacheline size is unknown. 758 1.14 fvdl */ 759 1.14 fvdl mvi CCHCNT, SG_PREFETCH_CNT; 760 1.14 fvdl and CCHADDR[0], SG_PREFETCH_ALIGN_MASK, SCB_RESIDUAL_SGPTR; 761 1.14 fvdl bmov CCHADDR[1], SCB_RESIDUAL_SGPTR[1], 3; 762 1.14 fvdl mvi CCSGCTL, CCSGEN|CCSGRESET ret; 763 1.14 fvdl idle_sgfetch_complete: 764 1.14 fvdl call disable_ccsgen_fetch_done; 765 1.14 fvdl and CCSGADDR, SG_PREFETCH_ADDR_MASK, SCB_RESIDUAL_SGPTR; 766 1.14 fvdl idle_sg_avail: 767 1.14 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 768 1.14 fvdl /* Does the hardware have space for another SG entry? */ 769 1.14 fvdl test DFSTATUS, PRELOAD_AVAIL jz return; 770 1.14 fvdl bmov HADDR, CCSGRAM, 7; 771 1.14 fvdl test HCNT[0], 0x1 jz . + 2; 772 1.14 fvdl xor DATA_COUNT_ODD, 0x1; 773 1.14 fvdl bmov SCB_RESIDUAL_DATACNT[3], CCSGRAM, 1; 774 1.14 fvdl if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) { 775 1.14 fvdl mov SCB_RESIDUAL_DATACNT[3] call set_hhaddr; 776 1.14 fvdl } 777 1.14 fvdl call sg_advance; 778 1.14 fvdl mov SINDEX, SCB_RESIDUAL_SGPTR[0]; 779 1.14 fvdl test DATA_COUNT_ODD, 0x1 jz . + 2; 780 1.14 fvdl or SINDEX, ODD_SEG; 781 1.14 fvdl test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 2; 782 1.14 fvdl or SINDEX, LAST_SEG; 783 1.14 fvdl mov SG_CACHE_PRE, SINDEX; 784 1.14 fvdl /* Load the segment */ 785 1.14 fvdl or DFCNTRL, PRELOADEN; 786 1.14 fvdl } 787 1.14 fvdl ret; 788 1.14 fvdl } 789 1.14 fvdl 790 1.14 fvdl if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0 && ahc->pci_cachesize != 0) { 791 1.2 mycroft /* 792 1.14 fvdl * Calculate the trailing portion of this S/G segment that cannot 793 1.16 perry * be transferred using memory write and invalidate PCI transactions. 794 1.14 fvdl * XXX Can we optimize this for PCI writes only??? 795 1.2 mycroft */ 796 1.14 fvdl calc_mwi_residual: 797 1.14 fvdl /* 798 1.14 fvdl * If the ending address is on a cacheline boundary, 799 1.14 fvdl * there is no need for an extra segment. 800 1.14 fvdl */ 801 1.14 fvdl mov A, HCNT[0]; 802 1.14 fvdl add A, A, HADDR[0]; 803 1.14 fvdl and A, CACHESIZE_MASK; 804 1.14 fvdl test A, 0xFF jz return; 805 1.14 fvdl 806 1.14 fvdl /* 807 1.14 fvdl * If the transfer is less than a cachline, 808 1.14 fvdl * there is no need for an extra segment. 809 1.14 fvdl */ 810 1.14 fvdl test HCNT[1], 0xFF jnz calc_mwi_residual_final; 811 1.14 fvdl test HCNT[2], 0xFF jnz calc_mwi_residual_final; 812 1.14 fvdl add NONE, INVERTED_CACHESIZE_MASK, HCNT[0]; 813 1.14 fvdl jnc return; 814 1.14 fvdl 815 1.14 fvdl calc_mwi_residual_final: 816 1.14 fvdl mov MWI_RESIDUAL, A; 817 1.14 fvdl not A; 818 1.14 fvdl inc A; 819 1.14 fvdl add HCNT[0], A; 820 1.14 fvdl adc HCNT[1], -1; 821 1.14 fvdl adc HCNT[2], -1 ret; 822 1.14 fvdl } 823 1.11 fvdl 824 1.11 fvdl p_data: 825 1.14 fvdl test SEQ_FLAGS,NOT_IDENTIFIED|NO_CDB_SENT jz p_data_allowed; 826 1.14 fvdl mvi PROTO_VIOLATION call set_seqint; 827 1.14 fvdl p_data_allowed: 828 1.11 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 829 1.11 fvdl mvi DMAPARAMS, PRELOADEN|SCSIEN|HDMAEN; 830 1.11 fvdl } else { 831 1.11 fvdl mvi DMAPARAMS, WIDEODD|SCSIEN|SDMAEN|HDMAEN|FIFORESET; 832 1.11 fvdl } 833 1.11 fvdl test LASTPHASE, IOI jnz . + 2; 834 1.11 fvdl or DMAPARAMS, DIRECTION; 835 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 836 1.14 fvdl /* We don't have any valid S/G elements */ 837 1.14 fvdl mvi CCSGADDR, SG_PREFETCH_CNT; 838 1.11 fvdl } 839 1.14 fvdl test SEQ_FLAGS, DPHASE jz data_phase_initialize; 840 1.1 mycroft 841 1.14 fvdl /* 842 1.14 fvdl * If we re-enter the data phase after going through another 843 1.14 fvdl * phase, our transfer location has almost certainly been 844 1.14 fvdl * corrupted by the interveining, non-data, transfers. Ask 845 1.14 fvdl * the host driver to fix us up based on the transfer residual. 846 1.14 fvdl */ 847 1.14 fvdl mvi PDATA_REINIT call set_seqint; 848 1.14 fvdl jmp data_phase_loop; 849 1.14 fvdl 850 1.14 fvdl data_phase_initialize: 851 1.14 fvdl /* We have seen a data phase for the first time */ 852 1.11 fvdl or SEQ_FLAGS, DPHASE; 853 1.11 fvdl 854 1.11 fvdl /* 855 1.11 fvdl * Initialize the DMA address and counter from the SCB. 856 1.14 fvdl * Also set SCB_RESIDUAL_SGPTR, including the LAST_SEG 857 1.14 fvdl * flag in the highest byte of the data count. We cannot 858 1.14 fvdl * modify the saved values in the SCB until we see a save 859 1.14 fvdl * data pointers message. 860 1.11 fvdl */ 861 1.14 fvdl if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) { 862 1.14 fvdl /* The lowest address byte must be loaded last. */ 863 1.14 fvdl mov SCB_DATACNT[3] call set_hhaddr; 864 1.14 fvdl } 865 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 866 1.11 fvdl bmov HADDR, SCB_DATAPTR, 7; 867 1.14 fvdl bmov SCB_RESIDUAL_DATACNT[3], SCB_DATACNT[3], 5; 868 1.11 fvdl } else { 869 1.11 fvdl mvi DINDEX, HADDR; 870 1.11 fvdl mvi SCB_DATAPTR call bcopy_7; 871 1.14 fvdl mvi DINDEX, SCB_RESIDUAL_DATACNT + 3; 872 1.14 fvdl mvi SCB_DATACNT + 3 call bcopy_5; 873 1.14 fvdl } 874 1.14 fvdl if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0 && ahc->pci_cachesize != 0) { 875 1.14 fvdl call calc_mwi_residual; 876 1.11 fvdl } 877 1.14 fvdl and SCB_RESIDUAL_SGPTR[0], ~SG_FULL_RESID; 878 1.14 fvdl and DATA_COUNT_ODD, 0x1, HCNT[0]; 879 1.11 fvdl 880 1.11 fvdl if ((ahc->features & AHC_ULTRA2) == 0) { 881 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 882 1.11 fvdl bmov STCNT, HCNT, 3; 883 1.11 fvdl } else { 884 1.11 fvdl call set_stcnt_from_hcnt; 885 1.11 fvdl } 886 1.11 fvdl } 887 1.11 fvdl 888 1.14 fvdl data_phase_loop: 889 1.14 fvdl /* Guard against overruns */ 890 1.14 fvdl test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz data_phase_inbounds; 891 1.1 mycroft 892 1.14 fvdl /* 893 1.14 fvdl * Turn on `Bit Bucket' mode, wait until the target takes 894 1.14 fvdl * us to another phase, and then notify the host. 895 1.14 fvdl */ 896 1.14 fvdl and DMAPARAMS, DIRECTION; 897 1.14 fvdl mov DFCNTRL, DMAPARAMS; 898 1.11 fvdl or SXFRCTL1,BITBUCKET; 899 1.14 fvdl if ((ahc->features & AHC_DT) == 0) { 900 1.14 fvdl test SSTAT1,PHASEMIS jz .; 901 1.11 fvdl } else { 902 1.14 fvdl test SCSIPHASE, DATA_PHASE_MASK jnz .; 903 1.11 fvdl } 904 1.14 fvdl and SXFRCTL1, ~BITBUCKET; 905 1.14 fvdl mvi DATA_OVERRUN call set_seqint; 906 1.14 fvdl jmp ITloop; 907 1.14 fvdl 908 1.4 explorer data_phase_inbounds: 909 1.11 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 910 1.14 fvdl mov SINDEX, SCB_RESIDUAL_SGPTR[0]; 911 1.14 fvdl test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz . + 2; 912 1.14 fvdl or SINDEX, LAST_SEG; 913 1.14 fvdl test DATA_COUNT_ODD, 0x1 jz . + 2; 914 1.14 fvdl or SINDEX, ODD_SEG; 915 1.14 fvdl mov SG_CACHE_PRE, SINDEX; 916 1.14 fvdl mov DFCNTRL, DMAPARAMS; 917 1.14 fvdl ultra2_dma_loop: 918 1.14 fvdl call idle_loop; 919 1.14 fvdl /* 920 1.14 fvdl * The transfer is complete if either the last segment 921 1.14 fvdl * completes or the target changes phase. 922 1.14 fvdl */ 923 1.14 fvdl test SG_CACHE_SHADOW, LAST_SEG_DONE jnz ultra2_dmafinish; 924 1.14 fvdl if ((ahc->features & AHC_DT) == 0) { 925 1.14 fvdl if ((ahc->flags & AHC_TARGETROLE) != 0) { 926 1.14 fvdl /* 927 1.14 fvdl * As a target, we control the phases, 928 1.14 fvdl * so ignore PHASEMIS. 929 1.14 fvdl */ 930 1.14 fvdl test SSTAT0, TARGET jnz ultra2_dma_loop; 931 1.14 fvdl } 932 1.14 fvdl if ((ahc->flags & AHC_INITIATORROLE) != 0) { 933 1.14 fvdl test SSTAT1,PHASEMIS jz ultra2_dma_loop; 934 1.14 fvdl } 935 1.14 fvdl } else { 936 1.14 fvdl test DFCNTRL, SCSIEN jnz ultra2_dma_loop; 937 1.14 fvdl } 938 1.14 fvdl 939 1.14 fvdl ultra2_dmafinish: 940 1.14 fvdl /* 941 1.14 fvdl * The transfer has terminated either due to a phase 942 1.14 fvdl * change, and/or the completion of the last segment. 943 1.14 fvdl * We have two goals here. Do as much other work 944 1.14 fvdl * as possible while the data fifo drains on a read 945 1.14 fvdl * and respond as quickly as possible to the standard 946 1.14 fvdl * messages (save data pointers/disconnect and command 947 1.14 fvdl * complete) that usually follow a data phase. 948 1.14 fvdl */ 949 1.14 fvdl if ((ahc->bugs & AHC_AUTOFLUSH_BUG) != 0) { 950 1.14 fvdl /* 951 1.14 fvdl * On chips with broken auto-flush, start 952 1.14 fvdl * the flushing process now. We'll poke 953 1.14 fvdl * the chip from time to time to keep the 954 1.14 fvdl * flush process going as we complete the 955 1.14 fvdl * data phase. 956 1.14 fvdl */ 957 1.14 fvdl or DFCNTRL, FIFOFLUSH; 958 1.14 fvdl } 959 1.14 fvdl /* 960 1.14 fvdl * We assume that, even though data may still be 961 1.14 fvdl * transferring to the host, that the SCSI side of 962 1.14 fvdl * the DMA engine is now in a static state. This 963 1.14 fvdl * allows us to update our notion of where we are 964 1.14 fvdl * in this transfer. 965 1.14 fvdl * 966 1.14 fvdl * If, by chance, we stopped before being able 967 1.14 fvdl * to fetch additional segments for this transfer, 968 1.14 fvdl * yet the last S/G was completely exhausted, 969 1.14 fvdl * call our idle loop until it is able to load 970 1.14 fvdl * another segment. This will allow us to immediately 971 1.14 fvdl * pickup on the next segment on the next data phase. 972 1.14 fvdl * 973 1.14 fvdl * If we happened to stop on the last segment, then 974 1.14 fvdl * our residual information is still correct from 975 1.14 fvdl * the idle loop and there is no need to perform 976 1.14 fvdl * any fixups. 977 1.14 fvdl */ 978 1.14 fvdl ultra2_ensure_sg: 979 1.14 fvdl test SG_CACHE_SHADOW, LAST_SEG jz ultra2_shvalid; 980 1.14 fvdl /* Record if we've consumed all S/G entries */ 981 1.14 fvdl test SSTAT2, SHVALID jnz residuals_correct; 982 1.14 fvdl or SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL; 983 1.14 fvdl jmp residuals_correct; 984 1.14 fvdl 985 1.14 fvdl ultra2_shvalid: 986 1.14 fvdl test SSTAT2, SHVALID jnz sgptr_fixup; 987 1.14 fvdl call idle_loop; 988 1.14 fvdl jmp ultra2_ensure_sg; 989 1.14 fvdl 990 1.14 fvdl sgptr_fixup: 991 1.14 fvdl /* 992 1.14 fvdl * Fixup the residual next S/G pointer. The S/G preload 993 1.14 fvdl * feature of the chip allows us to load two elements 994 1.14 fvdl * in addition to the currently active element. We 995 1.14 fvdl * store the bottom byte of the next S/G pointer in 996 1.14 fvdl * the SG_CACEPTR register so we can restore the 997 1.14 fvdl * correct value when the DMA completes. If the next 998 1.14 fvdl * sg ptr value has advanced to the point where higher 999 1.14 fvdl * bytes in the address have been affected, fix them 1000 1.14 fvdl * too. 1001 1.14 fvdl */ 1002 1.14 fvdl test SG_CACHE_SHADOW, 0x80 jz sgptr_fixup_done; 1003 1.14 fvdl test SCB_RESIDUAL_SGPTR[0], 0x80 jnz sgptr_fixup_done; 1004 1.14 fvdl add SCB_RESIDUAL_SGPTR[1], -1; 1005 1.16 perry adc SCB_RESIDUAL_SGPTR[2], -1; 1006 1.14 fvdl adc SCB_RESIDUAL_SGPTR[3], -1; 1007 1.14 fvdl sgptr_fixup_done: 1008 1.14 fvdl and SCB_RESIDUAL_SGPTR[0], SG_ADDR_MASK, SG_CACHE_SHADOW; 1009 1.14 fvdl clr DATA_COUNT_ODD; 1010 1.14 fvdl test SG_CACHE_SHADOW, ODD_SEG jz . + 2; 1011 1.14 fvdl or DATA_COUNT_ODD, 0x1; 1012 1.14 fvdl clr SCB_RESIDUAL_DATACNT[3]; /* We are not the last seg */ 1013 1.14 fvdl residuals_correct: 1014 1.14 fvdl /* 1015 1.14 fvdl * Go ahead and shut down the DMA engine now. 1016 1.14 fvdl * In the future, we'll want to handle end of 1017 1.14 fvdl * transfer messages prior to doing this, but this 1018 1.14 fvdl * requires similar restructuring for pre-ULTRA2 1019 1.14 fvdl * controllers. 1020 1.14 fvdl */ 1021 1.14 fvdl test DMAPARAMS, DIRECTION jnz ultra2_fifoempty; 1022 1.14 fvdl ultra2_fifoflush: 1023 1.14 fvdl if ((ahc->features & AHC_DT) == 0) { 1024 1.14 fvdl if ((ahc->bugs & AHC_AUTOFLUSH_BUG) != 0) { 1025 1.14 fvdl /* 1026 1.14 fvdl * On Rev A of the aic7890, the autoflush 1027 1.14 fvdl * feature doesn't function correctly. 1028 1.14 fvdl * Perform an explicit manual flush. During 1029 1.14 fvdl * a manual flush, the FIFOEMP bit becomes 1030 1.14 fvdl * true every time the PCI FIFO empties 1031 1.14 fvdl * regardless of the state of the SCSI FIFO. 1032 1.14 fvdl * It can take up to 4 clock cycles for the 1033 1.14 fvdl * SCSI FIFO to get data into the PCI FIFO 1034 1.14 fvdl * and for FIFOEMP to de-assert. Here we 1035 1.14 fvdl * guard against this condition by making 1036 1.14 fvdl * sure the FIFOEMP bit stays on for 5 full 1037 1.14 fvdl * clock cycles. 1038 1.14 fvdl */ 1039 1.14 fvdl or DFCNTRL, FIFOFLUSH; 1040 1.14 fvdl test DFSTATUS, FIFOEMP jz ultra2_fifoflush; 1041 1.14 fvdl test DFSTATUS, FIFOEMP jz ultra2_fifoflush; 1042 1.14 fvdl test DFSTATUS, FIFOEMP jz ultra2_fifoflush; 1043 1.14 fvdl test DFSTATUS, FIFOEMP jz ultra2_fifoflush; 1044 1.14 fvdl } 1045 1.14 fvdl test DFSTATUS, FIFOEMP jz ultra2_fifoflush; 1046 1.14 fvdl } else { 1047 1.14 fvdl /* 1048 1.14 fvdl * We enable the auto-ack feature on DT capable 1049 1.14 fvdl * controllers. This means that the controller may 1050 1.14 fvdl * have already transferred some overrun bytes into 1051 1.14 fvdl * the data FIFO and acked them on the bus. The only 1052 1.14 fvdl * way to detect this situation is to wait for 1053 1.14 fvdl * LAST_SEG_DONE to come true on a completed transfer 1054 1.14 fvdl * and then test to see if the data FIFO is non-empty. 1055 1.14 fvdl */ 1056 1.14 fvdl test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 4; 1057 1.14 fvdl test SG_CACHE_SHADOW, LAST_SEG_DONE jz .; 1058 1.14 fvdl test DFSTATUS, FIFOEMP jnz ultra2_fifoempty; 1059 1.14 fvdl /* Overrun */ 1060 1.14 fvdl jmp data_phase_loop; 1061 1.14 fvdl test DFSTATUS, FIFOEMP jz .; 1062 1.14 fvdl } 1063 1.14 fvdl ultra2_fifoempty: 1064 1.14 fvdl /* Don't clobber an inprogress host data transfer */ 1065 1.14 fvdl test DFSTATUS, MREQPEND jnz ultra2_fifoempty; 1066 1.14 fvdl ultra2_dmahalt: 1067 1.14 fvdl and DFCNTRL, ~(SCSIEN|HDMAEN); 1068 1.14 fvdl test DFCNTRL, SCSIEN|HDMAEN jnz .; 1069 1.14 fvdl if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) { 1070 1.14 fvdl /* 1071 1.14 fvdl * Keep HHADDR cleared for future, 32bit addressed 1072 1.14 fvdl * only, DMA operations. 1073 1.14 fvdl * 1074 1.14 fvdl * Due to bayonette style S/G handling, our residual 1075 1.14 fvdl * data must be "fixed up" once the transfer is halted. 1076 1.14 fvdl * Here we fixup the HSHADDR stored in the high byte 1077 1.14 fvdl * of the residual data cnt. By postponing the fixup, 1078 1.14 fvdl * we can batch the clearing of HADDR with the fixup. 1079 1.14 fvdl * If we halted on the last segment, the residual is 1080 1.14 fvdl * already correct. If we are not on the last 1081 1.14 fvdl * segment, copy the high address directly from HSHADDR. 1082 1.14 fvdl * We don't need to worry about maintaining the 1083 1.14 fvdl * SG_LAST_SEG flag as it will always be false in the 1084 1.14 fvdl * case where an update is required. 1085 1.14 fvdl */ 1086 1.14 fvdl or DSCOMMAND1, HADDLDSEL0; 1087 1.14 fvdl test SG_CACHE_SHADOW, LAST_SEG jnz . + 2; 1088 1.14 fvdl mov SCB_RESIDUAL_DATACNT[3], SHADDR; 1089 1.14 fvdl clr HADDR; 1090 1.14 fvdl and DSCOMMAND1, ~HADDLDSEL0; 1091 1.14 fvdl } 1092 1.11 fvdl } else { 1093 1.14 fvdl /* If we are the last SG block, tell the hardware. */ 1094 1.14 fvdl if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0 1095 1.14 fvdl && ahc->pci_cachesize != 0) { 1096 1.14 fvdl test MWI_RESIDUAL, 0xFF jnz dma_mid_sg; 1097 1.11 fvdl } 1098 1.14 fvdl test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz dma_mid_sg; 1099 1.14 fvdl if ((ahc->flags & AHC_TARGETROLE) != 0) { 1100 1.14 fvdl test SSTAT0, TARGET jz dma_last_sg; 1101 1.14 fvdl if ((ahc->flags & AHC_TMODE_WIDEODD_BUG) != 0) { 1102 1.14 fvdl test DMAPARAMS, DIRECTION jz dma_mid_sg; 1103 1.14 fvdl } 1104 1.14 fvdl } 1105 1.14 fvdl dma_last_sg: 1106 1.11 fvdl and DMAPARAMS, ~WIDEODD; 1107 1.14 fvdl dma_mid_sg: 1108 1.14 fvdl /* Start DMA data transfer. */ 1109 1.11 fvdl mov DFCNTRL, DMAPARAMS; 1110 1.14 fvdl dma_loop: 1111 1.14 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 1112 1.14 fvdl call idle_loop; 1113 1.14 fvdl } 1114 1.14 fvdl test SSTAT0,DMADONE jnz dma_dmadone; 1115 1.14 fvdl test SSTAT1,PHASEMIS jz dma_loop; /* ie. underrun */ 1116 1.14 fvdl dma_phasemis: 1117 1.14 fvdl /* 1118 1.14 fvdl * We will be "done" DMAing when the transfer count goes to 1119 1.14 fvdl * zero, or the target changes the phase (in light of this, 1120 1.14 fvdl * it makes sense that the DMA circuitry doesn't ACK when 1121 1.14 fvdl * PHASEMIS is active). If we are doing a SCSI->Host transfer, 1122 1.14 fvdl * the data FIFO should be flushed auto-magically on STCNT=0 1123 1.14 fvdl * or a phase change, so just wait for FIFO empty status. 1124 1.14 fvdl */ 1125 1.14 fvdl dma_checkfifo: 1126 1.14 fvdl test DFCNTRL,DIRECTION jnz dma_fifoempty; 1127 1.14 fvdl dma_fifoflush: 1128 1.14 fvdl test DFSTATUS,FIFOEMP jz dma_fifoflush; 1129 1.14 fvdl dma_fifoempty: 1130 1.14 fvdl /* Don't clobber an inprogress host data transfer */ 1131 1.14 fvdl test DFSTATUS, MREQPEND jnz dma_fifoempty; 1132 1.2 mycroft 1133 1.14 fvdl /* 1134 1.14 fvdl * Now shut off the DMA and make sure that the DMA 1135 1.14 fvdl * hardware has actually stopped. Touching the DMA 1136 1.14 fvdl * counters, etc. while a DMA is active will result 1137 1.14 fvdl * in an ILLSADDR exception. 1138 1.14 fvdl */ 1139 1.14 fvdl dma_dmadone: 1140 1.14 fvdl and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN); 1141 1.14 fvdl dma_halt: 1142 1.14 fvdl /* 1143 1.14 fvdl * Some revisions of the aic78XX have a problem where, if the 1144 1.16 perry * data fifo is full, but the PCI input latch is not empty, 1145 1.14 fvdl * HDMAEN cannot be cleared. The fix used here is to drain 1146 1.14 fvdl * the prefetched but unused data from the data fifo until 1147 1.14 fvdl * there is space for the input latch to drain. 1148 1.14 fvdl */ 1149 1.14 fvdl if ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0) { 1150 1.14 fvdl mov NONE, DFDAT; 1151 1.14 fvdl } 1152 1.14 fvdl test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz dma_halt; 1153 1.4 explorer 1154 1.14 fvdl /* See if we have completed this last segment */ 1155 1.14 fvdl test STCNT[0], 0xff jnz data_phase_finish; 1156 1.14 fvdl test STCNT[1], 0xff jnz data_phase_finish; 1157 1.14 fvdl test STCNT[2], 0xff jnz data_phase_finish; 1158 1.14 fvdl 1159 1.14 fvdl /* 1160 1.16 perry * Advance the scatter-gather pointers if needed 1161 1.14 fvdl */ 1162 1.14 fvdl if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0 1163 1.14 fvdl && ahc->pci_cachesize != 0) { 1164 1.14 fvdl test MWI_RESIDUAL, 0xFF jz no_mwi_resid; 1165 1.14 fvdl /* 1166 1.14 fvdl * Reload HADDR from SHADDR and setup the 1167 1.14 fvdl * count to be the size of our residual. 1168 1.14 fvdl */ 1169 1.14 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 1170 1.14 fvdl bmov HADDR, SHADDR, 4; 1171 1.14 fvdl mov HCNT, MWI_RESIDUAL; 1172 1.14 fvdl bmov HCNT[1], ALLZEROS, 2; 1173 1.14 fvdl } else { 1174 1.14 fvdl mvi DINDEX, HADDR; 1175 1.14 fvdl mvi SHADDR call bcopy_4; 1176 1.14 fvdl mov MWI_RESIDUAL call set_hcnt; 1177 1.14 fvdl } 1178 1.14 fvdl clr MWI_RESIDUAL; 1179 1.14 fvdl jmp sg_load_done; 1180 1.14 fvdl no_mwi_resid: 1181 1.14 fvdl } 1182 1.14 fvdl test SCB_RESIDUAL_DATACNT[3], SG_LAST_SEG jz sg_load; 1183 1.14 fvdl or SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL; 1184 1.14 fvdl jmp data_phase_finish; 1185 1.2 mycroft sg_load: 1186 1.11 fvdl /* 1187 1.14 fvdl * Load the next SG element's data address and length 1188 1.14 fvdl * into the DMA engine. If we don't have hardware 1189 1.14 fvdl * to perform a prefetch, we'll have to fetch the 1190 1.14 fvdl * segment from host memory first. 1191 1.11 fvdl */ 1192 1.14 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 1193 1.14 fvdl /* Wait for the idle loop to complete */ 1194 1.14 fvdl test CCSGCTL, CCSGEN jz . + 3; 1195 1.14 fvdl call idle_loop; 1196 1.14 fvdl test CCSGCTL, CCSGEN jnz . - 1; 1197 1.14 fvdl bmov HADDR, CCSGRAM, 7; 1198 1.14 fvdl /* 1199 1.14 fvdl * Workaround for flaky external SCB RAM 1200 1.14 fvdl * on certain aic7895 setups. It seems 1201 1.14 fvdl * unable to handle direct transfers from 1202 1.14 fvdl * S/G ram to certain SCB locations. 1203 1.14 fvdl */ 1204 1.14 fvdl mov SINDEX, CCSGRAM; 1205 1.14 fvdl mov SCB_RESIDUAL_DATACNT[3], SINDEX; 1206 1.14 fvdl } else { 1207 1.14 fvdl if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) { 1208 1.14 fvdl mov ALLZEROS call set_hhaddr; 1209 1.14 fvdl } 1210 1.14 fvdl mvi DINDEX, HADDR; 1211 1.14 fvdl mvi SCB_RESIDUAL_SGPTR call bcopy_4; 1212 1.14 fvdl 1213 1.14 fvdl mvi SG_SIZEOF call set_hcnt; 1214 1.11 fvdl 1215 1.14 fvdl or DFCNTRL, HDMAEN|DIRECTION|FIFORESET; 1216 1.11 fvdl 1217 1.14 fvdl call dma_finish; 1218 1.11 fvdl 1219 1.14 fvdl mvi DINDEX, HADDR; 1220 1.14 fvdl call dfdat_in_7; 1221 1.14 fvdl mov SCB_RESIDUAL_DATACNT[3], DFDAT; 1222 1.14 fvdl } 1223 1.11 fvdl 1224 1.14 fvdl if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) { 1225 1.14 fvdl mov SCB_RESIDUAL_DATACNT[3] call set_hhaddr; 1226 1.11 fvdl 1227 1.14 fvdl /* 1228 1.14 fvdl * The lowest address byte must be loaded 1229 1.14 fvdl * last as it triggers the computation of 1230 1.14 fvdl * some items in the PCI block. The ULTRA2 1231 1.14 fvdl * chips do this on PRELOAD. 1232 1.14 fvdl */ 1233 1.14 fvdl mov HADDR, HADDR; 1234 1.14 fvdl } 1235 1.14 fvdl if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0 1236 1.14 fvdl && ahc->pci_cachesize != 0) { 1237 1.14 fvdl call calc_mwi_residual; 1238 1.14 fvdl } 1239 1.11 fvdl 1240 1.14 fvdl /* Point to the new next sg in memory */ 1241 1.14 fvdl call sg_advance; 1242 1.11 fvdl 1243 1.14 fvdl sg_load_done: 1244 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 1245 1.11 fvdl bmov STCNT, HCNT, 3; 1246 1.11 fvdl } else { 1247 1.11 fvdl call set_stcnt_from_hcnt; 1248 1.11 fvdl } 1249 1.14 fvdl /* Track odd'ness */ 1250 1.14 fvdl test HCNT[0], 0x1 jz . + 2; 1251 1.14 fvdl xor DATA_COUNT_ODD, 0x1; 1252 1.14 fvdl 1253 1.14 fvdl if ((ahc->flags & AHC_TARGETROLE) != 0) { 1254 1.14 fvdl test SSTAT0, TARGET jnz data_phase_loop; 1255 1.14 fvdl } 1256 1.14 fvdl } 1257 1.14 fvdl data_phase_finish: 1258 1.14 fvdl /* 1259 1.14 fvdl * If the target has left us in data phase, loop through 1260 1.15 wiz * the DMA code again. In the case of ULTRA2 adapters, 1261 1.14 fvdl * we should only loop if there is a data overrun. For 1262 1.14 fvdl * all other adapters, we'll loop after each S/G element 1263 1.14 fvdl * is loaded as well as if there is an overrun. 1264 1.14 fvdl */ 1265 1.14 fvdl if ((ahc->flags & AHC_TARGETROLE) != 0) { 1266 1.14 fvdl test SSTAT0, TARGET jnz data_phase_done; 1267 1.14 fvdl } 1268 1.14 fvdl if ((ahc->flags & AHC_INITIATORROLE) != 0) { 1269 1.14 fvdl test SSTAT1, REQINIT jz .; 1270 1.14 fvdl if ((ahc->features & AHC_DT) == 0) { 1271 1.14 fvdl test SSTAT1,PHASEMIS jz data_phase_loop; 1272 1.14 fvdl } else { 1273 1.14 fvdl test SCSIPHASE, DATA_PHASE_MASK jnz data_phase_loop; 1274 1.14 fvdl } 1275 1.11 fvdl } 1276 1.11 fvdl 1277 1.14 fvdl data_phase_done: 1278 1.14 fvdl /* 1279 1.14 fvdl * After a DMA finishes, save the SG and STCNT residuals back into 1280 1.14 fvdl * the SCB. We use STCNT instead of HCNT, since it's a reflection 1281 1.14 fvdl * of how many bytes were transferred on the SCSI (as opposed to the 1282 1.14 fvdl * host) bus. 1283 1.14 fvdl */ 1284 1.14 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 1285 1.14 fvdl /* Kill off any pending prefetch */ 1286 1.14 fvdl call disable_ccsgen; 1287 1.11 fvdl } 1288 1.11 fvdl 1289 1.14 fvdl if ((ahc->features & AHC_ULTRA2) == 0) { 1290 1.14 fvdl /* 1291 1.14 fvdl * Clear the high address byte so that all other DMA 1292 1.14 fvdl * operations, which use 32bit addressing, can assume 1293 1.14 fvdl * HHADDR is 0. 1294 1.14 fvdl */ 1295 1.14 fvdl if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) { 1296 1.14 fvdl mov ALLZEROS call set_hhaddr; 1297 1.14 fvdl } 1298 1.11 fvdl } 1299 1.2 mycroft 1300 1.14 fvdl /* 1301 1.14 fvdl * Update our residual information before the information is 1302 1.14 fvdl * lost by some other type of SCSI I/O (e.g. PIO). If we have 1303 1.14 fvdl * transferred all data, no update is needed. 1304 1.14 fvdl * 1305 1.14 fvdl */ 1306 1.14 fvdl test SCB_RESIDUAL_SGPTR, SG_LIST_NULL jnz residual_update_done; 1307 1.14 fvdl if ((ahc->bugs & AHC_PCI_MWI_BUG) != 0 1308 1.14 fvdl && ahc->pci_cachesize != 0) { 1309 1.14 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 1310 1.14 fvdl test MWI_RESIDUAL, 0xFF jz bmov_resid; 1311 1.14 fvdl } 1312 1.14 fvdl mov A, MWI_RESIDUAL; 1313 1.14 fvdl add SCB_RESIDUAL_DATACNT[0], A, STCNT[0]; 1314 1.14 fvdl clr A; 1315 1.14 fvdl adc SCB_RESIDUAL_DATACNT[1], A, STCNT[1]; 1316 1.14 fvdl adc SCB_RESIDUAL_DATACNT[2], A, STCNT[2]; 1317 1.14 fvdl clr MWI_RESIDUAL; 1318 1.14 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 1319 1.14 fvdl jmp . + 2; 1320 1.14 fvdl bmov_resid: 1321 1.14 fvdl bmov SCB_RESIDUAL_DATACNT, STCNT, 3; 1322 1.14 fvdl } 1323 1.14 fvdl } else if ((ahc->features & AHC_CMD_CHAN) != 0) { 1324 1.14 fvdl bmov SCB_RESIDUAL_DATACNT, STCNT, 3; 1325 1.11 fvdl } else { 1326 1.14 fvdl mov SCB_RESIDUAL_DATACNT[0], STCNT[0]; 1327 1.14 fvdl mov SCB_RESIDUAL_DATACNT[1], STCNT[1]; 1328 1.14 fvdl mov SCB_RESIDUAL_DATACNT[2], STCNT[2]; 1329 1.11 fvdl } 1330 1.14 fvdl residual_update_done: 1331 1.14 fvdl /* 1332 1.14 fvdl * Since we've been through a data phase, the SCB_RESID* fields 1333 1.14 fvdl * are now initialized. Clear the full residual flag. 1334 1.14 fvdl */ 1335 1.14 fvdl and SCB_SGPTR[0], ~SG_FULL_RESID; 1336 1.11 fvdl 1337 1.11 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 1338 1.14 fvdl /* Clear the channel in case we return to data phase later */ 1339 1.14 fvdl or SXFRCTL0, CLRSTCNT|CLRCHN; 1340 1.11 fvdl or SXFRCTL0, CLRSTCNT|CLRCHN; 1341 1.11 fvdl } 1342 1.11 fvdl 1343 1.14 fvdl if ((ahc->flags & AHC_TARGETROLE) != 0) { 1344 1.11 fvdl test SEQ_FLAGS, DPHASE_PENDING jz ITloop; 1345 1.11 fvdl and SEQ_FLAGS, ~DPHASE_PENDING; 1346 1.11 fvdl /* 1347 1.11 fvdl * For data-in phases, wait for any pending acks from the 1348 1.14 fvdl * initiator before changing phase. We only need to 1349 1.14 fvdl * send Ignore Wide Residue messages for data-in phases. 1350 1.11 fvdl */ 1351 1.11 fvdl test DFCNTRL, DIRECTION jz target_ITloop; 1352 1.11 fvdl test SSTAT1, REQINIT jnz .; 1353 1.14 fvdl test DATA_COUNT_ODD, 0x1 jz target_ITloop; 1354 1.14 fvdl test SCSIRATE, WIDEXFER jz target_ITloop; 1355 1.14 fvdl /* 1356 1.14 fvdl * Issue an Ignore Wide Residue Message. 1357 1.14 fvdl */ 1358 1.14 fvdl mvi P_MESGIN|BSYO call change_phase; 1359 1.14 fvdl mvi MSG_IGN_WIDE_RESIDUE call target_outb; 1360 1.14 fvdl mvi 1 call target_outb; 1361 1.11 fvdl jmp target_ITloop; 1362 1.14 fvdl } else { 1363 1.14 fvdl jmp ITloop; 1364 1.11 fvdl } 1365 1.4 explorer 1366 1.14 fvdl if ((ahc->flags & AHC_INITIATORROLE) != 0) { 1367 1.2 mycroft /* 1368 1.2 mycroft * Command phase. Set up the DMA registers and let 'er rip. 1369 1.2 mycroft */ 1370 1.1 mycroft p_command: 1371 1.14 fvdl test SEQ_FLAGS, NOT_IDENTIFIED jz p_command_okay; 1372 1.14 fvdl mvi PROTO_VIOLATION call set_seqint; 1373 1.14 fvdl p_command_okay: 1374 1.1 mycroft 1375 1.14 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 1376 1.14 fvdl bmov HCNT[0], SCB_CDB_LEN, 1; 1377 1.11 fvdl bmov HCNT[1], ALLZEROS, 2; 1378 1.14 fvdl mvi SG_CACHE_PRE, LAST_SEG; 1379 1.14 fvdl } else if ((ahc->features & AHC_CMD_CHAN) != 0) { 1380 1.14 fvdl bmov STCNT[0], SCB_CDB_LEN, 1; 1381 1.14 fvdl bmov STCNT[1], ALLZEROS, 2; 1382 1.14 fvdl } else { 1383 1.14 fvdl mov STCNT[0], SCB_CDB_LEN; 1384 1.14 fvdl clr STCNT[1]; 1385 1.14 fvdl clr STCNT[2]; 1386 1.14 fvdl } 1387 1.14 fvdl add NONE, -13, SCB_CDB_LEN; 1388 1.14 fvdl mvi SCB_CDB_STORE jnc p_command_embedded; 1389 1.14 fvdl p_command_from_host: 1390 1.14 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 1391 1.14 fvdl bmov HADDR[0], SCB_CDB_PTR, 4; 1392 1.14 fvdl mvi DFCNTRL, (PRELOADEN|SCSIEN|HDMAEN|DIRECTION); 1393 1.14 fvdl } else { 1394 1.14 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 1395 1.14 fvdl bmov HADDR[0], SCB_CDB_PTR, 4; 1396 1.14 fvdl bmov HCNT, STCNT, 3; 1397 1.14 fvdl } else { 1398 1.14 fvdl mvi DINDEX, HADDR; 1399 1.14 fvdl mvi SCB_CDB_PTR call bcopy_4; 1400 1.14 fvdl mov SCB_CDB_LEN call set_hcnt; 1401 1.11 fvdl } 1402 1.14 fvdl mvi DFCNTRL, (SCSIEN|SDMAEN|HDMAEN|DIRECTION|FIFORESET); 1403 1.14 fvdl } 1404 1.14 fvdl jmp p_command_xfer; 1405 1.14 fvdl p_command_embedded: 1406 1.14 fvdl /* 1407 1.14 fvdl * The data fifo seems to require 4 byte aligned 1408 1.14 fvdl * transfers from the sequencer. Force this to 1409 1.14 fvdl * be the case by clearing HADDR[0] even though 1410 1.14 fvdl * we aren't going to touch host memory. 1411 1.14 fvdl */ 1412 1.14 fvdl clr HADDR[0]; 1413 1.14 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 1414 1.14 fvdl mvi DFCNTRL, (PRELOADEN|SCSIEN|DIRECTION); 1415 1.16 perry bmov DFDAT, SCB_CDB_STORE, 12; 1416 1.14 fvdl } else if ((ahc->features & AHC_CMD_CHAN) != 0) { 1417 1.14 fvdl if ((ahc->flags & AHC_SCB_BTT) != 0) { 1418 1.14 fvdl /* 1419 1.14 fvdl * On the 7895 the data FIFO will 1420 1.14 fvdl * get corrupted if you try to dump 1421 1.14 fvdl * data from external SCB memory into 1422 1.14 fvdl * the FIFO while it is enabled. So, 1423 1.14 fvdl * fill the fifo and then enable SCSI 1424 1.14 fvdl * transfers. 1425 1.14 fvdl */ 1426 1.14 fvdl mvi DFCNTRL, (DIRECTION|FIFORESET); 1427 1.11 fvdl } else { 1428 1.11 fvdl mvi DFCNTRL, (SCSIEN|SDMAEN|DIRECTION|FIFORESET); 1429 1.11 fvdl } 1430 1.16 perry bmov DFDAT, SCB_CDB_STORE, 12; 1431 1.14 fvdl if ((ahc->flags & AHC_SCB_BTT) != 0) { 1432 1.14 fvdl mvi DFCNTRL, (SCSIEN|SDMAEN|DIRECTION|FIFOFLUSH); 1433 1.14 fvdl } else { 1434 1.14 fvdl or DFCNTRL, FIFOFLUSH; 1435 1.14 fvdl } 1436 1.11 fvdl } else { 1437 1.14 fvdl mvi DFCNTRL, (SCSIEN|SDMAEN|DIRECTION|FIFORESET); 1438 1.14 fvdl call copy_to_fifo_6; 1439 1.14 fvdl call copy_to_fifo_6; 1440 1.14 fvdl or DFCNTRL, FIFOFLUSH; 1441 1.11 fvdl } 1442 1.14 fvdl p_command_xfer: 1443 1.14 fvdl and SEQ_FLAGS, ~NO_CDB_SENT; 1444 1.14 fvdl if ((ahc->features & AHC_DT) == 0) { 1445 1.14 fvdl test SSTAT0, SDONE jnz . + 2; 1446 1.14 fvdl test SSTAT1, PHASEMIS jz . - 1; 1447 1.14 fvdl /* 1448 1.19 snj * Wait for our ACK to go-away on its own 1449 1.14 fvdl * instead of being killed by SCSIEN getting cleared. 1450 1.14 fvdl */ 1451 1.14 fvdl test SCSISIGI, ACKI jnz .; 1452 1.11 fvdl } else { 1453 1.14 fvdl test DFCNTRL, SCSIEN jnz .; 1454 1.11 fvdl } 1455 1.14 fvdl test SSTAT0, SDONE jnz p_command_successful; 1456 1.11 fvdl /* 1457 1.14 fvdl * Don't allow a data phase if the command 1458 1.14 fvdl * was not fully transferred. 1459 1.11 fvdl */ 1460 1.14 fvdl or SEQ_FLAGS, NO_CDB_SENT; 1461 1.14 fvdl p_command_successful: 1462 1.11 fvdl and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN); 1463 1.11 fvdl test DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz .; 1464 1.11 fvdl jmp ITloop; 1465 1.1 mycroft 1466 1.2 mycroft /* 1467 1.2 mycroft * Status phase. Wait for the data byte to appear, then read it 1468 1.2 mycroft * and store it into the SCB. 1469 1.2 mycroft */ 1470 1.1 mycroft p_status: 1471 1.14 fvdl test SEQ_FLAGS, NOT_IDENTIFIED jnz mesgin_proto_violation; 1472 1.14 fvdl p_status_okay: 1473 1.14 fvdl mov SCB_SCSI_STATUS, SCSIDATL; 1474 1.14 fvdl or SCB_CONTROL, STATUS_RCVD; 1475 1.11 fvdl jmp ITloop; 1476 1.1 mycroft 1477 1.2 mycroft /* 1478 1.11 fvdl * Message out phase. If MSG_OUT is MSG_IDENTIFYFLAG, build a full 1479 1.22 andvar * identify message sequence and send it to the target. The host may 1480 1.11 fvdl * override this behavior by setting the MK_MESSAGE bit in the SCB 1481 1.11 fvdl * control byte. This will cause us to interrupt the host and allow 1482 1.11 fvdl * it to handle the message phase completely on its own. If the bit 1483 1.11 fvdl * associated with this target is set, we will also interrupt the host, 1484 1.11 fvdl * thereby allowing it to send a message on the next selection regardless 1485 1.11 fvdl * of the transaction being sent. 1486 1.16 perry * 1487 1.11 fvdl * If MSG_OUT is == HOST_MSG, also interrupt the host and take a message. 1488 1.11 fvdl * This is done to allow the host to send messages outside of an identify 1489 1.22 andvar * sequence while protecting the sequencer from testing the MK_MESSAGE bit 1490 1.11 fvdl * on an SCB that might not be for the current nexus. (For example, a 1491 1.22 andvar * BDR message in response to a bad reselection would leave us pointed to 1492 1.11 fvdl * an SCB that doesn't have anything to do with the current target). 1493 1.11 fvdl * 1494 1.11 fvdl * Otherwise, treat MSG_OUT as a 1 byte message to send (abort, abort tag, 1495 1.11 fvdl * bus device reset). 1496 1.11 fvdl * 1497 1.11 fvdl * When there are no messages to send, MSG_OUT should be set to MSG_NOOP, 1498 1.11 fvdl * in case the target decides to put us in this phase for some strange 1499 1.11 fvdl * reason. 1500 1.2 mycroft */ 1501 1.11 fvdl p_mesgout_retry: 1502 1.14 fvdl /* Turn on ATN for the retry */ 1503 1.14 fvdl if ((ahc->features & AHC_DT) == 0) { 1504 1.14 fvdl or SCSISIGO, ATNO, LASTPHASE; 1505 1.14 fvdl } else { 1506 1.14 fvdl mvi SCSISIGO, ATNO; 1507 1.14 fvdl } 1508 1.1 mycroft p_mesgout: 1509 1.11 fvdl mov SINDEX, MSG_OUT; 1510 1.11 fvdl cmp SINDEX, MSG_IDENTIFYFLAG jne p_mesgout_from_host; 1511 1.11 fvdl test SCB_CONTROL,MK_MESSAGE jnz host_message_loop; 1512 1.11 fvdl p_mesgout_identify: 1513 1.14 fvdl or SINDEX, MSG_IDENTIFYFLAG|DISCENB, SCB_LUN; 1514 1.14 fvdl test SCB_CONTROL, DISCENB jnz . + 2; 1515 1.14 fvdl and SINDEX, ~DISCENB; 1516 1.2 mycroft /* 1517 1.11 fvdl * Send a tag message if TAG_ENB is set in the SCB control block. 1518 1.11 fvdl * Use SCB_TAG (the position in the kernel's SCB array) as the tag value. 1519 1.2 mycroft */ 1520 1.11 fvdl p_mesgout_tag: 1521 1.11 fvdl test SCB_CONTROL,TAG_ENB jz p_mesgout_onebyte; 1522 1.11 fvdl mov SCSIDATL, SINDEX; /* Send the identify message */ 1523 1.11 fvdl call phase_lock; 1524 1.11 fvdl cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; 1525 1.11 fvdl and SCSIDATL,TAG_ENB|SCB_TAG_TYPE,SCB_CONTROL; 1526 1.11 fvdl call phase_lock; 1527 1.11 fvdl cmp LASTPHASE, P_MESGOUT jne p_mesgout_done; 1528 1.11 fvdl mov SCB_TAG jmp p_mesgout_onebyte; 1529 1.11 fvdl /* 1530 1.11 fvdl * Interrupt the driver, and allow it to handle this message 1531 1.11 fvdl * phase and any required retries. 1532 1.11 fvdl */ 1533 1.11 fvdl p_mesgout_from_host: 1534 1.11 fvdl cmp SINDEX, HOST_MSG jne p_mesgout_onebyte; 1535 1.11 fvdl jmp host_message_loop; 1536 1.11 fvdl 1537 1.11 fvdl p_mesgout_onebyte: 1538 1.11 fvdl mvi CLRSINT1, CLRATNO; 1539 1.11 fvdl mov SCSIDATL, SINDEX; 1540 1.2 mycroft 1541 1.2 mycroft /* 1542 1.11 fvdl * If the next bus phase after ATN drops is message out, it means 1543 1.2 mycroft * that the target is requesting that the last message(s) be resent. 1544 1.2 mycroft */ 1545 1.11 fvdl call phase_lock; 1546 1.11 fvdl cmp LASTPHASE, P_MESGOUT je p_mesgout_retry; 1547 1.1 mycroft 1548 1.2 mycroft p_mesgout_done: 1549 1.11 fvdl mvi CLRSINT1,CLRATNO; /* Be sure to turn ATNO off */ 1550 1.11 fvdl mov LAST_MSG, MSG_OUT; 1551 1.11 fvdl mvi MSG_OUT, MSG_NOOP; /* No message left */ 1552 1.11 fvdl jmp ITloop; 1553 1.1 mycroft 1554 1.2 mycroft /* 1555 1.2 mycroft * Message in phase. Bytes are read using Automatic PIO mode. 1556 1.2 mycroft */ 1557 1.1 mycroft p_mesgin: 1558 1.11 fvdl mvi ACCUM call inb_first; /* read the 1st message byte */ 1559 1.2 mycroft 1560 1.11 fvdl test A,MSG_IDENTIFYFLAG jnz mesgin_identify; 1561 1.11 fvdl cmp A,MSG_DISCONNECT je mesgin_disconnect; 1562 1.11 fvdl cmp A,MSG_SAVEDATAPOINTER je mesgin_sdptrs; 1563 1.11 fvdl cmp ALLZEROS,A je mesgin_complete; 1564 1.11 fvdl cmp A,MSG_RESTOREPOINTERS je mesgin_rdptrs; 1565 1.14 fvdl cmp A,MSG_IGN_WIDE_RESIDUE je mesgin_ign_wide_residue; 1566 1.11 fvdl cmp A,MSG_NOOP je mesgin_done; 1567 1.11 fvdl 1568 1.11 fvdl /* 1569 1.11 fvdl * Pushed message loop to allow the kernel to 1570 1.19 snj * run its own message state engine. To avoid an 1571 1.11 fvdl * extra nop instruction after signaling the kernel, 1572 1.11 fvdl * we perform the phase_lock before checking to see 1573 1.11 fvdl * if we should exit the loop and skip the phase_lock 1574 1.11 fvdl * in the ITloop. Performing back to back phase_locks 1575 1.11 fvdl * shouldn't hurt, but why do it twice... 1576 1.11 fvdl */ 1577 1.11 fvdl host_message_loop: 1578 1.14 fvdl mvi HOST_MSG_LOOP call set_seqint; 1579 1.11 fvdl call phase_lock; 1580 1.11 fvdl cmp RETURN_1, EXIT_MSG_LOOP je ITloop + 1; 1581 1.11 fvdl jmp host_message_loop; 1582 1.2 mycroft 1583 1.14 fvdl mesgin_ign_wide_residue: 1584 1.14 fvdl if ((ahc->features & AHC_WIDE) != 0) { 1585 1.14 fvdl test SCSIRATE, WIDEXFER jz mesgin_reject; 1586 1.14 fvdl /* Pull the residue byte */ 1587 1.14 fvdl mvi ARG_1 call inb_next; 1588 1.14 fvdl cmp ARG_1, 0x01 jne mesgin_reject; 1589 1.14 fvdl test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz . + 2; 1590 1.14 fvdl test DATA_COUNT_ODD, 0x1 jz mesgin_done; 1591 1.14 fvdl mvi IGN_WIDE_RES call set_seqint; 1592 1.14 fvdl jmp mesgin_done; 1593 1.14 fvdl } 1594 1.14 fvdl 1595 1.14 fvdl mesgin_proto_violation: 1596 1.14 fvdl mvi PROTO_VIOLATION call set_seqint; 1597 1.14 fvdl jmp mesgin_done; 1598 1.14 fvdl mesgin_reject: 1599 1.14 fvdl mvi MSG_MESSAGE_REJECT call mk_mesg; 1600 1.2 mycroft mesgin_done: 1601 1.11 fvdl mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 1602 1.11 fvdl jmp ITloop; 1603 1.2 mycroft 1604 1.2 mycroft /* 1605 1.14 fvdl * We received a "command complete" message. Put the SCB_TAG into the QOUTFIFO, 1606 1.11 fvdl * and trigger a completion interrupt. Before doing so, check to see if there 1607 1.11 fvdl * is a residual or the status byte is something other than STATUS_GOOD (0). 1608 1.11 fvdl * In either of these conditions, we upload the SCB back to the host so it can 1609 1.16 perry * process this information. In the case of a non zero status byte, we 1610 1.11 fvdl * additionally interrupt the kernel driver synchronously, allowing it to 1611 1.11 fvdl * decide if sense should be retrieved. If the kernel driver wishes to request 1612 1.14 fvdl * sense, it will fill the kernel SCB with a request sense command, requeue 1613 1.16 perry * it to the QINFIFO and tell us not to post to the QOUTFIFO by setting 1614 1.14 fvdl * RETURN_1 to SEND_SENSE. 1615 1.2 mycroft */ 1616 1.14 fvdl mesgin_complete: 1617 1.14 fvdl 1618 1.14 fvdl /* 1619 1.14 fvdl * If ATN is raised, we still want to give the target a message. 1620 1.14 fvdl * Perhaps there was a parity error on this last message byte. 1621 1.14 fvdl * Either way, the target should take us to message out phase 1622 1.14 fvdl * and then attempt to complete the command again. We should use a 1623 1.14 fvdl * critical section here to guard against a timeout triggering 1624 1.14 fvdl * for this command and setting ATN while we are still processing 1625 1.14 fvdl * the completion. 1626 1.14 fvdl test SCSISIGI, ATNI jnz mesgin_done; 1627 1.14 fvdl */ 1628 1.14 fvdl 1629 1.14 fvdl /* 1630 1.14 fvdl * If we are identified and have successfully sent the CDB, 1631 1.14 fvdl * any status will do. Optimize this fast path. 1632 1.14 fvdl */ 1633 1.14 fvdl test SCB_CONTROL, STATUS_RCVD jz mesgin_proto_violation; 1634 1.16 perry test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT jz complete_accepted; 1635 1.14 fvdl 1636 1.14 fvdl /* 1637 1.14 fvdl * If the target never sent an identify message but instead went 1638 1.14 fvdl * to mesgin to give an invalid message, let the host abort us. 1639 1.14 fvdl */ 1640 1.14 fvdl test SEQ_FLAGS, NOT_IDENTIFIED jnz mesgin_proto_violation; 1641 1.11 fvdl 1642 1.14 fvdl /* 1643 1.20 msaitoh * If we received good status but never successfully sent the 1644 1.14 fvdl * cdb, abort the command. 1645 1.14 fvdl */ 1646 1.14 fvdl test SCB_SCSI_STATUS,0xff jnz complete_accepted; 1647 1.14 fvdl test SEQ_FLAGS, NO_CDB_SENT jnz mesgin_proto_violation; 1648 1.14 fvdl 1649 1.14 fvdl complete_accepted: 1650 1.14 fvdl /* 1651 1.23 andvar * See if we attempted to deliver a message but the target ignored us. 1652 1.14 fvdl */ 1653 1.14 fvdl test SCB_CONTROL, MK_MESSAGE jz . + 2; 1654 1.14 fvdl mvi MKMSG_FAILED call set_seqint; 1655 1.14 fvdl 1656 1.14 fvdl /* 1657 1.14 fvdl * Check for residuals 1658 1.14 fvdl */ 1659 1.14 fvdl test SCB_SGPTR, SG_LIST_NULL jnz check_status;/* No xfer */ 1660 1.14 fvdl test SCB_SGPTR, SG_FULL_RESID jnz upload_scb;/* Never xfered */ 1661 1.14 fvdl test SCB_RESIDUAL_SGPTR, SG_LIST_NULL jz upload_scb; 1662 1.14 fvdl check_status: 1663 1.14 fvdl test SCB_SCSI_STATUS,0xff jz complete; /* Good Status? */ 1664 1.11 fvdl upload_scb: 1665 1.14 fvdl or SCB_SGPTR, SG_RESID_VALID; 1666 1.11 fvdl mvi DMAPARAMS, FIFORESET; 1667 1.11 fvdl mov SCB_TAG call dma_scb; 1668 1.14 fvdl test SCB_SCSI_STATUS, 0xff jz complete; /* Just a residual? */ 1669 1.14 fvdl mvi BAD_STATUS call set_seqint; /* let driver know */ 1670 1.11 fvdl cmp RETURN_1, SEND_SENSE jne complete; 1671 1.14 fvdl call add_scb_to_free_list; 1672 1.11 fvdl jmp await_busfree; 1673 1.1 mycroft complete: 1674 1.11 fvdl mov SCB_TAG call complete_post; 1675 1.11 fvdl jmp await_busfree; 1676 1.11 fvdl } 1677 1.11 fvdl 1678 1.11 fvdl complete_post: 1679 1.11 fvdl /* Post the SCBID in SINDEX and issue an interrupt */ 1680 1.11 fvdl call add_scb_to_free_list; 1681 1.11 fvdl mov ARG_1, SINDEX; 1682 1.11 fvdl if ((ahc->features & AHC_QUEUE_REGS) != 0) { 1683 1.11 fvdl mov A, SDSCB_QOFF; 1684 1.11 fvdl } else { 1685 1.11 fvdl mov A, QOUTPOS; 1686 1.11 fvdl } 1687 1.11 fvdl mvi QOUTFIFO_OFFSET call post_byte_setup; 1688 1.11 fvdl mov ARG_1 call post_byte; 1689 1.11 fvdl if ((ahc->features & AHC_QUEUE_REGS) == 0) { 1690 1.11 fvdl inc QOUTPOS; 1691 1.11 fvdl } 1692 1.11 fvdl mvi INTSTAT,CMDCMPLT ret; 1693 1.2 mycroft 1694 1.14 fvdl if ((ahc->flags & AHC_INITIATORROLE) != 0) { 1695 1.2 mycroft /* 1696 1.2 mycroft * Is it a disconnect message? Set a flag in the SCB to remind us 1697 1.14 fvdl * and await the bus going free. If this is an untagged transaction 1698 1.14 fvdl * store the SCB id for it in our untagged target table for lookup on 1699 1.22 andvar * a reselection. 1700 1.2 mycroft */ 1701 1.2 mycroft mesgin_disconnect: 1702 1.14 fvdl /* 1703 1.14 fvdl * If ATN is raised, we still want to give the target a message. 1704 1.14 fvdl * Perhaps there was a parity error on this last message byte 1705 1.14 fvdl * or we want to abort this command. Either way, the target 1706 1.14 fvdl * should take us to message out phase and then attempt to 1707 1.14 fvdl * disconnect again. 1708 1.14 fvdl * XXX - Wait for more testing. 1709 1.14 fvdl test SCSISIGI, ATNI jnz mesgin_done; 1710 1.14 fvdl */ 1711 1.14 fvdl test SEQ_FLAGS, NOT_IDENTIFIED|NO_CDB_SENT 1712 1.14 fvdl jnz mesgin_proto_violation; 1713 1.11 fvdl or SCB_CONTROL,DISCONNECTED; 1714 1.14 fvdl if ((ahc->flags & AHC_PAGESCBS) != 0) { 1715 1.14 fvdl call add_scb_to_disc_list; 1716 1.14 fvdl } 1717 1.14 fvdl test SCB_CONTROL, TAG_ENB jnz await_busfree; 1718 1.14 fvdl mov ARG_1, SCB_TAG; 1719 1.14 fvdl mov SAVED_LUN, SCB_LUN; 1720 1.14 fvdl mov SCB_SCSIID call set_busy_target; 1721 1.11 fvdl jmp await_busfree; 1722 1.2 mycroft 1723 1.2 mycroft /* 1724 1.11 fvdl * Save data pointers message: 1725 1.11 fvdl * Copying RAM values back to SCB, for Save Data Pointers message, but 1726 1.11 fvdl * only if we've actually been into a data phase to change them. This 1727 1.11 fvdl * protects against bogus data in scratch ram and the residual counts 1728 1.11 fvdl * since they are only initialized when we go into data_in or data_out. 1729 1.14 fvdl * Ack the message as soon as possible. For chips without S/G pipelining, 1730 1.14 fvdl * we can only ack the message after SHADDR has been saved. On these 1731 1.14 fvdl * chips, SHADDR increments with every bus transaction, even PIO. 1732 1.2 mycroft */ 1733 1.2 mycroft mesgin_sdptrs: 1734 1.14 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 1735 1.14 fvdl mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 1736 1.14 fvdl test SEQ_FLAGS, DPHASE jz ITloop; 1737 1.14 fvdl } else { 1738 1.14 fvdl test SEQ_FLAGS, DPHASE jz mesgin_done; 1739 1.14 fvdl } 1740 1.14 fvdl 1741 1.14 fvdl /* 1742 1.14 fvdl * If we are asked to save our position at the end of the 1743 1.14 fvdl * transfer, just mark us at the end rather than perform a 1744 1.14 fvdl * full save. 1745 1.14 fvdl */ 1746 1.14 fvdl test SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL jz mesgin_sdptrs_full; 1747 1.14 fvdl or SCB_SGPTR, SG_LIST_NULL; 1748 1.14 fvdl if ((ahc->features & AHC_ULTRA2) != 0) { 1749 1.14 fvdl jmp ITloop; 1750 1.14 fvdl } else { 1751 1.14 fvdl jmp mesgin_done; 1752 1.14 fvdl } 1753 1.14 fvdl 1754 1.14 fvdl mesgin_sdptrs_full: 1755 1.11 fvdl 1756 1.11 fvdl /* 1757 1.14 fvdl * The SCB_SGPTR becomes the next one we'll download, 1758 1.14 fvdl * and the SCB_DATAPTR becomes the current SHADDR. 1759 1.11 fvdl * Use the residual number since STCNT is corrupted by 1760 1.11 fvdl * any message transfer. 1761 1.11 fvdl */ 1762 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 1763 1.11 fvdl bmov SCB_DATAPTR, SHADDR, 4; 1764 1.14 fvdl if ((ahc->features & AHC_ULTRA2) == 0) { 1765 1.14 fvdl mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 1766 1.14 fvdl } 1767 1.14 fvdl bmov SCB_DATACNT, SCB_RESIDUAL_DATACNT, 8; 1768 1.11 fvdl } else { 1769 1.11 fvdl mvi DINDEX, SCB_DATAPTR; 1770 1.14 fvdl mvi SHADDR call bcopy_4; 1771 1.14 fvdl mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 1772 1.14 fvdl mvi SCB_RESIDUAL_DATACNT call bcopy_8; 1773 1.11 fvdl } 1774 1.14 fvdl jmp ITloop; 1775 1.1 mycroft 1776 1.2 mycroft /* 1777 1.2 mycroft * Restore pointers message? Data pointers are recopied from the 1778 1.2 mycroft * SCB anytime we enter a data phase for the first time, so all 1779 1.2 mycroft * we need to do is clear the DPHASE flag and let the data phase 1780 1.14 fvdl * code do the rest. We also reset/reallocate the FIFO to make 1781 1.14 fvdl * sure we have a clean start for the next data or command phase. 1782 1.2 mycroft */ 1783 1.2 mycroft mesgin_rdptrs: 1784 1.11 fvdl and SEQ_FLAGS, ~DPHASE; /* 1785 1.11 fvdl * We'll reload them 1786 1.2 mycroft * the next time through 1787 1.11 fvdl * the dataphase. 1788 1.2 mycroft */ 1789 1.14 fvdl or SXFRCTL0, CLRSTCNT|CLRCHN; 1790 1.11 fvdl jmp mesgin_done; 1791 1.2 mycroft 1792 1.2 mycroft /* 1793 1.14 fvdl * Index into our Busy Target table. SINDEX and DINDEX are modified 1794 1.14 fvdl * upon return. SCBPTR may be modified by this action. 1795 1.14 fvdl */ 1796 1.14 fvdl set_busy_target: 1797 1.14 fvdl shr DINDEX, 4, SINDEX; 1798 1.14 fvdl if ((ahc->flags & AHC_SCB_BTT) != 0) { 1799 1.14 fvdl mov SCBPTR, SAVED_LUN; 1800 1.14 fvdl add DINDEX, SCB_64_BTT; 1801 1.14 fvdl } else { 1802 1.14 fvdl add DINDEX, BUSY_TARGETS; 1803 1.14 fvdl } 1804 1.14 fvdl mov DINDIR, ARG_1 ret; 1805 1.14 fvdl 1806 1.14 fvdl /* 1807 1.2 mycroft * Identify message? For a reconnecting target, this tells us the lun 1808 1.2 mycroft * that the reconnection is for - find the correct SCB and switch to it, 1809 1.2 mycroft * clearing the "disconnected" bit so we don't "find" it by accident later. 1810 1.2 mycroft */ 1811 1.2 mycroft mesgin_identify: 1812 1.14 fvdl /* 1813 1.14 fvdl * Determine whether a target is using tagged or non-tagged 1814 1.14 fvdl * transactions by first looking at the transaction stored in 1815 1.14 fvdl * the busy target array. If there is no untagged transaction 1816 1.14 fvdl * for this target or the transaction is for a different lun, then 1817 1.14 fvdl * this must be a tagged transaction. 1818 1.14 fvdl */ 1819 1.14 fvdl shr SINDEX, 4, SAVED_SCSIID; 1820 1.14 fvdl and SAVED_LUN, MSG_IDENTIFY_LUNMASK, A; 1821 1.14 fvdl if ((ahc->flags & AHC_SCB_BTT) != 0) { 1822 1.14 fvdl add SINDEX, SCB_64_BTT; 1823 1.14 fvdl mov SCBPTR, SAVED_LUN; 1824 1.14 fvdl if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { 1825 1.14 fvdl add NONE, -SCB_64_BTT, SINDEX; 1826 1.14 fvdl jc . + 2; 1827 1.14 fvdl mvi INTSTAT, OUT_OF_RANGE; 1828 1.14 fvdl nop; 1829 1.14 fvdl add NONE, -(SCB_64_BTT + 16), SINDEX; 1830 1.14 fvdl jnc . + 2; 1831 1.14 fvdl mvi INTSTAT, OUT_OF_RANGE; 1832 1.14 fvdl nop; 1833 1.14 fvdl } 1834 1.11 fvdl } else { 1835 1.14 fvdl add SINDEX, BUSY_TARGETS; 1836 1.14 fvdl if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { 1837 1.14 fvdl add NONE, -BUSY_TARGETS, SINDEX; 1838 1.14 fvdl jc . + 2; 1839 1.14 fvdl mvi INTSTAT, OUT_OF_RANGE; 1840 1.14 fvdl nop; 1841 1.14 fvdl add NONE, -(BUSY_TARGETS + 16), SINDEX; 1842 1.14 fvdl jnc . + 2; 1843 1.14 fvdl mvi INTSTAT, OUT_OF_RANGE; 1844 1.14 fvdl nop; 1845 1.14 fvdl } 1846 1.11 fvdl } 1847 1.14 fvdl mov ARG_1, SINDIR; 1848 1.11 fvdl cmp ARG_1, SCB_LIST_NULL je snoop_tag; 1849 1.11 fvdl if ((ahc->flags & AHC_PAGESCBS) != 0) { 1850 1.14 fvdl mov ARG_1 call findSCB; 1851 1.14 fvdl } else { 1852 1.14 fvdl mov SCBPTR, ARG_1; 1853 1.14 fvdl } 1854 1.14 fvdl if ((ahc->flags & AHC_SCB_BTT) != 0) { 1855 1.14 fvdl jmp setup_SCB_id_lun_okay; 1856 1.14 fvdl } else { 1857 1.14 fvdl /* 1858 1.14 fvdl * We only allow one untagged command per-target 1859 1.14 fvdl * at a time. So, if the lun doesn't match, look 1860 1.14 fvdl * for a tag message. 1861 1.14 fvdl */ 1862 1.14 fvdl mov A, SCB_LUN; 1863 1.14 fvdl cmp SAVED_LUN, A je setup_SCB_id_lun_okay; 1864 1.14 fvdl if ((ahc->flags & AHC_PAGESCBS) != 0) { 1865 1.14 fvdl /* 1866 1.14 fvdl * findSCB removes the SCB from the 1867 1.14 fvdl * disconnected list, so we must replace 1868 1.14 fvdl * it there should this SCB be for another 1869 1.14 fvdl * lun. 1870 1.14 fvdl */ 1871 1.14 fvdl call cleanup_scb; 1872 1.14 fvdl } 1873 1.11 fvdl } 1874 1.14 fvdl 1875 1.2 mycroft /* 1876 1.2 mycroft * Here we "snoop" the bus looking for a SIMPLE QUEUE TAG message. 1877 1.11 fvdl * If we get one, we use the tag returned to find the proper 1878 1.14 fvdl * SCB. With SCB paging, we must search for non-tagged 1879 1.14 fvdl * transactions since the SCB may exist in any slot. If we're not 1880 1.14 fvdl * using SCB paging, we can use the tag as the direct index to the 1881 1.14 fvdl * SCB. 1882 1.2 mycroft */ 1883 1.11 fvdl snoop_tag: 1884 1.14 fvdl if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { 1885 1.14 fvdl or SEQ_FLAGS, 0x80; 1886 1.14 fvdl } 1887 1.11 fvdl mov NONE,SCSIDATL; /* ACK Identify MSG */ 1888 1.11 fvdl call phase_lock; 1889 1.14 fvdl if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { 1890 1.14 fvdl or SEQ_FLAGS, 0x1; 1891 1.14 fvdl } 1892 1.11 fvdl cmp LASTPHASE, P_MESGIN jne not_found; 1893 1.14 fvdl if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { 1894 1.14 fvdl or SEQ_FLAGS, 0x2; 1895 1.14 fvdl } 1896 1.11 fvdl cmp SCSIBUSL,MSG_SIMPLE_Q_TAG jne not_found; 1897 1.2 mycroft get_tag: 1898 1.14 fvdl if ((ahc->flags & AHC_PAGESCBS) != 0) { 1899 1.14 fvdl mvi ARG_1 call inb_next; /* tag value */ 1900 1.14 fvdl mov ARG_1 call findSCB; 1901 1.14 fvdl } else { 1902 1.14 fvdl mvi ARG_1 call inb_next; /* tag value */ 1903 1.14 fvdl mov SCBPTR, ARG_1; 1904 1.14 fvdl } 1905 1.2 mycroft 1906 1.14 fvdl /* 1907 1.14 fvdl * Ensure that the SCB the tag points to is for 1908 1.14 fvdl * an SCB transaction to the reconnecting target. 1909 1.14 fvdl */ 1910 1.1 mycroft setup_SCB: 1911 1.14 fvdl if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { 1912 1.14 fvdl or SEQ_FLAGS, 0x4; 1913 1.14 fvdl } 1914 1.14 fvdl mov A, SCB_SCSIID; 1915 1.14 fvdl cmp SAVED_SCSIID, A jne not_found_cleanup_scb; 1916 1.14 fvdl if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { 1917 1.14 fvdl or SEQ_FLAGS, 0x8; 1918 1.14 fvdl } 1919 1.14 fvdl setup_SCB_id_okay: 1920 1.14 fvdl mov A, SCB_LUN; 1921 1.14 fvdl cmp SAVED_LUN, A jne not_found_cleanup_scb; 1922 1.14 fvdl setup_SCB_id_lun_okay: 1923 1.14 fvdl if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { 1924 1.14 fvdl or SEQ_FLAGS, 0x10; 1925 1.14 fvdl } 1926 1.11 fvdl test SCB_CONTROL,DISCONNECTED jz not_found_cleanup_scb; 1927 1.11 fvdl and SCB_CONTROL,~DISCONNECTED; 1928 1.14 fvdl test SCB_CONTROL, TAG_ENB jnz setup_SCB_tagged; 1929 1.14 fvdl if ((ahc->flags & AHC_SCB_BTT) != 0) { 1930 1.14 fvdl mov A, SCBPTR; 1931 1.14 fvdl } 1932 1.14 fvdl mvi ARG_1, SCB_LIST_NULL; 1933 1.14 fvdl mov SAVED_SCSIID call set_busy_target; 1934 1.14 fvdl if ((ahc->flags & AHC_SCB_BTT) != 0) { 1935 1.14 fvdl mov SCBPTR, A; 1936 1.14 fvdl } 1937 1.14 fvdl setup_SCB_tagged: 1938 1.14 fvdl clr SEQ_FLAGS; /* make note of IDENTIFY */ 1939 1.11 fvdl call set_transfer_settings; 1940 1.11 fvdl /* See if the host wants to send a message upon reconnection */ 1941 1.11 fvdl test SCB_CONTROL, MK_MESSAGE jz mesgin_done; 1942 1.11 fvdl mvi HOST_MSG call mk_mesg; 1943 1.11 fvdl jmp mesgin_done; 1944 1.11 fvdl 1945 1.11 fvdl not_found_cleanup_scb: 1946 1.14 fvdl if ((ahc->flags & AHC_PAGESCBS) != 0) { 1947 1.14 fvdl call cleanup_scb; 1948 1.14 fvdl } 1949 1.11 fvdl not_found: 1950 1.14 fvdl mvi NO_MATCH call set_seqint; 1951 1.11 fvdl jmp mesgin_done; 1952 1.2 mycroft 1953 1.2 mycroft mk_mesg: 1954 1.14 fvdl if ((ahc->features & AHC_DT) == 0) { 1955 1.14 fvdl or SCSISIGO, ATNO, LASTPHASE; 1956 1.14 fvdl } else { 1957 1.14 fvdl mvi SCSISIGO, ATNO; 1958 1.14 fvdl } 1959 1.11 fvdl mov MSG_OUT,SINDEX ret; 1960 1.2 mycroft 1961 1.2 mycroft /* 1962 1.2 mycroft * Functions to read data in Automatic PIO mode. 1963 1.2 mycroft * 1964 1.2 mycroft * According to Adaptec's documentation, an ACK is not sent on input from 1965 1.2 mycroft * the target until SCSIDATL is read from. So we wait until SCSIDATL is 1966 1.2 mycroft * latched (the usual way), then read the data byte directly off the bus 1967 1.2 mycroft * using SCSIBUSL. When we have pulled the ATN line, or we just want to 1968 1.2 mycroft * acknowledge the byte, then we do a dummy read from SCISDATL. The SCSI 1969 1.2 mycroft * spec guarantees that the target will hold the data byte on the bus until 1970 1.2 mycroft * we send our ACK. 1971 1.2 mycroft * 1972 1.2 mycroft * The assumption here is that these are called in a particular sequence, 1973 1.2 mycroft * and that REQ is already set when inb_first is called. inb_{first,next} 1974 1.2 mycroft * use the same calling convention as inb. 1975 1.2 mycroft */ 1976 1.11 fvdl inb_next_wait_perr: 1977 1.14 fvdl mvi PERR_DETECTED call set_seqint; 1978 1.11 fvdl jmp inb_next_wait; 1979 1.2 mycroft inb_next: 1980 1.11 fvdl mov NONE,SCSIDATL; /*dummy read from latch to ACK*/ 1981 1.2 mycroft inb_next_wait: 1982 1.11 fvdl /* 1983 1.11 fvdl * If there is a parity error, wait for the kernel to 1984 1.11 fvdl * see the interrupt and prepare our message response 1985 1.11 fvdl * before continuing. 1986 1.11 fvdl */ 1987 1.11 fvdl test SSTAT1, REQINIT jz inb_next_wait; 1988 1.11 fvdl test SSTAT1, SCSIPERR jnz inb_next_wait_perr; 1989 1.11 fvdl inb_next_check_phase: 1990 1.11 fvdl and LASTPHASE, PHASE_MASK, SCSISIGI; 1991 1.11 fvdl cmp LASTPHASE, P_MESGIN jne mesgin_phasemis; 1992 1.1 mycroft inb_first: 1993 1.11 fvdl mov DINDEX,SINDEX; 1994 1.11 fvdl mov DINDIR,SCSIBUSL ret; /*read byte directly from bus*/ 1995 1.2 mycroft inb_last: 1996 1.11 fvdl mov NONE,SCSIDATL ret; /*dummy read from latch to ACK*/ 1997 1.11 fvdl } 1998 1.1 mycroft 1999 1.14 fvdl if ((ahc->flags & AHC_TARGETROLE) != 0) { 2000 1.11 fvdl /* 2001 1.11 fvdl * Change to a new phase. If we are changing the state of the I/O signal, 2002 1.11 fvdl * from out to in, wait an additional data release delay before continuing. 2003 1.11 fvdl */ 2004 1.11 fvdl change_phase: 2005 1.18 christos /* Wait for preceding I/O session to complete. */ 2006 1.11 fvdl test SCSISIGI, ACKI jnz .; 2007 1.11 fvdl 2008 1.11 fvdl /* Change the phase */ 2009 1.11 fvdl and DINDEX, IOI, SCSISIGI; 2010 1.11 fvdl mov SCSISIGO, SINDEX; 2011 1.11 fvdl and A, IOI, SINDEX; 2012 1.11 fvdl 2013 1.11 fvdl /* 2014 1.11 fvdl * If the data direction has changed, from 2015 1.11 fvdl * out (initiator driving) to in (target driving), 2016 1.14 fvdl * we must wait at least a data release delay plus 2017 1.11 fvdl * the normal bus settle delay. [SCSI III SPI 10.11.0] 2018 1.11 fvdl */ 2019 1.11 fvdl cmp DINDEX, A je change_phase_wait; 2020 1.11 fvdl test SINDEX, IOI jz change_phase_wait; 2021 1.11 fvdl call change_phase_wait; 2022 1.11 fvdl change_phase_wait: 2023 1.11 fvdl nop; 2024 1.11 fvdl nop; 2025 1.11 fvdl nop; 2026 1.11 fvdl nop ret; 2027 1.11 fvdl 2028 1.11 fvdl /* 2029 1.11 fvdl * Send a byte to an initiator in Automatic PIO mode. 2030 1.11 fvdl */ 2031 1.11 fvdl target_outb: 2032 1.11 fvdl or SXFRCTL0, SPIOEN; 2033 1.11 fvdl test SSTAT0, SPIORDY jz .; 2034 1.11 fvdl mov SCSIDATL, SINDEX; 2035 1.11 fvdl test SSTAT0, SPIORDY jz .; 2036 1.11 fvdl and SXFRCTL0, ~SPIOEN ret; 2037 1.11 fvdl } 2038 1.16 perry 2039 1.2 mycroft /* 2040 1.14 fvdl * Locate a disconnected SCB by SCBID. Upon return, SCBPTR and SINDEX will 2041 1.14 fvdl * be set to the position of the SCB. If the SCB cannot be found locally, 2042 1.14 fvdl * it will be paged in from host memory. RETURN_2 stores the address of the 2043 1.14 fvdl * preceding SCB in the disconnected list which can be used to speed up 2044 1.14 fvdl * removal of the found SCB from the disconnected list. 2045 1.2 mycroft */ 2046 1.14 fvdl if ((ahc->flags & AHC_PAGESCBS) != 0) { 2047 1.14 fvdl BEGIN_CRITICAL; 2048 1.1 mycroft findSCB: 2049 1.14 fvdl mov A, SINDEX; /* Tag passed in SINDEX */ 2050 1.14 fvdl cmp DISCONNECTED_SCBH, SCB_LIST_NULL je findSCB_notFound; 2051 1.14 fvdl mov SCBPTR, DISCONNECTED_SCBH; /* Initialize SCBPTR */ 2052 1.14 fvdl mvi ARG_2, SCB_LIST_NULL; /* Head of list */ 2053 1.14 fvdl jmp findSCB_loop; 2054 1.11 fvdl findSCB_next: 2055 1.14 fvdl cmp SCB_NEXT, SCB_LIST_NULL je findSCB_notFound; 2056 1.11 fvdl mov ARG_2, SCBPTR; 2057 1.11 fvdl mov SCBPTR,SCB_NEXT; 2058 1.11 fvdl findSCB_loop: 2059 1.14 fvdl cmp SCB_TAG, A jne findSCB_next; 2060 1.11 fvdl rem_scb_from_disc_list: 2061 1.11 fvdl cmp ARG_2, SCB_LIST_NULL je rHead; 2062 1.11 fvdl mov DINDEX, SCB_NEXT; 2063 1.14 fvdl mov SINDEX, SCBPTR; 2064 1.11 fvdl mov SCBPTR, ARG_2; 2065 1.11 fvdl mov SCB_NEXT, DINDEX; 2066 1.11 fvdl mov SCBPTR, SINDEX ret; 2067 1.2 mycroft rHead: 2068 1.11 fvdl mov DISCONNECTED_SCBH,SCB_NEXT ret; 2069 1.14 fvdl END_CRITICAL; 2070 1.14 fvdl findSCB_notFound: 2071 1.14 fvdl /* 2072 1.14 fvdl * We didn't find it. Page in the SCB. 2073 1.14 fvdl */ 2074 1.14 fvdl mov ARG_1, A; /* Save tag */ 2075 1.14 fvdl mov ALLZEROS call get_free_or_disc_scb; 2076 1.11 fvdl mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET; 2077 1.11 fvdl mov ARG_1 jmp dma_scb; 2078 1.14 fvdl } 2079 1.11 fvdl 2080 1.11 fvdl /* 2081 1.11 fvdl * Prepare the hardware to post a byte to host memory given an 2082 1.14 fvdl * index of (A + (256 * SINDEX)) and a base address of SHARED_DATA_ADDR. 2083 1.11 fvdl */ 2084 1.11 fvdl post_byte_setup: 2085 1.11 fvdl mov ARG_2, SINDEX; 2086 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 2087 1.11 fvdl mvi DINDEX, CCHADDR; 2088 1.14 fvdl mvi SHARED_DATA_ADDR call set_1byte_addr; 2089 1.11 fvdl mvi CCHCNT, 1; 2090 1.11 fvdl mvi CCSCBCTL, CCSCBRESET ret; 2091 1.11 fvdl } else { 2092 1.11 fvdl mvi DINDEX, HADDR; 2093 1.14 fvdl mvi SHARED_DATA_ADDR call set_1byte_addr; 2094 1.14 fvdl mvi 1 call set_hcnt; 2095 1.11 fvdl mvi DFCNTRL, FIFORESET ret; 2096 1.11 fvdl } 2097 1.11 fvdl 2098 1.11 fvdl post_byte: 2099 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 2100 1.11 fvdl bmov CCSCBRAM, SINDEX, 1; 2101 1.11 fvdl or CCSCBCTL, CCSCBEN|CCSCBRESET; 2102 1.11 fvdl test CCSCBCTL, CCSCBDONE jz .; 2103 1.11 fvdl clr CCSCBCTL ret; 2104 1.11 fvdl } else { 2105 1.11 fvdl mov DFDAT, SINDEX; 2106 1.11 fvdl or DFCNTRL, HDMAEN|FIFOFLUSH; 2107 1.11 fvdl jmp dma_finish; 2108 1.11 fvdl } 2109 1.11 fvdl 2110 1.11 fvdl phase_lock_perr: 2111 1.14 fvdl mvi PERR_DETECTED call set_seqint; 2112 1.16 perry phase_lock: 2113 1.11 fvdl /* 2114 1.11 fvdl * If there is a parity error, wait for the kernel to 2115 1.11 fvdl * see the interrupt and prepare our message response 2116 1.11 fvdl * before continuing. 2117 1.11 fvdl */ 2118 1.11 fvdl test SSTAT1, REQINIT jz phase_lock; 2119 1.11 fvdl test SSTAT1, SCSIPERR jnz phase_lock_perr; 2120 1.11 fvdl phase_lock_latch_phase: 2121 1.14 fvdl if ((ahc->features & AHC_DT) == 0) { 2122 1.14 fvdl and SCSISIGO, PHASE_MASK, SCSISIGI; 2123 1.14 fvdl } 2124 1.11 fvdl and LASTPHASE, PHASE_MASK, SCSISIGI ret; 2125 1.11 fvdl 2126 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) == 0) { 2127 1.14 fvdl set_hcnt: 2128 1.14 fvdl mov HCNT[0], SINDEX; 2129 1.14 fvdl clear_hcnt: 2130 1.14 fvdl clr HCNT[1]; 2131 1.14 fvdl clr HCNT[2] ret; 2132 1.14 fvdl 2133 1.11 fvdl set_stcnt_from_hcnt: 2134 1.11 fvdl mov STCNT[0], HCNT[0]; 2135 1.11 fvdl mov STCNT[1], HCNT[1]; 2136 1.11 fvdl mov STCNT[2], HCNT[2] ret; 2137 1.11 fvdl 2138 1.14 fvdl bcopy_8: 2139 1.14 fvdl mov DINDIR, SINDIR; 2140 1.11 fvdl bcopy_7: 2141 1.11 fvdl mov DINDIR, SINDIR; 2142 1.11 fvdl mov DINDIR, SINDIR; 2143 1.11 fvdl bcopy_5: 2144 1.11 fvdl mov DINDIR, SINDIR; 2145 1.11 fvdl bcopy_4: 2146 1.11 fvdl mov DINDIR, SINDIR; 2147 1.11 fvdl bcopy_3: 2148 1.11 fvdl mov DINDIR, SINDIR; 2149 1.11 fvdl mov DINDIR, SINDIR; 2150 1.11 fvdl mov DINDIR, SINDIR ret; 2151 1.11 fvdl } 2152 1.11 fvdl 2153 1.14 fvdl if ((ahc->flags & AHC_TARGETROLE) != 0) { 2154 1.11 fvdl /* 2155 1.11 fvdl * Setup addr assuming that A is an index into 2156 1.11 fvdl * an array of 32byte objects, SINDEX contains 2157 1.11 fvdl * the base address of that array, and DINDEX 2158 1.11 fvdl * contains the base address of the location 2159 1.11 fvdl * to store the indexed address. 2160 1.11 fvdl */ 2161 1.11 fvdl set_32byte_addr: 2162 1.11 fvdl shr ARG_2, 3, A; 2163 1.11 fvdl shl A, 5; 2164 1.11 fvdl jmp set_1byte_addr; 2165 1.11 fvdl } 2166 1.11 fvdl 2167 1.11 fvdl /* 2168 1.11 fvdl * Setup addr assuming that A is an index into 2169 1.11 fvdl * an array of 64byte objects, SINDEX contains 2170 1.11 fvdl * the base address of that array, and DINDEX 2171 1.11 fvdl * contains the base address of the location 2172 1.11 fvdl * to store the indexed address. 2173 1.11 fvdl */ 2174 1.11 fvdl set_64byte_addr: 2175 1.11 fvdl shr ARG_2, 2, A; 2176 1.11 fvdl shl A, 6; 2177 1.11 fvdl 2178 1.11 fvdl /* 2179 1.14 fvdl * Setup addr assuming that A + (ARG_2 * 256) is an 2180 1.11 fvdl * index into an array of 1byte objects, SINDEX contains 2181 1.11 fvdl * the base address of that array, and DINDEX contains 2182 1.11 fvdl * the base address of the location to store the computed 2183 1.11 fvdl * address. 2184 1.11 fvdl */ 2185 1.11 fvdl set_1byte_addr: 2186 1.11 fvdl add DINDIR, A, SINDIR; 2187 1.11 fvdl mov A, ARG_2; 2188 1.11 fvdl adc DINDIR, A, SINDIR; 2189 1.11 fvdl clr A; 2190 1.11 fvdl adc DINDIR, A, SINDIR; 2191 1.11 fvdl adc DINDIR, A, SINDIR ret; 2192 1.11 fvdl 2193 1.11 fvdl /* 2194 1.14 fvdl * Either post or fetch an SCB from host memory based on the 2195 1.11 fvdl * DIRECTION bit in DMAPARAMS. The host SCB index is in SINDEX. 2196 1.11 fvdl */ 2197 1.11 fvdl dma_scb: 2198 1.11 fvdl mov A, SINDEX; 2199 1.11 fvdl if ((ahc->features & AHC_CMD_CHAN) != 0) { 2200 1.11 fvdl mvi DINDEX, CCHADDR; 2201 1.11 fvdl mvi HSCB_ADDR call set_64byte_addr; 2202 1.11 fvdl mov CCSCBPTR, SCBPTR; 2203 1.11 fvdl test DMAPARAMS, DIRECTION jz dma_scb_tohost; 2204 1.14 fvdl if ((ahc->flags & AHC_SCB_BTT) != 0) { 2205 1.14 fvdl mvi CCHCNT, SCB_DOWNLOAD_SIZE_64; 2206 1.14 fvdl } else { 2207 1.14 fvdl mvi CCHCNT, SCB_DOWNLOAD_SIZE; 2208 1.14 fvdl } 2209 1.11 fvdl mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBDIR|CCSCBRESET; 2210 1.11 fvdl cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN|CCSCBDIR jne .; 2211 1.11 fvdl jmp dma_scb_finish; 2212 1.11 fvdl dma_scb_tohost: 2213 1.14 fvdl mvi CCHCNT, SCB_UPLOAD_SIZE; 2214 1.14 fvdl if ((ahc->features & AHC_ULTRA2) == 0) { 2215 1.11 fvdl mvi CCSCBCTL, CCSCBRESET; 2216 1.14 fvdl bmov CCSCBRAM, SCB_BASE, SCB_UPLOAD_SIZE; 2217 1.11 fvdl or CCSCBCTL, CCSCBEN|CCSCBRESET; 2218 1.11 fvdl test CCSCBCTL, CCSCBDONE jz .; 2219 1.14 fvdl } else if ((ahc->bugs & AHC_SCBCHAN_UPLOAD_BUG) != 0) { 2220 1.14 fvdl mvi CCSCBCTL, CCARREN|CCSCBRESET; 2221 1.14 fvdl cmp CCSCBCTL, ARRDONE|CCARREN jne .; 2222 1.14 fvdl mvi CCHCNT, SCB_UPLOAD_SIZE; 2223 1.14 fvdl mvi CCSCBCTL, CCSCBEN|CCSCBRESET; 2224 1.14 fvdl cmp CCSCBCTL, CCSCBDONE|CCSCBEN jne .; 2225 1.11 fvdl } else { 2226 1.11 fvdl mvi CCSCBCTL, CCARREN|CCSCBEN|CCSCBRESET; 2227 1.11 fvdl cmp CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN jne .; 2228 1.11 fvdl } 2229 1.11 fvdl dma_scb_finish: 2230 1.11 fvdl clr CCSCBCTL; 2231 1.11 fvdl test CCSCBCTL, CCARREN|CCSCBEN jnz .; 2232 1.11 fvdl ret; 2233 1.11 fvdl } else { 2234 1.11 fvdl mvi DINDEX, HADDR; 2235 1.11 fvdl mvi HSCB_ADDR call set_64byte_addr; 2236 1.14 fvdl mvi SCB_DOWNLOAD_SIZE call set_hcnt; 2237 1.11 fvdl mov DFCNTRL, DMAPARAMS; 2238 1.11 fvdl test DMAPARAMS, DIRECTION jnz dma_scb_fromhost; 2239 1.11 fvdl /* Fill it with the SCB data */ 2240 1.11 fvdl copy_scb_tofifo: 2241 1.14 fvdl mvi SINDEX, SCB_BASE; 2242 1.14 fvdl add A, SCB_DOWNLOAD_SIZE, SINDEX; 2243 1.11 fvdl copy_scb_tofifo_loop: 2244 1.14 fvdl call copy_to_fifo_8; 2245 1.11 fvdl cmp SINDEX, A jne copy_scb_tofifo_loop; 2246 1.11 fvdl or DFCNTRL, HDMAEN|FIFOFLUSH; 2247 1.14 fvdl jmp dma_finish; 2248 1.11 fvdl dma_scb_fromhost: 2249 1.14 fvdl mvi DINDEX, SCB_BASE; 2250 1.14 fvdl if ((ahc->bugs & AHC_PCI_2_1_RETRY_BUG) != 0) { 2251 1.14 fvdl /* 2252 1.14 fvdl * The PCI module will only issue a PCI 2253 1.14 fvdl * retry if the data FIFO is empty. If the 2254 1.14 fvdl * host disconnects in the middle of a 2255 1.14 fvdl * transfer, we must empty the fifo of all 2256 1.14 fvdl * available data to force the chip to 2257 1.14 fvdl * continue the transfer. This does not 2258 1.14 fvdl * happen for SCSI transfers as the SCSI module 2259 1.14 fvdl * will drain the FIFO as data are made available. 2260 1.14 fvdl * When the hang occurs, we know that a multiple 2261 1.14 fvdl * of 8 bytes is in the FIFO because the PCI 2262 1.14 fvdl * module has an 8 byte input latch that only 2263 1.14 fvdl * dumps to the FIFO when HCNT == 0 or the 2264 1.14 fvdl * latch is full. 2265 1.14 fvdl */ 2266 1.14 fvdl clr A; 2267 1.14 fvdl /* Wait for at least 8 bytes of data to arrive. */ 2268 1.14 fvdl dma_scb_hang_fifo: 2269 1.14 fvdl test DFSTATUS, FIFOQWDEMP jnz dma_scb_hang_fifo; 2270 1.14 fvdl dma_scb_hang_wait: 2271 1.14 fvdl test DFSTATUS, MREQPEND jnz dma_scb_hang_wait; 2272 1.14 fvdl test DFSTATUS, HDONE jnz dma_scb_hang_dma_done; 2273 1.14 fvdl test DFSTATUS, HDONE jnz dma_scb_hang_dma_done; 2274 1.14 fvdl test DFSTATUS, HDONE jnz dma_scb_hang_dma_done; 2275 1.14 fvdl /* 2276 1.14 fvdl * The PCI module no longer intends to perform 2277 1.14 fvdl * a PCI transaction. Drain the fifo. 2278 1.14 fvdl */ 2279 1.14 fvdl dma_scb_hang_dma_drain_fifo: 2280 1.14 fvdl not A, HCNT; 2281 1.14 fvdl add A, SCB_DOWNLOAD_SIZE+SCB_BASE+1; 2282 1.14 fvdl and A, ~0x7; 2283 1.14 fvdl mov DINDIR,DFDAT; 2284 1.14 fvdl cmp DINDEX, A jne . - 1; 2285 1.14 fvdl cmp DINDEX, SCB_DOWNLOAD_SIZE+SCB_BASE 2286 1.14 fvdl je dma_finish_nowait; 2287 1.14 fvdl /* Restore A as the lines left to transfer. */ 2288 1.14 fvdl add A, -SCB_BASE, DINDEX; 2289 1.14 fvdl shr A, 3; 2290 1.14 fvdl jmp dma_scb_hang_fifo; 2291 1.14 fvdl dma_scb_hang_dma_done: 2292 1.14 fvdl and DFCNTRL, ~HDMAEN; 2293 1.14 fvdl test DFCNTRL, HDMAEN jnz .; 2294 1.14 fvdl add SEQADDR0, A; 2295 1.14 fvdl } else { 2296 1.14 fvdl call dma_finish; 2297 1.14 fvdl } 2298 1.14 fvdl call dfdat_in_8; 2299 1.14 fvdl call dfdat_in_8; 2300 1.14 fvdl call dfdat_in_8; 2301 1.14 fvdl dfdat_in_8: 2302 1.14 fvdl mov DINDIR,DFDAT; 2303 1.11 fvdl dfdat_in_7: 2304 1.11 fvdl mov DINDIR,DFDAT; 2305 1.11 fvdl mov DINDIR,DFDAT; 2306 1.11 fvdl mov DINDIR,DFDAT; 2307 1.11 fvdl mov DINDIR,DFDAT; 2308 1.11 fvdl mov DINDIR,DFDAT; 2309 1.14 fvdl dfdat_in_2: 2310 1.11 fvdl mov DINDIR,DFDAT; 2311 1.11 fvdl mov DINDIR,DFDAT ret; 2312 1.11 fvdl } 2313 1.11 fvdl 2314 1.14 fvdl copy_to_fifo_8: 2315 1.14 fvdl mov DFDAT,SINDIR; 2316 1.14 fvdl mov DFDAT,SINDIR; 2317 1.14 fvdl copy_to_fifo_6: 2318 1.14 fvdl mov DFDAT,SINDIR; 2319 1.14 fvdl copy_to_fifo_5: 2320 1.14 fvdl mov DFDAT,SINDIR; 2321 1.14 fvdl copy_to_fifo_4: 2322 1.14 fvdl mov DFDAT,SINDIR; 2323 1.14 fvdl mov DFDAT,SINDIR; 2324 1.14 fvdl mov DFDAT,SINDIR; 2325 1.14 fvdl mov DFDAT,SINDIR ret; 2326 1.2 mycroft 2327 1.2 mycroft /* 2328 1.11 fvdl * Wait for DMA from host memory to data FIFO to complete, then disable 2329 1.11 fvdl * DMA and wait for it to acknowledge that it's off. 2330 1.2 mycroft */ 2331 1.11 fvdl dma_finish: 2332 1.11 fvdl test DFSTATUS,HDONE jz dma_finish; 2333 1.14 fvdl dma_finish_nowait: 2334 1.11 fvdl /* Turn off DMA */ 2335 1.11 fvdl and DFCNTRL, ~HDMAEN; 2336 1.11 fvdl test DFCNTRL, HDMAEN jnz .; 2337 1.11 fvdl ret; 2338 1.11 fvdl 2339 1.14 fvdl /* 2340 1.14 fvdl * Restore an SCB that failed to match an incoming reselection 2341 1.14 fvdl * to the correct/safe state. If the SCB is for a disconnected 2342 1.14 fvdl * transaction, it must be returned to the disconnected list. 2343 1.14 fvdl * If it is not in the disconnected state, it must be free. 2344 1.14 fvdl */ 2345 1.14 fvdl cleanup_scb: 2346 1.14 fvdl if ((ahc->flags & AHC_PAGESCBS) != 0) { 2347 1.14 fvdl test SCB_CONTROL,DISCONNECTED jnz add_scb_to_disc_list; 2348 1.14 fvdl } 2349 1.11 fvdl add_scb_to_free_list: 2350 1.11 fvdl if ((ahc->flags & AHC_PAGESCBS) != 0) { 2351 1.14 fvdl BEGIN_CRITICAL; 2352 1.11 fvdl mov SCB_NEXT, FREE_SCBH; 2353 1.11 fvdl mvi SCB_TAG, SCB_LIST_NULL; 2354 1.11 fvdl mov FREE_SCBH, SCBPTR ret; 2355 1.14 fvdl END_CRITICAL; 2356 1.11 fvdl } else { 2357 1.11 fvdl mvi SCB_TAG, SCB_LIST_NULL ret; 2358 1.11 fvdl } 2359 1.11 fvdl 2360 1.14 fvdl if ((ahc->flags & AHC_39BIT_ADDRESSING) != 0) { 2361 1.14 fvdl set_hhaddr: 2362 1.14 fvdl or DSCOMMAND1, HADDLDSEL0; 2363 1.14 fvdl and HADDR, SG_HIGH_ADDR_BITS, SINDEX; 2364 1.14 fvdl and DSCOMMAND1, ~HADDLDSEL0 ret; 2365 1.14 fvdl } 2366 1.14 fvdl 2367 1.11 fvdl if ((ahc->flags & AHC_PAGESCBS) != 0) { 2368 1.11 fvdl get_free_or_disc_scb: 2369 1.14 fvdl BEGIN_CRITICAL; 2370 1.11 fvdl cmp FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb; 2371 1.11 fvdl cmp DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb; 2372 1.11 fvdl return_error: 2373 1.14 fvdl mvi NO_FREE_SCB call set_seqint; 2374 1.11 fvdl mvi SINDEX, SCB_LIST_NULL ret; 2375 1.11 fvdl dequeue_disc_scb: 2376 1.11 fvdl mov SCBPTR, DISCONNECTED_SCBH; 2377 1.14 fvdl mov DISCONNECTED_SCBH, SCB_NEXT; 2378 1.14 fvdl END_CRITICAL; 2379 1.11 fvdl mvi DMAPARAMS, FIFORESET; 2380 1.14 fvdl mov SCB_TAG jmp dma_scb; 2381 1.14 fvdl BEGIN_CRITICAL; 2382 1.11 fvdl dequeue_free_scb: 2383 1.11 fvdl mov SCBPTR, FREE_SCBH; 2384 1.11 fvdl mov FREE_SCBH, SCB_NEXT ret; 2385 1.14 fvdl END_CRITICAL; 2386 1.2 mycroft 2387 1.11 fvdl add_scb_to_disc_list: 2388 1.2 mycroft /* 2389 1.11 fvdl * Link this SCB into the DISCONNECTED list. This list holds the 2390 1.11 fvdl * candidates for paging out an SCB if one is needed for a new command. 2391 1.11 fvdl * Modifying the disconnected list is a critical(pause dissabled) section. 2392 1.2 mycroft */ 2393 1.14 fvdl BEGIN_CRITICAL; 2394 1.11 fvdl mov SCB_NEXT, DISCONNECTED_SCBH; 2395 1.11 fvdl mov DISCONNECTED_SCBH, SCBPTR ret; 2396 1.14 fvdl END_CRITICAL; 2397 1.14 fvdl } 2398 1.14 fvdl set_seqint: 2399 1.14 fvdl mov INTSTAT, SINDEX; 2400 1.14 fvdl nop; 2401 1.14 fvdl return: 2402 1.14 fvdl ret; 2403