kern/128165: [aac] [patch] sync aac(4) with the latest vendor version

pluknet pluknet at gmail.com
Thu Oct 16 22:40:02 UTC 2008


>Number:         128165
>Category:       kern
>Synopsis:       [aac] [patch] sync aac(4) with the latest vendor version
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Oct 16 22:40:01 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     pluknet
>Release:        7.1-PRERELEASE
>Organization:
RIPN
>Environment:
>Description:
I found that the latest vendor's driver
AACRAID Driver v5.2.0 Build 15753
is available and may have improvements
which could be integrated into the FreeBSD src tree.

The latest driver (b15753) is on vendor site.
It's originally for 6.x.
http://www.adaptec.com/en-US/speed/raid/aac/unix/aacraid_freebsd6_b15753_tar_gz.htm

>How-To-Repeat:

>Fix:
I've tried to extract the useful chunks from it
and prepare the patch against head (unfortunately not tested).

Patch attached with submission follows:

diff -uN /media/cvs-cur/src/sys/dev/aac/aac.c ./aac.c
--- /media/cvs-cur/src/sys/dev/aac/aac.c	2008-06-24 07:26:41.000000000 +0400
+++ ./aac.c	2008-10-17 01:00:37.000000000 +0400
@@ -28,12 +28,11 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/aac/aac.c,v 1.138 2008/06/24 03:26:41 emaste Exp $");
+__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac.c,v 1.118 2006/04/08 06:05:29 scottl Exp $");
 
 /*
  * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
  */
-#define AAC_DRIVER_VERSION		0x02000000
 #define AAC_DRIVERNAME			"aac"
 
 #include "opt_aac.h"
@@ -64,6 +63,7 @@
 
 #include <dev/aac/aacreg.h>
 #include <sys/aac_ioctl.h>
+#include <dev/aac/aac_fwdb.h>
 #include <dev/aac/aacvar.h>
 #include <dev/aac/aac_tables.h>
 
@@ -71,6 +71,7 @@
 static void	aac_add_container(struct aac_softc *sc,
 				  struct aac_mntinforesp *mir, int f);
 static void	aac_get_bus_info(struct aac_softc *sc);
+static void	aac_daemon(void *arg);
 
 /* Command Processing */
 static void	aac_timeout(struct aac_softc *sc);
@@ -95,9 +96,6 @@
 			       int error);
 static int	aac_check_firmware(struct aac_softc *sc);
 static int	aac_init(struct aac_softc *sc);
-static int	aac_sync_command(struct aac_softc *sc, u_int32_t command,
-				 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
-				 u_int32_t arg3, u_int32_t *sp);
 static int	aac_setup_intr(struct aac_softc *sc);
 static int	aac_enqueue_fib(struct aac_softc *sc, int queue,
 				struct aac_command *cm);
@@ -229,8 +227,11 @@
 static int		aac_supported_features(struct aac_softc *sc, caddr_t uptr);
 static void		aac_ioctl_event(struct aac_softc *sc,
 				        struct aac_event *event, void *arg);
+static int		aac_reset_adapter(struct aac_softc *sc);
 static struct aac_mntinforesp *
 	aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid);
+static u_int32_t
+	aac_check_adapter_health(struct aac_softc *sc, u_int8_t *bled);
 
 static struct cdevsw aac_cdevsw = {
 	.d_version =	D_VERSION,
@@ -258,6 +259,7 @@
 aac_attach(struct aac_softc *sc)
 {
 	int error, unit;
+	struct timeval tv;
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
@@ -349,6 +351,10 @@
 		aac_get_bus_info(sc);
 	}
 
+	tv.tv_sec = 60;
+	tv.tv_usec = 0;
+	sc->timeout_id = timeout(aac_daemon, (void *)sc, tvtohz(&tv));
+
 	return(0);
 }
 
@@ -369,6 +375,28 @@
 	return;
 }
 
+/* daemon */
+static void
+aac_daemon(void *arg)
+{
+	struct aac_softc *sc = (struct aac_softc *)arg;
+	struct timeval tv;
+	struct aac_fib *fib;
+
+	/* time sync. with firmware */
+	getmicrotime(&tv);
+	mtx_lock(&sc->aac_io_lock);
+	aac_alloc_sync_fib(sc, &fib);
+	*(uint32_t *)fib->data = tv.tv_sec;
+	aac_sync_fib(sc, SendHostTime, 0, fib, sizeof(uint32_t));
+	aac_release_sync_fib(sc);
+	mtx_unlock(&sc->aac_io_lock);
+
+	tv.tv_sec = 30*60;		/* 30 minutes */
+	tv.tv_usec = 0;
+	sc->timeout_id = timeout(aac_daemon, (void *)sc, tvtohz(&tv));
+}
+
 /*
  * Request information of container #cid
  */
@@ -632,9 +660,12 @@
 		bus_dma_tag_destroy(sc->aac_parent_dmat);
 
 	/* release the register window mapping */
-	if (sc->aac_regs_resource != NULL)
+	if (sc->aac_regs_res0 != NULL)
+		bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
+				     sc->aac_regs_rid0, sc->aac_regs_res0);
+	if (sc->aac_hwif == AAC_HWIF_NARK && sc->aac_regs_res1 != NULL)
 		bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
-				     sc->aac_regs_rid, sc->aac_regs_resource);
+				     sc->aac_regs_rid1, sc->aac_regs_res1);
 }
 
 /*
@@ -654,6 +685,8 @@
 	if (sc->aac_state & AAC_STATE_OPEN)
 		return(EBUSY);
 
+	untimeout(aac_daemon, (void *)sc, sc->timeout_id);
+
 	/* Remove the child containers */
 	while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) {
 		error = device_delete_child(dev, co->co_disk);
@@ -834,7 +867,7 @@
 			}
 			index &= ~2;
 			for (i = 0; i < sizeof(struct aac_fib)/4; ++i)
-				((u_int32_t *)fib)[i] = AAC_GETREG4(sc, index + i*4);
+				((u_int32_t *)fib)[i] = AAC_MEM1_GETREG4(sc, index + i*4);
 			aac_handle_aif(sc, fib);
 			free(fib, M_AACBUF);
 
@@ -935,6 +968,8 @@
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
 	for (;;) {
+		if (sc->aac_state & AAC_STATE_RESET)
+			break;
 		/*
 		 * This flag might be set if the card is out of resources.
 		 * Checking it here prevents an infinite loop of deferrals.
@@ -1181,7 +1216,6 @@
 	cm->cm_complete = aac_bio_complete;
 	cm->cm_private = bp;
 	cm->cm_timestamp = time_uptime;
-	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
 
 	/* build the FIB */
 	fib = cm->cm_fib;
@@ -1294,7 +1328,9 @@
 
 	/* fetch relevant status and then release the command */
 	bp = (struct bio *)cm->cm_private;
-	if (bp->bio_cmd == BIO_READ) {
+	if (cm->cm_flags & AAC_CMD_RESET) {
+		status = ST_BUS_RESET;
+	} else if (bp->bio_cmd == BIO_READ) {
 		brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
 		status = brr->Status;
 	} else {
@@ -1336,7 +1372,6 @@
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
 	/* Put the command on the ready queue and get things going */
-	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
 	aac_enqueue_ready(cm);
 	aac_startio(sc);
 	error = msleep(cm, &sc->aac_io_lock, PRIBIO, "aacwait", 0);
@@ -1386,6 +1421,8 @@
 	cm->cm_flags = 0;
 	cm->cm_complete = NULL;
 	cm->cm_private = NULL;
+	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
+	cm->cm_passthr_dmat = 0;
 	cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
 	cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
 	cm->cm_fib->Header.Flags = 0;
@@ -1586,12 +1623,14 @@
 	/* save a pointer to the command for speedy reverse-lookup */
 	cm->cm_fib->Header.SenderData = cm->cm_index;
 
-	if (cm->cm_flags & AAC_CMD_DATAIN)
-		bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
-				BUS_DMASYNC_PREREAD);
-	if (cm->cm_flags & AAC_CMD_DATAOUT)
-		bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
-				BUS_DMASYNC_PREWRITE);
+	if (cm->cm_passthr_dmat == 0) {
+		if (cm->cm_flags & AAC_CMD_DATAIN)
+			bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
+					BUS_DMASYNC_PREREAD);
+		if (cm->cm_flags & AAC_CMD_DATAOUT)
+			bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
+					BUS_DMASYNC_PREWRITE);
+	}
 	cm->cm_flags |= AAC_CMD_MAPPED;
 
 	if (sc->flags & AAC_FLAGS_NEW_COMM) {
@@ -1630,7 +1669,7 @@
 	if (!(cm->cm_flags & AAC_CMD_MAPPED))
 		return;
 
-	if (cm->cm_datalen != 0) {
+	if (cm->cm_datalen != 0 && cm->cm_passthr_dmat == 0) {
 		if (cm->cm_flags & AAC_CMD_DATAIN)
 			bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
 					BUS_DMASYNC_POSTREAD);
@@ -1754,26 +1793,33 @@
 
 	/* Remap mem. resource, if required */
 	if ((sc->flags & AAC_FLAGS_NEW_COMM) &&
-		atu_size > rman_get_size(sc->aac_regs_resource)) {
+		atu_size > rman_get_size(sc->aac_regs_res1)) {
 		bus_release_resource(
 			sc->aac_dev, SYS_RES_MEMORY,
-			sc->aac_regs_rid, sc->aac_regs_resource);
-		sc->aac_regs_resource = bus_alloc_resource(
-			sc->aac_dev, SYS_RES_MEMORY, &sc->aac_regs_rid,
+			sc->aac_regs_rid1, sc->aac_regs_res1);
+		sc->aac_regs_res1 = bus_alloc_resource(
+			sc->aac_dev, SYS_RES_MEMORY, &sc->aac_regs_rid1,
 			0ul, ~0ul, atu_size, RF_ACTIVE);
-		if (sc->aac_regs_resource == NULL) {
-			sc->aac_regs_resource = bus_alloc_resource_any(
+		if (sc->aac_regs_res1 == NULL) {
+			sc->aac_regs_res1 = bus_alloc_resource_any(
 				sc->aac_dev, SYS_RES_MEMORY,
-				&sc->aac_regs_rid, RF_ACTIVE);
-			if (sc->aac_regs_resource == NULL) {
+				&sc->aac_regs_rid1, RF_ACTIVE);
+			if (sc->aac_regs_res1 == NULL) {
 				device_printf(sc->aac_dev,
 				    "couldn't allocate register window\n");
 				return (ENXIO);
 			}
 			sc->flags &= ~AAC_FLAGS_NEW_COMM;
 		}
-		sc->aac_btag = rman_get_bustag(sc->aac_regs_resource);
-		sc->aac_bhandle = rman_get_bushandle(sc->aac_regs_resource);
+		sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1);
+		sc->aac_bhandle1 = rman_get_bushandle(sc->aac_regs_res1);
+
+		if (sc->aac_hwif == AAC_HWIF_NARK) {
+			sc->aac_regs_res0 = sc->aac_regs_res1;
+			sc->aac_regs_rid0 = sc->aac_regs_rid1;
+			sc->aac_btag0 = sc->aac_btag1;
+			sc->aac_bhandle0 = sc->aac_bhandle1;
+		}
 	}
 
 	/* Read preferred settings */
@@ -1807,10 +1853,12 @@
 	}
 	if ((sc->flags & AAC_FLAGS_RAW_IO) &&
 	    (sc->flags & AAC_FLAGS_ARRAY_64BIT)) {
+		/* enable 64-bit LBA support */
 		sc->flags |= AAC_FLAGS_LBA_64BIT;
 		device_printf(sc->aac_dev, "Enable 64-bit array\n");
 	}
 
+	aac_get_fw_debug_buffer(sc);
 	return (0);
 }
 
@@ -1944,10 +1992,10 @@
 	 */
 	switch (sc->aac_hwif) {
 	case AAC_HWIF_I960RX:
-		AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
+		AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, ~0);
 		break;
 	case AAC_HWIF_RKT:
-		AAC_SETREG4(sc, AAC_RKT_ODBR, ~0);
+		AAC_MEM0_SETREG4(sc, AAC_RKT_ODBR, ~0);
 		break;
 	default:
 		break;
@@ -1984,15 +2032,15 @@
 	}
 	if (sc->flags & AAC_FLAGS_NEW_COMM) {
 		if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
-				   INTR_MPSAFE|INTR_TYPE_BIO, NULL, 
+				   INTR_MPSAFE|INTR_TYPE_BIO, NULL,
 				   aac_new_intr, sc, &sc->aac_intr)) {
 			device_printf(sc->aac_dev, "can't set up interrupt\n");
 			return (EINVAL);
 		}
 	} else {
 		if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
-				   INTR_TYPE_BIO, aac_fast_intr, NULL,
-				   sc, &sc->aac_intr)) {
+				   INTR_FAST|INTR_TYPE_BIO, aac_fast_intr,
+				   NULL, sc, &sc->aac_intr)) {
 			device_printf(sc->aac_dev,
 				      "can't set up FAST interrupt\n");
 			if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
@@ -2012,7 +2060,7 @@
  * Send a synchronous command to the controller and wait for a result.
  * Indicate if the controller completed the command with an error status.
  */
-static int
+int
 aac_sync_command(struct aac_softc *sc, u_int32_t command,
 		 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3,
 		 u_int32_t *sp)
@@ -2022,6 +2070,9 @@
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
+	if (sp != NULL)
+		*sp = AAC_SRB_STS_SUCCESS;
+
 	/* populate the mailbox */
 	AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
 
@@ -2350,6 +2401,7 @@
 		if (code != AAC_UP_AND_RUNNING) {
 			device_printf(sc->aac_dev, "WARNING! Controller is no "
 				      "longer running! code= 0x%x\n", code);
+			aac_reset_adapter(sc);
 		}
 	}
 	return;
