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 --- |