Deleted Added
full compact
aac.c (108329) aac.c (109088)
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 108329 2002-12-27 17:52:16Z rwatson $
29 * $FreeBSD: head/sys/dev/aac/aac.c 109088 2003-01-11 01:59:21Z scottl $
30 */
31
32/*
33 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
34 */
35
36#include "opt_aac.h"
37

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

619/*
620 * Take an interrupt.
621 */
622void
623aac_intr(void *arg)
624{
625 struct aac_softc *sc;
626 u_int16_t reason;
30 */
31
32/*
33 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
34 */
35
36#include "opt_aac.h"
37

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

619/*
620 * Take an interrupt.
621 */
622void
623aac_intr(void *arg)
624{
625 struct aac_softc *sc;
626 u_int16_t reason;
627 u_int32_t *resp_queue;
627
628 debug_called(2);
629
630 sc = (struct aac_softc *)arg;
631
628
629 debug_called(2);
630
631 sc = (struct aac_softc *)arg;
632
632 reason = AAC_GET_ISTATUS(sc);
633 /*
634 * Optimize the common case of adapter response interrupts.
635 * We must read from the card prior to processing the responses
636 * to ensure the clear is flushed prior to accessing the queues.
637 * Reading the queues from local memory might save us a PCI read.
638 */
639 resp_queue = sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE];
640 if (resp_queue[AAC_PRODUCER_INDEX] != resp_queue[AAC_CONSUMER_INDEX])
641 reason = AAC_DB_RESPONSE_READY;
642 else
643 reason = AAC_GET_ISTATUS(sc);
644 AAC_CLEAR_ISTATUS(sc, reason);
645 (void)AAC_GET_ISTATUS(sc);
633
646
647 /* It's not ok to return here because of races with the previous step */
648 if (reason & AAC_DB_RESPONSE_READY)
649 aac_host_response(sc);
650
634 /* controller wants to talk to the log */
651 /* controller wants to talk to the log */
635 if (reason & AAC_DB_PRINTF) {
636 AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF);
652 if (reason & AAC_DB_PRINTF)
637 aac_print_printf(sc);
653 aac_print_printf(sc);
638 }
639
640 /* controller has a message for us? */
641 if (reason & AAC_DB_COMMAND_READY) {
654
655 /* controller has a message for us? */
656 if (reason & AAC_DB_COMMAND_READY) {
642 AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_READY);
643 /* XXX What happens if the thread is already awake? */
644 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
645 sc->aifflags |= AAC_AIFFLAGS_PENDING;
646 wakeup(sc->aifthread);
647 }
648 }
657 /* XXX What happens if the thread is already awake? */
658 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
659 sc->aifflags |= AAC_AIFFLAGS_PENDING;
660 wakeup(sc->aifthread);
661 }
662 }
649
650 /* controller has a response for us? */
651 if (reason & AAC_DB_RESPONSE_READY) {
652 AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
653 aac_host_response(sc);
654 }
663}
655
664
656 /*
657 * spurious interrupts that we don't use - reset the mask and clear the
658 * interrupts
659 */
660 if (reason & (AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL)) {
661 AAC_UNMASK_INTERRUPTS(sc);
662 AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_NOT_FULL |
663 AAC_DB_RESPONSE_NOT_FULL);
664 }
665};
666
667/*
668 * Command Processing
669 */
670
671/*
672 * Start as much queued I/O as possible on the controller
673 */
674void

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

724
725 /* fix up the address values in the FIB */
726 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
727 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
728
729 /* save a pointer to the command for speedy reverse-lookup */
730 cm->cm_fib->Header.SenderData = (u_int32_t)cm; /* XXX 64-bit physical
731 * address issue */
665/*
666 * Command Processing
667 */
668
669/*
670 * Start as much queued I/O as possible on the controller
671 */
672void

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

722
723 /* fix up the address values in the FIB */
724 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
725 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
726
727 /* save a pointer to the command for speedy reverse-lookup */
728 cm->cm_fib->Header.SenderData = (u_int32_t)cm; /* XXX 64-bit physical
729 * address issue */
732
733 /* put the FIB on the outbound queue */
734 error = aac_enqueue_fib(sc, cm->cm_queue, cm);
735 return(error);
736}
737
738/*
739 * Handle notification of one or more FIBs coming from the controller.
740 */

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