@@ -2367,7 +2419,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_SA_FWSTATUS));
+	return(AAC_MEM0_GETREG4(sc, AAC_SA_FWSTATUS));
 }
 
 static int
@@ -2375,7 +2427,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RX_FWSTATUS));
+	return(AAC_MEM0_GETREG4(sc, AAC_RX_OMR0));
 }
 
 static int
@@ -2385,7 +2437,7 @@
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	val = AAC_GETREG4(sc, AAC_FA_FWSTATUS);
+	val = AAC_MEM0_GETREG4(sc, AAC_FA_FWSTATUS);
 	return (val);
 }
 
@@ -2394,7 +2446,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RKT_FWSTATUS));
+	return(AAC_MEM0_GETREG4(sc, AAC_RKT_OMR0));
 }
 
 /*
@@ -2406,7 +2458,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
+	AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
 }
 
 static void
@@ -2414,7 +2466,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
+	AAC_MEM0_SETREG4(sc, AAC_RX_IDBR, qbit);
 }
 
 static void
@@ -2422,7 +2474,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG2(sc, AAC_FA_DOORBELL1, qbit);
+	AAC_MEM0_SETREG2(sc, AAC_FA_DOORBELL1, qbit);
 	AAC_FA_HACK(sc);
 }
 
@@ -2431,7 +2483,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RKT_IDBR, qbit);
+	AAC_MEM0_SETREG4(sc, AAC_RKT_IDBR, qbit);
 }
 
 /*
@@ -2442,7 +2494,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG2(sc, AAC_SA_DOORBELL0));
+	return(AAC_MEM0_GETREG2(sc, AAC_SA_DOORBELL0));
 }
 
 static int
@@ -2450,7 +2502,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RX_ODBR));
+	return(AAC_MEM0_GETREG4(sc, AAC_RX_ODBR));
 }
 
 static int
@@ -2460,7 +2512,7 @@
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	val = AAC_GETREG2(sc, AAC_FA_DOORBELL0);
+	val = AAC_MEM0_GETREG2(sc, AAC_FA_DOORBELL0);
 	return (val);
 }
 
@@ -2469,7 +2521,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RKT_ODBR));
+	return(AAC_MEM0_GETREG4(sc, AAC_RKT_ODBR));
 }
 
 /*
@@ -2480,7 +2532,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
+	AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
 }
 
 static void
@@ -2488,7 +2540,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RX_ODBR, mask);
+	AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, mask);
 }
 
 static void
@@ -2496,7 +2548,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask);
+	AAC_MEM0_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask);
 	AAC_FA_HACK(sc);
 }
 
@@ -2505,7 +2557,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RKT_ODBR, mask);
+	AAC_MEM0_SETREG4(sc, AAC_RKT_ODBR, mask);
 }
 
 /*
@@ -2517,11 +2569,11 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
-	AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
-	AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
-	AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
-	AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
+	AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX, command);
+	AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
+	AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
+	AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
+	AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
 }
 
 static void
@@ -2530,11 +2582,11 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
-	AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
-	AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
-	AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
-	AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
+	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX, command);
+	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
+	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
+	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
+	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
 }
 
 static void
@@ -2543,15 +2595,15 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_FA_MAILBOX, command);
+	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX, command);
 	AAC_FA_HACK(sc);
-	AAC_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0);
+	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0);
 	AAC_FA_HACK(sc);
-	AAC_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1);
+	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1);
 	AAC_FA_HACK(sc);
-	AAC_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2);
+	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2);
 	AAC_FA_HACK(sc);
-	AAC_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3);
+	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3);
 	AAC_FA_HACK(sc);
 }
 
@@ -2561,11 +2613,11 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RKT_MAILBOX, command);
-	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
-	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
-	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
-	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
+	AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX, command);
+	AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
+	AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
+	AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
+	AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
 }
 
 /*
@@ -2576,7 +2628,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
+	return(AAC_MEM1_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
 }
 
 static int
@@ -2584,7 +2636,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
+	return(AAC_MEM1_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
 }
 
 static int
@@ -2594,7 +2646,7 @@
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	val = AAC_GETREG4(sc, AAC_FA_MAILBOX + (mb * 4));
+	val = AAC_MEM1_GETREG4(sc, AAC_FA_MAILBOX + (mb * 4));
 	return (val);
 }
 
@@ -2603,7 +2655,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
+	return(AAC_MEM1_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
 }
 
 /*
@@ -2615,9 +2667,9 @@
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
 
 	if (enable) {
-		AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
+		AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
 	} else {
-		AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
+		AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
 	}
 }
 
@@ -2628,11 +2680,11 @@
 
 	if (enable) {
 		if (sc->flags & AAC_FLAGS_NEW_COMM)
-			AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INT_NEW_COMM);
+			AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INT_NEW_COMM);
 		else
-			AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
+			AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
 	} else {
-		AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
+		AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~0);
 	}
 }
 
@@ -2642,10 +2694,10 @@
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
 
 	if (enable) {
-		AAC_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
+		AAC_MEM0_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
 		AAC_FA_HACK(sc);
 	} else {
-		AAC_SETREG2((sc), AAC_FA_MASK0, ~0);
+		AAC_MEM0_SETREG2((sc), AAC_FA_MASK0, ~0);
 		AAC_FA_HACK(sc);
 	}
 }
@@ -2657,11 +2709,11 @@
 
 	if (enable) {
 		if (sc->flags & AAC_FLAGS_NEW_COMM)
-			AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INT_NEW_COMM);
+			AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INT_NEW_COMM);
 		else
-			AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
+			AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
 	} else {
-		AAC_SETREG4(sc, AAC_RKT_OIMR, ~0);
+		AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~0);
 	}
 }
 
@@ -2675,19 +2727,19 @@
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
 
-	index = AAC_GETREG4(sc, AAC_RX_IQUE);
+	index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
 	if (index == 0xffffffffL)
-		index = AAC_GETREG4(sc, AAC_RX_IQUE);
+		index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
 	if (index == 0xffffffffL)
 		return index;
 	aac_enqueue_busy(cm);
 	device = index;
-	AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
+	AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
 	device += 4;
-	AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
+	AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
 	device += 4;
-	AAC_SETREG4(sc, device, cm->cm_fib->Header.Size);
-	AAC_SETREG4(sc, AAC_RX_IQUE, index);
+	AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
+	AAC_MEM0_SETREG4(sc, AAC_RX_IQUE, index);
 	return 0;
 }
 
@@ -2698,19 +2750,19 @@
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
 
-	index = AAC_GETREG4(sc, AAC_RKT_IQUE);
+	index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
 	if (index == 0xffffffffL)
-		index = AAC_GETREG4(sc, AAC_RKT_IQUE);
+		index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
 	if (index == 0xffffffffL)
 		return index;
 	aac_enqueue_busy(cm);
 	device = index;
-	AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
+	AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
 	device += 4;
-	AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
+	AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
 	device += 4;
-	AAC_SETREG4(sc, device, cm->cm_fib->Header.Size);
-	AAC_SETREG4(sc, AAC_RKT_IQUE, index);
+	AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
+	AAC_MEM0_SETREG4(sc, AAC_RKT_IQUE, index);
 	return 0;
 }
 
@@ -2722,7 +2774,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RX_OQUE));
+	return(AAC_MEM0_GETREG4(sc, AAC_RX_OQUE));
 }
 
 static int
@@ -2730,7 +2782,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RKT_OQUE));
+	return(AAC_MEM0_GETREG4(sc, AAC_RKT_OQUE));
 }
 
 static void
@@ -2738,7 +2790,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RX_OQUE, index);
+	AAC_MEM0_SETREG4(sc, AAC_RX_OQUE, index);
 }
 
 static void
@@ -2746,7 +2798,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RKT_OQUE, index);
+	AAC_MEM0_SETREG4(sc, AAC_RKT_OQUE, index);
 }
 
 /*
@@ -2761,13 +2813,30 @@
 {
 	struct aac_fib *fib;
 	struct aac_adapter_info	*info;
-	char *adapter_type = "Adaptec RAID controller";
+	char *adapter_type = "Adaptec RAID Controller";
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
 	mtx_lock(&sc->aac_io_lock);
 	aac_alloc_sync_fib(sc, &fib);
 
+	if (sc->supported_options & AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO) {
+		fib->data[0] = 0;
+		if (aac_sync_fib(sc, RequestSupplementAdapterInfo, 0, fib, 1)) 
+			device_printf(sc->aac_dev, "RequestSupplementAdapterInfo failed\n");
+		else
+			adapter_type = ((struct aac_supplement_adapter_info *)
+				&fib->data[0])->AdapterTypeText;
+	}
+	device_printf(sc->aac_dev, "%s, aac driver %d.%d.%d-%d\n",
+		adapter_type,
+		AAC_DRIVER_MAJOR_VERSION, AAC_DRIVER_MINOR_VERSION,
+		AAC_DRIVER_BUGFIX_LEVEL, AAC_DRIVER_BUILD);
+/*
+	device_printf(sc->aac_dev, 
+		"Please note: THIS IS A BETA VERSION, NOT AN OFFICIAL RELEASE!\n");
+*/
+
 	fib->data[0] = 0;
 	if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
 		device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
@@ -2821,23 +2890,6 @@
 			      "\23ARRAY64BIT"
 			      "\24HEATSENSOR");
 	}
-
-	if (sc->supported_options & AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO) {
-		fib->data[0] = 0;
-		if (aac_sync_fib(sc, RequestSupplementAdapterInfo, 0, fib, 1))
-			device_printf(sc->aac_dev,
-			    "RequestSupplementAdapterInfo failed\n");
-		else
-			adapter_type = ((struct aac_supplement_adapter_info *)
-			    &fib->data[0])->AdapterTypeText;
-	}
-	device_printf(sc->aac_dev, "%s, aac driver %d.%d.%d-%d\n",
-		adapter_type,
-		AAC_DRIVER_VERSION >> 24,
-		(AAC_DRIVER_VERSION >> 16) & 0xFF,
-		AAC_DRIVER_VERSION & 0xFF,
-		AAC_DRIVER_BUILD);
-
 	aac_release_sync_fib(sc);
 	mtx_unlock(&sc->aac_io_lock);
 }
@@ -3073,7 +3125,7 @@
 		event->ev_callback = aac_ioctl_event;
 		event->ev_arg = &cm;
 		aac_add_event(sc, event);
-		msleep(&cm, &sc->aac_io_lock, 0, "sendfib", 0);
+		msleep(cm, &sc->aac_io_lock, 0, "sndfib", 0);
 	}
 	mtx_unlock(&sc->aac_io_lock);
 
