aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorJustin T. Gibbs <gibbs@FreeBSD.org>2001-01-22 21:03:48 +0000
committerJustin T. Gibbs <gibbs@FreeBSD.org>2001-01-22 21:03:48 +0000
commita5847d5c279eb40a86d4d9f32ac95824357fb3bc (patch)
tree22701b27f0320d6f557b0e998659531067640778 /sys/dev
parente26aac8d24e9f452d85df0332140b4b7cf30af61 (diff)
Notes
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/aic7xxx/ahc_eisa.c6
-rw-r--r--sys/dev/aic7xxx/ahc_pci.c2
-rw-r--r--sys/dev/aic7xxx/aic7770.c7
-rw-r--r--sys/dev/aic7xxx/aic7xxx.c120
-rw-r--r--sys/dev/aic7xxx/aic7xxx.h28
-rw-r--r--sys/dev/aic7xxx/aic7xxx.reg21
-rw-r--r--sys/dev/aic7xxx/aic7xxx.seq74
-rw-r--r--sys/dev/aic7xxx/aic7xxx_freebsd.c36
-rw-r--r--sys/dev/aic7xxx/aic7xxx_inline.h8
-rw-r--r--sys/dev/aic7xxx/aic7xxx_osm.c36
-rw-r--r--sys/dev/aic7xxx/aic7xxx_pci.c105
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");