Deleted Added
full compact
aac.c (95350) aac.c (95536)
1/*-
2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2001 Scott Long
4 * Copyright (c) 2000 BSDi
5 * Copyright (c) 2001 Adaptec, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 12 unchanged lines hidden (view full) ---

21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
1/*-
2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2001 Scott Long
4 * Copyright (c) 2000 BSDi
5 * Copyright (c) 2001 Adaptec, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 12 unchanged lines hidden (view full) ---

21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $FreeBSD: head/sys/dev/aac/aac.c 95350 2002-04-24 05:12:50Z scottl $
29 * $FreeBSD: head/sys/dev/aac/aac.c 95536 2002-04-27 01:31:17Z scottl $
30 */
31
32/*
33 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
34 */
35
36#include "opt_aac.h"
37

--- 27 unchanged lines hidden (view full) ---

65#include <machine/bus_memio.h>
66#include <machine/bus.h>
67#include <machine/resource.h>
68
69#include <dev/aac/aacreg.h>
70#include <dev/aac/aac_ioctl.h>
71#include <dev/aac/aacvar.h>
72#include <dev/aac/aac_tables.h>
30 */
31
32/*
33 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
34 */
35
36#include "opt_aac.h"
37

--- 27 unchanged lines hidden (view full) ---

65#include <machine/bus_memio.h>
66#include <machine/bus.h>
67#include <machine/resource.h>
68
69#include <dev/aac/aacreg.h>
70#include <dev/aac/aac_ioctl.h>
71#include <dev/aac/aacvar.h>
72#include <dev/aac/aac_tables.h>
73#include <dev/aac/aac_cam.h>
73
74static void aac_startup(void *arg);
75static void aac_add_container(struct aac_softc *sc,
76 struct aac_mntinforesp *mir, int f);
74
75static void aac_startup(void *arg);
76static void aac_add_container(struct aac_softc *sc,
77 struct aac_mntinforesp *mir, int f);
78static void aac_get_bus_info(struct aac_softc *sc);
77
78/* Command Processing */
79
80/* Command Processing */
79static void aac_startio(struct aac_softc *sc);
80static void aac_timeout(struct aac_softc *sc);
81static int aac_start(struct aac_command *cm);
82static void aac_complete(void *context, int pending);
83static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
84static void aac_bio_complete(struct aac_command *cm);
85static int aac_wait_command(struct aac_command *cm, int timeout);
86static void aac_host_command(struct aac_softc *sc);
87static void aac_host_response(struct aac_softc *sc);
88
89/* Command Buffer Management */
81static void aac_timeout(struct aac_softc *sc);
82static int aac_start(struct aac_command *cm);
83static void aac_complete(void *context, int pending);
84static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
85static void aac_bio_complete(struct aac_command *cm);
86static int aac_wait_command(struct aac_command *cm, int timeout);
87static void aac_host_command(struct aac_softc *sc);
88static void aac_host_response(struct aac_softc *sc);
89
90/* Command Buffer Management */
90static int aac_alloc_command(struct aac_softc *sc,
91 struct aac_command **cmp);
92static void aac_release_command(struct aac_command *cm);
93static void aac_map_command_helper(void *arg, bus_dma_segment_t *segs,
94 int nseg, int error);
95static int aac_alloc_commands(struct aac_softc *sc);
96static void aac_free_commands(struct aac_softc *sc);
97static void aac_map_command(struct aac_command *cm);
98static void aac_unmap_command(struct aac_command *cm);
99
100/* Hardware Interface */

--- 221 unchanged lines hidden (view full) ---

322#endif
323 panic("Could not create AIF thread\n");
324
325 /* Register the shutdown method to only be called post-dump */
326 if ((EVENTHANDLER_REGISTER(shutdown_final, aac_shutdown, sc->aac_dev,
327 SHUTDOWN_PRI_DEFAULT)) == NULL)
328 device_printf(sc->aac_dev, "shutdown event registration failed\n");
329
91static void aac_map_command_helper(void *arg, bus_dma_segment_t *segs,
92 int nseg, int error);
93static int aac_alloc_commands(struct aac_softc *sc);
94static void aac_free_commands(struct aac_softc *sc);
95static void aac_map_command(struct aac_command *cm);
96static void aac_unmap_command(struct aac_command *cm);
97
98/* Hardware Interface */

--- 221 unchanged lines hidden (view full) ---