@@ -3132,7 +3184,209 @@
 static int
 aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg)
 {
-	return (EINVAL);
+	struct aac_command *cm;
+	struct aac_fib *fib;
+	struct aac_srb *srbcmd;
+	struct aac_srb *user_srb = (struct aac_srb *)arg;
+	void *user_reply;
+	int error, transfer_data = 0;
+	bus_dmamap_t orig_map = 0;
+	u_int32_t fibsize = 0;
+	u_int64_t srb_sg_address;
+	u_int32_t srb_sg_bytecount;
+
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+	cm = NULL;
+
+	mtx_lock(&sc->aac_io_lock);
+	if (aac_alloc_command(sc, &cm)) {
+		struct aac_event *event;
+
+		event = malloc(sizeof(struct aac_event), M_AACBUF,
+		    M_NOWAIT | M_ZERO);
+		if (event == NULL) {
+			error = EBUSY;
+			mtx_unlock(&sc->aac_io_lock);
+			goto out;
+		}
+		event->ev_type = AAC_EVENT_CMFREE;
+		event->ev_callback = aac_ioctl_event;
+		event->ev_arg = &cm;
+		aac_add_event(sc, event);
+		msleep(cm, &sc->aac_io_lock, 0, "sndraw", 0);
+	}
+	mtx_unlock(&sc->aac_io_lock);
+
+	cm->cm_data = NULL;
+	/* save original dma map */
+	orig_map = cm->cm_datamap;
+
+	fib = cm->cm_fib;
+	srbcmd = (struct aac_srb *)fib->data;
+	if ((error = copyin((void *)&user_srb->data_len, &fibsize, 
+	    sizeof (u_int32_t)) != 0)) 
+		goto out;
+	if (fibsize > (sc->aac_max_fib_size-sizeof(struct aac_fib_header))) {
+		error = EINVAL;
+		goto out;
+	}
+	if ((error = copyin((void *)user_srb, srbcmd, fibsize) != 0)) 
+		goto out;
+
+	srbcmd->function = 0;		/* SRBF_ExecuteScsi */
+	srbcmd->retry_limit = 0;	/* obsolete */
+
+	/* only one sg element from userspace supported */
+	if (srbcmd->sg_map.SgCount > 1) {
+		error = EINVAL;
+		goto out;
+	}
+	/* check fibsize */
+	if (fibsize == (sizeof(struct aac_srb) + 
+	    srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry))) {
+		struct aac_sg_entry *sgp = srbcmd->sg_map.SgEntry;
+
+		srb_sg_bytecount = sgp->SgByteCount;
+		srb_sg_address = (u_int64_t)sgp->SgAddress;
+	} else if (fibsize == (sizeof(struct aac_srb) + 
+	    srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry64))) {
+#ifdef __amd64__
+		struct aac_sg_entry64 *sgp = 
+		    (struct aac_sg_entry64 *)srbcmd->sg_map.SgEntry;
+
+		srb_sg_bytecount = sgp->SgByteCount;
+		srb_sg_address = sgp->SgAddress;
+		if (srb_sg_address > 0xffffffffull && 
+		    !(sc->flags & AAC_FLAGS_SG_64BIT))
+#endif	
+		{
+			error = EINVAL;
+			goto out;
+		}
+	} else {
+		error = EINVAL;
+		goto out;
+	}
+	user_reply = (char *)arg + fibsize;
+	if (srbcmd->sg_map.SgCount == 1) 
+		transfer_data = 1;
+
+	if (transfer_data) {
+		/*
+		 * Create DMA tag for the passthr. data buffer and allocate it.
+		 */
+		if (bus_dma_tag_create(sc->aac_parent_dmat, 	/* parent */
+				1, 0,			/* algnmnt, boundary */
+				(sc->flags & AAC_FLAGS_SG_64BIT) ?
+				BUS_SPACE_MAXADDR_32BIT :
+				0x7fffffff,		/* lowaddr */
+				BUS_SPACE_MAXADDR, 	/* highaddr */
+				NULL, NULL, 		/* filter, filterarg */
+				srb_sg_bytecount, 	/* size */
+				sc->aac_sg_tablesize,	/* nsegments */
+				srb_sg_bytecount, 	/* maxsegsize */
+				0,			/* flags */
+				NULL, NULL,		/* No locking needed */
+				&cm->cm_passthr_dmat)) {
+	                device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
+			error = ENOMEM;
+			goto out;
+		}
+		if (bus_dmamem_alloc(cm->cm_passthr_dmat, (void **)&cm->cm_data,
+			BUS_DMA_NOWAIT, &cm->cm_datamap)) {
+	                device_printf(sc->aac_dev, "can't allocate common structure\n")
+			error = ENOMEM;
+			goto out;
+		}
+		/* fill some cm variables */
+		cm->cm_datalen = srb_sg_bytecount;
+		if (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN) 
+			cm->cm_flags |= AAC_CMD_DATAIN;
+		if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT)
+			cm->cm_flags |= AAC_CMD_DATAOUT;
+
+		if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT) {
+			if ((error = copyin(
+#ifdef __amd64__
+					    (void *)srb_sg_address,
+#else
+					    (void *)(u_int32_t)srb_sg_address,
+#endif
+					    cm->cm_data, cm->cm_datalen)) != 0)
+				goto out;
+			/* sync required for bus_dmamem_alloc() alloc. mem.? */
+			bus_dmamap_sync(cm->cm_passthr_dmat, cm->cm_datamap,
+			    BUS_DMASYNC_PREWRITE);
+		}
+	}
+
+	/* build the FIB */
+	fib->Header.Size = sizeof(struct aac_fib_header) + 
+	    sizeof(struct aac_srb);
+	fib->Header.XferState =
+	    AAC_FIBSTATE_HOSTOWNED	|
+	    AAC_FIBSTATE_INITIALISED	|
+	    AAC_FIBSTATE_EMPTY		|
+	    AAC_FIBSTATE_FROMHOS	|
+	    AAC_FIBSTATE_REXPECTED	|
+	    AAC_FIBSTATE_NORM		|
+	    AAC_FIBSTATE_ASYNC		|
+	    AAC_FIBSTATE_FAST_RESPONSE;
+
+	fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) ? 
+	    ScsiPortCommandU64 : ScsiPortCommand;
+	cm->cm_sgtable = (struct aac_sg_table *)&srbcmd->sg_map;
+
+	/* send command */
+	if (transfer_data) {
+		bus_dmamap_load(cm->cm_passthr_dmat,
+		    cm->cm_datamap, cm->cm_data,
+		    cm->cm_datalen,
+		    aac_map_command_sg, cm, 0);
+	} else {
+		aac_map_command_sg(cm, NULL, 0, 0);
+	}
+
+	/* wait for completion */
+	mtx_lock(&sc->aac_io_lock);
+	while (!(cm->cm_flags & AAC_CMD_COMPLETED))
+		msleep(cm, &sc->aac_io_lock, 0, "sndrw2", 0);
+	mtx_unlock(&sc->aac_io_lock);
+
+	/* copy data */
+	if (transfer_data && (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN)) {
+		if ((error = copyout(cm->cm_data, 
+#ifdef __amd64__
+				    (void *)srb_sg_address,
+#else
+				    (void *)(u_int32_t)srb_sg_address,
+#endif
+				    cm->cm_datalen)) != 0)
+			goto out;
+		/* sync required for bus_dmamem_alloc() allocated mem.? */
+		bus_dmamap_sync(cm->cm_passthr_dmat, cm->cm_datamap,
+				BUS_DMASYNC_POSTREAD);
+	}
+
+	/* status */
+	error = copyout(fib->data, user_reply, sizeof(struct aac_srb_response));
+
+out:
+	if (cm && cm->cm_data) {
+		if (transfer_data)
+			bus_dmamap_unload(cm->cm_passthr_dmat, cm->cm_datamap);
+		bus_dmamem_free(cm->cm_passthr_dmat, cm->cm_data, cm->cm_datamap);
+		cm->cm_datamap = orig_map;
+	}
+	if (cm && cm->cm_passthr_dmat) 
+		bus_dma_tag_destroy(cm->cm_passthr_dmat);
+	if (cm) { 
+		mtx_lock(&sc->aac_io_lock);
+		aac_release_command(cm);
+		mtx_unlock(&sc->aac_io_lock);
+	}
+	return(error);
 }
 
 /*
@@ -3176,8 +3430,10 @@
 				 */
 				if ((mir = aac_get_container_info(sc, fib, i)) == NULL)
 					continue;
-				if (i == 0)
+
+				if (i == 0) { /* the first time */
 					count = mir->MntRespCount;
+				}
 				/*
 				 * Check the container against our list.
 				 * co->co_found was already set to 0 in a
@@ -3278,7 +3534,7 @@
 				ctx->ctx_wrap = 1;
 			else if (current == ctx->ctx_idx && ctx->ctx_wrap)
 				ctx->ctx_idx = next;
-		}	
+		}
 	}
 	sc->aifq_idx = next;
 	/* On the off chance that someone is sleeping for an aif... */
@@ -3321,10 +3577,16 @@
 	 * Doctor up the response struct.
 	 */
 	rev_check_resp.possiblyCompatible = 1;
-	rev_check_resp.adapterSWRevision.external.ul =
-	    sc->aac_revision.external.ul;
+	rev_check_resp.adapterSWRevision.external.comp.major =
+	    AAC_DRIVER_MAJOR_VERSION;
+	rev_check_resp.adapterSWRevision.external.comp.minor =
+	    AAC_DRIVER_MINOR_VERSION;
+	rev_check_resp.adapterSWRevision.external.comp.type =
+	    AAC_DRIVER_TYPE;
+	rev_check_resp.adapterSWRevision.external.comp.dash =
+	    AAC_DRIVER_BUGFIX_LEVEL;
 	rev_check_resp.adapterSWRevision.buildNumber =
-	    sc->aac_revision.buildNumber;
+	    (u_int32_t)AAC_DRIVER_BUILD;
 
 	return(copyout((caddr_t)&rev_check_resp, udata,
 			sizeof(struct aac_rev_check_resp)));
@@ -3357,7 +3619,7 @@
 	}
 
 	/* evaluate unique value */
-	fibctx->unique = (*(u_int32_t *)&fibctx & 0xffffffff);
+	fibctx->unique = *(u_int32_t *)&fibctx;
 	ctx = sc->fibctx;
 	while (ctx != fibctx) {
 		if (ctx->unique == fibctx->unique) {
@@ -3438,7 +3700,7 @@
 			sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
 		}
 	}
-	return(error);
+	return (error);
 }
 
 /*
@@ -3468,7 +3730,7 @@
 		ctx->ctx_idx = (current + 1) % AAC_AIFQ_LENGTH;
 	}
 	mtx_unlock(&sc->aac_aifq_lock);
-	return(error);
+	return (error);
 }
 
 static int
@@ -3513,7 +3775,7 @@
 	 * associated with the feature in the data field or perform whatever
 	 * action needed indicates in the data field.
 	 */
