Deleted Added
full compact
aac.c (117362) aac.c (117363)
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 117362 2003-07-09 19:30:30Z scottl $
29 * $FreeBSD: head/sys/dev/aac/aac.c 117363 2003-07-09 21:16:23Z scottl $
30 */
31
32/*
33 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
34 */
35
36#include "opt_aac.h"
37

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

62
63static void aac_startup(void *arg);
64static void aac_add_container(struct aac_softc *sc,
65 struct aac_mntinforesp *mir, int f);
66static void aac_get_bus_info(struct aac_softc *sc);
67
68/* Command Processing */
69static void aac_timeout(struct aac_softc *sc);
30 */
31
32/*
33 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
34 */
35
36#include "opt_aac.h"
37

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

62
63static void aac_startup(void *arg);
64static void aac_add_container(struct aac_softc *sc,
65 struct aac_mntinforesp *mir, int f);
66static void aac_get_bus_info(struct aac_softc *sc);
67
68/* Command Processing */
69static void aac_timeout(struct aac_softc *sc);
70static int aac_start(struct aac_command *cm);
70static int aac_map_command(struct aac_command *cm);
71static void aac_complete(void *context, int pending);
72static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
73static void aac_bio_complete(struct aac_command *cm);
74static int aac_wait_command(struct aac_command *cm, int timeout);
75static void aac_command_thread(struct aac_softc *sc);
76
77/* Command Buffer Management */
71static void aac_complete(void *context, int pending);
72static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
73static void aac_bio_complete(struct aac_command *cm);
74static int aac_wait_command(struct aac_command *cm, int timeout);
75static void aac_command_thread(struct aac_softc *sc);
76
77/* Command Buffer Management */
78static void aac_map_command_sg(void *arg, bus_dma_segment_t *segs,
79 int nseg, int error);
78static void aac_map_command_helper(void *arg, bus_dma_segment_t *segs,
79 int nseg, int error);
80static int aac_alloc_commands(struct aac_softc *sc);
81static void aac_free_commands(struct aac_softc *sc);
80static void aac_map_command_helper(void *arg, bus_dma_segment_t *segs,
81 int nseg, int error);
82static int aac_alloc_commands(struct aac_softc *sc);
83static void aac_free_commands(struct aac_softc *sc);
82static void aac_map_command(struct aac_command *cm);
83static void aac_unmap_command(struct aac_command *cm);
84
85/* Hardware Interface */
86static void aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg,
87 int error);
88static int aac_check_firmware(struct aac_softc *sc);
89static int aac_init(struct aac_softc *sc);
90static int aac_sync_command(struct aac_softc *sc, u_int32_t command,

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

662 */
663void
664aac_startio(struct aac_softc *sc)
665{
666 struct aac_command *cm;
667
668 debug_called(2);
669
84static void aac_unmap_command(struct aac_command *cm);
85
86/* Hardware Interface */
87static void aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg,
88 int error);
89static int aac_check_firmware(struct aac_softc *sc);
90static int aac_init(struct aac_softc *sc);
91static int aac_sync_command(struct aac_softc *sc, u_int32_t command,

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

663 */
664void
665aac_startio(struct aac_softc *sc)
666{
667 struct aac_command *cm;
668
669 debug_called(2);
670
671 if (sc->flags & AAC_QUEUE_FRZN)
672 return;
673
670 for (;;) {
671 /*
672 * Try to get a command that's been put off for lack of
673 * resources
674 */
675 cm = aac_dequeue_ready(sc);
676
677 /*
678 * Try to build a command off the bio queue (ignore error
679 * return)
680 */
681 if (cm == NULL)
682 aac_bio_command(sc, &cm);
683
684 /* nothing to do? */
685 if (cm == NULL)
686 break;
687
688 /* try to give the command to the controller */
674 for (;;) {
675 /*
676 * Try to get a command that's been put off for lack of
677 * resources
678 */
679 cm = aac_dequeue_ready(sc);
680
681 /*
682 * Try to build a command off the bio queue (ignore error
683 * return)
684 */
685 if (cm == NULL)
686 aac_bio_command(sc, &cm);
687
688 /* nothing to do? */
689 if (cm == NULL)
690 break;
691
692 /* try to give the command to the controller */
689 if (aac_start(cm) == EBUSY) {
693 if (aac_map_command(cm) == EBUSY) {
690 /* put it on the ready queue for later */
691 aac_requeue_ready(cm);
692 break;
693 }
694 }
695}
696
697/*
698 * Deliver a command to the controller; allocate controller resources at the
699 * last moment when possible.
700 */
701static int
694 /* put it on the ready queue for later */
695 aac_requeue_ready(cm);
696 break;
697 }
698 }
699}
700
701/*
702 * Deliver a command to the controller; allocate controller resources at the
703 * last moment when possible.
704 */
705static int
702aac_start(struct aac_command *cm)
706aac_map_command(struct aac_command *cm)
703{
704 struct aac_softc *sc;
705 int error;
706
707 debug_called(2);
708
709 sc = cm->cm_sc;
707{
708 struct aac_softc *sc;
709 int error;
710
711 debug_called(2);
712
713 sc = cm->cm_sc;
714 error = 0;
710
715
711 /* get the command mapped */
712 aac_map_command(cm);
716 /* don't map more than once */
717 if (cm->cm_flags & AAC_CMD_MAPPED)
718 return (0);
713
719
714 /* Fix up the address values in the FIB. Use the command array index
715 * instead of a pointer since these fields are only 32 bits. Shift
716 * the SenderFibAddress over to make room for the fast response bit.
717 */
718 cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 1);
719 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
720
721 /* save a pointer to the command for speedy reverse-lookup */
722 cm->cm_fib->Header.SenderData = cm->cm_index;
723 /* put the FIB on the outbound queue */
724 error = aac_enqueue_fib(sc, cm->cm_queue, cm);
725 return(error);
720 if (cm->cm_datalen != 0) {
721 error = bus_dmamap_load(sc->aac_buffer_dmat, cm->cm_datamap,
722 cm->cm_data, cm->cm_datalen,
723 aac_map_command_sg, cm, 0);
724 if (error == EINPROGRESS) {
725 debug(1, "freezing queue\n");
726 sc->flags |= AAC_QUEUE_FRZN;
727 error = 0;
728 }
729 }
730 return (error);
726}
727
728/*
729 * Handle notification of one or more FIBs coming from the controller.
730 */
731static void
732aac_command_thread(struct aac_softc *sc)
733{

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

854 cm->cm_complete(cm);
855 } else {
856 /* assume that someone is sleeping on this command */
857 wakeup(cm);
858 }
859 }
860
861 /* see if we can start some more I/O */
731}
732
733/*
734 * Handle notification of one or more FIBs coming from the controller.
735 */
736static void
737aac_command_thread(struct aac_softc *sc)
738{

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

859 cm->cm_complete(cm);
860 } else {
861 /* assume that someone is sleeping on this command */
862 wakeup(cm);
863 }
864 }
865
866 /* see if we can start some more I/O */
867 sc->flags &= ~AAC_QUEUE_FRZN;
862 aac_startio(sc);
863
864 AAC_LOCK_RELEASE(&sc->aac_io_lock);
865}
866
867/*
868 * Handle a bio submitted from a disk device.
869 */

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