923 cm->cm_complete = aac_bio_complete;
924 cm->cm_private = bp;
925 cm->cm_timestamp = time_second;
926 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
927
928 /* build the FIB */
929 fib = cm->cm_fib;
930 fib->Header.XferState =
730 /* put the FIB on the outbound queue */
731 error = aac_enqueue_fib(sc, cm->cm_queue, cm);
732 return(error);
733}
734
735/*
736 * Handle notification of one or more FIBs coming from the controller.
737 */

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

920 cm->cm_complete = aac_bio_complete;
921 cm->cm_private = bp;
922 cm->cm_timestamp = time_second;
923 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
924
925 /* build the FIB */
926 fib = cm->cm_fib;
927 fib->Header.XferState =
931 AAC_FIBSTATE_HOSTOWNED |
932 AAC_FIBSTATE_INITIALISED |
933 AAC_FIBSTATE_FROMHOST |
934 AAC_FIBSTATE_REXPECTED |
935 AAC_FIBSTATE_NORM;
928 AAC_FIBSTATE_HOSTOWNED |
929 AAC_FIBSTATE_INITIALISED |
930 AAC_FIBSTATE_EMPTY |
931 AAC_FIBSTATE_FROMHOST |
932 AAC_FIBSTATE_REXPECTED |
933 AAC_FIBSTATE_NORM |
934 AAC_FIBSTATE_ASYNC |
935 AAC_FIBSTATE_FAST_RESPONSE;
936 fib->Header.Command = ContainerCommand;
937 fib->Header.Size = sizeof(struct aac_fib_header);
938
939 /* build the read/write request */
940 ad = (struct aac_disk *)bp->bio_dev->si_drv1;
941 if (BIO_IS_READ(bp)) {
942 br = (struct aac_blockread *)&fib->data[0];
943 br->Command = VM_CtBlockRead;

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

1076 cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib);
1077
1078 /*
1079 * These are duplicated in aac_start to cover the case where an
1080 * intermediate stage may have destroyed them. They're left
1081 * initialised here for debugging purposes only.
1082 */
1083 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
936 fib->Header.Command = ContainerCommand;
937 fib->Header.Size = sizeof(struct aac_fib_header);
938
939 /* build the read/write request */
940 ad = (struct aac_disk *)bp->bio_dev->si_drv1;
941 if (BIO_IS_READ(bp)) {
942 br = (struct aac_blockread *)&fib->data[0];
943 br->Command = VM_CtBlockRead;

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

1076 cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib);
1077
1078 /*
1079 * These are duplicated in aac_start to cover the case where an
1080 * intermediate stage may have destroyed them. They're left
1081 * initialised here for debugging purposes only.
1082 */
1083 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
1084 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
1084 cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1085 cm->cm_fib->Header.SenderData = 0;
1085
1086 aac_enqueue_free(cm);
1087}
1088
1089/*
1090 * Map helper for command/FIB allocation.
1091 */
1092static void

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

1116 if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&sc->aac_fibs,
1117 BUS_DMA_NOWAIT, &sc->aac_fibmap)) {
1118 printf("Not enough contiguous memory available.\n");
1119 return (ENOMEM);
1120 }
1121 bus_dmamap_load(sc->aac_fib_dmat, sc->aac_fibmap, sc->aac_fibs,
1122 AAC_FIB_COUNT * sizeof(struct aac_fib),
1123 aac_map_command_helper, sc, 0);
1086
1087 aac_enqueue_free(cm);
1088}
1089
1090/*
1091 * Map helper for command/FIB allocation.
1092 */
1093static void

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