-	 if (f.feat.fValue == 0) {
+	if (f.feat.fValue == 0) {
 		f.feat.fBits.largeLBA =
 		    (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
 		/* TODO: In the future, add other features state here as well */
@@ -3700,3 +3962,161 @@
 
 	return;
 }
+
+/*
+ * Check to see if the kernel is up and running. If we are in a
+ * BlinkLED state, return the BlinkLED code.
+ */
+static u_int32_t
+aac_check_adapter_health(struct aac_softc *sc, u_int8_t *bled)
+{
+	u_int32_t ret;
+
+	ret = AAC_GET_FWSTATUS(sc);
+
+	if (ret & AAC_UP_AND_RUNNING)
+		ret = 0;
+	else if (ret & AAC_KERNEL_PANIC && bled)
+		*bled = (ret >> 16) & 0xff;
+
+	return (ret);
+}
+
+/*
+ * Once do an IOP reset, basically have to re-initialize the card as
+ * if coming up from a cold boot, and the driver is responsible for
+ * any IO that was outstanding to the adapter at the time of the IOP
+ * RESET. And prepare the driver for IOP RESET by making the init code
+ * modular with the ability to call it from multiple places.
+ */
+static int
+aac_reset_adapter(struct aac_softc *sc)
+{
+	struct aac_command *cm;
+	u_int32_t status, old_flags;
+
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+	if (sc->aac_state & AAC_STATE_RESET) {
+		device_printf(sc->aac_dev, "aac_reset_adapter() already in progress\n");
+		return (EINVAL);
+	}
+	sc->aac_state |= AAC_STATE_RESET;
+
+	/* disable interrupt */
+	AAC_MASK_INTERRUPTS(sc);
+
+	/*
+	 * Abort all pending commands:
+	 * a) on the controller
+	 */
+	while ((cm = aac_dequeue_busy(sc)) != NULL) {
+		cm->cm_flags |= AAC_CMD_RESET;
+
+		/* is there a completion handler? */
+		if (cm->cm_complete != NULL) {
+			cm->cm_complete(cm);
+		} else {
+			/*
+			 * Assume that someone is sleeping on this
+			 * command.
+			 */
+			wakeup(cm);
+		}
+	}
+
+	/* b) in the waiting queues */
+	while ((cm = aac_dequeue_ready(sc)) != NULL) {
+		cm->cm_flags |= AAC_CMD_RESET;
+
+		/* is there a completion handler? */
+		if (cm->cm_complete != NULL) {
+			cm->cm_complete(cm);
+		} else {
+			/*
+			 * Assume that someone is sleeping on this
+			 * command.
+			 */
+			wakeup(cm);
+		}
+	}
+
+	/* flush drives */
+	if (aac_check_adapter_health(sc, NULL) == 0)
+		(void) aac_shutdown(sc->aac_dev);
+
+	/* execute IOP reset */
+	if ((aac_sync_command(sc, AAC_IOP_RESET, 0, 0, 0, 0, &status)) != 0) {
+		struct aac_fib *fib;
+		struct aac_pause_command *pc;
+		u_int32_t waitCount;
+
+		if ((status & 0xf) == 0xf) {
+
+			/* Sunrise Lake has dual cores and we must drag the other core
+			 * with us to reset simultaneously. There are 2 bits in the
+			 * Inbound Reset Control and Status Register (offset 0x38) of the
+			 * Sunrise Lake to reset the chip without clearing out the
+			 * PCI configuration info (COMMAND & BARS).
+			 */
+			AAC_MEM0_SETREG4(sc, AAC_IRCSR, AAC_IRCSR_CORES_RST);
+
+			/* We need to wait for 5 seconds before accessing the MU again
+			 * 10000 * 100us = 1000,000us = 1000ms = 1s
+			 */
+			waitCount = 5 * 10000;
+			while (waitCount) {
+				DELAY(100);			/* delay 100 microseconds */
+				waitCount--;
+			}
+		} else {
+			if (status == AAC_SRB_STS_INVALID_REQUEST)
+				device_printf(sc->aac_dev, "IOP_RESET not supported\n");
+			else
+				/* probably timeout */
+				device_printf(sc->aac_dev, "IOP_RESET failed\n");
+
+			/* unwind aac_shutdown() */
+			aac_alloc_sync_fib(sc, &fib);
+			pc = (struct aac_pause_command *)&fib->data[0];
+			pc->Command = VM_ContainerConfig;
+			pc->Type = CT_PAUSE_IO;
+			pc->Timeout = 1;
+			pc->Min = 1;
+			pc->NoRescan = 1;
+
+			(void) aac_sync_fib(sc, ContainerCommand, 0, fib,
+				sizeof (struct aac_pause_command));
+			aac_release_sync_fib(sc);
+
+			goto finish;
+		}
+	}
+
+	/*
+	 * Re-read and renegotiate the FIB parameters, as one of the actions
+	 * that can result from an IOP reset is the running of a new firmware
+	 * image.
+	 */
+	old_flags = sc->flags;
+
+	/*
+	 * Initialize the adapter.
+	 */
+	if (aac_check_firmware(sc) != 0)
+		goto finish;
+	if (aac_init(sc) != 0)
+		goto finish;
+
+	if ((old_flags & AAC_FLAGS_NEW_COMM) &&
+		!(sc->flags & AAC_FLAGS_NEW_COMM)) {
+		/* remap interrupt handler */
+		aac_setup_intr(sc);
+	}
+
+finish:
+	sc->aac_state &= ~AAC_STATE_RESET;
+	AAC_UNMASK_INTERRUPTS(sc);
+	aac_startio(sc);
+	return (0);
+}
diff -uN /media/cvs-cur/src/sys/dev/aac/aac_cam.c ./aac_cam.c
--- /media/cvs-cur/src/sys/dev/aac/aac_cam.c	2008-03-24 22:23:33.000000000 +0300
+++ ./aac_cam.c	2008-10-17 01:30:20.000000000 +0400
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/aac/aac_cam.c,v 1.31 2008/03/24 19:23:33 emaste Exp $");
+__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_cam.c,v 1.26 2007/01/15 16:22:20 scottl Exp $");
 
 /*
  * CAM front-end for communicating with non-DASD devices
@@ -61,6 +61,7 @@
 
 #include <dev/aac/aacreg.h>
 #include <sys/aac_ioctl.h>
+#include <dev/aac/aac_fwdb.h>
 #include <dev/aac/aacvar.h>
 
 struct aac_cam {
@@ -211,7 +212,7 @@
 {
 	struct	aac_cam *camsc;
 	struct	aac_softc *sc;
-	struct	aac_srb32 *srb;
+	struct	aac_srb *srb;
 	struct	aac_fib *fib;
 	struct	aac_command *cm;
 
@@ -272,30 +273,15 @@
 		strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN);
 		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
 		cpi->unit_number = cam_sim_unit(sim);
-                cpi->transport = XPORT_SPI;
-                cpi->transport_version = 2;
-                cpi->protocol = PROTO_SCSI;
-                cpi->protocol_version = SCSI_REV_2;
+
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_done(ccb);
 		return;
 	}
 	case XPT_GET_TRAN_SETTINGS:
 	{
-		struct ccb_trans_settings_scsi *scsi =
-			&ccb->cts.proto_specific.scsi;
-		struct ccb_trans_settings_spi *spi =
-			&ccb->cts.xport_specific.spi;
-		ccb->cts.protocol = PROTO_SCSI;
-		ccb->cts.protocol_version = SCSI_REV_2;
-		ccb->cts.transport = XPORT_SPI;
-		ccb->cts.transport_version = 2;
-		if (ccb->ccb_h.target_lun != CAM_LUN_WILDCARD) {
-			scsi->valid = CTS_SCSI_VALID_TQ;
-			spi->valid |= CTS_SPI_VALID_DISC;
-		} else {
-			scsi->valid = 0;
-		}
+		ccb->cts.flags &= ~(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB);
+		ccb->cts.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
 		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_done(ccb);
 		return;
@@ -351,7 +337,7 @@
 	}
 
 	fib = cm->cm_fib;
-	srb = (struct aac_srb32 *)&fib->data[0];
+	srb = (struct aac_srb *)&fib->data[0];
 	cm->cm_datalen = 0;
 
 	switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
@@ -402,10 +388,10 @@
 				if (ccb->ccb_h.flags & CAM_DATA_PHYS) {
 					/* Send a 32bit command */
 					fib->Header.Command = ScsiPortCommand;
-					srb->sg_map32.SgCount = 1;
-					srb->sg_map32.SgEntry[0].SgAddress =
+					srb->sg_map.SgCount = 1;
+					srb->sg_map.SgEntry[0].SgAddress =
 					    (uint32_t)(uintptr_t)csio->data_ptr;
-					srb->sg_map32.SgEntry[0].SgByteCount =
+					srb->sg_map.SgEntry[0].SgByteCount =
 					    csio->dxfer_len;
 				} else {
 					/*
@@ -414,15 +400,15 @@
 					 */
 					cm->cm_data = (void *)csio->data_ptr;
 					cm->cm_datalen = csio->dxfer_len;
-					cm->cm_sgtable = &srb->sg_map32;
+					cm->cm_sgtable = &srb->sg_map;
 				}
 			} else {
 				/* XXX Need to handle multiple s/g elements */
 				panic("aac_cam: multiple s/g elements");
 			}
 		} else {
-			srb->sg_map32.SgCount = 0;
-			srb->sg_map32.SgEntry[0].SgByteCount = 0;
+			srb->sg_map.SgCount = 0;
+			srb->sg_map.SgEntry[0].SgByteCount = 0;
 			srb->data_len = 0;
 		}
 
@@ -450,7 +436,6 @@
 	cm->cm_complete = aac_cam_complete;
 	cm->cm_private = ccb;
 	cm->cm_timestamp = time_uptime;
-	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
 
 	fib->Header.XferState =
 	    AAC_FIBSTATE_HOSTOWNED	|
@@ -459,7 +444,7 @@
 	    AAC_FIBSTATE_REXPECTED	|
 	    AAC_FIBSTATE_NORM;
 	fib->Header.Size = sizeof(struct aac_fib_header) +
-	    sizeof(struct aac_srb32);
+	    sizeof(struct aac_srb);
 
 	aac_enqueue_ready(cm);
 	aac_startio(cm->cm_sc);
@@ -488,7 +473,9 @@
 	ccb = cm->cm_private;
 	srbr = (struct aac_srb_response *)&cm->cm_fib->data[0];
 
