aac.c (110604) | aac.c (111141) |
---|---|
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 110604 2003-02-10 00:34:24Z scottl $ | 29 * $FreeBSD: head/sys/dev/aac/aac.c 111141 2003-02-19 21:38:29Z scottl $ |
30 */ 31 32/* 33 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters. 34 */ 35 36#include "opt_aac.h" 37 --- 46 unchanged lines hidden (view full) --- 84static int aac_wait_command(struct aac_command *cm, int timeout); 85static void aac_command_thread(struct aac_softc *sc); 86static void aac_host_response(struct aac_softc *sc); 87 88/* Command Buffer Management */ 89static void aac_map_command_helper(void *arg, bus_dma_segment_t *segs, 90 int nseg, int error); 91static int aac_alloc_commands(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 --- 46 unchanged lines hidden (view full) --- 84static int aac_wait_command(struct aac_command *cm, int timeout); 85static void aac_command_thread(struct aac_softc *sc); 86static void aac_host_response(struct aac_softc *sc); 87 88/* Command Buffer Management */ 89static void aac_map_command_helper(void *arg, bus_dma_segment_t *segs, 90 int nseg, int error); 91static int aac_alloc_commands(struct aac_softc *sc); |
92static void aac_free_commands(struct aac_softc *sc, struct aac_fibmap *fm); | 92static void aac_free_commands(struct aac_softc *sc); |
93static void aac_map_command(struct aac_command *cm); 94static void aac_unmap_command(struct aac_command *cm); 95 96/* Hardware Interface */ 97static void aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, 98 int error); 99static int aac_check_firmware(struct aac_softc *sc); 100static int aac_init(struct aac_softc *sc); --- 321 unchanged lines hidden (view full) --- 422/* 423 * Free all of the resources associated with (sc) 424 * 425 * Should not be called if the controller is active. 426 */ 427void 428aac_free(struct aac_softc *sc) 429{ | 93static void aac_map_command(struct aac_command *cm); 94static void aac_unmap_command(struct aac_command *cm); 95 96/* Hardware Interface */ 97static void aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, 98 int error); 99static int aac_check_firmware(struct aac_softc *sc); 100static int aac_init(struct aac_softc *sc); --- 321 unchanged lines hidden (view full) --- 422/* 423 * Free all of the resources associated with (sc) 424 * 425 * Should not be called if the controller is active. 426 */ 427void 428aac_free(struct aac_softc *sc) 429{ |
430 struct aac_fibmap *fm; | |
431 432 debug_called(1); 433 434 /* remove the control device */ 435 if (sc->aac_dev_t != NULL) 436 destroy_dev(sc->aac_dev_t); 437 438 /* throw away any FIB buffers, discard the FIB DMA tag */ | 430 431 debug_called(1); 432 433 /* remove the control device */ 434 if (sc->aac_dev_t != NULL) 435 destroy_dev(sc->aac_dev_t); 436 437 /* throw away any FIB buffers, discard the FIB DMA tag */ |
439 while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) { 440 TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link); 441 aac_free_commands(sc, fm); 442 free(fm, M_AACBUF); 443 } | 438 aac_free_commands(sc); |
444 if (sc->aac_fib_dmat) 445 bus_dma_tag_destroy(sc->aac_fib_dmat); 446 447 free(sc->aac_commands, M_AACBUF); 448 449 /* destroy the common area */ 450 if (sc->aac_common) { 451 bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap); --- 640 unchanged lines hidden (view full) --- 1092int 1093aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp) 1094{ 1095 struct aac_command *cm; 1096 1097 debug_called(3); 1098 1099 if ((cm = aac_dequeue_free(sc)) == NULL) { | 439 if (sc->aac_fib_dmat) 440 bus_dma_tag_destroy(sc->aac_fib_dmat); 441 442 free(sc->aac_commands, M_AACBUF); 443 444 /* destroy the common area */ 445 if (sc->aac_common) { 446 bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap); --- 640 unchanged lines hidden (view full) --- 1087int 1088aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp) 1089{ 1090 struct aac_command *cm; 1091 1092 debug_called(3); 1093 1094 if ((cm = aac_dequeue_free(sc)) == NULL) { |
1100 if (aac_alloc_commands(sc)) 1101 return(ENOMEM); 1102 if ((cm = aac_dequeue_free(sc)) == NULL) | 1095 if ((aac_alloc_commands(sc) != 0) || 1096 (cm = aac_dequeue_free(sc)) == NULL) |
1103 return (ENOMEM); 1104 } 1105 1106 *cmp = cm; 1107 return(0); 1108} 1109 1110/* --- 27 unchanged lines hidden (view full) --- 1138} 1139 1140/* 1141 * Map helper for command/FIB allocation. 1142 */ 1143static void 1144aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1145{ | 1097 return (ENOMEM); 1098 } 1099 1100 *cmp = cm; 1101 return(0); 1102} 1103 1104/* --- 27 unchanged lines hidden (view full) --- 1132} 1133 1134/* 1135 * Map helper for command/FIB allocation. 1136 */ 1137static void 1138aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1139{ |
1146 uintptr_t *fibphys; | 1140 uint32_t *fibphys; |
1147 | 1141 |
1148 fibphys = (uintptr_t *)arg; | 1142 fibphys = (uint32_t *)arg; |
1149 1150 debug_called(3); 1151 1152 *fibphys = segs[0].ds_addr; 1153} 1154 1155/* 1156 * Allocate and initialise commands/FIBs for this adapter. 1157 */ 1158static int 1159aac_alloc_commands(struct aac_softc *sc) 1160{ 1161 struct aac_command *cm; 1162 struct aac_fibmap *fm; | 1143 1144 debug_called(3); 1145 1146 *fibphys = segs[0].ds_addr; 1147} 1148 1149/* 1150 * Allocate and initialise commands/FIBs for this adapter. 1151 */ 1152static int 1153aac_alloc_commands(struct aac_softc *sc) 1154{ 1155 struct aac_command *cm; 1156 struct aac_fibmap *fm; |
1163 uintptr_t fibphys; | 1157 uint32_t fibphys; |
1164 int i, error; 1165 1166 debug_called(1); 1167 1168 if (sc->total_fibs + AAC_FIB_COUNT > AAC_MAX_FIBS) 1169 return (ENOMEM); 1170 | 1158 int i, error; 1159 1160 debug_called(1); 1161 1162 if (sc->total_fibs + AAC_FIB_COUNT > AAC_MAX_FIBS) 1163 return (ENOMEM); 1164 |
1171 fm = malloc(sizeof(struct aac_fibmap), M_AACBUF, /*M_WAITOK|*/M_ZERO); | 1165 fm = malloc(sizeof(struct aac_fibmap), M_AACBUF, M_NOWAIT|M_ZERO); |
1172 1173 /* allocate the FIBs in DMAable memory and load them */ 1174 if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&fm->aac_fibs, 1175 BUS_DMA_NOWAIT, &fm->aac_fibmap)) { 1176 device_printf(sc->aac_dev, 1177 "Not enough contiguous memory available.\n"); | 1166 1167 /* allocate the FIBs in DMAable memory and load them */ 1168 if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&fm->aac_fibs, 1169 BUS_DMA_NOWAIT, &fm->aac_fibmap)) { 1170 device_printf(sc->aac_dev, 1171 "Not enough contiguous memory available.\n"); |
1172 free(fm, M_AACBUF); |
|
1178 return (ENOMEM); 1179 } 1180 1181 bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs, 1182 AAC_FIB_COUNT * sizeof(struct aac_fib), 1183 aac_map_command_helper, &fibphys, 0); 1184 1185 /* initialise constant fields in the command structure */ 1186 bzero(fm->aac_fibs, AAC_FIB_COUNT * sizeof(struct aac_fib)); 1187 for (i = 0; i < AAC_FIB_COUNT; i++) { | 1173 return (ENOMEM); 1174 } 1175 1176 bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs, 1177 AAC_FIB_COUNT * sizeof(struct aac_fib), 1178 aac_map_command_helper, &fibphys, 0); 1179 1180 /* initialise constant fields in the command structure */ 1181 bzero(fm->aac_fibs, AAC_FIB_COUNT * sizeof(struct aac_fib)); 1182 for (i = 0; i < AAC_FIB_COUNT; i++) { |
1188 cm = sc->aac_commands + sc->total_fibs + i; | 1183 cm = sc->aac_commands + sc->total_fibs; |
1189 fm->aac_commands = cm; 1190 cm->cm_sc = sc; 1191 cm->cm_fib = fm->aac_fibs + i; | 1184 fm->aac_commands = cm; 1185 cm->cm_sc = sc; 1186 cm->cm_fib = fm->aac_fibs + i; |
1192 cm->cm_fibphys = (uint32_t)fibphys + 1193 (i * sizeof(struct aac_fib)); | 1187 cm->cm_fibphys = fibphys + (i * sizeof(struct aac_fib)); |
1194 1195 if ((error = bus_dmamap_create(sc->aac_buffer_dmat, 0, 1196 &cm->cm_datamap)) == 0) 1197 aac_release_command(cm); | 1188 1189 if ((error = bus_dmamap_create(sc->aac_buffer_dmat, 0, 1190 &cm->cm_datamap)) == 0) 1191 aac_release_command(cm); |
1198 else 1199 return (error); | 1192 else 1193 break; 1194 sc->total_fibs++; |
1200 } 1201 | 1195 } 1196 |
1202 sc->total_fibs += AAC_FIB_COUNT; 1203 TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link); | 1197 if (i > 0) { 1198 TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link); 1199 return (0); 1200 } |
1204 | 1201 |
1205 return (0); | 1202 bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap); 1203 bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap); 1204 free(fm, M_AACBUF); 1205 return (ENOMEM); |
1206} 1207 1208/* 1209 * Free FIBs owned by this adapter. 1210 */ 1211static void | 1206} 1207 1208/* 1209 * Free FIBs owned by this adapter. 1210 */ 1211static void |
1212aac_free_commands(struct aac_softc *sc, struct aac_fibmap *fm) | 1212aac_free_commands(struct aac_softc *sc) |
1213{ | 1213{ |
1214 struct aac_fibmap *fm; |
|
1214 struct aac_command *cm; 1215 int i; 1216 1217 debug_called(1); 1218 | 1215 struct aac_command *cm; 1216 int i; 1217 1218 debug_called(1); 1219 |
1219 for (i = 0; i < AAC_FIB_COUNT; i++) { 1220 cm = fm->aac_commands + i; 1221 bus_dmamap_destroy(sc->aac_buffer_dmat, cm->cm_datamap); 1222 } | 1220 while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) { |
1223 | 1221 |
1224 bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap); 1225 bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap); | 1222 TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link); 1223 /* 1224 * We check against total_fibs to handle partially 1225 * allocated blocks. 1226 */ 1227 for (i = 0; i < AAC_FIB_COUNT && sc->total_fibs--; i++) { 1228 cm = fm->aac_commands + i; 1229 bus_dmamap_destroy(sc->aac_buffer_dmat, cm->cm_datamap); 1230 } 1231 bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap); 1232 bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap); 1233 free(fm, M_AACBUF); 1234 } |
1226} 1227 1228/* 1229 * Command-mapping helper function - populate this command's s/g table. 1230 */ 1231static void 1232aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1233{ --- 136 unchanged lines hidden (view full) --- 1370 1371static int 1372aac_init(struct aac_softc *sc) 1373{ 1374 struct aac_adapter_init *ip; 1375 time_t then; 1376 u_int32_t code; 1377 u_int8_t *qaddr; | 1235} 1236 1237/* 1238 * Command-mapping helper function - populate this command's s/g table. 1239 */ 1240static void 1241aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1242{ --- 136 unchanged lines hidden (view full) --- 1379 1380static int 1381aac_init(struct aac_softc *sc) 1382{ 1383 struct aac_adapter_init *ip; 1384 time_t then; 1385 u_int32_t code; 1386 u_int8_t *qaddr; |
1378 int i; | |
1379 1380 debug_called(1); 1381 1382 /* 1383 * First wait for the adapter to come ready. 1384 */ 1385 then = time_second; 1386 do { --- 52 unchanged lines hidden (view full) --- 1439 (uint8_t *)sc->aac_common += 8192; 1440 sc->aac_common_busaddr += 8192; 1441 } 1442 bzero(sc->aac_common, sizeof(*sc->aac_common)); 1443 1444 /* Allocate some FIBs and associated command structs */ 1445 TAILQ_INIT(&sc->aac_fibmap_tqh); 1446 sc->aac_commands = malloc(AAC_MAX_FIBS * sizeof(struct aac_command), | 1387 1388 debug_called(1); 1389 1390 /* 1391 * First wait for the adapter to come ready. 1392 */ 1393 then = time_second; 1394 do { --- 52 unchanged lines hidden (view full) --- 1447 (uint8_t *)sc->aac_common += 8192; 1448 sc->aac_common_busaddr += 8192; 1449 } 1450 bzero(sc->aac_common, sizeof(*sc->aac_common)); 1451 1452 /* Allocate some FIBs and associated command structs */ 1453 TAILQ_INIT(&sc->aac_fibmap_tqh); 1454 sc->aac_commands = malloc(AAC_MAX_FIBS * sizeof(struct aac_command), |
1447 M_AACBUF, /*M_WAITOK|*/M_ZERO); 1448 for (i = 0; i < 16; i++) { | 1455 M_AACBUF, M_WAITOK|M_ZERO); 1456 while (sc->total_fibs < AAC_PREALLOCATE_FIBS) { |
1449 if (aac_alloc_commands(sc) != 0) 1450 break; 1451 } 1452 if (sc->total_fibs == 0) 1453 return (ENOMEM); 1454 1455 /* 1456 * Fill in the init structure. This tells the adapter about the --- 1393 unchanged lines hidden --- | 1457 if (aac_alloc_commands(sc) != 0) 1458 break; 1459 } 1460 if (sc->total_fibs == 0) 1461 return (ENOMEM); 1462 1463 /* 1464 * Fill in the init structure. This tells the adapter about the --- 1393 unchanged lines hidden --- |