1153 if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&fm->aac_fibs,
1154 BUS_DMA_NOWAIT, &fm->aac_fibmap)) {
1155 device_printf(sc->aac_dev,
1156 "Not enough contiguous memory available.\n");
1157 free(fm, M_AACBUF);
1158 return (ENOMEM);
1159 }
1160
868 aac_startio(sc);
869
870 AAC_LOCK_RELEASE(&sc->aac_io_lock);
871}
872
873/*
874 * Handle a bio submitted from a disk device.
875 */

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

1159 if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&fm->aac_fibs,
1160 BUS_DMA_NOWAIT, &fm->aac_fibmap)) {
1161 device_printf(sc->aac_dev,
1162 "Not enough contiguous memory available.\n");
1163 free(fm, M_AACBUF);
1164 return (ENOMEM);
1165 }
1166
1161 bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs,
1162 AAC_FIB_COUNT * sizeof(struct aac_fib),
1163 aac_map_command_helper, &fibphys, 0);
1167 /* Ignore errors since this doesn't bounce */
1168 (void)bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs,
1169 AAC_FIB_COUNT * sizeof(struct aac_fib),
1170 aac_map_command_helper, &fibphys, 0);
1164
1165 /* initialise constant fields in the command structure */
1166 bzero(fm->aac_fibs, AAC_FIB_COUNT * sizeof(struct aac_fib));
1167 for (i = 0; i < AAC_FIB_COUNT; i++) {
1168 cm = sc->aac_commands + sc->total_fibs;
1169 fm->aac_commands = cm;
1170 cm->cm_sc = sc;
1171 cm->cm_fib = fm->aac_fibs + i;

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

1222}
1223
1224/*
1225 * Command-mapping helper function - populate this command's s/g table.
1226 */
1227static void
1228aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1229{
1171
1172 /* initialise constant fields in the command structure */
1173 bzero(fm->aac_fibs, AAC_FIB_COUNT * sizeof(struct aac_fib));
1174 for (i = 0; i < AAC_FIB_COUNT; i++) {
1175 cm = sc->aac_commands + sc->total_fibs;
1176 fm->aac_commands = cm;
1177 cm->cm_sc = sc;
1178 cm->cm_fib = fm->aac_fibs + i;

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

1229}
1230
1231/*
1232 * Command-mapping helper function - populate this command's s/g table.
1233 */
1234static void
1235aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1236{
1237 struct aac_softc *sc;
1230 struct aac_command *cm;
1231 struct aac_fib *fib;
1232 int i;
1233
1234 debug_called(3);
1235
1236 cm = (struct aac_command *)arg;
1238 struct aac_command *cm;
1239 struct aac_fib *fib;
1240 int i;
1241
1242 debug_called(3);
1243
1244 cm = (struct aac_command *)arg;
1245 sc = cm->cm_sc;
1237 fib = cm->cm_fib;
1238
1239 /* copy into the FIB */
1240 if (cm->cm_sgtable != NULL) {
1241 if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1242 struct aac_sg_table *sg;
1243 sg = cm->cm_sgtable;
1244 sg->SgCount = nseg;

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

1255 for (i = 0; i < nseg; i++) {
1256 sg->SgEntry64[i].SgAddress = segs[i].ds_addr;
1257 sg->SgEntry64[i].SgByteCount = segs[i].ds_len;
1258 }
1259 /* update the FIB size for the s/g count */
1260 fib->Header.Size += nseg*sizeof(struct aac_sg_entry64);
1261 }
1262 }
1246 fib = cm->cm_fib;
1247
1248 /* copy into the FIB */
1249 if (cm->cm_sgtable != NULL) {
1250 if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1251 struct aac_sg_table *sg;
1252 sg = cm->cm_sgtable;
1253 sg->SgCount = nseg;

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

1264 for (i = 0; i < nseg; i++) {
1265 sg->SgEntry64[i].SgAddress = segs[i].ds_addr;
1266 sg->SgEntry64[i].SgByteCount = segs[i].ds_len;
1267 }
1268 /* update the FIB size for the s/g count */
1269 fib->Header.Size += nseg*sizeof(struct aac_sg_entry64);
1270 }
1271 }
1263}
1264
1272
1265/*
1266 * Map a command into controller-visible space.
1267 */
1268static void
1269aac_map_command(struct aac_command *cm)
1270{
1271 struct aac_softc *sc;
1273 /* Fix up the address values in the FIB. Use the command array index
1274 * instead of a pointer since these fields are only 32 bits. Shift
1275 * the SenderFibAddress over to make room for the fast response bit.
1276 */
1277 cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 1);
1278 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
1272
1279
1273 debug_called(2);
1280 /* save a pointer to the command for speedy reverse-lookup */
1281 cm->cm_fib->Header.SenderData = cm->cm_index;
1274
1282
1275 sc = cm->cm_sc;
1283 if (cm->cm_flags & AAC_CMD_DATAIN)
1284 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1285 BUS_DMASYNC_PREREAD);
1286 if (cm->cm_flags & AAC_CMD_DATAOUT)
1287 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1288 BUS_DMASYNC_PREWRITE);
1289 cm->cm_flags |= AAC_CMD_MAPPED;
1276
1290
1277 /* don't map more than once */
1278 if (cm->cm_flags & AAC_CMD_MAPPED)
1279 return;
1291 /* put the FIB on the outbound queue */
1292 if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY)
1293 aac_requeue_ready(cm);
1280
1294
1281 if (cm->cm_datalen != 0) {
1282 bus_dmamap_load(sc->aac_buffer_dmat, cm->cm_datamap,
1283 cm->cm_data, cm->cm_datalen,
1284 aac_map_command_sg, cm, 0);
1285
1286 if (cm->cm_flags & AAC_CMD_DATAIN)
1287 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1288 BUS_DMASYNC_PREREAD);
1289 if (cm->cm_flags & AAC_CMD_DATAOUT)
1290 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1291 BUS_DMASYNC_PREWRITE);
1292 }
1293 cm->cm_flags |= AAC_CMD_MAPPED;
1295 return;
1294}
1295
1296/*
1297 * Unmap a command from controller-visible space.
1298 */
1299static void
1300aac_unmap_command(struct aac_command *cm)
1301{

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

1381 options = AAC_GET_MAILBOX(sc, 1);
1382 sc->supported_options = options;
1383
1384 if ((options & AAC_SUPPORTED_4GB_WINDOW) != 0 &&
1385 (sc->flags & AAC_FLAGS_NO4GB) == 0)
1386 sc->flags |= AAC_FLAGS_4GB_WINDOW;
1387 if (options & AAC_SUPPORTED_NONDASD)
1388 sc->flags |= AAC_FLAGS_ENABLE_CAM;
1296}
1297
1298/*
1299 * Unmap a command from controller-visible space.
1300 */
1301static void
1302aac_unmap_command(struct aac_command *cm)
1303{

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

1383 options = AAC_GET_MAILBOX(sc, 1);
1384 sc->supported_options = options;
1385
1386 if ((options & AAC_SUPPORTED_4GB_WINDOW) != 0 &&
1387 (sc->flags & AAC_FLAGS_NO4GB) == 0)
1388 sc->flags |= AAC_FLAGS_4GB_WINDOW;
1389 if (options & AAC_SUPPORTED_NONDASD)
1390 sc->flags |= AAC_FLAGS_ENABLE_CAM;
1389 if ((options & AAC_SUPPORTED_SGMAP_HOST64) != 0 && (sizeof(bus_addr_t) > 4)) {
1391 if ((options & AAC_SUPPORTED_SGMAP_HOST64) != 0
1392 && (sizeof(bus_addr_t) > 4)) {
1390 device_printf(sc->aac_dev, "Enabling 64-bit address support\n");
1391 sc->flags |= AAC_FLAGS_SG_64BIT;
1392 }
1393
1394 /* Check for broken hardware that does a lower number of commands */
1395 if ((sc->flags & AAC_FLAGS_256FIBS) == 0)
1396 sc->aac_max_fibs = AAC_MAX_FIBS;
1397 else

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

1505 }
1506
1507 /*
1508 * Work around a bug in the 2120 and 2200 that cannot DMA commands
1509 * below address 8192 in physical memory.
1510 * XXX If the padding is not needed, can it be put to use instead
1511 * of ignored?
1512 */
1393 device_printf(sc->aac_dev, "Enabling 64-bit address support\n");
1394 sc->flags |= AAC_FLAGS_SG_64BIT;
1395 }
1396
1397 /* Check for broken hardware that does a lower number of commands */
1398 if ((sc->flags & AAC_FLAGS_256FIBS) == 0)
1399 sc->aac_max_fibs = AAC_MAX_FIBS;
1400 else

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

1508 }
1509
1510 /*
1511 * Work around a bug in the 2120 and 2200 that cannot DMA commands
1512 * below address 8192 in physical memory.
1513 * XXX If the padding is not needed, can it be put to use instead
1514 * of ignored?
1515 */
1513 bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
1516 (void)bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
1514 sc->aac_common, 8192 + sizeof(*sc->aac_common),
1515 aac_common_map, sc, 0);
1516
1517 if (sc->aac_common_busaddr < 8192) {
1518 (uint8_t *)sc->aac_common += 8192;
1519 sc->aac_common_busaddr += 8192;
1520 }
1521 bzero(sc->aac_common, sizeof(*sc->aac_common));

--- 1461 unchanged lines hidden ---
1517 sc->aac_common, 8192 + sizeof(*sc->aac_common),
1518 aac_common_map, sc, 0);
1519
1520 if (sc->aac_common_busaddr < 8192) {
1521 (uint8_t *)sc->aac_common += 8192;
1522 sc->aac_common_busaddr += 8192;
1523 }
1524 bzero(sc->aac_common, sizeof(*sc->aac_common));

--- 1461 unchanged lines hidden ---