-	if (srbr->fib_status != 0) {
+	if (cm->cm_flags & AAC_CMD_RESET) {
+		ccb->ccb_h.status = CAM_SCSI_BUS_RESET;
+	} else if (srbr->fib_status != 0) {
 		device_printf(sc->aac_dev, "Passthru FIB failed!\n");
 		ccb->ccb_h.status = CAM_REQ_ABORTED;
 	} else {
@@ -528,16 +515,16 @@
 
 			if (command == INQUIRY) {
 				if (ccb->ccb_h.status == CAM_REQ_CMP) {
-				device = ccb->csio.data_ptr[0] & 0x1f;
-				/*
-				 * We want DASD and PROC devices to only be
-				 * visible through the pass device.
-				 */
-				if ((device == T_DIRECT) ||
-				    (device == T_PROCESSOR) ||
-				    (sc->flags & AAC_FLAGS_CAM_PASSONLY))
-					ccb->csio.data_ptr[0] =
-					    ((device & 0xe0) | T_NODEVICE);
+					device = ccb->csio.data_ptr[0] & 0x1f;
+					/*
+					 * We want DASD and PROC devices to only be
+					 * visible through the pass device.
+					 */
+					if ((device == T_DIRECT) ||
+						(device == T_PROCESSOR) ||
+						(sc->flags & AAC_FLAGS_CAM_PASSONLY))
+						ccb->csio.data_ptr[0] =
+							((device & 0xe0) | T_NODEVICE);
 				} else if (ccb->ccb_h.status == CAM_SEL_TIMEOUT &&
 					ccb->ccb_h.target_lun != 0) {
 					/* fix for INQUIRYs on Lun>0 */
diff -uN /media/cvs-cur/src/sys/dev/aac/aac_debug.c ./aac_debug.c
--- /media/cvs-cur/src/sys/dev/aac/aac_debug.c	2008-03-24 22:23:33.000000000 +0300
+++ ./aac_debug.c	2008-10-17 01:34:17.000000000 +0400
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/aac/aac_debug.c,v 1.24 2008/03/24 19:23:33 emaste Exp $");
+__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_debug.c,v 1.20.2.2 2006/01/30 17:56:07 scottl Exp $");
 
 /*
  * Debugging support.
@@ -47,10 +47,10 @@
 
 #include <dev/aac/aacreg.h>
 #include <sys/aac_ioctl.h>
+#include <dev/aac/aac_fwdb.h>
 #include <dev/aac/aacvar.h>
 
 #ifdef AAC_DEBUG
-int	aac_debug_enable = 0;
 void	aac_printstate0(void);
 
 /*
@@ -135,16 +135,16 @@
 	switch (sc->aac_hwif) {
 	case AAC_HWIF_I960RX:
 		device_printf(sc->aac_dev, "IDBR 0x%08x  IIMR 0x%08x  "
-		    "IISR 0x%08x\n", AAC_GETREG4(sc, AAC_RX_IDBR),
-		    AAC_GETREG4(sc, AAC_RX_IIMR), AAC_GETREG4(sc, AAC_RX_IISR));
+		    "IISR 0x%08x\n", AAC_MEM0_GETREG4(sc, AAC_RX_IDBR),
+		    AAC_MEM0_GETREG4(sc, AAC_RX_IIMR), AAC_MEM0_GETREG4(sc, AAC_RX_IISR));
 		device_printf(sc->aac_dev, "ODBR 0x%08x  OIMR 0x%08x  "
-		    "OISR 0x%08x\n", AAC_GETREG4(sc, AAC_RX_ODBR),
-		    AAC_GETREG4(sc, AAC_RX_OIMR), AAC_GETREG4(sc, AAC_RX_OISR));
-		AAC_SETREG4(sc, AAC_RX_OIMR, 0/*~(AAC_DB_COMMAND_READY |
+		    "OISR 0x%08x\n", AAC_MEM0_GETREG4(sc, AAC_RX_ODBR),
+		    AAC_MEM0_GETREG4(sc, AAC_RX_OIMR), AAC_MEM0_GETREG4(sc, AAC_RX_OISR));
+		AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, 0/*~(AAC_DB_COMMAND_READY |
 			    AAC_DB_RESPONSE_READY | AAC_DB_PRINTF)*/);
 		device_printf(sc->aac_dev, "ODBR 0x%08x  OIMR 0x%08x  "
-		    "OISR 0x%08x\n", AAC_GETREG4(sc, AAC_RX_ODBR),
-		    AAC_GETREG4(sc, AAC_RX_OIMR), AAC_GETREG4(sc, AAC_RX_OISR));
+		    "OISR 0x%08x\n", AAC_MEM0_GETREG4(sc, AAC_RX_ODBR),
+		    AAC_MEM0_GETREG4(sc, AAC_RX_OIMR), AAC_MEM0_GETREG4(sc, AAC_RX_OISR));
 		break;
 	case AAC_HWIF_STRONGARM:
 		/* XXX implement */
diff -uN /media/cvs-cur/src/sys/dev/aac/aac_disk.c ./aac_disk.c
--- /media/cvs-cur/src/sys/dev/aac/aac_disk.c	2008-04-04 03:29:31.000000000 +0400
+++ ./aac_disk.c	2008-10-17 01:43:32.000000000 +0400
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/aac/aac_disk.c,v 1.46 2008/04/03 23:29:31 emaste Exp $");
+__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_disk.c,v 1.43 2005/05/02 22:56:52 scottl Exp $");
 
 #include "opt_aac.h"
 
@@ -51,6 +51,7 @@
 
 #include <dev/aac/aacreg.h>
 #include <sys/aac_ioctl.h>
+#include <dev/aac/aac_fwdb.h>
 #include <dev/aac/aacvar.h>
 
 /*
@@ -183,6 +184,9 @@
 
 /*
  * Map the S/G elements for doing a dump.
+ *
+ * XXX This does not handle >4GB of RAM.  Fixing it is possible except on
+ *     adapters that cannot do 64bit s/g lists.
  */
 static void
 aac_dump_map_sg(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
@@ -209,31 +213,6 @@
 }
 
 /*
- * Map the S/G elements for doing a dump on 64-bit capable devices.
- */
-static void
-aac_dump_map_sg64(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
-{
-	struct aac_fib *fib;
-	struct aac_blockwrite64 *bw;
-	struct aac_sg_table64 *sg;
-	int i;
-
-	fib = (struct aac_fib *)arg;
-	bw = (struct aac_blockwrite64 *)&fib->data[0];
-	sg = &bw->SgMap64;
-
-	if (sg != NULL) {
-		sg->SgCount = nsegs;
-		for (i = 0; i < nsegs; i++) {
-			sg->SgEntry64[i].SgAddress = segs[i].ds_addr;
-			sg->SgEntry64[i].SgByteCount = segs[i].ds_len;
-		}
-		fib->Header.Size = nsegs * sizeof(struct aac_sg_entry64);
-	}
-}
-
-/*
  * Dump memory out to an array
  *
  * Send out one command at a time with up to AAC_MAXIO of data.
@@ -244,13 +223,12 @@
 	struct aac_disk *ad;
 	struct aac_softc *sc;
 	struct aac_fib *fib;
+	struct aac_blockwrite *bw;
 	size_t len;
 	int size;
 	static bus_dmamap_t dump_datamap;
 	static int first = 0;
 	struct disk *dp;
-	bus_dmamap_callback_t *callback;
-	u_int32_t command;
 
 	dp = arg;
 	ad = dp->d_drv1;
@@ -270,33 +248,15 @@
 
 	/* Skip aac_alloc_sync_fib().  We don't want to mess with sleep locks */
 	fib = &sc->aac_common->ac_sync_fib;
+	bw = (struct aac_blockwrite *)&fib->data[0];
 
 	while (length > 0) {
 		len = (length > AAC_MAXIO) ? AAC_MAXIO : length;
-		if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
-			struct aac_blockwrite *bw;
-			bw = (struct aac_blockwrite *)&fib->data[0];
-			bw->Command = VM_CtBlockWrite;
-			bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
-			bw->BlockNumber = offset / AAC_BLOCK_SIZE;
-			bw->ByteCount = len;
-			bw->Stable = CUNSTABLE;
-			command = ContainerCommand;
-			callback = aac_dump_map_sg;
-			size = sizeof(struct aac_blockwrite);
-		} else {
-			struct aac_blockwrite64 *bw;
-			bw = (struct aac_blockwrite64 *)&fib->data[0];
-			bw->Command = VM_CtHostWrite64;
-			bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
-			bw->BlockNumber = offset / AAC_BLOCK_SIZE;
-			bw->SectorCount = len / AAC_BLOCK_SIZE;
-			bw->Pad = 0;
-			bw->Flags = 0;
-			command = ContainerCommand64;
-			callback = aac_dump_map_sg64;
-			size = sizeof(struct aac_blockwrite64);
-		}
+		bw->Command = VM_CtBlockWrite;
+		bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
+		bw->BlockNumber = offset / AAC_BLOCK_SIZE;
+		bw->ByteCount = len;
+		bw->Stable = CUNSTABLE;
 
 		/*
 		 * There really isn't any way to recover from errors or
@@ -305,16 +265,16 @@
 		 * is too much required context.
 		 */
 		if (bus_dmamap_load(sc->aac_buffer_dmat, dump_datamap, virtual,
-		    len, callback, fib, BUS_DMA_NOWAIT) != 0)
+		    len, aac_dump_map_sg, fib, BUS_DMA_NOWAIT) != 0)
 			return (ENOMEM);
 
 		bus_dmamap_sync(sc->aac_buffer_dmat, dump_datamap,
 		    BUS_DMASYNC_PREWRITE);
 
 		/* fib->Header.Size is set in aac_dump_map_sg */
-		size += fib->Header.Size;
+		size = fib->Header.Size + sizeof(struct aac_blockwrite);
 
-		if (aac_sync_fib(sc, command, 0, fib, size)) {
+		if (aac_sync_fib(sc, ContainerCommand, 0, fib, size)) {
 			printf("Error dumping block 0x%jx\n",
 			       (uintmax_t)physical);
 			return (EIO);
@@ -383,8 +343,8 @@
 	 * require that extended translation be enabled - other drivers read the
 	 * disk!
 	 */
-	sc->ad_size = sc->ad_container->co_mntobj.Capacity;
-	if (sc->ad_controller->flags & AAC_FLAGS_LBA_64BIT)
+	sc->ad_size = (u_int64_t)sc->ad_container->co_mntobj.Capacity;
+	if (sc->ad_controller->flags & AAC_FLAGS_LBA_64BIT) /* 64-bit LBA */
 		sc->ad_size += (u_int64_t)
 			sc->ad_container->co_mntobj.CapacityHigh << 32;
 	if (sc->ad_size >= (2 * 1024 * 1024)) {		/* 2GB */
@@ -399,9 +359,9 @@
 	}
 	sc->ad_cylinders = (sc->ad_size / (sc->ad_heads * sc->ad_sectors));
 
-	device_printf(dev, "%juMB (%ju sectors)\n",
-		      (intmax_t)sc->ad_size / ((1024 * 1024) / AAC_BLOCK_SIZE),
-		      (intmax_t)sc->ad_size);
+	device_printf(dev, "%lluMB (%llu sectors)\n",
+		      (unsigned long long)sc->ad_size / ((1024 * 1024) / AAC_BLOCK_SIZE),
+		      (unsigned long long)sc->ad_size);
 
 	/* attach a generic disk device to ourselves */
 	sc->unit = device_get_unit(dev);
diff -uN /media/cvs-cur/src/sys/dev/aac/aac_fwdb.c ./aac_fwdb.c
--- /media/cvs-cur/src/sys/dev/aac/aac_fwdb.c	1970-01-01 03:00:00.000000000 +0300
+++ ./aac_fwdb.c	2008-09-07 04:26:20.000000000 +0400
@@ -0,0 +1,316 @@
+
+/*-
+ * Copyright (c) 2006 Adaptec Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+
+#include <sys/bus.h>
+
+#include <machine/resource.h>
+#include <machine/bus.h>
+
+#include <dev/aac/aacreg.h>
+#include <sys/aac_ioctl.h>
+#include <dev/aac/aacvar.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+
+#include <sys/bus.h>
+#include <sys/rman.h>
+
+#include <machine/resource.h>
+#include <machine/bus.h>
+#include <machine/stdarg.h>
+
+#include <dev/aac/aac_fwdb.h>
+
+/*
+ * Debug flags to be put into the HBA flags field when initialized
+ */
+const unsigned long aac_debug_flags = /* Variable to setup with above flags. */
+/*			HBA_FLAGS_DBG_KERNEL_PRINT_B |		*/
+			HBA_FLAGS_DBG_FW_PRINT_B |
+/*			HBA_FLAGS_DBG_FUNCTION_ENTRY_B |	*/
+			HBA_FLAGS_DBG_FUNCTION_EXIT_B |
+			HBA_FLAGS_DBG_ERROR_B |
+			HBA_FLAGS_DBG_INIT_B |			
+/*			HBA_FLAGS_DBG_OS_COMMANDS_B |		*/
+/*			HBA_FLAGS_DBG_SCAN_B |			*/
+/*			HBA_FLAGS_DBG_COALESCE_B |		*/
+/*			HBA_FLAGS_DBG_IOCTL_COMMANDS_B |	*/
+/*			HBA_FLAGS_DBG_SYNC_COMMANDS_B |		*/
+			HBA_FLAGS_DBG_COMM_B |			
+/*			HBA_FLAGS_DBG_AIF_B |			*/
+/*			HBA_FLAGS_DBG_CSMI_COMMANDS_B | 	*/
+/*			HBA_FLAGS_DBG_FLAGS_MASK | 		*/
+0;
+
+int aac_get_fw_debug_buffer(struct aac_softc *sc)
+{
+	u_int32_t MonDriverBufferPhysAddrLow = 0;
+	u_int32_t MonDriverBufferPhysAddrHigh = 0;
+	u_int32_t MonDriverBufferSize = 0;
+	u_int32_t MonDriverHeaderSize = 0;
+
+	/*
+	 * Get the firmware print buffer parameters from the firmware
+	 * If the command was successful map in the address.
+	 */
+	if (!aac_sync_command(sc, AAC_MONKER_GETDRVPROP, 0, 0, 0, 0, NULL)) {
+		MonDriverBufferPhysAddrLow = AAC_GET_MAILBOX(sc, 1);
+		MonDriverBufferPhysAddrHigh = AAC_GET_MAILBOX(sc, 2);
+		MonDriverBufferSize = AAC_GET_MAILBOX(sc, 3);
+		MonDriverHeaderSize = AAC_GET_MAILBOX(sc, 4); 
+		if (MonDriverBufferSize) {
+			unsigned long Offset = MonDriverBufferPhysAddrLow
+				- rman_get_start(sc->aac_regs_res1);
+
+			/*
+			 * See if the address is already mapped in and if so set it up
+			 * from the base address
+			 */
+			if ((MonDriverBufferPhysAddrHigh == 0) && 
+				(Offset + MonDriverBufferSize < 
+				rman_get_size(sc->aac_regs_res1))) {
+				sc->DebugOffset = Offset;
+				sc->DebugHeaderSize = MonDriverHeaderSize;
+				sc->FwDebugBufferSize = MonDriverBufferSize;
+				sc->FwDebugFlags = 0;
+				sc->DebugFlags = aac_debug_flags;
+				return 1;
+			}
+		}
+	}
+
+	/*
+	 * The GET_DRIVER_BUFFER_PROPERTIES command failed
+	 */
+	return 0;
+}
+
+#define PRINT_TIMEOUT 250000 /* 1/4 second */
+
+void aac_fw_printf(struct aac_softc *sc, unsigned long PrintFlags, const char * fmt, ...)
+{
+	va_list args;
+	u_int32_t Count, i;
+	char PrintBuffer_P[PRINT_BUFFER_SIZE];
+	unsigned long PrintType;
+
+	PrintType = PrintFlags & 
+		~(HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B);
+	if (((PrintType!=0) && (sc!=NULL) && ((sc->DebugFlags & PrintType)==0))
+		|| ((sc!=NULL) && (sc->DebugFlags
+		& (HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B)) == 0))
+		return;
+
+	/*
+	 * Set up parameters and call sprintf function to format the data
+	 */
+	va_start(args, fmt);
+	vsprintf(PrintBuffer_P, fmt, args);
+	va_end(args);
+
+	/*
+	 * Make sure the HBA structure has been passed in for this section
+	 */
+	if ((sc != NULL) && (sc->FwDebugBufferSize)) {
+		/*
+		 * If we are set up for a Firmware print
+		 */
+		if ((sc->DebugFlags & HBA_FLAGS_DBG_FW_PRINT_B)
+			&& ((PrintFlags
+			& (HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B))
+			!= HBA_FLAGS_DBG_KERNEL_PRINT_B)) {
+			/*
+			 * Make sure the string size is within boundaries
+			 */
+			Count = strlen(PrintBuffer_P);
+			if (Count > sc->FwDebugBufferSize)
+				Count = (u_int16_t)sc->FwDebugBufferSize;
+
+			/*
+			 * Wait for no more than PRINT_TIMEOUT for the previous
+			 * message length to clear (the handshake).
+			 */
+			for (i = 0; i < PRINT_TIMEOUT; ++i) {
+				if (!AAC_MEM1_GETREG4(sc,
+					sc->DebugOffset + FW_DEBUG_STR_LENGTH_OFFSET)) {
+					break;
+				}
+				DELAY(1);
+            }
+
+			/*
+			 * If the Length is clear, copy over the message, the
+			 * flags, and the length. Make sure the length is the
+			 * last because that is the signal for the Firmware to
+			 * pick it up.
+			 */
+			if (!AAC_MEM1_GETREG4(sc,
+				sc->DebugOffset + FW_DEBUG_STR_LENGTH_OFFSET)) {
+				for (i = 0; i < Count; ++i) {
+					AAC_MEM1_SETREG1(sc, sc->DebugOffset + sc->DebugHeaderSize + i,
+								PrintBuffer_P[i]);
+				}
+				AAC_MEM1_SETREG4(sc, sc->DebugOffset + FW_DEBUG_FLAGS_OFFSET,
+							sc->FwDebugFlags);
+				AAC_MEM1_SETREG4(sc, sc->DebugOffset + FW_DEBUG_STR_LENGTH_OFFSET,
+                            Count);
+			} else
+				sc->DebugFlags &= ~HBA_FLAGS_DBG_FW_PRINT_B;
+		}
+
+		/*
+		 * If the Kernel Debug Print flag is set, send it off to the
+		 * Kernel debugger
+		 */
+		if ((sc->DebugFlags & HBA_FLAGS_DBG_KERNEL_PRINT_B)
+			&& ((PrintFlags
+			& (HBA_FLAGS_DBG_KERNEL_PRINT_B|HBA_FLAGS_DBG_FW_PRINT_B))
+			!= HBA_FLAGS_DBG_FW_PRINT_B)) {
+			if (sc->FwDebugFlags & FW_DEBUG_FLAGS_NO_HEADERS_B)
+				printf ("%s\n", PrintBuffer_P);
+			else
+				device_printf (sc->aac_dev, "%s\n", PrintBuffer_P);
+		}
+
+	} else {
+		/*
+		 * No HBA structure passed in so it has to be for the Kernel Debugger
+		 */
+		if ((sc != NULL) && (sc->FwDebugFlags & FW_DEBUG_FLAGS_NO_HEADERS_B))
+			printf ("%s\n", PrintBuffer_P);
+		else if (sc != NULL)
+			device_printf (sc->aac_dev, "%s\n", PrintBuffer_P);
+		else
+			printf("%s\n", PrintBuffer_P);
+	}
+}
+
+void aac_fw_print_mem(struct aac_softc *sc, unsigned long PrintFlags, u_int8_t *Addr, int Count)
+{
+	int Offset, i;
+	u_int32_t DebugFlags = 0;
+	char Buffer[100];
+	char *LineBuffer_P;
+
+	/*
+	 * If we have an HBA structure, save off the flags and set the no
+	 * headers flag so we don't have garbage between our lines of data
+	 */
+	if (sc != NULL) {
+		DebugFlags = sc->FwDebugFlags;
+		sc->FwDebugFlags |= FW_DEBUG_FLAGS_NO_HEADERS_B;
+	}
+
+	Offset = 0;
+
+	/*
+	 * Loop through all the data
+	 */
+	while (Offset < Count) {
+		/*
+		 * We will format each line into a buffer and then print out
+		 * the entire line so set the pointer to the beginning of the
+		 * buffer
+		 */
+		LineBuffer_P = Buffer;
+
+		/*
+		 * Set up the address in HEX
+		 */
+		sprintf(LineBuffer_P, "\n%04x  ", Offset);
+		LineBuffer_P += 6;
+
+		/*
+		 * Set up 16 bytes in HEX format
+		 */
+		for (i = 0; i < 16; ++i) {
+			/*
+			 * If we are past the count of data bytes to output,
+			 * pad with blanks
+			 */
+			sprintf (LineBuffer_P,
+			  (((Offset + i) >= Count) ? "   " : "%02x "),
+			  Addr[Offset + i]);
+			LineBuffer_P += 3;
+
+			/*
+			 * At the mid point we will put in a divider
+			 */
+			if (i == 7) {
+				sprintf (LineBuffer_P, "- ");
+				LineBuffer_P += 2;
+			}
+		}
+		/*
+		 * Now do the same 16 bytes at the end of the line in ASCII
+		 * format
+		 */
+		sprintf (LineBuffer_P, "  ");
+		LineBuffer_P += 2;
+		for (i = 0; i < 16; ++i) {
+			/*
+			 * If all data processed, OUT-O-HERE
+			 */
+			if ((Offset + i) >= Count)
+				break;
+
+			/*
+			 * If this is a printable ASCII character, convert it
+			 */
+			sprintf (LineBuffer_P, 
+				(((Addr[Offset + i] > 0x1F) && (Addr[Offset + i] < 0x7F))
+				? "%c" : "."), Addr[Offset + i]);
+
+			++LineBuffer_P;
+		}
+		/*
+		 * The line is now formatted, so print it out
+		 */
+		aac_fw_printf(sc, PrintFlags, "%s", Buffer);
+
+		/*
+		 * Bump the offset by 16 for the next line
+		 */
+		Offset += 16;
+
+	}
+
+	/*
+	 * Restore the saved off flags
+	 */
+	if (sc != NULL)
+		sc->FwDebugFlags = DebugFlags;
+}
+
diff -uN /media/cvs-cur/src/sys/dev/aac/aac_fwdb.h ./aac_fwdb.h
--- /media/cvs-cur/src/sys/dev/aac/aac_fwdb.h	1970-01-01 03:00:00.000000000 +0300
+++ ./aac_fwdb.h	2008-09-07 04:26:20.000000000 +0400
@@ -0,0 +1,34 @@
+#ifndef PRINT_BUFFER_SIZE
+
+#define PRINT_BUFFER_SIZE 512
+
+#define HBA_FLAGS_DBG_FLAGS_MASK 	0x0000ffff
+#define HBA_FLAGS_DBG_KERNEL_PRINT_B 	0x00000001
+#define HBA_FLAGS_DBG_FW_PRINT_B 	0x00000002
+#define HBA_FLAGS_DBG_FUNCTION_ENTRY_B 	0x00000004
+#define HBA_FLAGS_DBG_FUNCTION_EXIT_B 	0x00000008
+#define HBA_FLAGS_DBG_ERROR_B 		0x00000010
+#define HBA_FLAGS_DBG_INIT_B 		0x00000020
+#define HBA_FLAGS_DBG_OS_COMMANDS_B 	0x00000040
+#define HBA_FLAGS_DBG_SCAN_B 		0x00000080
+#define HBA_FLAGS_DBG_COALESCE_B 	0x00000100
+#define HBA_FLAGS_DBG_IOCTL_COMMANDS_B 	0x00000200
+#define HBA_FLAGS_DBG_SYNC_COMMANDS_B 	0x00000400
+#define HBA_FLAGS_DBG_COMM_B 		0x00000800
+#define HBA_FLAGS_DBG_CSMI_COMMANDS_B 	0x00001000
+#define HBA_FLAGS_DBG_AIF_B 		0x00001000
+
+#define FW_DEBUG_STR_LENGTH_OFFSET 	0x00
+#define FW_DEBUG_FLAGS_OFFSET 		0x04
+#define FW_DEBUG_BLED_OFFSET 		0x08
+#define FW_DEBUG_FLAGS_NO_HEADERS_B 	0x01
+
+struct aac_softc;
+extern int aac_get_fw_debug_buffer(struct aac_softc *);
+extern void aac_fw_printf(struct aac_softc *, unsigned long, const char *, ...);
+extern void aac_fw_print_mem(struct aac_softc *, unsigned long, u_int8_t *,int);
+extern int aac_sync_command(struct aac_softc *sc, u_int32_t command,
+				 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
+				 u_int32_t arg3, u_int32_t *sp);
+
+#endif
diff -uN /media/cvs-cur/src/sys/dev/aac/aac_linux.c ./aac_linux.c
--- /media/cvs-cur/src/sys/dev/aac/aac_linux.c	2006-12-20 20:10:53.000000000 +0300
+++ ./aac_linux.c	2008-09-07 04:26:20.000000000 +0400
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/aac/aac_linux.c,v 1.4 2006/12/20 17:10:53 delphij Exp $");
+__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_linux.c,v 1.4 2006/12/20 17:10:53 delphij Exp $");
 
 /*
  * Linux ioctl handler for the aac device driver
diff -uN /media/cvs-cur/src/sys/dev/aac/aac_pci.c ./aac_pci.c
--- /media/cvs-cur/src/sys/dev/aac/aac_pci.c	2008-09-12 22:15:12.000000000 +0400
+++ ./aac_pci.c	2008-10-17 02:00:36.000000000 +0400
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/aac/aac_pci.c,v 1.69 2008/09/12 18:15:12 emaste Exp $");
+__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_pci.c,v 1.54.2.6.2.2 2006/12/21 21:00:47 mjacob Exp $");
 
 /*
  * PCI bus interface and resource allocation.
@@ -55,6 +55,7 @@
 
 #include <dev/aac/aacreg.h>
 #include <sys/aac_ioctl.h>
+#include <dev/aac/aac_fwdb.h>
 #include <dev/aac/aacvar.h>
 
 static int	aac_pci_probe(device_t dev);
@@ -163,13 +164,11 @@
 	{0x9005, 0x0286, 0x9005, 0x029d, AAC_HWIF_RKT, 0,
 	 "Adaptec SATA RAID 2420SA"},
 	{0x9005, 0x0286, 0x9005, 0x029e, AAC_HWIF_RKT, 0,
-	 "ICP ICP9024RO SCSI RAID"},
+	 "ICP9024RO SATA RAID"},
 	{0x9005, 0x0286, 0x9005, 0x029f, AAC_HWIF_RKT, 0,
-	 "ICP ICP9014RO SCSI RAID"},
+	 "ICP9014RO SATA RAID"},
 	{0x9005, 0x0285, 0x9005, 0x0294, AAC_HWIF_I960RX, 0,
 	 "Adaptec SATA RAID 2026ZCR"},
-	{0x9005, 0x0285, 0x103c, 0x3227, AAC_HWIF_I960RX, 0,
-	 "Adaptec SATA RAID 2610SA"},
 	{0x9005, 0x0285, 0x9005, 0x0296, AAC_HWIF_I960RX, 0,
 	 "Adaptec SCSI RAID 2240S"},
 	{0x9005, 0x0285, 0x9005, 0x0297, AAC_HWIF_I960RX, 0,
@@ -179,7 +178,7 @@
 	{0x9005, 0x0285, 0x1014, 0x0312, AAC_HWIF_I960RX, 0,
 	 "IBM ServeRAID 8i"},
 	{0x9005, 0x0285, 0x9005, 0x0298, AAC_HWIF_I960RX, 0,
-	 "Adaptec SAS RAID 4000SAS"},
+	 "Adaptec RAID 4000"},
 	{0x9005, 0x0285, 0x9005, 0x0299, AAC_HWIF_I960RX, 0,
 	 "Adaptec SAS RAID 4800SAS"},
 	{0x9005, 0x0285, 0x9005, 0x029a, AAC_HWIF_I960RX, 0,
@@ -189,13 +188,13 @@
 	{0x9005, 0x0285, 0x9005, 0x028f, AAC_HWIF_I960RX, 0,
 	 "Adaptec SATA RAID 2025SA ZCR"},
 	{0x9005, 0x0285, 0x9005, 0x02a4, AAC_HWIF_I960RX, 0,
-	 "ICP ICP9085LI SAS RAID"},
+	 "ICP 9085LI SAS RAID"},
 	{0x9005, 0x0285, 0x9005, 0x02a5, AAC_HWIF_I960RX, 0,
-	 "ICP ICP5085BR SAS RAID"},
+	 "ICP 5085BR SAS RAID"},
 	{0x9005, 0x0286, 0x9005, 0x02a0, AAC_HWIF_RKT, 0,
-	 "ICP ICP9047MA SATA RAID"},
+	 "ICP9047MA SATA RAID"},
 	{0x9005, 0x0286, 0x9005, 0x02a1, AAC_HWIF_RKT, 0,
-	 "ICP ICP9087MA SATA RAID"},
+	 "ICP9087MA SATA RAID"},
 	{0x9005, 0x0286, 0x9005, 0x02a6, AAC_HWIF_RKT, 0,
 	 "ICP9067MA SATA RAID"},
 	{0x9005, 0x0285, 0x9005, 0x02b5, AAC_HWIF_I960RX, 0,
@@ -255,7 +254,7 @@
 	{0x9005, 0x0285, 0x9005, 0x02d7, AAC_HWIF_I960RX, 0,
 	 "Adaptec RAID 2805"},
 	{0x9005, 0x0286, 0x1014, 0x9580, AAC_HWIF_RKT, 0,
-	 "IBM ServeRAID-8k"},
+	 "IBM ServeRAID 8k"},
 	{0x9005, 0x0285, 0x1014, 0x034d, AAC_HWIF_I960RX, 0,
 	 "IBM ServeRAID 8s"},
 	{0x9005, 0x0285, 0x108e, 0x7aac, AAC_HWIF_I960RX, 0,
@@ -280,6 +279,7 @@
 	 "AOC-USAS-S8iR-LP"},
 	{0, 0, 0, 0, 0, 0, 0}
 };
+
 struct aac_ident
 aac_family_identifiers[] = {
 	{0x9005, 0x0285, 0, 0, AAC_HWIF_I960RX, 0,
@@ -327,7 +327,7 @@
 
 	if ((id = aac_find_ident(dev)) != NULL) {
 		device_set_desc(dev, id->desc);
-		return(BUS_PROBE_DEFAULT);
+		return(BUS_PROBE_SPECIFIC);
 	}
 	return(ENXIO);
 }
@@ -371,45 +371,6 @@
 		goto out;
 	}
 
-	/*
-	 * Allocate the PCI register window.
-	 */
-	sc->aac_regs_rid = PCIR_BAR(0);
-	if ((sc->aac_regs_resource = bus_alloc_resource_any(sc->aac_dev,
-							    SYS_RES_MEMORY,
-							    &sc->aac_regs_rid,
-							    RF_ACTIVE)) ==
-							    NULL) {
-		device_printf(sc->aac_dev,
-			      "couldn't allocate register window\n");
-		goto out;
-	}
-	sc->aac_btag = rman_get_bustag(sc->aac_regs_resource);
-	sc->aac_bhandle = rman_get_bushandle(sc->aac_regs_resource);
-
-	/* assume failure is 'out of memory' */
-	error = ENOMEM;
-
-	/*
-	 * Allocate the parent bus DMA tag appropriate for our PCI interface.
-	 * 
-	 * Note that some of these controllers are 64-bit capable.
-	 */
-	if (bus_dma_tag_create(NULL, 			/* parent */
-			       PAGE_SIZE, 0,		/* algnmnt, boundary */
-			       BUS_SPACE_MAXADDR,	/* lowaddr */
-			       BUS_SPACE_MAXADDR, 	/* highaddr */
-			       NULL, NULL, 		/* filter, filterarg */
-			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
-			       BUS_SPACE_UNRESTRICTED,	/* nsegments */
-			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
-			       0,			/* flags */
-			       NULL, NULL,		/* No locking needed */
-			       &sc->aac_parent_dmat)) {
-		device_printf(sc->aac_dev, "can't allocate parent DMA tag\n");
-		goto out;
-	}
-
 	/* 
 	 * Detect the hardware interface version, set up the bus interface
 	 * indirection.
@@ -418,7 +379,8 @@
 	sc->aac_hwif = id->hwif;
 	switch(sc->aac_hwif) {
 	case AAC_HWIF_I960RX:
-		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for i960Rx");
+	case AAC_HWIF_NARK:
+		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for i960Rx/NARK");
 		sc->aac_if = aac_rx_interface;
 		break;
 	case AAC_HWIF_STRONGARM:
@@ -440,6 +402,63 @@
 		goto out;
 	}
 
+	/* assume failure is 'out of memory' */
+	error = ENOMEM;
+
+	/*
+	 * Allocate the PCI register window.
+	 */
+	sc->aac_regs_rid0 = PCIR_BAR(0);
+	if ((sc->aac_regs_res0 = bus_alloc_resource_any(sc->aac_dev,
+					    SYS_RES_MEMORY,
+					    &sc->aac_regs_rid0,
+					    RF_ACTIVE)) == NULL) {
+		device_printf(sc->aac_dev,
+			      "couldn't allocate register window 0\n");
+		goto out;
+	}
+	sc->aac_btag0 = rman_get_bustag(sc->aac_regs_res0);
+	sc->aac_bhandle0 = rman_get_bushandle(sc->aac_regs_res0);
+
+	if (sc->aac_hwif == AAC_HWIF_NARK) {
+		sc->aac_regs_rid1 = PCIR_BAR(1);
+		if ((sc->aac_regs_res1 = bus_alloc_resource_any(sc->aac_dev,
+						    SYS_RES_MEMORY,
+						    &sc->aac_regs_rid1,
+						    RF_ACTIVE)) == NULL) {
+			device_printf(sc->aac_dev,
+				      "couldn't allocate register window 0\n");
+			goto out;
+		}
+		sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1);
+		sc->aac_bhandle1 = rman_get_bushandle(sc->aac_regs_res1);
+	} else {
+		sc->aac_regs_res1 = sc->aac_regs_res0;
+		sc->aac_regs_rid1 = sc->aac_regs_rid0;
+		sc->aac_btag1 = sc->aac_btag0;
+		sc->aac_bhandle1 = sc->aac_bhandle0;
+	}
+
+	/*
+	 * Allocate the parent bus DMA tag appropriate for our PCI interface.
+	 * 
+	 * Note that some of these controllers are 64-bit capable.
+	 */
+	if (bus_dma_tag_create(NULL, 			/* parent */
+			       PAGE_SIZE, 0,		/* algnmnt, boundary */
+			       BUS_SPACE_MAXADDR,	/* lowaddr */
+			       BUS_SPACE_MAXADDR, 	/* highaddr */
+			       NULL, NULL, 		/* filter, filterarg */
+			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
+			       BUS_SPACE_UNRESTRICTED,	/* nsegments */
+			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
+			       0,			/* flags */
+			       NULL, NULL,		/* No locking needed */
+			       &sc->aac_parent_dmat)) {
+		device_printf(sc->aac_dev, "can't allocate parent DMA tag\n");
+		goto out;
+	}
+
 	/* Set up quirks */
 	sc->flags = id->quirks;
 
diff -uN /media/cvs-cur/src/sys/dev/aac/aac_tables.h ./aac_tables.h
--- /media/cvs-cur/src/sys/dev/aac/aac_tables.h	2005-10-08 19:55:09.000000000 +0400
+++ ./aac_tables.h	2008-09-07 04:26:20.000000000 +0400
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$FreeBSD: src/sys/dev/aac/aac_tables.h,v 1.6 2005/10/08 15:55:09 scottl Exp $
+ *	$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_tables.h,v 1.5.2.1 2005/10/09 06:39:21 scottl Exp $
  */
 
 /*
@@ -68,6 +68,7 @@
 	{"not mounted",				10009},
 	{"in maintenance mode",			10010},
 	{"stale ACL",				10011},
+	{"bus reset - command aborted",		20001},
 	{NULL, 					0},
 	{"unknown command status",		0}
 };
diff -uN /media/cvs-cur/src/sys/dev/aac/aacreg.h ./aacreg.h
--- /media/cvs-cur/src/sys/dev/aac/aacreg.h	2008-03-26 00:39:06.000000000 +0300
+++ ./aacreg.h	2008-10-17 02:02:15.000000000 +0400
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$FreeBSD: src/sys/dev/aac/aacreg.h,v 1.25 2008/03/25 21:39:06 emaste Exp $
+ *	$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aacreg.h,v 1.21.2.1.2.1 2005/10/28 16:31:34 scottl Exp $
  */
 
 /*
@@ -673,6 +673,7 @@
 #define AAC_MONKER_RCVTEMP	0x25
 #define AAC_MONKER_GETCOMMPREF	0x26
 #define AAC_MONKER_REINIT	0xee
+#define AAC_IOP_RESET		0x1000
 
 /*
  *  Adapter Status Register
@@ -1091,7 +1092,8 @@
 	ST_JUKEBOX = 10008,
 	ST_NOTMOUNTED = 10009,
 	ST_MAINTMODE = 10010,
-	ST_STALEACL = 10011
+	ST_STALEACL = 10011,
+	ST_BUS_RESET = 20001
 } AAC_FSAStatus;
 
 /*
@@ -1123,6 +1125,27 @@
 	VM_NameServe64		 
 } AAC_VMCommand;
 
+/* Container Configuration Sub-Commands */
+#define CT_PAUSE_IO			65
+#define CT_RELEASE_IO			66
+#define CT_GET_CONFIG_STATUS		147
+#define CT_COMMIT_CONFIG		152
+
+/*
+ * CT_PAUSE_IO is immediate minimal runtime command that is used
+ * to restart the applications and cache.
+ */
+struct aac_pause_command {
+	u_int32_t	Command;
+	u_int32_t	Type;
+	u_int32_t	Timeout;
+	u_int32_t	Min;
+	u_int32_t	NoRescan;
+	u_int32_t	Parm3;
+	u_int32_t	Parm4;
+	u_int32_t	Count;
+} __packed;
+
 /*
  * "mountable object"
  */
@@ -1358,12 +1381,12 @@
 struct aac_close_command {
 	u_int32_t		Command;
 	u_int32_t		ContainerId;
-};
+} __packed;
 
 /*
  * SCSI Passthrough structures
  */
-struct aac_srb32 {
+struct aac_srb {
 	u_int32_t		function;
 	u_int32_t		bus;
 	u_int32_t		target;
@@ -1374,8 +1397,8 @@
 	u_int32_t		retry_limit;
 	u_int32_t		cdb_len;
 	u_int8_t		cdb[16];
-	struct aac_sg_table	sg_map32;
-};
+	struct aac_sg_table	sg_map;
+} __packed;
 
 enum {
 	AAC_SRB_FUNC_EXECUTE_SCSI	= 0x00,
@@ -1416,7 +1439,7 @@
 	u_int32_t	data_len;
 	u_int32_t	sense_len;
 	u_int8_t	sense[AAC_HOST_SENSE_DATA_MAX];
-};
+} __packed;
 
 /*
  * Status codes for SCSI passthrough commands.  Since they are based on ASPI,
@@ -1468,7 +1491,7 @@
 #define	AAC_FA_FWSTATUS			0x2c	/* Mailbox 7 */
 #define	AAC_FA_INTSRC			0x900
 
