summaryrefslogtreecommitdiffstats
path: root/sys/dev/aac/aac.c
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2008-03-24 16:38:47 +0000
committeremaste <emaste@FreeBSD.org>2008-03-24 16:38:47 +0000
commitbfdd190b82a1966a0dab092aa628b621d5bf054e (patch)
tree0351e35c901bfd66b1ec444b6e3cece25ad449e6 /sys/dev/aac/aac.c
parente1cf25141cc4502c7399cd734710dadf1abf0abd (diff)
downloadFreeBSD-src-bfdd190b82a1966a0dab092aa628b621d5bf054e.zip
FreeBSD-src-bfdd190b82a1966a0dab092aa628b621d5bf054e.tar.gz
Diff reduction to Adaptec driver build 15317 (refactoring and code shuffling):
- Resource allocation in aac_alloc (moved from from aac_init) - Interrupt setup in aac_setup_intr (from aac_attach) - Container probing in aac_get_container_info (from aac_startup and aac_handle_aif) - Firmware status check moved to aac_check_firmware from aac_init
Diffstat (limited to 'sys/dev/aac/aac.c')
-rw-r--r--sys/dev/aac/aac.c393
1 files changed, 206 insertions, 187 deletions
diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
index 7c6bfef..57f523d 100644
--- a/sys/dev/aac/aac.c
+++ b/sys/dev/aac/aac.c
@@ -90,6 +90,7 @@ static void aac_free_commands(struct aac_softc *sc);
static void aac_unmap_command(struct aac_command *cm);
/* Hardware Interface */
+static int aac_alloc(struct aac_softc *sc);
static void aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg,
int error);
static int aac_check_firmware(struct aac_softc *sc);
@@ -97,6 +98,7 @@ 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);
static int aac_dequeue_fib(struct aac_softc *sc, int queue,
@@ -226,6 +228,8 @@ static int aac_query_disk(struct aac_softc *sc, caddr_t uptr);
static int aac_get_pci_info(struct aac_softc *sc, caddr_t uptr);
static void aac_ioctl_event(struct aac_softc *sc,
struct aac_event *event, void *arg);
+static struct aac_mntinforesp *
+ aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid);
static struct cdevsw aac_cdevsw = {
.d_version = D_VERSION,
@@ -290,43 +294,16 @@ aac_attach(struct aac_softc *sc)
/*
* Initialize the adapter.
*/
+ if ((error = aac_alloc(sc)) != 0)
+ return(error);
if ((error = aac_init(sc)) != 0)
return(error);
/*
* Allocate and connect our interrupt.
*/
- sc->aac_irq_rid = 0;
- if ((sc->aac_irq = bus_alloc_resource_any(sc->aac_dev, SYS_RES_IRQ,
- &sc->aac_irq_rid,
- RF_SHAREABLE |
- RF_ACTIVE)) == NULL) {
- device_printf(sc->aac_dev, "can't allocate interrupt\n");
- return (EINVAL);
- }
- if (sc->flags & AAC_FLAGS_NEW_COMM) {
- if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
- 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)) {
- device_printf(sc->aac_dev,
- "can't set up FAST interrupt\n");
- if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
- INTR_MPSAFE|INTR_TYPE_BIO,
- NULL, (driver_intr_t *)aac_fast_intr,
- sc, &sc->aac_intr)) {
- device_printf(sc->aac_dev,
- "can't set up MPSAFE interrupt\n");
- return (EINVAL);
- }
- }
- }
+ if ((error = aac_setup_intr(sc)) != 0)
+ return(error);
/*
* Print a little information about the controller.
@@ -392,6 +369,28 @@ aac_add_event(struct aac_softc *sc, struct aac_event *event)
}
/*
+ * Request information of container #cid
+ */
+static struct aac_mntinforesp *
+aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid)
+{
+ struct aac_mntinfo *mi;
+
+ mi = (struct aac_mntinfo *)&fib->data[0];
+ mi->Command = VM_NameServe;
+ mi->MntType = FT_FILESYS;
+ mi->MntCount = cid;
+
+ if (aac_sync_fib(sc, ContainerCommand, 0, fib,
+ sizeof(struct aac_mntinfo))) {
+ printf("error probing container %d", cid);
+ return (NULL);
+ }
+
+ return ((struct aac_mntinforesp *)&fib->data[0]);
+}
+
+/*
* Probe for containers, create disks.
*/
static void
@@ -399,8 +398,7 @@ aac_startup(void *arg)
{
struct aac_softc *sc;
struct aac_fib *fib;
- struct aac_mntinfo *mi;
- struct aac_mntinforesp *mir = NULL;
+ struct aac_mntinforesp *mir;
int count = 0, i = 0;
debug_called(1);
@@ -412,24 +410,13 @@ aac_startup(void *arg)
mtx_lock(&sc->aac_io_lock);
aac_alloc_sync_fib(sc, &fib);
- mi = (struct aac_mntinfo *)&fib->data[0];
/* loop over possible containers */
do {
- /* request information on this container */
- bzero(mi, sizeof(struct aac_mntinfo));
- mi->Command = VM_NameServe;
- mi->MntType = FT_FILESYS;
- mi->MntCount = i;
- if (aac_sync_fib(sc, ContainerCommand, 0, fib,
- sizeof(struct aac_mntinfo))) {
- printf("error probing container %d", i);
+ if ((mir = aac_get_container_info(sc, fib, i)) == NULL)
continue;
- }
-
- mir = (struct aac_mntinforesp *)&fib->data[0];
- /* XXX Need to check if count changed */
- count = mir->MntRespCount;
+ if (i == 0)
+ count = mir->MntRespCount;
aac_add_container(sc, mir, 0);
i++;
} while ((i < count) && (i < AAC_MAX_CONTAINERS));
@@ -488,6 +475,112 @@ aac_add_container(struct aac_softc *sc, struct aac_mntinforesp *mir, int f)
}
/*
+ * Allocate resources associated with (sc)
+ */
+static int
+aac_alloc(struct aac_softc *sc)
+{
+ /*
+ * Create DMA tag for mapping buffers into controller-addressable space.
+ */
+ if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
+ 1, 0, /* algnmnt, boundary */
+ (sc->flags & AAC_FLAGS_SG_64BIT) ?
+ BUS_SPACE_MAXADDR :
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ MAXBSIZE, /* maxsize */
+ sc->aac_sg_tablesize, /* nsegments */
+ MAXBSIZE, /* maxsegsize */
+ BUS_DMA_ALLOCNOW, /* flags */
+ busdma_lock_mutex, /* lockfunc */
+ &sc->aac_io_lock, /* lockfuncarg */
+ &sc->aac_buffer_dmat)) {
+ device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
+ return (ENOMEM);
+ }
+
+ /*
+ * Create DMA tag for mapping FIBs into controller-addressable space..
+ */
+ if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
+ 1, 0, /* algnmnt, boundary */
+ (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
+ BUS_SPACE_MAXADDR_32BIT :
+ 0x7fffffff, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ sc->aac_max_fibs_alloc *
+ sc->aac_max_fib_size, /* maxsize */
+ 1, /* nsegments */
+ sc->aac_max_fibs_alloc *
+ sc->aac_max_fib_size, /* maxsize */
+ 0, /* flags */
+ NULL, NULL, /* No locking needed */
+ &sc->aac_fib_dmat)) {
+ device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");;
+ return (ENOMEM);
+ }
+
+ /*
+ * Create DMA tag for the common structure and allocate it.
+ */
+ if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
+ 1, 0, /* algnmnt, boundary */
+ (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
+ BUS_SPACE_MAXADDR_32BIT :
+ 0x7fffffff, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ 8192 + sizeof(struct aac_common), /* maxsize */
+ 1, /* nsegments */
+ BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* No locking needed */
+ &sc->aac_common_dmat)) {
+ device_printf(sc->aac_dev,
+ "can't allocate common structure DMA tag\n");
+ return (ENOMEM);
+ }
+ if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
+ BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
+ device_printf(sc->aac_dev, "can't allocate common structure\n");
+ return (ENOMEM);
+ }
+
+ /*
+ * Work around a bug in the 2120 and 2200 that cannot DMA commands
+ * below address 8192 in physical memory.
+ * XXX If the padding is not needed, can it be put to use instead
+ * of ignored?
+ */
+ (void)bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
+ sc->aac_common, 8192 + sizeof(*sc->aac_common),
+ aac_common_map, sc, 0);
+
+ if (sc->aac_common_busaddr < 8192) {
+ sc->aac_common = (struct aac_common *)
+ ((uint8_t *)sc->aac_common + 8192);
+ sc->aac_common_busaddr += 8192;
+ }
+ bzero(sc->aac_common, sizeof(*sc->aac_common));
+
+ /* Allocate some FIBs and associated command structs */
+ TAILQ_INIT(&sc->aac_fibmap_tqh);
+ sc->aac_commands = malloc(sc->aac_max_fibs * sizeof(struct aac_command),
+ M_AACBUF, M_WAITOK|M_ZERO);
+ while (sc->total_fibs < AAC_PREALLOCATE_FIBS) {
+ if (aac_alloc_commands(sc) != 0)
+ break;
+ }
+ if (sc->total_fibs == 0)
+ return (ENOMEM);
+
+ return (0);
+}
+
+/*
* Free all of the resources associated with (sc)
*
* Should not be called if the controller is active.
@@ -1580,10 +1673,33 @@ aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
static int
aac_check_firmware(struct aac_softc *sc)
{
- u_int32_t major, minor, options = 0, atu_size = 0;
+ u_int32_t code, major, minor, options = 0, atu_size = 0;
int status;
+ time_t then;
debug_called(1);
+ /*
+ * Wait for the adapter to come ready.
+ */
+ then = time_uptime;
+ do {
+ code = AAC_GET_FWSTATUS(sc);
+ if (code & AAC_SELF_TEST_FAILED) {
+ device_printf(sc->aac_dev, "FATAL: selftest failed\n");
+ return(ENXIO);
+ }
+ if (code & AAC_KERNEL_PANIC) {
+ device_printf(sc->aac_dev,
+ "FATAL: controller kernel panic\n");
+ return(ENXIO);
+ }
+ if (time_uptime > (then + AAC_BOOT_TIMEOUT)) {
+ device_printf(sc->aac_dev,
+ "FATAL: controller not coming ready, "
+ "status %x\n", code);
+ return(ENXIO);
+ }
+ } while (!(code & AAC_UP_AND_RUNNING));
/*
* Retrieve the firmware version numbers. Dell PERC2/QC cards with
@@ -1706,132 +1822,11 @@ static int
aac_init(struct aac_softc *sc)
{
struct aac_adapter_init *ip;
- time_t then;
- u_int32_t code, qoffset;
+ u_int32_t qoffset;
int error;
debug_called(1);
- /*
- * First wait for the adapter to come ready.
- */
- then = time_uptime;
- do {
- code = AAC_GET_FWSTATUS(sc);
- if (code & AAC_SELF_TEST_FAILED) {
- device_printf(sc->aac_dev, "FATAL: selftest failed\n");
- return(ENXIO);
- }
- if (code & AAC_KERNEL_PANIC) {
- device_printf(sc->aac_dev,
- "FATAL: controller kernel panic\n");
- return(ENXIO);
- }
- if (time_uptime > (then + AAC_BOOT_TIMEOUT)) {
- device_printf(sc->aac_dev,
- "FATAL: controller not coming ready, "
- "status %x\n", code);
- return(ENXIO);
- }
- } while (!(code & AAC_UP_AND_RUNNING));
-
- error = ENOMEM;
- /*
- * Create DMA tag for mapping buffers into controller-addressable space.
- */
- if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
- 1, 0, /* algnmnt, boundary */
- (sc->flags & AAC_FLAGS_SG_64BIT) ?
- BUS_SPACE_MAXADDR :
- BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- MAXBSIZE, /* maxsize */
- sc->aac_sg_tablesize, /* nsegments */
- MAXBSIZE, /* maxsegsize */
- BUS_DMA_ALLOCNOW, /* flags */
- busdma_lock_mutex, /* lockfunc */
- &sc->aac_io_lock, /* lockfuncarg */
- &sc->aac_buffer_dmat)) {
- device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
- goto out;
- }
-
- /*
- * Create DMA tag for mapping FIBs into controller-addressable space..
- */
- if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
- 1, 0, /* algnmnt, boundary */
- (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
- BUS_SPACE_MAXADDR_32BIT :
- 0x7fffffff, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- sc->aac_max_fibs_alloc *
- sc->aac_max_fib_size, /* maxsize */
- 1, /* nsegments */
- sc->aac_max_fibs_alloc *
- sc->aac_max_fib_size, /* maxsegsize */
- 0, /* flags */
- NULL, NULL, /* No locking needed */
- &sc->aac_fib_dmat)) {
- device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");;
- goto out;
- }
-
- /*
- * Create DMA tag for the common structure and allocate it.
- */
- if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
- 1, 0, /* algnmnt, boundary */
- (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
- BUS_SPACE_MAXADDR_32BIT :
- 0x7fffffff, /* lowaddr */
- BUS_SPACE_MAXADDR, /* highaddr */
- NULL, NULL, /* filter, filterarg */
- 8192 + sizeof(struct aac_common), /* maxsize */
- 1, /* nsegments */
- BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
- 0, /* flags */
- NULL, NULL, /* No locking needed */
- &sc->aac_common_dmat)) {
- device_printf(sc->aac_dev,
- "can't allocate common structure DMA tag\n");
- goto out;
- }
- if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
- BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
- device_printf(sc->aac_dev, "can't allocate common structure\n");
- goto out;
- }
-
- /*
- * Work around a bug in the 2120 and 2200 that cannot DMA commands
- * below address 8192 in physical memory.
- * XXX If the padding is not needed, can it be put to use instead
- * of ignored?
- */
- (void)bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
- sc->aac_common, 8192 + sizeof(*sc->aac_common),
- aac_common_map, sc, 0);
-
- if (sc->aac_common_busaddr < 8192) {
- sc->aac_common = (struct aac_common *)
- ((uint8_t *)sc->aac_common + 8192);
- sc->aac_common_busaddr += 8192;
- }
- bzero(sc->aac_common, sizeof(*sc->aac_common));
-
- /* Allocate some FIBs and associated command structs */
- TAILQ_INIT(&sc->aac_fibmap_tqh);
- sc->aac_commands = malloc(sc->aac_max_fibs * sizeof(struct aac_command),
- M_AACBUF, M_WAITOK|M_ZERO);
- while (sc->total_fibs < AAC_PREALLOCATE_FIBS) {
- if (aac_alloc_commands(sc) != 0)
- break;
- }
- if (sc->total_fibs == 0)
- goto out;
/*
* Fill in the init structure. This tells the adapter about the
@@ -1981,6 +1976,43 @@ out:
return(error);
}
+static int
+aac_setup_intr(struct aac_softc *sc)
+{
+ sc->aac_irq_rid = 0;
+ if ((sc->aac_irq = bus_alloc_resource_any(sc->aac_dev, SYS_RES_IRQ,
+ &sc->aac_irq_rid,
+ RF_SHAREABLE |
+ RF_ACTIVE)) == NULL) {
+ device_printf(sc->aac_dev, "can't allocate interrupt\n");
+ return (EINVAL);
+ }
+ if (sc->flags & AAC_FLAGS_NEW_COMM) {
+ if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
+ 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)) {
+ device_printf(sc->aac_dev,
+ "can't set up FAST interrupt\n");
+ if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
+ INTR_MPSAFE|INTR_TYPE_BIO,
+ NULL, (driver_intr_t *)aac_fast_intr,
+ sc, &sc->aac_intr)) {
+ device_printf(sc->aac_dev,
+ "can't set up MPSAFE interrupt\n");
+ return (EINVAL);
+ }
+ }
+ }
+ return (0);
+}
+
/*
* Send a synchronous command to the controller and wait for a result.
* Indicate if the controller completed the command with an error status.
@@ -3110,9 +3142,7 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
struct aac_aif_command *aif;
struct aac_container *co, *co_next;
struct aac_fib_context *ctx;
- struct aac_mntinfo *mi;
- struct aac_mntinforesp *mir = NULL;
- u_int16_t rsize;
+ struct aac_mntinforesp *mir;
int next, current, found;
int count = 0, added = 0, i = 0;
@@ -3133,7 +3163,6 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
* containers and sort things out.
*/
aac_alloc_sync_fib(sc, &fib);
- mi = (struct aac_mntinfo *)&fib->data[0];
do {
/*
* Ask the controller for its containers one at
@@ -3142,20 +3171,10 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
* midway through this enumaration?
* XXX This should be done async.
*/
- bzero(mi, sizeof(struct aac_mntinfo));
- mi->Command = VM_NameServe;
- mi->MntType = FT_FILESYS;
- mi->MntCount = i;
- rsize = sizeof(mir);
- if (aac_sync_fib(sc, ContainerCommand, 0, fib,
- sizeof(struct aac_mntinfo))) {
- printf("Error probing container %d\n",
- i);
+ if ((mir = aac_get_container_info(sc, fib, i)) == NULL)
continue;
- }
- mir = (struct aac_mntinforesp *)&fib->data[0];
- /* XXX Need to check if count changed */
- count = mir->MntRespCount;
+ if (i == 0)
+ count = mir->MntRespCount;
/*
* Check the container against our list.
* co->co_found was already set to 0 in a
OpenPOWER on IntegriCloud