diff options
| author | Justin T. Gibbs <gibbs@FreeBSD.org> | 2001-01-22 21:03:48 +0000 |
|---|---|---|
| committer | Justin T. Gibbs <gibbs@FreeBSD.org> | 2001-01-22 21:03:48 +0000 |
| commit | a5847d5c279eb40a86d4d9f32ac95824357fb3bc (patch) | |
| tree | 22701b27f0320d6f557b0e998659531067640778 /sys/dev | |
| parent | e26aac8d24e9f452d85df0332140b4b7cf30af61 (diff) | |
Notes
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/aic7xxx/ahc_eisa.c | 6 | ||||
| -rw-r--r-- | sys/dev/aic7xxx/ahc_pci.c | 2 | ||||
| -rw-r--r-- | sys/dev/aic7xxx/aic7770.c | 7 | ||||
| -rw-r--r-- | sys/dev/aic7xxx/aic7xxx.c | 120 | ||||
| -rw-r--r-- | sys/dev/aic7xxx/aic7xxx.h | 28 | ||||
| -rw-r--r-- | sys/dev/aic7xxx/aic7xxx.reg | 21 | ||||
| -rw-r--r-- | sys/dev/aic7xxx/aic7xxx.seq | 74 | ||||
| -rw-r--r-- | sys/dev/aic7xxx/aic7xxx_freebsd.c | 36 | ||||
| -rw-r--r-- | sys/dev/aic7xxx/aic7xxx_inline.h | 8 | ||||
| -rw-r--r-- | sys/dev/aic7xxx/aic7xxx_osm.c | 36 | ||||
| -rw-r--r-- | sys/dev/aic7xxx/aic7xxx_pci.c | 105 |
11 files changed, 270 insertions, 173 deletions
diff --git a/sys/dev/aic7xxx/ahc_eisa.c b/sys/dev/aic7xxx/ahc_eisa.c index 8613f61c4e44..fdc58aa80a80 100644 --- a/sys/dev/aic7xxx/ahc_eisa.c +++ b/sys/dev/aic7xxx/ahc_eisa.c @@ -59,6 +59,7 @@ aic7770_probe(device_t dev) eisa_add_iospace(dev, iobase, AHC_EISA_IOSIZE, RESVADDR_NONE); + rid = 0; regs = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); if (regs == NULL) { @@ -122,10 +123,12 @@ aic7770_attach(device_t dev) if (name == NULL) return (ENOMEM); strcpy(name, device_get_nameunit(dev)); - ahc = ahc_alloc(NULL, name); + ahc = ahc_alloc(dev, name); if (ahc == NULL) return (ENOMEM); + ahc_set_unit(ahc, device_get_unit(dev)); + /* Allocate a dmatag for our SCB DMA maps */ /* XXX Should be a child of the PCI bus dma tag */ error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1, @@ -161,6 +164,7 @@ aic7770_map_registers(struct ahc_softc *ahc) struct resource *regs; int rid; + rid = 0; regs = bus_alloc_resource(ahc->dev_softc, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); if (regs == NULL) { diff --git a/sys/dev/aic7xxx/ahc_pci.c b/sys/dev/aic7xxx/ahc_pci.c index 275469910072..f38f6f60d782 100644 --- a/sys/dev/aic7xxx/ahc_pci.c +++ b/sys/dev/aic7xxx/ahc_pci.c @@ -98,6 +98,8 @@ ahc_pci_attach(device_t dev) if (ahc == NULL) return (ENOMEM); + ahc_set_unit(ahc, device_get_unit(dev)); + /* Allocate a dmatag for our SCB DMA maps */ /* XXX Should be a child of the PCI bus dma tag */ error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1, diff --git a/sys/dev/aic7xxx/aic7770.c b/sys/dev/aic7xxx/aic7770.c index bcfa0f68a1ad..700d935fb784 100644 --- a/sys/dev/aic7xxx/aic7770.c +++ b/sys/dev/aic7xxx/aic7770.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: //depot/src/aic7xxx/aic7770.c#4 $ * * $FreeBSD$ */ @@ -184,6 +184,11 @@ aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry) return (error); /* + * Link this softc in with all other ahc instances. + */ + ahc_softc_insert(ahc); + + /* * Enable the board's BUS drivers */ ahc_outb(ahc, BCTL, ENABLE); diff --git a/sys/dev/aic7xxx/aic7xxx.c b/sys/dev/aic7xxx/aic7xxx.c index 70f22c7aee95..35511f332bc8 100644 --- a/sys/dev/aic7xxx/aic7xxx.c +++ b/sys/dev/aic7xxx/aic7xxx.c @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/src/aic7xxx/aic7xxx.c#21 $ + * $Id: //depot/src/aic7xxx/aic7xxx.c#24 $ * * $FreeBSD$ */ @@ -228,7 +228,6 @@ static int ahc_handle_target_cmd(struct ahc_softc *ahc, void restart_sequencer(struct ahc_softc *ahc) { - uint16_t stack[4]; pause_sequencer(ahc); ahc_outb(ahc, SCSISIGO, 0); /* De-assert BSY */ @@ -254,21 +253,6 @@ restart_sequencer(struct ahc_softc *ahc) ahc_outb(ahc, CCSCBCTL, 0); } ahc_outb(ahc, MWI_RESIDUAL, 0); - /* - * Avoid stack pointer lockup on aic7895 chips where SEQADDR0 - * cannot be changed without first writing to SEQADDR1. This - * seems to only happen if an interrupt or pause occurs mid - * update of the stack pointer (i.e. during a ret). - */ - stack[0] = ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8); - stack[1] = ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8); - stack[2] = ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8); - stack[3] = ahc_inb(ahc, STACK) | (ahc_inb(ahc, STACK) << 8); - if (stack[0] == stack[1] - && stack[1] == stack[2] - && stack[2] == stack[3] - && stack[0] != 0) - ahc_outb(ahc, SEQADDR1, 0); ahc_outb(ahc, SEQCTL, FASTMODE); ahc_outb(ahc, SEQADDR0, 0); ahc_outb(ahc, SEQADDR1, 0); @@ -580,6 +564,10 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat) ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID), ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG), ahc_inb(ahc, SCB_CONTROL)); + printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n", + ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI)); + printf("SXFRCTL0 == 0x%x\n", ahc_inb(ahc, SXFRCTL0)); + printf("SEQCTL == 0x%x\n", ahc_inb(ahc, SEQCTL)); ahc_dump_card_state(ahc); ahc->msgout_buf[0] = MSG_BUS_DEV_RESET; ahc->msgout_len = 1; @@ -810,11 +798,6 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat) SEARCH_REMOVE); break; } - case ABORT_QINSCB: - { - printf("%s: Abort QINSCB\n", ahc_name(ahc)); - break; - } case NO_FREE_SCB: { printf("%s: No free or disconnected SCBs\n", ahc_name(ahc)); @@ -854,6 +837,9 @@ ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat) ahc_inb(ahc, SCSIID), ahc_inb(ahc, SCB_SCSIID), ahc_inb(ahc, SCB_LUN), ahc_inb(ahc, SCB_TAG), ahc_inb(ahc, SCB_CONTROL)); + printf("SCSIBUSL == 0x%x, SCSISIGI == 0x%x\n", + ahc_inb(ahc, SCSIBUSL), ahc_inb(ahc, SCSISIGI)); + ahc_dump_card_state(ahc); panic("for safety"); break; } @@ -3033,7 +3019,7 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) * This transaction is now at the head of * the untagged queue for this target. */ - if ((ahc->features & AHC_SCB_BTT) == 0) { + if ((ahc->flags & AHC_SCB_BTT) == 0) { struct scb_tailq *untagged_q; untagged_q = &(ahc->untagged_queues[devinfo->target]); @@ -4056,7 +4042,7 @@ ahc_init(struct ahc_softc *ahc) if ((ahc->features & AHC_TARGETMODE) != 0) { ahc->targetcmds = (struct target_cmd *)ahc->qoutfifo; - ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[256]; + ahc->qoutfifo = (uint8_t *)&ahc->targetcmds[AHC_TMODE_CMDS]; ahc->dma_bug_buf = ahc->shared_data_busaddr + driver_data_size - 1; /* All target command blocks start out invalid. */ @@ -4287,7 +4273,7 @@ ahc_init(struct ahc_softc *ahc) /* There are no untagged SCBs active yet. */ for (i = 0; i < 16; i++) { ahc_unbusy_tcl(ahc, BUILD_TCL(i << 4, 0)); - if ((ahc->features & AHC_SCB_BTT) != 0) { + if ((ahc->flags & AHC_SCB_BTT) != 0) { int lun; /* @@ -4420,12 +4406,24 @@ ahc_init(struct ahc_softc *ahc) void ahc_pause_and_flushwork(struct ahc_softc *ahc) { + int intstat; + int maxloops; + + maxloops = 1000; ahc->flags |= AHC_ALL_INTERRUPTS; + intstat = 0; do { ahc_intr(ahc); pause_sequencer(ahc); ahc_clear_critical_section(ahc); - } while (ahc_inb(ahc, INTSTAT) & INT_PEND); + if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0) + break; + maxloops--; + } while (((intstat = ahc_inb(ahc, INTSTAT)) & INT_PEND) && --maxloops); + if (maxloops == 0) { + printf("Infinite interrupt loop, INTSTAT = %x", + ahc_inb(ahc, INTSTAT)); + } ahc_platform_flushwork(ahc); ahc->flags &= ~AHC_ALL_INTERRUPTS; } @@ -4610,7 +4608,7 @@ ahc_index_busy_tcl(struct ahc_softc *ahc, u_int tcl) u_int scbid; u_int target_offset; - if ((ahc->features & AHC_SCB_BTT) != 0) { + if ((ahc->flags & AHC_SCB_BTT) != 0) { u_int saved_scbptr; saved_scbptr = ahc_inb(ahc, SCBPTR); @@ -4630,7 +4628,7 @@ ahc_unbusy_tcl(struct ahc_softc *ahc, u_int tcl) { u_int target_offset; - if ((ahc->features & AHC_SCB_BTT) != 0) { + if ((ahc->flags & AHC_SCB_BTT) != 0) { u_int saved_scbptr; saved_scbptr = ahc_inb(ahc, SCBPTR); @@ -4648,7 +4646,7 @@ ahc_busy_tcl(struct ahc_softc *ahc, u_int tcl, u_int scbid) { u_int target_offset; - if ((ahc->features & AHC_SCB_BTT) != 0) { + if ((ahc->flags & AHC_SCB_BTT) != 0) { u_int saved_scbptr; saved_scbptr = ahc_inb(ahc, SCBPTR); @@ -4790,15 +4788,7 @@ ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel, } else qinstart = ahc_inb(ahc, QINPOS); qinpos = qinstart; - next = ahc_inb(ahc, NEXT_QUEUED_SCB); - if (qinstart == qintail) { - if (next != ahc->next_queued_scb->hscb->tag) - qinpos--; - } else if (next != ahc->qinfifo[qinstart]) { - qinpos--; - } - found = 0; prev_scb = NULL; @@ -4810,25 +4800,6 @@ ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel, ahc_freeze_untagged_queues(ahc); } - if (action != SEARCH_COUNT && (qinpos != qintail)) { - /* - * The sequencer may be in the process of dmaing - * down the SCB at the beginning of the queue. - * This could be problematic if either the first - * or the second SCB is removed from the queue - * (the first SCB includes a pointer to the "next" - * SCB to dma). If we have the prospect of removing - * any entries, swap the first element in the queue - * with the next HSCB so the sequencer will notice - * that NEXT_QUEUED_SCB has changed during its dma - * attempt and will retry the DMA. - */ - scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinpos]); - ahc->scb_data->scbindex[scb->hscb->tag] = NULL; - ahc_swap_with_next_hscb(ahc, scb); - ahc->qinfifo[qinpos] = scb->hscb->tag; - } - /* * Start with an empty queue. Entries that are not chosen * for removal will be re-added to the queue as we go. @@ -4879,6 +4850,41 @@ ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel, ahc_outb(ahc, KERNEL_QINPOS, ahc->qinfifonext); } + if (action != SEARCH_COUNT + && (found != 0) + && (qinstart != ahc->qinfifonext)) { + /* + * The sequencer may be in the process of dmaing + * down the SCB at the beginning of the queue. + * This could be problematic if either the first, + * or the second SCB is removed from the queue + * (the first SCB includes a pointer to the "next" + * SCB to dma). If we have removed any entries, swap + * the first element in the queue with the next HSCB + * so the sequencer will notice that NEXT_QUEUED_SCB + * has changed during its dma attempt and will retry + * the DMA. + */ + scb = ahc_lookup_scb(ahc, ahc->qinfifo[qinstart]); + + /* + * ahc_swap_with_next_hscb forces our next pointer to + * point to the reserved SCB for future commands. Save + * and restore our original next pointer to maintain + * queue integrity. + */ + next = scb->hscb->next; + ahc->scb_data->scbindex[scb->hscb->tag] = NULL; + ahc_swap_with_next_hscb(ahc, scb); + scb->hscb->next = next; + ahc->qinfifo[qinstart] = scb->hscb->tag; + + /* Fixup the tail "next" pointer. */ + qintail = ahc->qinfifonext - 1; + scb = ahc_lookup_scb(ahc, ahc->qinfifo[qintail]); + scb->hscb->next = ahc->next_queued_scb->hscb->tag; + } + /* * Search waiting for selection list. */ @@ -5930,6 +5936,8 @@ ahc_dump_card_state(struct ahc_softc *ahc) ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8)); printf("SCB count = %d\n", ahc->scb_data->numscbs); + printf("Kernel NEXTQSCB = %d\n", ahc->next_queued_scb->hscb->tag); + printf("Card NEXTQSCB = %d\n", ahc_inb(ahc, NEXT_QUEUED_SCB)); /* QINFIFO */ printf("QINFIFO entries: "); if ((ahc->features & AHC_QUEUE_REGS) != 0) { diff --git a/sys/dev/aic7xxx/aic7xxx.h b/sys/dev/aic7xxx/aic7xxx.h index 12bfdb297d98..2762ad261dd5 100644 --- a/sys/dev/aic7xxx/aic7xxx.h +++ b/sys/dev/aic7xxx/aic7xxx.h @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/src/aic7xxx/aic7xxx.h#14 $ + * $Id: //depot/src/aic7xxx/aic7xxx.h#17 $ * * $FreeBSD$ */ @@ -120,14 +120,31 @@ struct scb_platform_data; #define AHC_MAXTRANSFER_SIZE 0x00ffffff /* limited by 24bit counter */ /* + * The maximum amount of SCB storage in hardware on a controller. + * This value represents an upper bound. Controllers vary in the number + * they actually support. + */ +#define AHC_SCB_MAX 255 + +/* * The maximum number of concurrent transactions supported per driver instance. * Sequencer Control Blocks (SCBs) store per-transaction information. Although * the space for SCBs on the host adapter varies by model, the driver will * page the SCBs between host and controller memory as needed. We are limited - * to 255 because of the 8bit nature of the RISC engine and the need to - * reserve the value of 255 as a "No Transaction" value. + * to 253 because: + * 1) The 8bit nature of the RISC engine holds us to an 8bit value. + * 2) We reserve one value, 255, to represent the invalid element. + * 3) Our input queue scheme requires one SCB to always be reserved + * in advance of queuing any SCBs. This takes us down to 254. + * 4) To handle our output queue correctly on machines that only + * support 32bit stores, we must clear the array 4 bytes at a + * time. To avoid colliding with a DMA write from the sequencer, + * we must be sure that 4 slots are empty when we write to clear + * the queue. This reduces us to 253 SCBs: 1 that just completed + * and the known three additional empty slots in the queue that + * preceed it. */ -#define AHC_SCB_MAX 255 +#define AHC_MAX_QUEUE 253 /* * Ring Buffer of incoming target commands. @@ -190,6 +207,7 @@ typedef enum { AHC_AUTOPAUSE = 0x10000, /* Automatic pause on register access */ AHC_TARGETMODE = 0x20000, /* Has tested target mode support */ AHC_MULTIROLE = 0x40000, /* Space for two roles at a time */ + AHC_REMOVABLE = 0x80000, /* Hot-Swap supported */ AHC_AIC7770_FE = AHC_FENONE, AHC_AIC7850_FE = AHC_SPIOCAP|AHC_AUTOPAUSE|AHC_TARGETMODE, AHC_AIC7855_FE = AHC_AIC7850_FE, @@ -207,7 +225,7 @@ typedef enum { */ AHC_AIC7890_FE = AHC_MORE_SRAM|AHC_CMD_CHAN|AHC_ULTRA2 |AHC_QUEUE_REGS|AHC_SG_PRELOAD|AHC_MULTI_TID - |AHC_HS_MAILBOX |AHC_NEW_TERMCTL|AHC_LARGE_SCBS + |AHC_HS_MAILBOX|AHC_NEW_TERMCTL|AHC_LARGE_SCBS |AHC_TARGETMODE, AHC_AIC7892_FE = AHC_AIC7890_FE|AHC_DT|AHC_AUTORATE|AHC_AUTOPAUSE, AHC_AIC7895_FE = AHC_AIC7880_FE|AHC_MORE_SRAM|AHC_AUTOPAUSE diff --git a/sys/dev/aic7xxx/aic7xxx.reg b/sys/dev/aic7xxx/aic7xxx.reg index d60354457caf..e4326ea26c94 100644 --- a/sys/dev/aic7xxx/aic7xxx.reg +++ b/sys/dev/aic7xxx/aic7xxx.reg @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/src/aic7xxx/aic7xxx.reg#9 $ + * $Id: //depot/src/aic7xxx/aic7xxx.reg#10 $ * * $FreeBSD$ */ @@ -818,15 +818,10 @@ register INTSTAT { * not match the entry we * intended to download. */ - mask ABORT_QINSCB 0xd0|SEQINT /* - * An SCB was aborted - * during download. - * Informational. - */ - mask NO_FREE_SCB 0xe0|SEQINT /* + mask NO_FREE_SCB 0xd0|SEQINT /* * get_free_or_disc_scb failed. */ - mask OUT_OF_RANGE 0xf0|SEQINT + mask OUT_OF_RANGE 0xe0|SEQINT mask SEQINT_MASK 0xf0|SEQINT /* SEQINT Status Codes */ mask INT_PEND (BRKADRINT|SEQINT|SCSIINT|CMDCMPLT) @@ -1234,12 +1229,9 @@ scratch_ram { /* * 1 byte per target starting at this address for configuration values */ - CMDSIZE_TABLE { - alias TARG_SCSIRATE - size 8 - } BUSY_TARGETS { - size 8 + alias TARG_SCSIRATE + size 16 } /* * Bit vector of targets that have ULTRA enabled as set by @@ -1249,6 +1241,7 @@ scratch_ram { * entries in the busy target table. */ ULTRA_ENB { + alias CMDSIZE_TABLE size 2 } /* @@ -1260,7 +1253,7 @@ scratch_ram { DISC_DSB { size 2 } - BUSY_TARGETS_TAIL { + CMDSIZE_TABLE_TAIL { size 4 } /* diff --git a/sys/dev/aic7xxx/aic7xxx.seq b/sys/dev/aic7xxx/aic7xxx.seq index 3a536494b968..0aa62ae0f650 100644 --- a/sys/dev/aic7xxx/aic7xxx.seq +++ b/sys/dev/aic7xxx/aic7xxx.seq @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/src/aic7xxx/aic7xxx.seq#15 $ + * $Id: //depot/src/aic7xxx/aic7xxx.seq#16 $ * * $FreeBSD$ */ @@ -54,6 +54,13 @@ * automatically consume the entries. */ +bus_free_sel: + /* + * Turn off the selection hardware. We need to reset the + * selection request in order to perform a new selection. + */ + and SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ; + and SIMODE1, ~ENBUSFREE; poll_for_work: call clear_target_state; and SXFRCTL0, ~SPIOEN; @@ -135,7 +142,6 @@ start_waiting: jmp poll_for_work_loop; abort_qinscb: - mvi ABORT_QINSCB call set_seqint; call add_scb_to_free_list; jmp poll_for_work_loop; @@ -208,16 +214,14 @@ selection: * but prior to enabling the busfree interrupt. SELDI * and SELDO will be cleared in that case. */ + test SSTAT0, SELDI|SELDO jz bus_free_sel; test SSTAT0,SELDO jnz select_out; - test SSTAT0, SELDI jnz . + 3; - and SIMODE1, ~ENBUSFREE; - jmp poll_for_work; - mvi CLRSINT0, CLRSELDI; select_in: if ((ahc->flags & AHC_TARGETROLE) != 0) { if ((ahc->flags & AHC_INITIATORROLE) != 0) { test SSTAT0, TARGET jz initiator_reselect; } + mvi CLRSINT0, CLRSELDI; /* * We've just been selected. Assert BSY and @@ -407,6 +411,7 @@ if ((ahc->flags & AHC_INITIATORROLE) != 0) { */ initiator_reselect: /* XXX test for and handle ONE BIT condition */ + or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN; and SAVED_SCSIID, SELID_MASK, SELID; if ((ahc->features & AHC_ULTRA2) != 0) { and A, OID, SCSIID_ULTRA2; @@ -418,7 +423,7 @@ initiator_reselect: test SBLKCTL, SELBUSB jz . + 2; or SAVED_SCSIID, TWIN_CHNLB; } - or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN; + mvi CLRSINT0, CLRSELDI; jmp ITloop; } @@ -542,8 +547,8 @@ target_cmdphase: mov A, SINDIR; test A, 0xFF jz command_phase_done; -command_loop: or SXFRCTL0, SPIOEN; +command_loop: test SSTAT0, SPIORDY jz .; cmp A, 1 jne . + 2; and SXFRCTL0, ~SPIOEN; /* Last Byte */ @@ -1259,7 +1264,7 @@ p_command_embedded: mvi DFCNTRL, (PRELOADEN|SCSIEN|DIRECTION); bmov DFDAT, SCB_CDB_STORE, 12; } else if ((ahc->features & AHC_CMD_CHAN) != 0) { - if ((ahc->features & AHC_SCB_BTT) != 0) { + if ((ahc->flags & AHC_SCB_BTT) != 0) { /* * On the 7895 the data FIFO will * get corrupted if you try to dump @@ -1273,7 +1278,7 @@ p_command_embedded: mvi DFCNTRL, (SCSIEN|SDMAEN|DIRECTION|FIFORESET); } bmov DFDAT, SCB_CDB_STORE, 12; - if ((ahc->features & AHC_SCB_BTT) != 0) { + if ((ahc->flags & AHC_SCB_BTT) != 0) { mvi DFCNTRL, (SCSIEN|SDMAEN|DIRECTION|FIFOFLUSH); } else { or DFCNTRL, FIFOFLUSH; @@ -1583,7 +1588,7 @@ mesgin_rdptrs: */ set_busy_target: shr DINDEX, 4, SINDEX; - if ((ahc->features & AHC_SCB_BTT) != 0) { + if ((ahc->flags & AHC_SCB_BTT) != 0) { mov SCBPTR, SAVED_LUN; add DINDEX, SCB_64_BTT; } else { @@ -1597,7 +1602,6 @@ set_busy_target: * clearing the "disconnected" bit so we don't "find" it by accident later. */ mesgin_identify: - and SAVED_LUN, MSG_IDENTIFY_LUNMASK, A; /* * Determine whether a target is using tagged or non-tagged * transactions by first looking at the transaction stored in @@ -1605,19 +1609,29 @@ mesgin_identify: * for this target or the transaction is for a different lun, then * this must be an untagged transaction. */ -fetch_busy_target: - shr A, 4, SAVED_SCSIID; - if ((ahc->features & AHC_SCB_BTT) != 0) { - add SINDEX, SCB_64_BTT, A; + shr SINDEX, 4, SELID; + and SAVED_LUN, MSG_IDENTIFY_LUNMASK, A; + if ((ahc->flags & AHC_SCB_BTT) != 0) { + add SINDEX, SCB_64_BTT; mov SCBPTR, SAVED_LUN; + if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { + add NONE, -SCB_64_BTT, SINDEX; + jc . + 2; + mvi INTSTAT, OUT_OF_RANGE; + nop; + add NONE, -(SCB_64_BTT + 16), SINDEX; + jnc . + 2; + mvi INTSTAT, OUT_OF_RANGE; + nop; + } } else { - add SINDEX, BUSY_TARGETS, A; + add SINDEX, BUSY_TARGETS; if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { - add A, -BUSY_TARGETS, SINDEX; + add NONE, -BUSY_TARGETS, SINDEX; jc . + 2; mvi INTSTAT, OUT_OF_RANGE; nop; - add A, -(BUSY_TARGETS + 16), SINDEX; + add NONE, -(BUSY_TARGETS + 16), SINDEX; jnc . + 2; mvi INTSTAT, OUT_OF_RANGE; nop; @@ -1630,14 +1644,10 @@ fetch_busy_target: } else { mov SCBPTR, RETURN_1; } - if ((ahc->features & AHC_SCB_BTT) != 0) { + if ((ahc->flags & AHC_SCB_BTT) != 0) { jmp setup_SCB_id_lun_okay; } else { - mov A, SCB_LUN; - cmp SAVED_LUN, A je setup_SCB_id_lun_okay; - } - if ((ahc->flags & AHC_PAGESCBS) != 0) { - call add_scb_to_disc_list; + jmp setup_SCB_id_okay; } /* @@ -1649,6 +1659,9 @@ fetch_busy_target: * SCB. */ snoop_tag: + if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { + or SEQ_FLAGS, 0x80; + } mov NONE,SCSIDATL; /* ACK Identify MSG */ call phase_lock; if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { @@ -1673,16 +1686,17 @@ get_tag: * an SCB transaction to the reconnecting target. */ setup_SCB: - mov A, SAVED_SCSIID; if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { or SEQ_FLAGS, 0x4; } - cmp SCB_SCSIID, A jne not_found_cleanup_scb; - mov A, SAVED_LUN; + mov A, SCB_SCSIID; + cmp SAVED_SCSIID, A jne not_found_cleanup_scb; if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { or SEQ_FLAGS, 0x8; } - cmp SCB_LUN, A jne not_found_cleanup_scb; +setup_SCB_id_okay: + mov A, SCB_LUN; + cmp SAVED_LUN, A jne not_found_cleanup_scb; setup_SCB_id_lun_okay: if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) { or SEQ_FLAGS, 0x10; @@ -1965,7 +1979,7 @@ dma_scb: mvi HSCB_ADDR call set_64byte_addr; mov CCSCBPTR, SCBPTR; test DMAPARAMS, DIRECTION jz dma_scb_tohost; - if ((ahc->features & AHC_SCB_BTT) != 0) { + if ((ahc->flags & AHC_SCB_BTT) != 0) { mvi CCHCNT, SCB_DOWNLOAD_SIZE_64; } else { mvi CCHCNT, SCB_DOWNLOAD_SIZE; diff --git a/sys/dev/aic7xxx/aic7xxx_freebsd.c b/sys/dev/aic7xxx/aic7xxx_freebsd.c index 6fe99ab6ac96..7f6417e24b5f 100644 --- a/sys/dev/aic7xxx/aic7xxx_freebsd.c +++ b/sys/dev/aic7xxx/aic7xxx_freebsd.c @@ -133,7 +133,7 @@ ahc_attach(struct ahc_softc *ahc) /* * Create the device queue for our SIM(s). */ - devq = cam_simq_alloc(AHC_SCB_MAX - 1); + devq = cam_simq_alloc(AHC_MAX_QUEUE); if (devq == NULL) goto fail; @@ -142,7 +142,7 @@ ahc_attach(struct ahc_softc *ahc) */ sim = cam_sim_alloc(ahc_action, ahc_poll, "ahc", ahc, device_get_unit(ahc->dev_softc), - 1, AHC_SCB_MAX - 1, devq); + 1, AHC_MAX_QUEUE, devq); if (sim == NULL) { cam_simq_free(devq); goto fail; @@ -174,7 +174,7 @@ ahc_attach(struct ahc_softc *ahc) if (ahc->features & AHC_TWIN) { sim2 = cam_sim_alloc(ahc_action, ahc_poll, "ahc", ahc, device_get_unit(ahc->dev_softc), 1, - AHC_SCB_MAX - 1, devq); + AHC_MAX_QUEUE, devq); if (sim2 == NULL) { printf("ahc_attach: Unable to attach second " @@ -306,11 +306,17 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) */ LIST_FOREACH(list_scb, &ahc->pending_scbs, pending_links) { union ccb *ccb; + uint64_t time; ccb = list_scb->io_ctx; + if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) + continue; + + time = ccb->ccb_h.timeout; + time *= hz; + time /= 1000; ccb->ccb_h.timeout_ch = - timeout(ahc_timeout, list_scb, - (ccb->ccb_h.timeout * hz)/1000); + timeout(ahc_timeout, list_scb, time); } if (ahc_get_transaction_status(scb) == CAM_BDR_SENT @@ -1194,11 +1200,16 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments, ccb->ccb_h.status |= CAM_SIM_QUEUED; if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) { + uint64_t time; + if (ccb->ccb_h.timeout == CAM_TIME_DEFAULT) ccb->ccb_h.timeout = 5 * 1000; + + time = ccb->ccb_h.timeout; + time *= hz; + time /= 1000; ccb->ccb_h.timeout_ch = - timeout(ahc_timeout, (caddr_t)scb, - (ccb->ccb_h.timeout * hz) / 1000); + timeout(ahc_timeout, (caddr_t)scb, time); } /* @@ -1208,7 +1219,7 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments, * table in SCB space. */ if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0 - && (ahc->features & AHC_SCB_BTT) == 0) { + && (ahc->flags & AHC_SCB_BTT) == 0) { struct scb_tailq *untagged_q; untagged_q = &(ahc->untagged_queues[ccb->ccb_h.target_id]); @@ -1501,8 +1512,8 @@ bus_reset: */ active_scb = ahc_lookup_scb(ahc, active_scb_index); if (active_scb != scb) { - struct ccb_hdr *ccbh; - u_int newtimeout; + struct ccb_hdr *ccbh; + uint64_t newtimeout; ahc_print_path(ahc, scb); printf("Other SCB Timeout%s", @@ -1512,10 +1523,11 @@ bus_reset: newtimeout = MAX(active_scb->io_ctx->ccb_h.timeout, scb->io_ctx->ccb_h.timeout); + newtimeout *= hz; + newtimeout /= 1000; ccbh = &scb->io_ctx->ccb_h; scb->io_ctx->ccb_h.timeout_ch = - timeout(ahc_timeout, scb, - (newtimeout * hz) / 1000); + timeout(ahc_timeout, scb, newtimeout); ahc_unlock(ahc, &s); return; } diff --git a/sys/dev/aic7xxx/aic7xxx_inline.h b/sys/dev/aic7xxx/aic7xxx_inline.h index b95fd3f5f1be..8f55ad6baf3a 100644 --- a/sys/dev/aic7xxx/aic7xxx_inline.h +++ b/sys/dev/aic7xxx/aic7xxx_inline.h @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/src/aic7xxx/aic7xxx_inline.h#12 $ + * $Id: //depot/src/aic7xxx/aic7xxx_inline.h#14 $ * * $FreeBSD$ */ @@ -117,7 +117,7 @@ static __inline void ahc_release_untagged_queues(struct ahc_softc *ahc); static __inline void ahc_freeze_untagged_queues(struct ahc_softc *ahc) { - if ((ahc->features & AHC_SCB_BTT) == 0) + if ((ahc->flags & AHC_SCB_BTT) == 0) ahc->untagged_queue_lock++; } @@ -130,7 +130,7 @@ ahc_freeze_untagged_queues(struct ahc_softc *ahc) static __inline void ahc_release_untagged_queues(struct ahc_softc *ahc) { - if ((ahc->features & AHC_SCB_BTT) == 0) { + if ((ahc->flags & AHC_SCB_BTT) == 0) { ahc->untagged_queue_lock--; if (ahc->untagged_queue_lock == 0) ahc_run_untagged_queues(ahc); @@ -428,7 +428,7 @@ ahc_intr(struct ahc_softc *ahc) #endif } - if (intstat == 0xFF) + if (intstat == 0xFF && (ahc->features & AHC_REMOVABLE) != 0) /* Hot eject */ return; diff --git a/sys/dev/aic7xxx/aic7xxx_osm.c b/sys/dev/aic7xxx/aic7xxx_osm.c index 6fe99ab6ac96..7f6417e24b5f 100644 --- a/sys/dev/aic7xxx/aic7xxx_osm.c +++ b/sys/dev/aic7xxx/aic7xxx_osm.c @@ -133,7 +133,7 @@ ahc_attach(struct ahc_softc *ahc) /* * Create the device queue for our SIM(s). */ - devq = cam_simq_alloc(AHC_SCB_MAX - 1); + devq = cam_simq_alloc(AHC_MAX_QUEUE); if (devq == NULL) goto fail; @@ -142,7 +142,7 @@ ahc_attach(struct ahc_softc *ahc) */ sim = cam_sim_alloc(ahc_action, ahc_poll, "ahc", ahc, device_get_unit(ahc->dev_softc), - 1, AHC_SCB_MAX - 1, devq); + 1, AHC_MAX_QUEUE, devq); if (sim == NULL) { cam_simq_free(devq); goto fail; @@ -174,7 +174,7 @@ ahc_attach(struct ahc_softc *ahc) if (ahc->features & AHC_TWIN) { sim2 = cam_sim_alloc(ahc_action, ahc_poll, "ahc", ahc, device_get_unit(ahc->dev_softc), 1, - AHC_SCB_MAX - 1, devq); + AHC_MAX_QUEUE, devq); if (sim2 == NULL) { printf("ahc_attach: Unable to attach second " @@ -306,11 +306,17 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) */ LIST_FOREACH(list_scb, &ahc->pending_scbs, pending_links) { union ccb *ccb; + uint64_t time; ccb = list_scb->io_ctx; + if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) + continue; + + time = ccb->ccb_h.timeout; + time *= hz; + time /= 1000; ccb->ccb_h.timeout_ch = - timeout(ahc_timeout, list_scb, - (ccb->ccb_h.timeout * hz)/1000); + timeout(ahc_timeout, list_scb, time); } if (ahc_get_transaction_status(scb) == CAM_BDR_SENT @@ -1194,11 +1200,16 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments, ccb->ccb_h.status |= CAM_SIM_QUEUED; if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) { + uint64_t time; + if (ccb->ccb_h.timeout == CAM_TIME_DEFAULT) ccb->ccb_h.timeout = 5 * 1000; + + time = ccb->ccb_h.timeout; + time *= hz; + time /= 1000; ccb->ccb_h.timeout_ch = - timeout(ahc_timeout, (caddr_t)scb, - (ccb->ccb_h.timeout * hz) / 1000); + timeout(ahc_timeout, (caddr_t)scb, time); } /* @@ -1208,7 +1219,7 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments, * table in SCB space. */ if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0 - && (ahc->features & AHC_SCB_BTT) == 0) { + && (ahc->flags & AHC_SCB_BTT) == 0) { struct scb_tailq *untagged_q; untagged_q = &(ahc->untagged_queues[ccb->ccb_h.target_id]); @@ -1501,8 +1512,8 @@ bus_reset: */ active_scb = ahc_lookup_scb(ahc, active_scb_index); if (active_scb != scb) { - struct ccb_hdr *ccbh; - u_int newtimeout; + struct ccb_hdr *ccbh; + uint64_t newtimeout; ahc_print_path(ahc, scb); printf("Other SCB Timeout%s", @@ -1512,10 +1523,11 @@ bus_reset: newtimeout = MAX(active_scb->io_ctx->ccb_h.timeout, scb->io_ctx->ccb_h.timeout); + newtimeout *= hz; + newtimeout /= 1000; ccbh = &scb->io_ctx->ccb_h; scb->io_ctx->ccb_h.timeout_ch = - timeout(ahc_timeout, scb, - (newtimeout * hz) / 1000); + timeout(ahc_timeout, scb, newtimeout); ahc_unlock(ahc, &s); return; } diff --git a/sys/dev/aic7xxx/aic7xxx_pci.c b/sys/dev/aic7xxx/aic7xxx_pci.c index 07f53abe2c28..36714e5cf21d 100644 --- a/sys/dev/aic7xxx/aic7xxx_pci.c +++ b/sys/dev/aic7xxx/aic7xxx_pci.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/src/aic7xxx/aic7xxx_pci.c#10 $ + * $Id: //depot/src/aic7xxx/aic7xxx_pci.c#12 $ * * $FreeBSD$ */ @@ -184,12 +184,13 @@ ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) static ahc_device_setup_t ahc_aic7850_setup; static ahc_device_setup_t ahc_aic7855_setup; static ahc_device_setup_t ahc_aic7860_setup; +static ahc_device_setup_t ahc_apa1480_setup; static ahc_device_setup_t ahc_aic7870_setup; static ahc_device_setup_t ahc_aha394X_setup; static ahc_device_setup_t ahc_aha494X_setup; static ahc_device_setup_t ahc_aha398X_setup; static ahc_device_setup_t ahc_aic7880_setup; -static ahc_device_setup_t ahc_2940Pro_setup; +static ahc_device_setup_t ahc_aha2940Pro_setup; static ahc_device_setup_t ahc_aha394XU_setup; static ahc_device_setup_t ahc_aha398XU_setup; static ahc_device_setup_t ahc_aic7890_setup; @@ -197,6 +198,7 @@ static ahc_device_setup_t ahc_aic7892_setup; static ahc_device_setup_t ahc_aic7895_setup; static ahc_device_setup_t ahc_aic7896_setup; static ahc_device_setup_t ahc_aic7899_setup; +static ahc_device_setup_t ahc_aha29160C_setup; static ahc_device_setup_t ahc_raid_setup; static ahc_device_setup_t ahc_aha394XX_setup; static ahc_device_setup_t ahc_aha494XX_setup; @@ -222,7 +224,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] = ID_AHA_1480A & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec 1480A Ultra SCSI adapter", - ahc_aic7860_setup + ahc_apa1480_setup }, { ID_AHA_2940AU_0 & ID_DEV_VENDOR_MASK, @@ -330,7 +332,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] = ID_AHA_2940U_PRO & ID_DEV_VENDOR_MASK, ID_DEV_VENDOR_MASK, "Adaptec 2940 Pro Ultra SCSI adapter", - ahc_2940Pro_setup + ahc_aha2940Pro_setup }, { ID_AHA_2940U_CN & ID_DEV_VENDOR_MASK, @@ -398,7 +400,7 @@ struct ahc_pci_identity ahc_pci_ident_table [] = ID_AHA_29160C, ID_ALL_MASK, "Adaptec 29160C Ultra160 SCSI adapter", - ahc_aic7892_setup + ahc_aha29160C_setup }, { ID_AHA_29160B, @@ -1317,6 +1319,7 @@ configure_termination(struct ahc_softc *ahc, int enableSEC_high; int enablePRI_low; int enablePRI_high; + int sum; enableSEC_low = 0; enableSEC_high = 0; @@ -1361,21 +1364,22 @@ configure_termination(struct ahc_softc *ahc, if ((ahc->features & AHC_WIDE) == 0) internal68_present = 0; - if (bootverbose) { - if ((ahc->features & AHC_ULTRA2) == 0) { - printf("%s: internal 50 cable %s present, " - "internal 68 cable %s present\n", - ahc_name(ahc), - internal50_present ? "is":"not", - internal68_present ? "is":"not"); + if (bootverbose + && (ahc->features & AHC_ULTRA2) == 0) { + printf("%s: internal 50 cable %s present", + ahc_name(ahc), + internal50_present ? "is":"not"); - printf("%s: external cable %s present\n", - ahc_name(ahc), - externalcable_present ? "is":"not"); - } + if ((ahc->features & AHC_WIDE) != 0) + printf(", internal 68 cable %s present", + internal68_present ? "is":"not"); + printf("\n%s: external cable %s present\n", + ahc_name(ahc), + externalcable_present ? "is":"not"); + } + if (bootverbose) printf("%s: BIOS eeprom %s present\n", ahc_name(ahc), eeprom_present ? "is" : "not"); - } if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0) { /* @@ -1397,9 +1401,9 @@ configure_termination(struct ahc_softc *ahc, * Primary High Term Enable = BRDDAT4 (7890) */ if ((ahc->features & AHC_ULTRA2) == 0 - && (internal50_present != 0) - && (internal68_present != 0) - && (externalcable_present != 0)) { + && (internal50_present != 0) + && (internal68_present != 0) + && (externalcable_present != 0)) { printf("%s: Illegal cable configuration!!. " "Only two connectors on the " "adapter may be used at a " @@ -1423,10 +1427,9 @@ configure_termination(struct ahc_softc *ahc, } } - if (((internal50_present ? 1 : 0) - + (internal68_present ? 1 : 0) - + (externalcable_present ? 1 : 0)) <= 1 - || (enableSEC_low != 0)) { + sum = internal50_present + internal68_present + + externalcable_present; + if (sum < 2 || (enableSEC_low != 0)) { if ((ahc->features & AHC_ULTRA2) != 0) brddat |= BRDDAT5; else @@ -1477,7 +1480,8 @@ configure_termination(struct ahc_softc *ahc, : ""); } - if ((adapter_control & CFWSTERM) != 0) { + if ((adapter_control & CFWSTERM) != 0 + && (ahc->features & AHC_WIDE) != 0) { brddat |= BRDDAT6; if (bootverbose) printf("%s: %sHigh byte termination Enabled\n", @@ -1492,7 +1496,8 @@ configure_termination(struct ahc_softc *ahc, */ ahc_outb(ahc, SXFRCTL1, *sxfrctl1); - write_brdctl(ahc, brddat); + if ((ahc->features & AHC_WIDE) != 0) + write_brdctl(ahc, brddat); } SEEPROM_OUTB(sd, sd->sd_MS); /* Clear CS */ } @@ -1541,8 +1546,8 @@ aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present, * BRDDAT7 is INT68. */ brdctl = read_brdctl(ahc); - *internal50_present = !(brdctl & BRDDAT6); - *internal68_present = !(brdctl & BRDDAT7); + *internal50_present = (brdctl & BRDDAT6) ? 0 : 1; + *internal68_present = (brdctl & BRDDAT7) ? 0 : 1; /* * Set the rom bank to 1 and determine @@ -1556,8 +1561,8 @@ aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present, * BRDDAT7 is EPROMPS. */ brdctl = read_brdctl(ahc); - *externalcable_present = !(brdctl & BRDDAT6); - *eeprom_present = brdctl & BRDDAT7; + *externalcable_present = (brdctl & BRDDAT6) ? 0 : 1; + *eeprom_present = (brdctl & BRDDAT7) ? 1 : 0; } static void @@ -1569,10 +1574,10 @@ aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present, ahc_outb(ahc, BRDCTL, BRDRW|BRDCS); ahc_outb(ahc, BRDCTL, 0); brdctl = ahc_inb(ahc, BRDCTL); - *internal50_present = !(brdctl & BRDDAT5); - *externalcable_present = !(brdctl & BRDDAT6); + *internal50_present = (brdctl & BRDDAT5) ? 0 : 1; + *externalcable_present = (brdctl & BRDDAT6) ? 0 : 1; - *eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) != 0; + *eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) ? 1 : 0; } static int @@ -1625,16 +1630,16 @@ write_brdctl(struct ahc_softc *ahc, uint8_t value) brdctl = BRDSTB|BRDCS; } ahc_outb(ahc, BRDCTL, brdctl); - ahc_delay(20); + ahc_flush_device_writes(ahc); brdctl |= value; ahc_outb(ahc, BRDCTL, brdctl); - ahc_delay(20); + ahc_flush_device_writes(ahc); if ((ahc->features & AHC_ULTRA2) != 0) brdctl |= BRDSTB_ULTRA2; else brdctl &= ~BRDSTB; ahc_outb(ahc, BRDCTL, brdctl); - ahc_delay(20); + ahc_flush_device_writes(ahc); if ((ahc->features & AHC_ULTRA2) != 0) brdctl = 0; else @@ -1659,7 +1664,7 @@ read_brdctl(ahc) brdctl = BRDRW|BRDCS; } ahc_outb(ahc, BRDCTL, brdctl); - ahc_delay(20); + ahc_flush_device_writes(ahc); value = ahc_inb(ahc, BRDCTL); ahc_outb(ahc, BRDCTL, 0); return (value); @@ -1762,6 +1767,18 @@ ahc_aic7860_setup(ahc_dev_softc_t pci, struct ahc_probe_config *probe_config) } static int +ahc_apa1480_setup(ahc_dev_softc_t pci, struct ahc_probe_config *probe_config) +{ + int error; + + error = ahc_aic7860_setup(pci, probe_config); + if (error != 0) + return (error); + probe_config->features |= AHC_REMOVABLE; + return (0); +} + +static int ahc_aic7870_setup(ahc_dev_softc_t pci, struct ahc_probe_config *probe_config) { probe_config->channel = 'A'; @@ -1824,7 +1841,7 @@ ahc_aic7880_setup(ahc_dev_softc_t pci, struct ahc_probe_config *probe_config) } static int -ahc_2940Pro_setup(ahc_dev_softc_t pci, struct ahc_probe_config *probe_config) +ahc_aha2940Pro_setup(ahc_dev_softc_t pci, struct ahc_probe_config *probe_config) { int error; @@ -1957,6 +1974,18 @@ ahc_aic7899_setup(ahc_dev_softc_t pci, struct ahc_probe_config *probe_config) } static int +ahc_aha29160C_setup(ahc_dev_softc_t pci, struct ahc_probe_config *probe_config) +{ + int error; + + error = ahc_aic7899_setup(pci, probe_config); + if (error != 0) + return (error); + probe_config->features |= AHC_REMOVABLE; + return (0); +} + +static int ahc_raid_setup(ahc_dev_softc_t pci, struct ahc_probe_config *probe_config) { printf("RAID functionality unsupported\n"); |