-#define AAC_FA_HACK(sc)	(void)AAC_GETREG4(sc, AAC_FA_INTSRC)
+#define AAC_FA_HACK(sc)	(void)AAC_MEM0_GETREG4(sc, AAC_FA_INTSRC)
 
 /*
  * Register definitions for the Adaptec AAC-364 'Jalapeno I/II' adapters, based
@@ -1495,6 +1518,8 @@
  * and other related adapters.
  */
 
+#define AAC_RX_OMR0		0x18	/* outbound message register 0 */
+#define AAC_RX_OMR1		0x1c	/* outbound message register 1 */
 #define AAC_RX_IDBR		0x20	/* inbound doorbell register */
 #define AAC_RX_IISR		0x24	/* inbound interrupt status register */
 #define AAC_RX_IIMR		0x28	/* inbound interrupt mask register */
@@ -1512,6 +1537,8 @@
  * Unsurprisingly, it's quite similar to the i960!
  */
 
+#define AAC_RKT_OMR0		0x18	/* outbound message register 0 */
+#define AAC_RKT_OMR1		0x1c	/* outbound message register 1 */
 #define AAC_RKT_IDBR		0x20	/* inbound doorbell register */
 #define AAC_RKT_IISR		0x24	/* inbound interrupt status register */
 #define AAC_RKT_IIMR		0x28	/* inbound interrupt mask register */
