diff --git a/sys/i386/scsi/aic7xxx.c b/sys/i386/scsi/aic7xxx.c index d7a0c3925cd7..f4514110e6cc 100644 --- a/sys/i386/scsi/aic7xxx.c +++ b/sys/i386/scsi/aic7xxx.c @@ -32,7 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: aic7xxx.c,v 1.104 1997/02/28 03:58:21 gibbs Exp $ + * $Id: aic7xxx.c,v 1.105 1997/03/01 06:50:41 gibbs Exp $ */ /* * TODO: @@ -117,8 +117,9 @@ #if defined(__FreeBSD__) #include - -#include +#include +#include +#include #endif /* defined(__FreeBSD__) */ #if defined(__NetBSD__) @@ -127,7 +128,7 @@ #define bootverbose 1 -#if DEBUGTARGET < 0 /* Negative numbrs for disabling cause warnings */ +#if DEBUGTARGET < 0 /* Negative numbers for disabling cause warnings */ #define DEBUGTARGET 17 #endif #endif /* defined(__NetBSD__) */ @@ -272,6 +273,11 @@ static void ahc_handle_scsiint __P((struct ahc_softc *ahc, static void ahc_handle_devreset __P((struct ahc_softc *ahc, struct scb *scb)); static void ahc_loadseq __P((struct ahc_softc *ahc)); +static struct patch * + ahc_next_patch __P((struct patch *cur_patch, int options, + int instrptr)); +static void ahc_download_instr __P((struct ahc_softc *ahc, int options, + int instrptr)); static int ahc_match_scb __P((struct scb *scb, int target, char channel, int lun, u_int8_t tag)); static int ahc_poll __P((struct ahc_softc *ahc, int wait)); @@ -409,7 +415,7 @@ static int ahc_num_syncrates = sizeof(ahc_syncrates) / sizeof(ahc_syncrates[0]); /* - * Allocate a controller structures for a new device and initialize it. + * Allocate a controller structure for a new device and initialize it. */ #if defined(__FreeBSD__) struct ahc_softc * @@ -572,12 +578,12 @@ ahc_scsirate(ahc, scsirate, period, offset, channel, target ) } } if (i >= ahc_num_syncrates) { - /* Use asyncronous transfers. */ + /* Use asynchronous transfers. */ *scsirate = 0; *period = 0; *offset = 0; if (bootverbose) - printf("%s: target %d using asyncronous transfers\n", + printf("%s: target %d using asynchronous transfers\n", ahc_name(ahc), target ); } /* @@ -748,7 +754,7 @@ ahc_intr(arg) intstat = ahc_inb(ahc, INTSTAT); /* * Is this interrupt for me? or for - * someone who is sharing my interrupt + * someone who is sharing my interrupt? */ if (!(intstat & INT_PEND)) #if defined(__FreeBSD__) @@ -860,7 +866,7 @@ ahc_handle_seqint(ahc, intstat) int scratch_offset; char channel; - if ((ahc_inb(ahc, FLAGS) & RESELECTED) != 0) + if ((ahc_inb(ahc, SEQ_FLAGS) & RESELECTED) != 0) target = ahc_inb(ahc, SELID); else target = ahc_inb(ahc, SCSIID); @@ -869,7 +875,7 @@ ahc_handle_seqint(ahc, intstat) channel = ahc_inb(ahc, SBLKCTL) & SELBUSB ? 'B': 'A'; if (channel == 'B') scratch_offset += 8; - targ_mask = (0x01 << scratch_offset); + targ_mask = (0x01 << scratch_offset); switch (intstat & SEQINT_MASK) { case NO_MATCH: @@ -903,7 +909,7 @@ ahc_handle_seqint(ahc, intstat) * handler knows that there is an SCB to * cleanup. */ - ahc_outb(ahc, FLAGS, ahc_inb(ahc, FLAGS) + ahc_outb(ahc, SEQ_FLAGS, ahc_inb(ahc, SEQ_FLAGS) | IDENTIFY_SEEN); sc_print_addr(scb->xs->sc_link); printf("reconnect SCB abort successfull\n"); @@ -946,7 +952,7 @@ ahc_handle_seqint(ahc, intstat) case SEND_REJECT: { u_int8_t rejbyte = ahc_inb(ahc, REJBYTE); - printf("%s:%c:%d: Warning - unknown message recieved from " + printf("%s:%c:%d: Warning - unknown message received from " "target (0x%x). Rejecting\n", ahc_name(ahc), channel, target, rejbyte); break; @@ -967,13 +973,20 @@ ahc_handle_seqint(ahc, intstat) ahc_name(ahc), channel, target, ahc_inb(ahc, LASTPHASE), ahc_inb(ahc, SAVED_TCL)); found = ahc_reset_channel(ahc, channel, XS_TIMEOUT, - /*initiate reset*/TRUE); + /*initiate reset*/TRUE); printf("%s: Issued Channel %c Bus Reset. " "%d SCBs aborted\n", ahc_name(ahc), channel, found); + break; } case BAD_PHASE: - printf("%s:%c:%d: unknown scsi bus phase. Attempting to " - "continue\n", ahc_name(ahc), channel, target); + if (ahc_inb(ahc, LASTPHASE) == P_BUSFREE) { + printf("%s:%c:%d: Missed busfree.\n", ahc_name(ahc), + channel, target); + restart_sequencer(ahc); + } else { + printf("%s:%c:%d: unknown scsi bus phase. Attempting " + "to continue\n", ahc_name(ahc), channel, target); + } break; case EXTENDED_MSG: { @@ -999,8 +1012,8 @@ ahc_handle_seqint(ahc, intstat) ahc_outb(ahc, RETURN_1, SEND_REJ); break; } - period = ahc_inb(ahc, MSGIN_EXT_BYTE0); - saved_offset = ahc_inb(ahc, MSGIN_EXT_BYTE1); + period = ahc_inb(ahc, MSGIN_EXT_BYTES); + saved_offset = ahc_inb(ahc, MSGIN_EXT_BYTES + 1); targ_scratch = ahc_inb(ahc, TARG_SCRATCH + scratch_offset); if (targ_scratch & WIDEXFER) @@ -1058,7 +1071,7 @@ ahc_handle_seqint(ahc, intstat) break; } - bus_width = ahc_inb(ahc, MSGIN_EXT_BYTE0); + bus_width = ahc_inb(ahc, MSGIN_EXT_BYTES); scratch = ahc_inb(ahc, TARG_SCRATCH + scratch_offset); if ((scb->flags & SCB_MSGOUT_WDTR) != 0) { @@ -1161,8 +1174,8 @@ ahc_handle_seqint(ahc, intstat) /* note asynch xfers and clear flag */ targ_scratch &= 0xf0; ahc->needsdtr &= ~targ_mask; - printf("%s:%c:%d: refuses syncronous negotiation. " - "Using asyncronous transfers\n", + printf("%s:%c:%d: refuses synchronous negotiation. " + "Using asynchronous transfers\n", ahc_name(ahc), channel, target); } else { @@ -1361,16 +1374,17 @@ ahc_handle_seqint(ahc, intstat) */ message_offset = ahc_inb(ahc, MSG_LEN); if (scb->flags & SCB_DEVICE_RESET) { - ahc_outb(ahc, MSG0, MSG_BUS_DEV_RESET); + ahc_outb(ahc, MSG_OUT, MSG_BUS_DEV_RESET); ahc_outb(ahc, MSG_LEN, 1); sc_print_addr(scb->xs->sc_link); printf("Bus Device Reset Message Sent\n"); } else if (scb->flags & SCB_ABORT) { if ((scb->hscb->control & TAG_ENB) != 0) - ahc_outb(ahc, MSG0 + message_offset, + ahc_outb(ahc, MSG_OUT + message_offset, MSG_ABORT_TAG); else - ahc_outb(ahc, MSG0 + message_offset, MSG_ABORT); + ahc_outb(ahc, MSG_OUT + message_offset, + MSG_ABORT); ahc_outb(ahc, MSG_LEN, message_offset + 1); sc_print_addr(scb->xs->sc_link); printf("Abort Message Sent\n"); @@ -1420,9 +1434,9 @@ ahc_handle_seqint(ahc, intstat) u_int32_t overrun; int i; scb = ahc->scb_data->scbarray[scbindex]; - overrun = ahc_inb(ahc, STCNT0) - | (ahc_inb(ahc, STCNT1) << 8) - | (ahc_inb(ahc, STCNT2) << 16); + overrun = ahc_inb(ahc, STCNT) + | (ahc_inb(ahc, STCNT + 1) << 8) + | (ahc_inb(ahc, STCNT + 2) << 16); overrun = 0x00ffffff - overrun; sc_print_addr(scb->xs->sc_link); printf("data overrun of %d bytes detected in %s phase." @@ -1431,7 +1445,7 @@ ahc_handle_seqint(ahc, intstat) scb->hscb->tag); sc_print_addr(scb->xs->sc_link); printf("%s seen Data Phase. Length = %d. NumSGs = %d.\n", - ahc_inb(ahc, FLAGS) & DPHASE ? "Have" : "Haven't", + ahc_inb(ahc, SEQ_FLAGS) & DPHASE ? "Have" : "Haven't", scb->xs->datalen, scb->sg_count); for (i = 0; i < scb->sg_count; i++) { printf("sg[%d] - Addr 0x%x : Length %d\n", @@ -1568,8 +1582,9 @@ ahc_handle_scsiint(ahc, intstat) char channel = ahc_inb(ahc, SBLKCTL) & SELBUSB ? 'B': 'A'; int printerror = 1; + ahc_outb(ahc, SCSISEQ, 0); if (lastphase != P_BUSFREE) { - u_int8_t flags = ahc_inb(ahc, FLAGS) + u_int8_t flags = ahc_inb(ahc, SEQ_FLAGS) & (IDENTIFY_SEEN|RESELECTED); if (flags == 0 || flags == (IDENTIFY_SEEN|RESELECTED)) { @@ -1643,8 +1658,10 @@ ahc_handle_scsiint(ahc, intstat) scb = NULL; } else printf("%s: ", ahc_name(ahc)); - printf("Unexpected busfree. LASTPHASE == 0x%x\n", - lastphase); + printf("Unexpected busfree. LASTPHASE == 0x%x\n" + "SEQADDR == 0x%x\n", + lastphase, (ahc_inb(ahc, SEQADDR1) << 8) + | ahc_inb(ahc, SEQADDR0)); } ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE); ahc_outb(ahc, CLRSINT1, CLRBUSFREE); @@ -1652,8 +1669,13 @@ ahc_handle_scsiint(ahc, intstat) ahc_outb(ahc, CLRINT, CLRSCSIINT); } else if (scb == NULL) { printf("%s: ahc_intr - referenced scb not " - "valid during scsiint 0x%x scb(%d)\n", - ahc_name(ahc), status, scb_index); + "valid during scsiint 0x%x scb(%d)\n" + "SIMODE0 = 0x%x, SIMODE1 = 0x%x, SSTAT0 = 0x%x\n" + "SEQADDR = 0x%x\n", ahc_name(ahc), + status, scb_index, ahc_inb(ahc, SIMODE0), + ahc_inb(ahc, SIMODE1), ahc_inb(ahc, SSTAT0), + (ahc_inb(ahc, SEQADDR1) << 8) + | ahc_inb(ahc, SEQADDR0)); ahc_outb(ahc, CLRSINT1, status); unpause_sequencer(ahc, /*unpause_always*/TRUE); ahc_outb(ahc, CLRINT, CLRSCSIINT); @@ -1707,7 +1729,7 @@ ahc_handle_scsiint(ahc, intstat) * mesg_out to something other than MSG_NOP. */ if (mesg_out != MSG_NOOP) { - ahc_outb(ahc, MSG0, mesg_out); + ahc_outb(ahc, MSG_OUT, mesg_out); ahc_outb(ahc, MSG_LEN, 1); scb = NULL; } else @@ -1727,15 +1749,17 @@ ahc_handle_scsiint(ahc, intstat) struct scsi_xfer *xs; u_int8_t scbptr; u_int8_t nextscb; - u_int8_t flags; + /* + * XXX If we queued an abort tag, go clean up the + * disconnected list. + */ xs = scb->xs; xs->error = XS_SELTIMEOUT; /* * Clear any pending messages for the timed out * target, and mark the target as free */ - flags = ahc_inb(ahc, FLAGS); ahc_outb(ahc, MSG_LEN, 0); ahc_index_busy_target(ahc, xs->sc_link->target, IS_SCSIBUS_B(ahc, xs->sc_link) ? 'B' : 'A', @@ -1906,7 +1930,15 @@ ahc_done(ahc, scb) } untimeout(ahc_timeout, (caddr_t)scb); ahc_free_scb(ahc, scb); - scsi_done(xs); + /* + * If we're polling, we rely on the ITS_DONE flag in the xs structure + * to know that the command has completed. Unfortunately, scsi_done + * can cause the same xs to get requeued putting us in an infinite + * loop. So, we defer the scsi_done call until the poll routine exits + * its loop. I hate the way this works. + */ + if ((xs->flags & SCSI_NOMASK) == 0) + scsi_done(xs); } /* @@ -1942,7 +1974,7 @@ ahc_init(ahc) ahc->our_id); } else printf("Single Channel, SCSI Id=%d, ", ahc->our_id); - ahc_outb(ahc, FLAGS, SINGLE_BUS | (ahc->flags & AHC_PAGESCBS)); + ahc_outb(ahc, SEQ_FLAGS, ahc->flags & AHC_PAGESCBS); break; case 2: ahc->our_id = (ahc_inb(ahc, SCSICONF + 1) & HWSCSIID); @@ -1957,7 +1989,7 @@ ahc_init(ahc) } else printf("Wide Channel, SCSI Id=%d, ", ahc->our_id); ahc->type |= AHC_WIDE; - ahc_outb(ahc, FLAGS, WIDE_BUS | (ahc->flags & AHC_PAGESCBS)); + ahc_outb(ahc, SEQ_FLAGS, WIDE_BUS | (ahc->flags & AHC_PAGESCBS)); break; case 8: ahc->our_id = (ahc_inb(ahc, SCSICONF) & HSCSIID); @@ -1965,7 +1997,7 @@ ahc_init(ahc) printf("Twin Channel, A SCSI Id=%d, B SCSI Id=%d, ", ahc->our_id, ahc->our_id_b); ahc->type |= AHC_TWIN; - ahc_outb(ahc, FLAGS, TWIN_BUS | (ahc->flags & AHC_PAGESCBS)); + ahc_outb(ahc, SEQ_FLAGS, TWIN_BUS | (ahc->flags & AHC_PAGESCBS)); break; default: printf(" Unsupported adapter type. Ignoring\n"); @@ -1997,10 +2029,10 @@ ahc_init(ahc) ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL); /* No Busy non-tagged targets yet */ - ahc_outb(ahc, SCB_ACTIVE0, SCB_LIST_NULL); - ahc_outb(ahc, SCB_ACTIVE1, SCB_LIST_NULL); - ahc_outb(ahc, SCB_ACTIVE2, SCB_LIST_NULL); - ahc_outb(ahc, SCB_ACTIVE3, SCB_LIST_NULL); + ahc_outb(ahc, SCB_BUSYTARGETS, SCB_LIST_NULL); + ahc_outb(ahc, SCB_BUSYTARGETS + 1, SCB_LIST_NULL); + ahc_outb(ahc, SCB_BUSYTARGETS + 2, SCB_LIST_NULL); + ahc_outb(ahc, SCB_BUSYTARGETS + 3, SCB_LIST_NULL); } /* Make that the last SCB terminates the free list */ @@ -2062,7 +2094,7 @@ ahc_init(ahc) if (scsi_conf & RESET_SCSI) { /* Reset the bus */ if (bootverbose) - printf("%s: Reseting Channel B\n", + printf("%s: Resetting Channel B\n", ahc_name(ahc)); ahc_reset_current_bus(ahc); } @@ -2085,7 +2117,7 @@ ahc_init(ahc) if (scsi_conf & RESET_SCSI) { /* Reset the bus */ if (bootverbose) - printf("%s: Reseting Channel A\n", ahc_name(ahc)); + printf("%s: Resetting Channel A\n", ahc_name(ahc)); ahc_reset_current_bus(ahc); } @@ -2094,8 +2126,8 @@ ahc_init(ahc) * Look at the information that board initialization or * the board bios has left us. In the lower four bits of each * target's scratch space any value other than 0 indicates - * that we should initiate syncronous transfers. If it's zero, - * the user or the BIOS has decided to disable syncronous + * that we should initiate synchronous transfers. If it's zero, + * the user or the BIOS has decided to disable synchronous * negotiation to that target so we don't activate the needsdtr * flag. */ @@ -2128,7 +2160,7 @@ ahc_init(ahc) if (target_settings & 0x0f) { ahc->needsdtr_orig |= (0x01 << i); - /*Default to a asyncronous transfers(0 offset)*/ + /*Default to a asynchronous transfers(0 offset)*/ target_settings &= 0xf0; } if (target_settings & 0x80) { @@ -2185,7 +2217,7 @@ ahc_init(ahc) ahc->needwdtr, ahc->discenable); #endif /* - * Set the number of availible hardware SCBs + * Set the number of available hardware SCBs */ ahc_outb(ahc, SCBCOUNT, ahc->scb_data->maxhscbs); @@ -2228,10 +2260,10 @@ ahc_init(ahc) /* Tell the sequencer where it can find the hscb array. */ hscb_physaddr = vtophys(ahc->scb_data->hscbs); - ahc_outb(ahc, HSCB_ADDR0, hscb_physaddr & 0xFF); - ahc_outb(ahc, HSCB_ADDR1, (hscb_physaddr >> 8)& 0xFF); - ahc_outb(ahc, HSCB_ADDR2, (hscb_physaddr >> 16)& 0xFF); - ahc_outb(ahc, HSCB_ADDR3, (hscb_physaddr >> 24)& 0xFF); + ahc_outb(ahc, HSCB_ADDR, hscb_physaddr & 0xFF); + ahc_outb(ahc, HSCB_ADDR + 1, (hscb_physaddr >> 8)& 0xFF); + ahc_outb(ahc, HSCB_ADDR + 2, (hscb_physaddr >> 16)& 0xFF); + ahc_outb(ahc, HSCB_ADDR + 3, (hscb_physaddr >> 24)& 0xFF); } /* @@ -2256,7 +2288,7 @@ ahc_init(ahc) /* * QCount mask to deal with broken aic7850s that - * sporatically get garbage in the upper bits of + * sporadically get garbage in the upper bits of * their QCount registers. */ ahc_outb(ahc, QCNTMASK, ahc->qcntmask); @@ -2519,6 +2551,7 @@ ahc_scsi_cmd(xs) break; } } while ((xs->flags & ITSDONE) == 0); /* a non command complete intr */ + scsi_done(xs); splx(s); return (COMPLETE); } @@ -2559,7 +2592,7 @@ ahc_run_waiting_queue(ahc) } /* - * A scb (and hence an scb entry on the board is put onto the + * An scb (and hence an scb entry on the board) is put onto the * free list. */ static void @@ -2582,7 +2615,7 @@ ahc_free_scb(ahc, scb) STAILQ_INSERT_HEAD(&ahc->scb_data->free_scbs, scb, links); if (scb->links.stqe_next == NULL) { /* - * If there were no SCBs availible, wake anybody waiting + * If there were no SCBs available, wake anybody waiting * for one to come free. */ wakeup((caddr_t)&ahc->scb_data->free_scbs); @@ -2700,19 +2733,133 @@ static void ahc_loadseq(ahc) struct ahc_softc *ahc; { - static u_char seqprog[] = { -# include "aic7xxx_seq.h" - }; + int options; + struct patch *cur_patch; + int i; + int downloaded; + options = 1; /* Code for all options */ + downloaded = 0; + if ((ahc->type & AHC_ULTRA) != 0) + options |= ULTRA; + if ((ahc->type & AHC_TWIN) != 0) + options |= TWIN_CHANNEL; + if (ahc->scb_data->maxscbs > ahc->scb_data->maxhscbs) + options |= SCB_PAGING; + + cur_patch = patches; ahc_outb(ahc, SEQCTL, PERRORDIS|LOADRAM); ahc_outb(ahc, SEQADDR0, 0); ahc_outb(ahc, SEQADDR1, 0); - ahc_outsb(ahc, SEQRAM, seqprog, sizeof(seqprog)); + for(i = 0; i < sizeof(seqprog)/4; i++) { + cur_patch = ahc_next_patch(cur_patch, options, i); + + if (cur_patch && cur_patch->begin <= i && cur_patch->end > i) + /* Skip this instruction for this configuration */ + continue; + ahc_download_instr(ahc, options, i); + downloaded++; + } ahc_outb(ahc, SEQCTL, FASTMODE); ahc_outb(ahc, SEQADDR0, 0); ahc_outb(ahc, SEQADDR1, 0); + if (bootverbose) + printf("%s: %d instructions downloaded\n", ahc_name(ahc), + downloaded); +} + +static struct patch * +ahc_next_patch(cur_patch, options, instrptr) + struct patch *cur_patch; + int options; + int instrptr; +{ + while(cur_patch != NULL) { + if (((cur_patch->options & options) != 0 + && cur_patch->negative == FALSE) + || ((cur_patch->options & options) == 0 + && cur_patch->negative == TRUE) + || (instrptr >= cur_patch->end)) { + /* + * Either we want to keep this section of code, + * or we have consumed this patch. Skip to the + * next patch. + */ + cur_patch++; + if (cur_patch->options == 0) + /* Out of patches */ + cur_patch = NULL; + } else + /* Found an okay patch */ + break; + } + return (cur_patch); +} + +static void +ahc_download_instr(ahc, options, instrptr) + struct ahc_softc *ahc; + int options; + int instrptr; +{ + u_int8_t opcode; + struct ins_format3 *instr; + + instr = (struct ins_format3 *)&seqprog[instrptr * 4]; + /* Pull the opcode */ + opcode = instr->opcode_addr >> 1; + switch (opcode) { + case AIC_OP_JMP: + case AIC_OP_JC: + case AIC_OP_JNC: + case AIC_OP_CALL: + case AIC_OP_JNE: + case AIC_OP_JNZ: + case AIC_OP_JE: + case AIC_OP_JZ: + { + int address_offset; + struct ins_format3 new_instr; + u_int address; + struct patch *patch; + int i; + + address_offset = 0; + new_instr = *instr; /* structure copy */ + address = new_instr.address; + address |= (new_instr.opcode_addr & ADDR_HIGH_BIT) << 8; + for (i = 0; i < sizeof(patches)/sizeof(patches[0]); i++) { + patch = &patches[i]; + if (((patch->options & options) == 0 + && patch->negative == FALSE) + || ((patch->options & options) != 0 + && patch->negative == TRUE)) { + if (address >= patch->end) + address_offset += + patch->end - patch->begin; + } + } + address -= address_offset; + new_instr.address = address & 0xFF; + new_instr.opcode_addr &= ~ADDR_HIGH_BIT; + new_instr.opcode_addr |= (address >> 8) & ADDR_HIGH_BIT; + ahc_outsb(ahc, SEQRAM, &new_instr.immediate, 4); + break; + } + case AIC_OP_OR: + case AIC_OP_AND: + case AIC_OP_XOR: + case AIC_OP_ADD: + case AIC_OP_ADC: + case AIC_OP_ROL: + ahc_outsb(ahc, SEQRAM, &instr->immediate, 4); + break; + default: + panic("Unknown opcode encountered in seq program"); + break; + } } /* @@ -2918,9 +3065,17 @@ bus_reset: active_scb = ahc->scb_data->scbarray[active_scb_index]; if (bus_state != P_BUSFREE) { + if (active_scb_index >= ahc->scb_data->numscbs) { + /* Go "immediatly" to the bus reset */ + sc_print_addr(scb->xs->sc_link); + printf("SCB %d: Yucky Immediate reset. " + "Flags = 0x%x\n", scb->hscb->tag, + scb->flags); + goto bus_reset; + } /* Send the abort to the active SCB */ ahc_outb(ahc, MSG_LEN, 1); - ahc_outb(ahc, MSG0, + ahc_outb(ahc, MSG_OUT, (active_scb->hscb->control & TAG_ENB) == 0 ? MSG_ABORT : MSG_ABORT_TAG); ahc_outb(ahc, SCSISIGO, bus_state|ATNO); @@ -2954,7 +3109,8 @@ bus_reset: if (disconnected) { /* Simply set the ABORT_SCB control bit */ scb->hscb->control |= ABORT_SCB|MK_MESSAGE; - scb->hscb->control &= ~DISCONNECTED; + if ((ahc->flags & AHC_PAGESCBS) == 0) + scb->hscb->control &= ~DISCONNECTED; scb->flags |= SCB_QUEUED_ABORT | SCB_ABORT|SCB_RECOVERY_SCB; if (hscb_index != SCB_LIST_NULL) { @@ -2962,7 +3118,8 @@ bus_reset: scb_control = ahc_inb(ahc, SCB_CONTROL); ahc_outb(ahc, SCB_CONTROL, - scb_control | ABORT_SCB); + scb_control | MK_MESSAGE + | ABORT_SCB); } /* * Actually re-queue this SCB in case we can @@ -2977,9 +3134,6 @@ bus_reset: target = scb->xs->sc_link->target; lun = scb->xs->sc_link->lun; - ahc_index_busy_target(ahc, target, - channel, - /*unbusy*/TRUE); ahc_search_qinfifo(ahc, target, channel, lun, @@ -3381,7 +3535,7 @@ ahc_index_busy_target(ahc, target, channel, unbusy) info_scb += 2; active_scb = ahc_inb(ahc, SCBPTR); ahc_outb(ahc, SCBPTR, info_scb); - scb_offset = SCB_ACTIVE0 + (target & 0x03); + scb_offset = SCB_BUSYTARGETS + (target & 0x03); busy_scbid = ahc_inb(ahc, scb_offset); if (unbusy) ahc_outb(ahc, scb_offset, SCB_LIST_NULL); @@ -3406,7 +3560,7 @@ ahc_busy_target(ahc, target, channel, scbid) info_scb += 2; active_scb = ahc_inb(ahc, SCBPTR); ahc_outb(ahc, SCBPTR, info_scb); - scb_offset = SCB_ACTIVE0 + (target & 0x03); + scb_offset = SCB_BUSYTARGETS + (target & 0x03); ahc_outb(ahc, scb_offset, scbid); ahc_outb(ahc, SCBPTR, active_scb); return; @@ -3595,6 +3749,7 @@ ahc_reset_channel(ahc, channel, xs_error, initiate_reset) ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE); if (initiate_reset) ahc_reset_current_bus(ahc); + ahc_outb(ahc, SCSISEQ, 0); ahc_clear_intstat(ahc); ahc_outb(ahc, SBLKCTL, sblkctl); unpause_sequencer(ahc, /*unpause_always*/FALSE); @@ -3603,6 +3758,7 @@ ahc_reset_channel(ahc, channel, xs_error, initiate_reset) ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENBUSFREE); if (initiate_reset) ahc_reset_current_bus(ahc); + ahc_outb(ahc, SCSISEQ, 0); ahc_clear_intstat(ahc); restart_sequencer(ahc); } @@ -3655,11 +3811,11 @@ ahc_construct_sdtr(ahc, start_byte, period, offset) u_int8_t period; u_int8_t offset; { - ahc_outb(ahc, MSG0 + start_byte, MSG_EXTENDED); - ahc_outb(ahc, MSG1 + start_byte, MSG_EXT_SDTR_LEN); - ahc_outb(ahc, MSG2 + start_byte, MSG_EXT_SDTR); - ahc_outb(ahc, MSG3 + start_byte, period); - ahc_outb(ahc, MSG4 + start_byte, offset); + ahc_outb(ahc, MSG_OUT + start_byte, MSG_EXTENDED); + ahc_outb(ahc, MSG_OUT + 1 + start_byte, MSG_EXT_SDTR_LEN); + ahc_outb(ahc, MSG_OUT + 2 + start_byte, MSG_EXT_SDTR); + ahc_outb(ahc, MSG_OUT + 3 + start_byte, period); + ahc_outb(ahc, MSG_OUT + 4 + start_byte, offset); ahc_outb(ahc, MSG_LEN, start_byte + 5); } @@ -3669,10 +3825,10 @@ ahc_construct_wdtr(ahc, start_byte, bus_width) int start_byte; u_int8_t bus_width; { - ahc_outb(ahc, MSG0 + start_byte, MSG_EXTENDED); - ahc_outb(ahc, MSG1 + start_byte, MSG_EXT_WDTR_LEN); - ahc_outb(ahc, MSG2 + start_byte, MSG_EXT_WDTR); - ahc_outb(ahc, MSG3 + start_byte, bus_width); + ahc_outb(ahc, MSG_OUT + start_byte, MSG_EXTENDED); + ahc_outb(ahc, MSG_OUT + 1 + start_byte, MSG_EXT_WDTR_LEN); + ahc_outb(ahc, MSG_OUT + 2 + start_byte, MSG_EXT_WDTR); + ahc_outb(ahc, MSG_OUT + 3 + start_byte, bus_width); ahc_outb(ahc, MSG_LEN, start_byte + 4); }