320#endif
321 panic("Could not create AIF thread\n");
322
323 /* Register the shutdown method to only be called post-dump */
324 if ((EVENTHANDLER_REGISTER(shutdown_final, aac_shutdown, sc->aac_dev,
325 SHUTDOWN_PRI_DEFAULT)) == NULL)
326 device_printf(sc->aac_dev, "shutdown event registration failed\n");
327
328 /* Register with CAM for the non-DASD devices */
329 if (!(sc->quirks & AAC_QUIRK_NOCAM))
330 aac_get_bus_info(sc);
331
330 return(0);
331}
332
333/*
334 * Probe for containers, create disks.
335 */
336static void
337aac_startup(void *arg)

--- 6 unchanged lines hidden (view full) ---

344
345 debug_called(1);
346
347 sc = (struct aac_softc *)arg;
348
349 /* disconnect ourselves from the intrhook chain */
350 config_intrhook_disestablish(&sc->aac_ich);
351
332 return(0);
333}
334
335/*
336 * Probe for containers, create disks.
337 */
338static void
339aac_startup(void *arg)

--- 6 unchanged lines hidden (view full) ---

346
347 debug_called(1);
348
349 sc = (struct aac_softc *)arg;
350
351 /* disconnect ourselves from the intrhook chain */
352 config_intrhook_disestablish(&sc->aac_ich);
353
352 aac_get_sync_fib(sc, &fib, 0);
354 aac_alloc_sync_fib(sc, &fib, 0);
353 mi = (struct aac_mntinfo *)&fib->data[0];
354
355 /* loop over possible containers */
356 mi->Command = VM_NameServe;
357 mi->MntType = FT_FILESYS;
358 do {
359 /* request information on this container */
360 mi->MntCount = i;

--- 43 unchanged lines hidden (view full) ---

404 M_NOWAIT);
405 if (co == NULL)
406 panic("Out of memory?!\n");
407 debug(1, "id %x name '%.16s' size %u type %d",
408 mir->MntTable[0].ObjectId,
409 mir->MntTable[0].FileSystemName,
410 mir->MntTable[0].Capacity, mir->MntTable[0].VolType);
411
355 mi = (struct aac_mntinfo *)&fib->data[0];
356
357 /* loop over possible containers */
358 mi->Command = VM_NameServe;
359 mi->MntType = FT_FILESYS;
360 do {
361 /* request information on this container */
362 mi->MntCount = i;

--- 43 unchanged lines hidden (view full) ---

406 M_NOWAIT);
407 if (co == NULL)
408 panic("Out of memory?!\n");
409 debug(1, "id %x name '%.16s' size %u type %d",
410 mir->MntTable[0].ObjectId,
411 mir->MntTable[0].FileSystemName,
412 mir->MntTable[0].Capacity, mir->MntTable[0].VolType);
413
412 if ((child = device_add_child(sc->aac_dev, NULL, -1)) == NULL)
414 if ((child = device_add_child(sc->aac_dev, "aacd", -1)) == NULL)
413 device_printf(sc->aac_dev, "device_add_child failed\n");
414 else
415 device_set_ivars(child, co);
416 device_set_desc(child, aac_describe_code(aac_container_types,
417 mir->MntTable[0].VolType));
418 co->co_disk = child;
419 co->co_found = f;
420 bcopy(&mir->MntTable[0], &co->co_mntobj,

--- 119 unchanged lines hidden (view full) ---

540
541 /*
542 * Send a Container shutdown followed by a HostShutdown FIB to the
543 * controller to convince it that we don't want to talk to it anymore.
544 * We've been closed and all I/O completed already
545 */
546 device_printf(sc->aac_dev, "shutting down controller...");
547
415 device_printf(sc->aac_dev, "device_add_child failed\n");
416 else
417 device_set_ivars(child, co);
418 device_set_desc(child, aac_describe_code(aac_container_types,
419 mir->MntTable[0].VolType));
420 co->co_disk = child;
421 co->co_found = f;
422 bcopy(&mir->MntTable[0], &co->co_mntobj,

--- 119 unchanged lines hidden (view full) ---

542
543 /*
544 * Send a Container shutdown followed by a HostShutdown FIB to the
545 * controller to convince it that we don't want to talk to it anymore.
546 * We've been closed and all I/O completed already
547 */
548 device_printf(sc->aac_dev, "shutting down controller...");
549
548 aac_get_sync_fib(sc, &fib, AAC_SYNC_LOCK_FORCE);
550 aac_alloc_sync_fib(sc, &fib, AAC_SYNC_LOCK_FORCE);
549 cc = (struct aac_close_command *)&fib->data[0];
550
551 cc->Command = VM_CloseAll;
552 cc->ContainerId = 0xffffffff;
553 if (aac_sync_fib(sc, ContainerCommand, 0, fib,
554 sizeof(struct aac_close_command)))
555 printf("FAILED.\n");
556 else {

--- 107 unchanged lines hidden (view full) ---

664
665/*
666 * Command Processing
667 */
668
669/*
670 * Start as much queued I/O as possible on the controller
671 */
551 cc = (struct aac_close_command *)&fib->data[0];
552
553 cc->Command = VM_CloseAll;
554 cc->ContainerId = 0xffffffff;
555 if (aac_sync_fib(sc, ContainerCommand, 0, fib,
556 sizeof(struct aac_close_command)))
557 printf("FAILED.\n");
558 else {

--- 107 unchanged lines hidden (view full) ---

666
667/*
668 * Command Processing
669 */
670
671/*
672 * Start as much queued I/O as possible on the controller
673 */
672static void
674void
673aac_startio(struct aac_softc *sc)
674{
675 struct aac_command *cm;
676
677 debug_called(2);
678
679 for (;;) {
680 /*

--- 95 unchanged lines hidden (view full) ---

776
777 if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
778 fib->Header.XferState |= AAC_FIBSTATE_DONEHOST;
779 *(AAC_FSAStatus*)fib->data = ST_OK;
780
781 /* XXX Compute the Size field? */
782 size = fib->Header.Size;
783 if (size > sizeof(struct aac_fib)) {
675aac_startio(struct aac_softc *sc)
676{
677 struct aac_command *cm;
678
679 debug_called(2);
680
681 for (;;) {
682 /*

--- 95 unchanged lines hidden (view full) ---

778
779 if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
780 fib->Header.XferState |= AAC_FIBSTATE_DONEHOST;
781 *(AAC_FSAStatus*)fib->data = ST_OK;
782
783 /* XXX Compute the Size field? */
784 size = fib->Header.Size;
785 if (size > sizeof(struct aac_fib)) {
784 size = sizeof(struct aac_fib);
786 size = sizeof(struct aac_fib);
785 fib->Header.Size = size;
786 }
787 /*
788 * Since we did not generate this command, it
789 * cannot go through the normal
790 * enqueue->startio chain.
791 */
792 aac_enqueue_response(sc,

--- 243 unchanged lines hidden (view full) ---

1036
1037/*
1038 *Command Buffer Management
1039 */
1040
1041/*
1042 * Allocate a command.
1043 */
787 fib->Header.Size = size;
788 }
789 /*
790 * Since we did not generate this command, it
791 * cannot go through the normal
792 * enqueue->startio chain.
793 */
794 aac_enqueue_response(sc,

--- 243 unchanged lines hidden (view full) ---

1038
1039/*
1040 *Command Buffer Management
1041 */
1042
1043/*
1044 * Allocate a command.
1045 */
1044static int
1046int
1045aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
1046{
1047 struct aac_command *cm;
1048
1049 debug_called(3);
1050
1051 if ((cm = aac_dequeue_free(sc)) == NULL)
1052 return(ENOMEM);
1053
1054 *cmp = cm;
1055 return(0);
1056}
1057
1058/*
1059 * Release a command back to the freelist.
1060 */
1047aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
1048{
1049 struct aac_command *cm;
1050
1051 debug_called(3);
1052
1053 if ((cm = aac_dequeue_free(sc)) == NULL)
1054 return(ENOMEM);
1055
1056 *cmp = cm;
1057 return(0);
1058}
1059
1060/*
1061 * Release a command back to the freelist.
1062 */
1061static void
1063void
1062aac_release_command(struct aac_command *cm)
1063{
1064 debug_called(3);
1065
1066 /* (re)initialise the command/FIB */
1067 cm->cm_sgtable = NULL;
1068 cm->cm_flags = 0;
1069 cm->cm_complete = NULL;

--- 255 unchanged lines hidden (view full) ---

1325 return(ENXIO);
1326 }
1327 } while (!(code & AAC_UP_AND_RUNNING));
1328
1329 /*
1330 * Create DMA tag for the common structure and allocate it.
1331 */
1332 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
1064aac_release_command(struct aac_command *cm)
1065{
1066 debug_called(3);
1067
1068 /* (re)initialise the command/FIB */
1069 cm->cm_sgtable = NULL;
1070 cm->cm_flags = 0;
1071 cm->cm_complete = NULL;

--- 255 unchanged lines hidden (view full) ---

1327 return(ENXIO);
1328 }
1329 } while (!(code & AAC_UP_AND_RUNNING));
1330
1331 /*
1332 * Create DMA tag for the common structure and allocate it.
1333 */
1334 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
1333 1, 0, /* algnmnt, boundary */
1334 BUS_SPACE_MAXADDR, /* lowaddr */
1335 1, 0, /* algnmnt, boundary */
1336 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
1335 BUS_SPACE_MAXADDR, /* highaddr */
1336 NULL, NULL, /* filter, filterarg */
1337 sizeof(struct aac_common), /* maxsize */
1338 1, /* nsegments */
1339 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
1340 0, /* flags */
1341 &sc->aac_common_dmat)) {
1342 device_printf(sc->aac_dev,
1343 "can't allocate common structure DMA tag\n");
1344 return(ENOMEM);
1345 }
1346 if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
1347 BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
1348 device_printf(sc->aac_dev, "can't allocate common structure\n");
1349 return(ENOMEM);
1350 }
1351 bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
1352 sc->aac_common, sizeof(*sc->aac_common), aac_common_map,
1337 BUS_SPACE_MAXADDR, /* highaddr */
1338 NULL, NULL, /* filter, filterarg */
1339 sizeof(struct aac_common), /* maxsize */
1340 1, /* nsegments */
1341 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
1342 0, /* flags */
1343 &sc->aac_common_dmat)) {
1344 device_printf(sc->aac_dev,
1345 "can't allocate common structure DMA tag\n");
1346 return(ENOMEM);
1347 }
1348 if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
1349 BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
1350 device_printf(sc->aac_dev, "can't allocate common structure\n");
1351 return(ENOMEM);
1352 }
1353 bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
1354 sc->aac_common, sizeof(*sc->aac_common), aac_common_map,
1353 sc, 0);
1355 sc, 0);
1354 bzero(sc->aac_common, sizeof(*sc->aac_common));
1355
1356 /*
1357 * Fill in the init structure. This tells the adapter about the
1358 * physical location of various important shared data structures.
1359 */
1360 ip = &sc->aac_common->ac_init;
1361 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;