@@ -1524,6 +1551,11 @@
 #define AAC_RKT_MAILBOX		0x1000	/* mailbox */
 #define AAC_RKT_FWSTATUS	0x101c	/* Firmware Status (mailbox 7) */
 
+/* Sunrise Lake dual core reset */
+#define AAC_IRCSR		0x38	/* inbound dual cores reset */
+#define AAC_IRCSR_CORES_RST	3
+
+
 /*
  * Common bit definitions for the doorbell registers.
  */
diff -uN /media/cvs-cur/src/sys/dev/aac/aacvar.h ./aacvar.h
--- /media/cvs-cur/src/sys/dev/aac/aacvar.h	2008-03-26 00:39:06.000000000 +0300
+++ ./aacvar.h	2008-10-17 02:07:03.000000000 +0400
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$FreeBSD: src/sys/dev/aac/aacvar.h,v 1.51 2008/03/25 21:39:06 emaste Exp $
+ *	$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aacvar.h,v 1.46.8.1 2005/10/09 06:39:21 scottl Exp $
  */
 
 #include <sys/bio.h>
@@ -36,8 +36,18 @@
 #include <sys/selinfo.h>
 #include <geom/geom_disk.h>
 
+#define AAC_TYPE_DEVO			1
+#define AAC_TYPE_ALPHA			2
+#define AAC_TYPE_BETA			3
+#define AAC_TYPE_RELEASE		4
+
+#define AAC_DRIVER_MAJOR_VERSION	2
+#define AAC_DRIVER_MINOR_VERSION	1
+#define AAC_DRIVER_BUGFIX_LEVEL		15
+#define AAC_DRIVER_TYPE			AAC_TYPE_RELEASE
+
 #ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 1