1117 if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&sc->aac_fibs,
1118 BUS_DMA_NOWAIT, &sc->aac_fibmap)) {
1119 printf("Not enough contiguous memory available.\n");
1120 return (ENOMEM);
1121 }
1122 bus_dmamap_load(sc->aac_fib_dmat, sc->aac_fibmap, sc->aac_fibs,
1123 AAC_FIB_COUNT * sizeof(struct aac_fib),
1124 aac_map_command_helper, sc, 0);
1124
1125 bzero(sc->aac_fibs, AAC_FIB_COUNT * sizeof(struct aac_fib));
1125 /* initialise constant fields in the command structure */
1126 for (i = 0; i < AAC_FIB_COUNT; i++) {
1127 cm = &sc->aac_command[i];
1128 cm->cm_sc = sc;
1129 cm->cm_fib = sc->aac_fibs + i;
1130 cm->cm_fibphys = sc->aac_fibphys + (i * sizeof(struct aac_fib));
1131
1132 if (!bus_dmamap_create(sc->aac_buffer_dmat, 0, &cm->cm_datamap))

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

1201 if (cm->cm_flags & AAC_CMD_MAPPED)
1202 return;
1203
1204 if (cm->cm_datalen != 0) {
1205 bus_dmamap_load(sc->aac_buffer_dmat, cm->cm_datamap,
1206 cm->cm_data, cm->cm_datalen,
1207 aac_map_command_sg, cm, 0);
1208
1126 /* initialise constant fields in the command structure */
1127 for (i = 0; i < AAC_FIB_COUNT; i++) {
1128 cm = &sc->aac_command[i];
1129 cm->cm_sc = sc;
1130 cm->cm_fib = sc->aac_fibs + i;
1131 cm->cm_fibphys = sc->aac_fibphys + (i * sizeof(struct aac_fib));
1132
1133 if (!bus_dmamap_create(sc->aac_buffer_dmat, 0, &cm->cm_datamap))

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

1202 if (cm->cm_flags & AAC_CMD_MAPPED)
1203 return;
1204
1205 if (cm->cm_datalen != 0) {
1206 bus_dmamap_load(sc->aac_buffer_dmat, cm->cm_datamap,
1207 cm->cm_data, cm->cm_datalen,
1208 aac_map_command_sg, cm, 0);
1209
1209 if (cm->cm_flags & AAC_CMD_DATAIN)
1210 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1211 BUS_DMASYNC_PREREAD);
1212 if (cm->cm_flags & AAC_CMD_DATAOUT)
1213 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1214 BUS_DMASYNC_PREWRITE);
1210 if (cm->cm_flags & AAC_CMD_DATAIN)
1211 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1212 BUS_DMASYNC_PREREAD);
1213 if (cm->cm_flags & AAC_CMD_DATAOUT)
1214 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1215 BUS_DMASYNC_PREWRITE);
1215 }
1216 cm->cm_flags |= AAC_CMD_MAPPED;
1217}
1218
1219/*
1220 * Unmap a command from controller-visible space.
1221 */
1222static void

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

1357 bzero(sc->aac_common, sizeof(*sc->aac_common));
1358
1359 /*
1360 * Fill in the init structure. This tells the adapter about the
1361 * physical location of various important shared data structures.
1362 */
1363 ip = &sc->aac_common->ac_init;
1364 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1216 }
1217 cm->cm_flags |= AAC_CMD_MAPPED;
1218}
1219
1220/*
1221 * Unmap a command from controller-visible space.
1222 */
1223static void

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

