summaryrefslogtreecommitdiffstats
path: root/sys/dev/aic7xxx
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>2001-01-22 21:03:48 +0000
committergibbs <gibbs@FreeBSD.org>2001-01-22 21:03:48 +0000
commit4d9966a39e21a860c94ca29856fe63127e18c48d (patch)
treed137c74f4eb490e11a9df0a0f24b3dbbc410c210 /sys/dev/aic7xxx
parent301ceeb33db1ab75db3abfda07d22a539af7cd24 (diff)
downloadFreeBSD-src-4d9966a39e21a860c94ca29856fe63127e18c48d.zip
FreeBSD-src-4d9966a39e21a860c94ca29856fe63127e18c48d.tar.gz
ahc_eisa.c:
Initialize rid to 0. This doesn't seem to make any difference (the driver doesn't care what rid it gets and no-one seems to check rid's value), but follows standard conventions. Pass in our device_t to ahc_alloc(). We now use device_T softc storage, so passing NULL results in a panic. Set the unit number in our softc so that the driver core can retrieve it. ahc_pci.c: Set the unit number in our softc so that the driver core can retrieve it. aic7770.c: Insert our softc into the list of softcs when initialization is successful. aic7xxx.c: Remove a workaround for an aic7895 bug we will never trigger. Add additional diagnostic info to ahc_dump_card_state(). Always panic the system if a sequencer assertion fails. AHC_SCB_BTT is a "flag" not a "feature". Check the right field in the softc. Replace a hard coded number with a constant. Guard against looping forever in ahc_pause_and_flushwork(). A hot eject or card failure may make the intstat register return 0xFF, so limit the number of interrupts we'll process. Correct the code in ahc_search_qinfifo() that guarantees that the sequencer will see an abort collision if the qinfifo is modified when a DMA is in progress. We now do this fixup after modifying the queue. This guarantees that the HSCB we place at the head of the queue is not the same as the old head. Using "next hscb" (guaranteed not to be the same as the first SCB) before clearing the queue could free up the original head hscb to be used during a remove operation placing it again at the head of the qinfifo. aic7xxx.h: Reduce the maximum number of outstanding commands to 253 from 254. 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. Yahoo was able to force this race on one of their systems. Interrupts were disabled for such a time that the entire output queue was filled (254 entries complete without any processing), and our 32bit write to clear the status clobbered one entry. Add a feature tag for devices that are removable. aic7xxx.reg: Never use the sequencer interrupt value of 0xF0. We need to guanrantee that an INTSTAT value of 0xFF can only occur during card failure or a hot-eject. Align the busy targets table with the begining of scratch space. This seems to appease a chip bug in the aic7895. aic7xxx.seq: Be sure to disable select-out after a bus free event that occurs early in a selection. If we don't disable select-out, we will believe that it is enabled even though a new selection will never occur. Move the clearing of SELDI to just before a jump. This appeases another chip bug of the aic7895. Make the target mode command loop a bit more efficient. AHC_SCB_BTT is a "flag" not a "feature". Check the right field in the softc. Properly cleanup the last SCB we tested against should we fail to properly find an SCB for a reselection. Add some additional sequencer debugging code. aic7xxx_freebsd.c: Limit the driver to 253 outstanding commands per adapter. Guard against overflow in timeout handling. aic7xxx_inline.h: AHC_SCB_BTT is a "flag" not a "feature". Check the right field in the softc. aic7xxx_pci.c: Set the removable feature for the apa1480 cardbus and the 29160C Compact PCI card. Don't report high byte termination information for narrow cards. Use a PCI read rather than a questionable delay when fetching/setting termination settings.
Diffstat (limited to 'sys/dev/aic7xxx')
-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 8613f61..fdc58aa 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 2754699..f38f6f6 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 bcfa0f6..700d935 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 70f22c7..35511f3 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 12bfdb2..2762ad2 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 d603544..e4326ea 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 3a53649..0aa62ae 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 6fe99ab..7f6417e 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 b95fd3f..8f55ad6 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 6fe99ab..7f6417e 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 07f53ab..36714e5 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");
OpenPOWER on IntegriCloud