+# define AAC_DRIVER_BUILD 15753 
 #endif
 
 /*
@@ -45,12 +55,6 @@
  */
 
 /*
- * The firmware interface allows for a 16-bit s/g list length.  We limit 
- * ourselves to a reasonable maximum and ensure alignment.
- */
-#define AAC_MAXSGENTRIES	64	/* max S/G entries, limit 65535 */		
-
-/*
  * We allocate a small set of FIBs for the adapter to use to send us messages.
  */
 #define AAC_ADAPTER_FIBS	8
@@ -59,7 +63,7 @@
  * FIBs are allocated in page-size chunks and can grow up to the 512
  * limit imposed by the hardware.
  */
-#define AAC_PREALLOCATE_FIBS	128
+#define AAC_PREALLOCATE_FIBS	512
 #define AAC_NUM_MGT_FIB		8
 
 /*
@@ -170,14 +174,15 @@
 #define AAC_ON_AACQ_AIF		(1<<8)
 #define AAC_ON_AACQ_NORM	(1<<10)
 #define AAC_ON_AACQ_MASK	((1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<10))
-#define AAC_QUEUE_FRZN		(1<<9)		/* Freeze the processing of
-						 * commands on the queue. */
+#define AAC_CMD_RESET		(1<<9)
 
 	void			(* cm_complete)(struct aac_command *cm);
 	void			*cm_private;
 	time_t			cm_timestamp;	/* command creation time */
 	int			cm_queue;
 	int			cm_index;
+	bus_dma_tag_t		cm_passthr_dmat;	/* passthrough buffer/command
+							 * DMA tag */
 };
 
 struct aac_fibmap {
@@ -259,24 +264,37 @@
 #define AAC_GET_OUTB_QUEUE(sc)		((sc)->aac_if.aif_get_outb_queue((sc)))
 #define AAC_SET_OUTB_QUEUE(sc, idx)	((sc)->aac_if.aif_set_outb_queue((sc), (idx)))
 
-#define AAC_SETREG4(sc, reg, val)	bus_space_write_4(sc->aac_btag, \
-					sc->aac_bhandle, reg, val)
-#define AAC_GETREG4(sc, reg)		bus_space_read_4 (sc->aac_btag, \
-					sc->aac_bhandle, reg)
-#define AAC_SETREG2(sc, reg, val)	bus_space_write_2(sc->aac_btag, \
-					sc->aac_bhandle, reg, val)
-#define AAC_GETREG2(sc, reg)		bus_space_read_2 (sc->aac_btag, \
-					sc->aac_bhandle, reg)
-#define AAC_SETREG1(sc, reg, val)	bus_space_write_1(sc->aac_btag, \
-					sc->aac_bhandle, reg, val)
-#define AAC_GETREG1(sc, reg)		bus_space_read_1 (sc->aac_btag, \
-					sc->aac_bhandle, reg)
+#define AAC_MEM0_SETREG4(sc, reg, val)	bus_space_write_4(sc->aac_btag0, \
+					sc->aac_bhandle0, reg, val)
+#define AAC_MEM0_GETREG4(sc, reg)		bus_space_read_4 (sc->aac_btag0, \
+					sc->aac_bhandle0, reg)
+#define AAC_MEM0_SETREG2(sc, reg, val)	bus_space_write_2(sc->aac_btag0, \
+					sc->aac_bhandle0, reg, val)
+#define AAC_MEM0_GETREG2(sc, reg)		bus_space_read_2 (sc->aac_btag0, \
+					sc->aac_bhandle0, reg)
+#define AAC_MEM0_SETREG1(sc, reg, val)	bus_space_write_1(sc->aac_btag0, \
+					sc->aac_bhandle0, reg, val)
+#define AAC_MEM0_GETREG1(sc, reg)		bus_space_read_1 (sc->aac_btag0, \
+					sc->aac_bhandle0, reg)
+
+#define AAC_MEM1_SETREG4(sc, reg, val)	bus_space_write_4(sc->aac_btag1, \
+					sc->aac_bhandle1, reg, val)
+#define AAC_MEM1_GETREG4(sc, reg)		bus_space_read_4 (sc->aac_btag1, \
+					sc->aac_bhandle1, reg)
+#define AAC_MEM1_SETREG2(sc, reg, val)	bus_space_write_2(sc->aac_btag1, \
+					sc->aac_bhandle1, reg, val)
+#define AAC_MEM1_GETREG2(sc, reg)		bus_space_read_2 (sc->aac_btag1, \
+					sc->aac_bhandle1, reg)
+#define AAC_MEM1_SETREG1(sc, reg, val)	bus_space_write_1(sc->aac_btag1, \
+					sc->aac_bhandle1, reg, val)
+#define AAC_MEM1_GETREG1(sc, reg)		bus_space_read_1 (sc->aac_btag1, \
+					sc->aac_bhandle1, reg)
 
 /* fib context (IOCTL) */
 struct aac_fib_context {
-	u_int32_t		unique;
-	int			ctx_idx;
-	int			ctx_wrap;
+	u_int32_t unique;
+	int ctx_idx;
+	int ctx_wrap;
 	struct aac_fib_context *next, *prev;
 };
 
@@ -287,11 +305,10 @@
 {
 	/* bus connections */
 	device_t		aac_dev;
-	struct resource		*aac_regs_resource;	/* register interface
-							 * window */
-	int			aac_regs_rid;		/* resource ID */
-	bus_space_handle_t	aac_bhandle;		/* bus space handle */
-	bus_space_tag_t		aac_btag;		/* bus space tag */
+	struct resource		*aac_regs_res0, *aac_regs_res1;	/* reg. if. window */
+	int			aac_regs_rid0, aac_regs_rid1;		/* resource ID */
+	bus_space_handle_t	aac_bhandle0, aac_bhandle1;		/* bus space handle */
+	bus_space_tag_t		aac_btag0, aac_btag1;		/* bus space tag */
 	bus_dma_tag_t		aac_parent_dmat;	/* parent DMA tag */
 	bus_dma_tag_t		aac_buffer_dmat;	/* data buffer/command
 							 * DMA tag */
@@ -299,6 +316,7 @@
 	int			aac_irq_rid;
 	void			*aac_intr;		/* interrupt handle */
 	eventhandler_tag	eh;
+	struct callout_handle	timeout_id;		/* timeout handle */
 
 	/* controller features, limits and status */
 	int			aac_state;
@@ -306,6 +324,7 @@
 #define	AAC_STATE_OPEN		(1<<1)
 #define AAC_STATE_INTERRUPTS_ON	(1<<2)
 #define AAC_STATE_AIF_SLEEPER	(1<<3)
+#define AAC_STATE_RESET		(1<<4)
 	int			aac_open_cnt;
 	struct FsaRevision		aac_revision;
 
@@ -315,6 +334,7 @@
 #define AAC_HWIF_STRONGARM	1
 #define AAC_HWIF_FALCON		2
 #define AAC_HWIF_RKT		3
+#define AAC_HWIF_NARK		4
 #define AAC_HWIF_UNKNOWN	-1
 	bus_dma_tag_t		aac_common_dmat;	/* common structure
 							 * DMA tag */
@@ -392,8 +412,11 @@
 #define AAC_FLAGS_NEW_COMM	(1 << 11)	/* New comm. interface supported */
 #define AAC_FLAGS_RAW_IO	(1 << 12)	/* Raw I/O interface */
 #define AAC_FLAGS_ARRAY_64BIT	(1 << 13)	/* 64-bit array size */
-#define	AAC_FLAGS_LBA_64BIT	(1 << 14)	/* 64-bit LBA support */
+#define AAC_FLAGS_LBA_64BIT	(1 << 14)	/* 64-bit LBA support */
+#define AAC_QUEUE_FRZN		(1<<15)		/* Freeze the processing of
+						 * commands on the queue. */
 
+	int	sim_freezed;				/* flag for sim_freeze/release */		
 	u_int32_t		supported_options;
 	u_int32_t		scsi_method_id;
 	TAILQ_HEAD(,aac_sim)	aac_sim_tqh;
@@ -403,6 +426,12 @@
 	u_int32_t	aac_max_fib_size;		/* max. FIB size */
 	u_int32_t	aac_sg_tablesize;		/* max. sg count from host */
 	u_int32_t	aac_max_sectors;		/* max. I/O size from host (blocks) */
+
+	u_int32_t	DebugFlags;			/* Debug print flags bitmap */
+	u_int32_t	DebugOffset;			/* Offset from DPMEM start */
+	u_int32_t	DebugHeaderSize;		/* Size of debug header */
+	u_int32_t	FwDebugFlags;			/* FW Debug Flags */
+	u_int32_t	FwDebugBufferSize;		/* FW Debug Buffer Size in Bytes */
 };
 
 /*
@@ -432,7 +461,7 @@
 extern int		aac_suspend(device_t dev); 
 extern int		aac_resume(device_t dev);
 extern void		aac_new_intr(void *arg);
-extern int		aac_fast_intr(void *arg);
+extern void		aac_fast_intr(void *arg);
 extern void		aac_submit_bio(struct bio *bp);
 extern void		aac_biodone(struct bio *bp);
 extern void		aac_startio(struct aac_softc *sc);
@@ -446,17 +475,8 @@
 				      *event);
 
 #ifdef AAC_DEBUG
-extern int	aac_debug_enable;
-# define fwprintf(sc, flags, fmt, args...)				\
-do {									\
-	if (!aac_debug_enable)						\
-		break;							\
-	if (sc != NULL)							\
-		device_printf(((struct aac_softc *)sc)->aac_dev,	\
-		    "%s: " fmt "\n", __func__, ##args);			\
-	else								\
-		printf("%s: " fmt "\n", __func__, ##args);		\
-} while(0)
+# define fwprintf(sc, flags, fmt, args...)	\
+	aac_fw_printf(sc, flags, "%s: " fmt, __func__, ##args);	
 
 extern void	aac_print_queues(struct aac_softc *sc);
 extern void	aac_panic(struct aac_softc *sc, char *reason);


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list