--- 148 unchanged lines hidden (view full) ---

1510 *sp = status;
1511 return(0);
1512}
1513
1514/*
1515 * Grab the sync fib area.
1516 */
1517int
1356 bzero(sc->aac_common, sizeof(*sc->aac_common));
1357
1358 /*
1359 * Fill in the init structure. This tells the adapter about the
1360 * physical location of various important shared data structures.
1361 */
1362 ip = &sc->aac_common->ac_init;
1363 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;

--- 148 unchanged lines hidden (view full) ---

1512 *sp = status;
1513 return(0);
1514}
1515
1516/*
1517 * Grab the sync fib area.
1518 */
1519int
1518aac_get_sync_fib(struct aac_softc *sc, struct aac_fib **fib, int flags)
1520aac_alloc_sync_fib(struct aac_softc *sc, struct aac_fib **fib, int flags)
1519{
1520
1521 /*
1522 * If the force flag is set, the system is shutting down, or in
1523 * trouble. Ignore the mutex.
1524 */
1525 if (!(flags & AAC_SYNC_LOCK_FORCE))
1526 AAC_LOCK_ACQUIRE(&sc->aac_sync_lock);

--- 538 unchanged lines hidden (view full) ---

2065static void
2066aac_describe_controller(struct aac_softc *sc)
2067{
2068 struct aac_fib *fib;
2069 struct aac_adapter_info *info;
2070
2071 debug_called(2);
2072
1521{
1522
1523 /*
1524 * If the force flag is set, the system is shutting down, or in
1525 * trouble. Ignore the mutex.
1526 */
1527 if (!(flags & AAC_SYNC_LOCK_FORCE))
1528 AAC_LOCK_ACQUIRE(&sc->aac_sync_lock);

--- 538 unchanged lines hidden (view full) ---

2067static void
2068aac_describe_controller(struct aac_softc *sc)
2069{
2070 struct aac_fib *fib;
2071 struct aac_adapter_info *info;
2072
2073 debug_called(2);
2074
2073 aac_get_sync_fib(sc, &fib, 0);
2075 aac_alloc_sync_fib(sc, &fib, 0);
2074
2075 fib->data[0] = 0;
2076 if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
2077 device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
2076
2077 fib->data[0] = 0;
2078 if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
2079 device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
2080 aac_release_sync_fib(sc);
2078 return;
2079 }
2080 info = (struct aac_adapter_info *)&fib->data[0];
2081
2082 device_printf(sc->aac_dev, "%s %dMHz, %dMB cache memory, %s\n",
2083 aac_describe_code(aac_cpu_variant, info->CpuVariant),
2084 info->ClockSpeed, info->BufferMem / (1024 * 1024),
2085 aac_describe_code(aac_battery_platform,
2086 info->batteryPlatform));
2087
2088 /* save the kernel revision structure for later use */
2089 sc->aac_revision = info->KernelRevision;
2090 device_printf(sc->aac_dev, "Kernel %d.%d-%d, Build %d, S/N %6X\n",
2091 info->KernelRevision.external.comp.major,
2092 info->KernelRevision.external.comp.minor,
2093 info->KernelRevision.external.comp.dash,
2094 info->KernelRevision.buildNumber,
2095 (u_int32_t)(info->SerialNumber & 0xffffff));
2081 return;
2082 }
2083 info = (struct aac_adapter_info *)&fib->data[0];
2084
2085 device_printf(sc->aac_dev, "%s %dMHz, %dMB cache memory, %s\n",
2086 aac_describe_code(aac_cpu_variant, info->CpuVariant),
2087 info->ClockSpeed, info->BufferMem / (1024 * 1024),
2088 aac_describe_code(aac_battery_platform,
2089 info->batteryPlatform));
2090
2091 /* save the kernel revision structure for later use */
2092 sc->aac_revision = info->KernelRevision;
2093 device_printf(sc->aac_dev, "Kernel %d.%d-%d, Build %d, S/N %6X\n",
2094 info->KernelRevision.external.comp.major,
2095 info->KernelRevision.external.comp.minor,
2096 info->KernelRevision.external.comp.dash,
2097 info->KernelRevision.buildNumber,
2098 (u_int32_t)(info->SerialNumber & 0xffffff));
2099
2100 aac_release_sync_fib(sc);
2096}
2097
2098/*
2099 * Look up a text description of a numeric error code and return a pointer to
2100 * same.
2101 */
2102static char *
2103aac_describe_code(struct aac_code_lookup *table, u_int32_t code)

--- 257 unchanged lines hidden (view full) ---

2361 switch (aif->data.EN.type) {
2362 case AifEnAddContainer:
2363 case AifEnDeleteContainer:
2364 /*
2365 * A container was added or deleted, but the message
2366 * doesn't tell us anything else! Re-enumerate the
2367 * containers and sort things out.
2368 */
2101}
2102
2103/*
2104 * Look up a text description of a numeric error code and return a pointer to
2105 * same.
2106 */
2107static char *
2108aac_describe_code(struct aac_code_lookup *table, u_int32_t code)

--- 257 unchanged lines hidden (view full) ---

2366 switch (aif->data.EN.type) {
2367 case AifEnAddContainer:
2368 case AifEnDeleteContainer:
2369 /*
2370 * A container was added or deleted, but the message
2371 * doesn't tell us anything else! Re-enumerate the
2372 * containers and sort things out.
2373 */
2369 aac_get_sync_fib(sc, &fib, 0);
2374 aac_alloc_sync_fib(sc, &fib, 0);
2370 mi = (struct aac_mntinfo *)&fib->data[0];
2371 mi->Command = VM_NameServe;
2372 mi->MntType = FT_FILESYS;
2373 do {
2374 /*
2375 * Ask the controller for its containers one at
2376 * a time.
2377 * XXX What if the controller's list changes

--- 314 unchanged lines hidden (view full) ---

2692 AAC_LOCK_RELEASE(&sc->aac_container_lock);
2693
2694 error = copyout((caddr_t)&query_disk, uptr,
2695 sizeof(struct aac_query_disk));
2696
2697 return (error);
2698}
2699
2375 mi = (struct aac_mntinfo *)&fib->data[0];
2376 mi->Command = VM_NameServe;
2377 mi->MntType = FT_FILESYS;
2378 do {
2379 /*
2380 * Ask the controller for its containers one at
2381 * a time.
2382 * XXX What if the controller's list changes

--- 314 unchanged lines hidden (view full) ---

2697 AAC_LOCK_RELEASE(&sc->aac_container_lock);
2698
2699 error = copyout((caddr_t)&query_disk, uptr,
2700 sizeof(struct aac_query_disk));
2701
2702 return (error);
2703}
2704
2705static void
2706aac_get_bus_info(struct aac_softc *sc)
2707{
2708 struct aac_fib *fib;
2709 struct aac_ctcfg *c_cmd;
2710 struct aac_ctcfg_resp *c_resp;
2711 struct aac_vmioctl *vmi;
2712 struct aac_vmi_businf_resp *vmi_resp;
2713 struct aac_getbusinf businfo;
2714 struct aac_cam_inf *caminf;
2715 device_t child;
2716 int i, found, error;
2717
2718 aac_alloc_sync_fib(sc, &fib, 0);
2719 c_cmd = (struct aac_ctcfg *)&fib->data[0];
2720
2721 c_cmd->Command = VM_ContainerConfig;
2722 c_cmd->cmd = CT_GET_SCSI_METHOD;
2723 c_cmd->param = 0;
2724
2725 error = aac_sync_fib(sc, ContainerCommand, 0, fib,
2726 sizeof(struct aac_ctcfg));
2727 if (error) {
2728 device_printf(sc->aac_dev, "Error %d sending "
2729 "VM_ContainerConfig command\n", error);
2730 aac_release_sync_fib(sc);
2731 return;
2732 }
2733
2734 c_resp = (struct aac_ctcfg_resp *)&fib->data[0];
2735 if (c_resp->Status != ST_OK) {
2736 device_printf(sc->aac_dev, "VM_ContainerConfig returned 0x%x\n",
2737 c_resp->Status);
2738 aac_release_sync_fib(sc);
2739 return;
2740 }
2741
2742 sc->scsi_method_id = c_resp->param;
2743
2744 vmi = (struct aac_vmioctl *)&fib->data[0];
2745 vmi->Command = VM_Ioctl;
2746 vmi->ObjType = FT_DRIVE;
2747 vmi->MethId = sc->scsi_method_id;
2748 vmi->ObjId = 0;
2749 vmi->IoctlCmd = GetBusInfo;
2750
2751 error = aac_sync_fib(sc, ContainerCommand, 0, fib,
2752 sizeof(struct aac_vmioctl));
2753 if (error) {
2754 device_printf(sc->aac_dev, "Error %d sending VMIoctl command\n",
2755 error);
2756 aac_release_sync_fib(sc);
2757 return;
2758 }
2759
2760 vmi_resp = (struct aac_vmi_businf_resp *)&fib->data[0];
2761 if (vmi_resp->Status != ST_OK) {
2762 device_printf(sc->aac_dev, "VM_Ioctl returned %d\n",
2763 vmi_resp->Status);
2764 aac_release_sync_fib(sc);
2765 return;
2766 }
2767
2768 bcopy(&vmi_resp->BusInf, &businfo, sizeof(struct aac_getbusinf));
2769 aac_release_sync_fib(sc);
2770
2771 found = 0;
2772 for (i = 0; i < businfo.BusCount; i++) {
2773 if (businfo.BusValid[i] != AAC_BUS_VALID)
2774 continue;
2775
2776 MALLOC(caminf, struct aac_cam_inf *,
2777 sizeof(struct aac_cam_inf), M_AACBUF, M_NOWAIT | M_ZERO);
2778 if (caminf == NULL)
2779 continue;
2780
2781 child = device_add_child(sc->aac_dev, "aacp", -1);
2782 if (child == NULL) {
2783 device_printf(sc->aac_dev, "device_add_child failed\n");
2784 continue;
2785 }
2786
2787 caminf->TargetsPerBus = businfo.TargetsPerBus;
2788 caminf->BusNumber = i;
2789 caminf->InitiatorBusId = businfo.InitiatorBusId[i];
2790 caminf->aac_sc = sc;
2791
2792 device_set_ivars(child, caminf);
2793 device_set_desc(child, "SCSI Passthrough Bus");
2794
2795 found = 1;
2796 }
2797
2798 if (found)
2799 bus_generic_attach(sc->aac_dev);
2800
2801 return;
2802}