1358 bzero(sc->aac_common, sizeof(*sc->aac_common));
1359
1360 /*
1361 * Fill in the init structure. This tells the adapter about the
1362 * physical location of various important shared data structures.
1363 */
1364 ip = &sc->aac_common->ac_init;
1365 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1366 ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION;
1365
1366 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1367 offsetof(struct aac_common, ac_fibs);
1367
1368 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1369 offsetof(struct aac_common, ac_fibs);
1368 ip->AdapterFibsVirtualAddress = &sc->aac_common->ac_fibs[0];
1370 ip->AdapterFibsVirtualAddress = (u_int32_t)&sc->aac_common->ac_fibs[0];
1369 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1370 ip->AdapterFibAlign = sizeof(struct aac_fib);
1371
1372 ip->PrintfBufferAddress = sc->aac_common_busaddr +
1373 offsetof(struct aac_common, ac_printf);
1374 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1375
1371 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1372 ip->AdapterFibAlign = sizeof(struct aac_fib);
1373
1374 ip->PrintfBufferAddress = sc->aac_common_busaddr +
1375 offsetof(struct aac_common, ac_printf);
1376 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1377
1376 ip->HostPhysMemPages = 0; /* not used? */
1378 /* The adapter assumes that pages are 4K in size */
1379 ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE;
1377 ip->HostElapsedSeconds = time_second; /* reset later if invalid */
1378
1379 /*
1380 * Initialise FIB queues. Note that it appears that the layout of the
1381 * indexes and the segmentation of the entries may be mandated by the
1382 * adapter, which is only told about the base of the queue index fields.
1383 *
1384 * The initial values of the indices are assumed to inform the adapter

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

1393 * virtue of a table.
1394 */
1395 qaddr = &sc->aac_common->ac_qbuf[0] + AAC_QUEUE_ALIGN;
1396 qaddr -= (u_int32_t)qaddr % AAC_QUEUE_ALIGN;
1397 sc->aac_queues = (struct aac_queue_table *)qaddr;
1398 ip->CommHeaderAddress = sc->aac_common_busaddr +
1399 ((u_int32_t)sc->aac_queues -
1400 (u_int32_t)sc->aac_common);
1380 ip->HostElapsedSeconds = time_second; /* reset later if invalid */
1381
1382 /*
1383 * Initialise FIB queues. Note that it appears that the layout of the
1384 * indexes and the segmentation of the entries may be mandated by the
1385 * adapter, which is only told about the base of the queue index fields.
1386 *
1387 * The initial values of the indices are assumed to inform the adapter

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

1396 * virtue of a table.
1397 */
1398 qaddr = &sc->aac_common->ac_qbuf[0] + AAC_QUEUE_ALIGN;
1399 qaddr -= (u_int32_t)qaddr % AAC_QUEUE_ALIGN;
1400 sc->aac_queues = (struct aac_queue_table *)qaddr;
1401 ip->CommHeaderAddress = sc->aac_common_busaddr +
1402 ((u_int32_t)sc->aac_queues -
1403 (u_int32_t)sc->aac_common);
1401 bzero(sc->aac_queues, sizeof(struct aac_queue_table));
1402
1403 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1404 AAC_HOST_NORM_CMD_ENTRIES;
1405 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1406 AAC_HOST_NORM_CMD_ENTRIES;
1407 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1408 AAC_HOST_HIGH_CMD_ENTRIES;
1409 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =

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

1699 if (ci >= aac_qinfo[queue].size)
1700 ci = 0;
1701
1702 /* fetch the entry */
1703 *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
1704 *fib_addr = (struct aac_fib *)(sc->aac_qentries[queue] +
1705 ci)->aq_fib_addr;
1706
1404
1405 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1406 AAC_HOST_NORM_CMD_ENTRIES;
1407 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1408 AAC_HOST_NORM_CMD_ENTRIES;
1409 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1410 AAC_HOST_HIGH_CMD_ENTRIES;
1411 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =

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

1701 if (ci >= aac_qinfo[queue].size)
1702 ci = 0;
1703
1704 /* fetch the entry */
1705 *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
1706 *fib_addr = (struct aac_fib *)(sc->aac_qentries[queue] +
1707 ci)->aq_fib_addr;
1708
1709 /*
1710 * Is this a fast response? If it is, update the fib fields in
1711 * local memory so the whole fib doesn't have to be DMA'd back up.
1712 */
1713 if (*(uintptr_t *)fib_addr & 0x01) {
1714 *(uintptr_t *)fib_addr &= ~0x01;
1715 (*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP;
1716 *((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL;
1717 }
1707 /* update consumer index */
1708 sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
1709
1710 /* if we have made the queue un-full, notify the adapter */
1711 if (notify && (aac_qinfo[queue].notify != 0))
1712 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1713 error = 0;
1714

--- 1042 unchanged lines hidden ---
1718 /* update consumer index */
1719 sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
1720
1721 /* if we have made the queue un-full, notify the adapter */
1722 if (notify && (aac_qinfo[queue].notify != 0))
1723 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1724 error = 0;
1725

--- 1042 unchanged lines hidden ---