aic7xxx.c (41887) | aic7xxx.c (42652) |
---|---|
1/* 2 * Generic driver for the aic7xxx based adaptec SCSI controllers 3 * Product specific probe and attach routines can be found in: 4 * i386/eisa/ahc_eisa.c 27/284X and aic7770 motherboard controllers 5 * pci/ahc_pci.c 3985, 3980, 3940, 2940, aic7895, aic7890, 6 * aic7880, aic7870, aic7860, and aic7850 controllers 7 * | 1/* 2 * Generic driver for the aic7xxx based adaptec SCSI controllers 3 * Product specific probe and attach routines can be found in: 4 * i386/eisa/ahc_eisa.c 27/284X and aic7770 motherboard controllers 5 * pci/ahc_pci.c 3985, 3980, 3940, 2940, aic7895, aic7890, 6 * aic7880, aic7870, aic7860, and aic7850 controllers 7 * |
8 * Copyright (c) 1994, 1995, 1996, 1997, 1998 Justin T. Gibbs. | 8 * Copyright (c) 1994, 1995, 1996, 1997, 1998, 1999 Justin T. Gibbs. |
9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification, immediately at the beginning of the file. --- 14 unchanged lines hidden (view full) --- 31 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * | 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification, immediately at the beginning of the file. --- 14 unchanged lines hidden (view full) --- 31 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * |
39 * $Id: aic7xxx.c,v 1.13 1998/12/15 08:22:40 gibbs Exp $ | 39 * $Id: aic7xxx.c,v 1.14 1998/12/17 00:06:52 gibbs Exp $ |
40 */ 41/* 42 * A few notes on features of the driver. 43 * 44 * SCB paging takes advantage of the fact that devices stay disconnected 45 * from the bus a relatively long time and that while they're disconnected, 46 * having the SCBs for these transactions down on the host adapter is of 47 * little use. Instead of leaving this idle SCB down on the card we copy --- 166 unchanged lines hidden (view full) --- 214 ahc_alloc_scb(struct ahc_softc *ahc); 215static void ahc_fetch_devinfo(struct ahc_softc *ahc, 216 struct ahc_devinfo *devinfo); 217static void ahc_compile_devinfo(struct ahc_devinfo *devinfo, 218 u_int target, u_int lun, char channel, 219 role_t role); 220static u_int ahc_abort_wscb(struct ahc_softc *ahc, u_int scbpos, u_int prev); 221static void ahc_done(struct ahc_softc *ahc, struct scb *scbp); | 40 */ 41/* 42 * A few notes on features of the driver. 43 * 44 * SCB paging takes advantage of the fact that devices stay disconnected 45 * from the bus a relatively long time and that while they're disconnected, 46 * having the SCBs for these transactions down on the host adapter is of 47 * little use. Instead of leaving this idle SCB down on the card we copy --- 166 unchanged lines hidden (view full) --- 214 ahc_alloc_scb(struct ahc_softc *ahc); 215static void ahc_fetch_devinfo(struct ahc_softc *ahc, 216 struct ahc_devinfo *devinfo); 217static void ahc_compile_devinfo(struct ahc_devinfo *devinfo, 218 u_int target, u_int lun, char channel, 219 role_t role); 220static u_int ahc_abort_wscb(struct ahc_softc *ahc, u_int scbpos, u_int prev); 221static void ahc_done(struct ahc_softc *ahc, struct scb *scbp); |
222static void ahc_handle_target_cmd(struct ahc_softc *ahc, | 222static void ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, 223 union ccb *ccb); 224static int ahc_handle_target_cmd(struct ahc_softc *ahc, |
223 struct target_cmd *cmd); 224static void ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat); 225static void ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat); 226static void ahc_build_transfer_msg(struct ahc_softc *ahc, 227 struct ahc_devinfo *devinfo); 228static void ahc_setup_initiator_msgout(struct ahc_softc *ahc, 229 struct ahc_devinfo *devinfo, 230 struct scb *scb); 231static void ahc_setup_target_msgin(struct ahc_softc *ahc, 232 struct ahc_devinfo *devinfo); 233static int ahc_handle_msg_reject(struct ahc_softc *ahc, 234 struct ahc_devinfo *devinfo); 235static void ahc_clear_msg_state(struct ahc_softc *ahc); 236static void ahc_handle_message_phase(struct ahc_softc *ahc, 237 struct cam_path *path); 238static int ahc_sent_msg(struct ahc_softc *ahc, u_int msgtype, int full); 239static int ahc_parse_msg(struct ahc_softc *ahc, struct cam_path *path, 240 struct ahc_devinfo *devinfo); | 225 struct target_cmd *cmd); 226static void ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat); 227static void ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat); 228static void ahc_build_transfer_msg(struct ahc_softc *ahc, 229 struct ahc_devinfo *devinfo); 230static void ahc_setup_initiator_msgout(struct ahc_softc *ahc, 231 struct ahc_devinfo *devinfo, 232 struct scb *scb); 233static void ahc_setup_target_msgin(struct ahc_softc *ahc, 234 struct ahc_devinfo *devinfo); 235static int ahc_handle_msg_reject(struct ahc_softc *ahc, 236 struct ahc_devinfo *devinfo); 237static void ahc_clear_msg_state(struct ahc_softc *ahc); 238static void ahc_handle_message_phase(struct ahc_softc *ahc, 239 struct cam_path *path); 240static int ahc_sent_msg(struct ahc_softc *ahc, u_int msgtype, int full); 241static int ahc_parse_msg(struct ahc_softc *ahc, struct cam_path *path, 242 struct ahc_devinfo *devinfo); |
243static void ahc_handle_ign_wide_residue(struct ahc_softc *ahc, 244 struct ahc_devinfo *devinfo); |
|
241static void ahc_handle_devreset(struct ahc_softc *ahc, int target, 242 char channel, cam_status status, 243 ac_code acode, char *message, 244 int verbose_only); 245static void ahc_loadseq(struct ahc_softc *ahc); 246static int ahc_check_patch(struct ahc_softc *ahc, 247 struct patch **start_patch, 248 int start_instr, int *skip_addr); --- 925 unchanged lines hidden (view full) --- 1174 ahc_calc_residual(scb); 1175 ahc_done(ahc, scb); 1176 } 1177 1178 if ((ahc->flags & AHC_TARGETMODE) != 0) { 1179 while (ahc->targetcmds[ahc->tqinfifonext].cmd_valid) { 1180 struct target_cmd *cmd; 1181 | 245static void ahc_handle_devreset(struct ahc_softc *ahc, int target, 246 char channel, cam_status status, 247 ac_code acode, char *message, 248 int verbose_only); 249static void ahc_loadseq(struct ahc_softc *ahc); 250static int ahc_check_patch(struct ahc_softc *ahc, 251 struct patch **start_patch, 252 int start_instr, int *skip_addr); --- 925 unchanged lines hidden (view full) --- 1178 ahc_calc_residual(scb); 1179 ahc_done(ahc, scb); 1180 } 1181 1182 if ((ahc->flags & AHC_TARGETMODE) != 0) { 1183 while (ahc->targetcmds[ahc->tqinfifonext].cmd_valid) { 1184 struct target_cmd *cmd; 1185 |
1182 cmd = &ahc->targetcmds[ahc->tqinfifonext++]; 1183 ahc_handle_target_cmd(ahc, cmd); | 1186 cmd = &ahc->targetcmds[ahc->tqinfifonext]; 1187 1188 /* 1189 * Only advance through the queue if we 1190 * had the resources to process the command. 1191 */ 1192 if (ahc_handle_target_cmd(ahc, cmd) != 0) 1193 break; 1194 ahc->tqinfifonext++; |
1184 cmd->cmd_valid = 0; 1185 } 1186 } 1187 } 1188 if (intstat & BRKADRINT) { 1189 /* 1190 * We upset the sequencer :-( 1191 * Lookup the error message --- 16 unchanged lines hidden (view full) --- 1208 if (intstat & SEQINT) 1209 ahc_handle_seqint(ahc, intstat); 1210 1211 if (intstat & SCSIINT) 1212 ahc_handle_scsiint(ahc, intstat); 1213} 1214 1215static void | 1195 cmd->cmd_valid = 0; 1196 } 1197 } 1198 } 1199 if (intstat & BRKADRINT) { 1200 /* 1201 * We upset the sequencer :-( 1202 * Lookup the error message --- 16 unchanged lines hidden (view full) --- 1219 if (intstat & SEQINT) 1220 ahc_handle_seqint(ahc, intstat); 1221 1222 if (intstat & SCSIINT) 1223 ahc_handle_scsiint(ahc, intstat); 1224} 1225 1226static void |
1227ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb) 1228{ 1229 struct tmode_tstate *tstate; 1230 struct tmode_lstate *lstate; 1231 struct ccb_en_lun *cel; 1232 cam_status status; 1233 int target; 1234 int lun; 1235 1236 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, &lstate, 1237 /* notfound_failure*/FALSE); 1238 1239 if (status != CAM_REQ_CMP) { 1240 ccb->ccb_h.status = status; 1241 return; 1242 } 1243 1244 cel = &ccb->cel; 1245 target = ccb->ccb_h.target_id; 1246 lun = ccb->ccb_h.target_lun; 1247 if (cel->enable != 0) { 1248 u_int scsiseq; 1249 1250 /* Are we already enabled?? */ 1251 if (lstate != NULL) { 1252 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA; 1253 return; 1254 } 1255 1256 if (cel->grp6_len != 0 1257 || cel->grp7_len != 0) { 1258 /* 1259 * Don't (yet?) support vendor 1260 * specific commands. 1261 */ 1262 ccb->ccb_h.status = CAM_REQ_INVALID; 1263 return; 1264 } 1265 1266 /* 1267 * Seems to be okay. 1268 * Setup our data structures. 1269 */ 1270 if (target != CAM_TARGET_WILDCARD && tstate == NULL) { 1271 tstate = malloc(sizeof(*tstate), M_DEVBUF, M_NOWAIT); 1272 if (tstate == NULL) { 1273 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 1274 return; 1275 } 1276 bzero(tstate, sizeof(*tstate)); 1277 ahc->enabled_targets[target] = tstate; 1278 } 1279 lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT); 1280 if (lstate == NULL) { 1281 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 1282 return; 1283 } 1284 bzero(lstate, sizeof(*lstate)); 1285 SLIST_INIT(&lstate->accept_tios); 1286 SLIST_INIT(&lstate->immed_notifies); 1287 if (target != CAM_TARGET_WILDCARD) { 1288 tstate->enabled_luns[lun] = lstate; 1289 ahc->enabled_luns++; 1290 } else 1291 ahc->black_hole = lstate; 1292 pause_sequencer(ahc); 1293 if ((ahc->features & AHC_MULTI_TID) != 0) { 1294 u_int16_t targid_mask; 1295 1296 targid_mask = ahc_inb(ahc, TARGID) 1297 | (ahc_inb(ahc, TARGID + 1) << 8); 1298 1299 targid_mask |= (0x01 << target); 1300 ahc_outb(ahc, TARGID, targid_mask); 1301 ahc_outb(ahc, TARGID+1, (targid_mask >> 8)); 1302 } 1303 /* Allow select-in operations */ 1304 if (ahc->black_hole != NULL && ahc->enabled_luns > 0) { 1305 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE); 1306 scsiseq |= ENSELI; 1307 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq); 1308 scsiseq = ahc_inb(ahc, SCSISEQ); 1309 scsiseq |= ENSELI; 1310 ahc_outb(ahc, SCSISEQ, scsiseq); 1311 } 1312 unpause_sequencer(ahc, /*always?*/FALSE); 1313 ccb->ccb_h.status = CAM_REQ_CMP; 1314 xpt_print_path(ccb->ccb_h.path); 1315 printf("Lun now enabled for target mode\n"); 1316 xpt_done(ccb); 1317 } else { 1318 struct ccb_hdr *elm; 1319 1320 if (lstate == NULL) { 1321 ccb->ccb_h.status = CAM_LUN_INVALID; 1322 return; 1323 } 1324 1325 ccb->ccb_h.status = CAM_REQ_CMP; 1326 LIST_FOREACH(elm, &ahc->pending_ccbs, sim_links.le) { 1327 if (elm->func_code == XPT_CONT_TARGET_IO 1328 && !xpt_path_comp(elm->path, ccb->ccb_h.path)){ 1329 printf("CTIO pending\n"); 1330 ccb->ccb_h.status = CAM_REQ_INVALID; 1331 return; 1332 } 1333 } 1334 1335 if (SLIST_FIRST(&lstate->accept_tios) != NULL) { 1336 printf("ATIOs pending\n"); 1337 ccb->ccb_h.status = CAM_REQ_INVALID; 1338 } 1339 1340 if (SLIST_FIRST(&lstate->immed_notifies) != NULL) { 1341 printf("INOTs pending\n"); 1342 ccb->ccb_h.status = CAM_REQ_INVALID; 1343 } 1344 1345 if (ccb->ccb_h.status == CAM_REQ_CMP) { 1346 int i, empty; 1347 1348 xpt_print_path(ccb->ccb_h.path); 1349 printf("Target mode disabled\n"); 1350 free(lstate, M_DEVBUF); 1351 1352 pause_sequencer(ahc); 1353 /* Can we clean up the target too? */ 1354 if (target != CAM_TARGET_WILDCARD) { 1355 tstate->enabled_luns[lun] = NULL; 1356 ahc->enabled_luns--; 1357 for (empty = 1, i = 0; i < 8; i++) 1358 if (tstate->enabled_luns[i] != NULL) { 1359 empty = 0; 1360 break; 1361 } 1362 if (empty) { 1363 free(tstate, M_DEVBUF); 1364 ahc->enabled_targets[target] = NULL; 1365 if (ahc->features & AHC_MULTI_TID) { 1366 u_int16_t targid_mask; 1367 1368 targid_mask = 1369 ahc_inb(ahc, TARGID) 1370 | (ahc_inb(ahc, TARGID + 1) 1371 << 8); 1372 1373 targid_mask &= (0x01 << target); 1374 ahc_outb(ahc, TARGID, 1375 targid_mask); 1376 ahc_outb(ahc, TARGID+1, 1377 (targid_mask >> 8)); 1378 } 1379 1380 for (empty = 1, i = 0; i < 16; i++) 1381 if (ahc->enabled_targets[i] 1382 != NULL) { 1383 empty = 0; 1384 break; 1385 } 1386 } 1387 } else { 1388 1389 ahc->black_hole = NULL; 1390 1391 /* 1392 * We can't allow selections without 1393 * our black hole device. 1394 */ 1395 empty = TRUE; 1396 } 1397 if (empty) { 1398 /* Disallow select-in */ 1399 u_int scsiseq; 1400 1401 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE); 1402 scsiseq &= ~ENSELI; 1403 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq); 1404 scsiseq = ahc_inb(ahc, SCSISEQ); 1405 scsiseq &= ~ENSELI; 1406 ahc_outb(ahc, SCSISEQ, scsiseq); 1407 } 1408 unpause_sequencer(ahc, /*always?*/FALSE); 1409 } 1410 } 1411} 1412 1413static int |
|
1216ahc_handle_target_cmd(struct ahc_softc *ahc, struct target_cmd *cmd) 1217{ 1218 struct tmode_tstate *tstate; 1219 struct tmode_lstate *lstate; 1220 struct ccb_accept_tio *atio; 1221 u_int8_t *byte; 1222 int initiator; 1223 int target; --- 5 unchanged lines hidden (view full) --- 1229 1230 byte = cmd->bytes; 1231 tstate = ahc->enabled_targets[target]; 1232 lstate = NULL; 1233 if (tstate != NULL && lun < 8) 1234 lstate = tstate->enabled_luns[lun]; 1235 1236 /* | 1414ahc_handle_target_cmd(struct ahc_softc *ahc, struct target_cmd *cmd) 1415{ 1416 struct tmode_tstate *tstate; 1417 struct tmode_lstate *lstate; 1418 struct ccb_accept_tio *atio; 1419 u_int8_t *byte; 1420 int initiator; 1421 int target; --- 5 unchanged lines hidden (view full) --- 1427 1428 byte = cmd->bytes; 1429 tstate = ahc->enabled_targets[target]; 1430 lstate = NULL; 1431 if (tstate != NULL && lun < 8) 1432 lstate = tstate->enabled_luns[lun]; 1433 1434 /* |
1237 * XXX Need to have a default TMODE devce that attaches to luns 1238 * that wouldn't otherwise be enabled and returns the proper 1239 * inquiry information. After all, we don't want to duplicate 1240 * this code in each driver. For now, simply drop it on the 1241 * floor. | 1435 * Commands for disabled luns go to the black hole driver. |
1242 */ 1243 if (lstate == NULL) { 1244 printf("Incoming Command on disabled lun\n"); | 1436 */ 1437 if (lstate == NULL) { 1438 printf("Incoming Command on disabled lun\n"); |
1245 return; | 1439 lstate = ahc->black_hole; 1440 atio = 1441 (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios); 1442 /* Fill in the wildcards */ 1443 atio->ccb_h.target_id = target; 1444 atio->ccb_h.target_lun = lun; 1445 } else { 1446 atio = 1447 (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios); |
1246 } | 1448 } |
1247 1248 atio = (struct ccb_accept_tio*)SLIST_FIRST(&lstate->accept_tios); 1249 /* XXX Should reconnect and return BUSY status */ | |
1250 if (atio == NULL) { 1251 printf("No ATIOs for incoming command\n"); | 1449 if (atio == NULL) { 1450 printf("No ATIOs for incoming command\n"); |
1252 return; | 1451 /* 1452 * Wait for more ATIOs from the peripheral driver for this lun. 1453 */ 1454 return (1); |
1253 } 1254 SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle); 1255 1256 /* 1257 * Package it up and send it off to 1258 * whomever has this lun enabled. 1259 */ 1260 atio->init_id = initiator; --- 38 unchanged lines hidden (view full) --- 1299 * We weren't allowed to disconnect. 1300 * We're hanging on the bus until a 1301 * continue target I/O comes in response 1302 * to this accept tio. 1303 */ 1304 ahc->pending_device = lstate; 1305 } 1306 xpt_done((union ccb*)atio); | 1455 } 1456 SLIST_REMOVE_HEAD(&lstate->accept_tios, sim_links.sle); 1457 1458 /* 1459 * Package it up and send it off to 1460 * whomever has this lun enabled. 1461 */ 1462 atio->init_id = initiator; --- 38 unchanged lines hidden (view full) --- 1501 * We weren't allowed to disconnect. 1502 * We're hanging on the bus until a 1503 * continue target I/O comes in response 1504 * to this accept tio. 1505 */ 1506 ahc->pending_device = lstate; 1507 } 1508 xpt_done((union ccb*)atio); |
1509 return (0); |
|
1307} 1308 1309static void 1310ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat) 1311{ 1312 struct scb *scb; 1313 struct ahc_devinfo devinfo; 1314 --- 213 unchanged lines hidden (view full) --- 1528 * sent yet. 1529 */ 1530 ahc_freeze_devq(ahc, scb->ccb->ccb_h.path); 1531 ahc_freeze_ccb(scb->ccb); 1532 break; 1533 } 1534 break; 1535 } | 1510} 1511 1512static void 1513ahc_handle_seqint(struct ahc_softc *ahc, u_int intstat) 1514{ 1515 struct scb *scb; 1516 struct ahc_devinfo devinfo; 1517 --- 213 unchanged lines hidden (view full) --- 1731 * sent yet. 1732 */ 1733 ahc_freeze_devq(ahc, scb->ccb->ccb_h.path); 1734 ahc_freeze_ccb(scb->ccb); 1735 break; 1736 } 1737 break; 1738 } |
1739 case TRACE_POINT: 1740 { 1741 printf("SSTAT2 = 0x%x DFCNTRL = 0x%x\n", ahc_inb(ahc, SSTAT2), 1742 ahc_inb(ahc, DFCNTRL)); 1743 printf("SSTAT3 = 0x%x DSTATUS = 0x%x\n", ahc_inb(ahc, SSTAT3), 1744 ahc_inb(ahc, DFSTATUS)); 1745 printf("SSTAT0 = 0x%x, SCB_DATACNT = 0x%x\n", 1746 ahc_inb(ahc, SSTAT0), 1747 ahc_inb(ahc, SCB_DATACNT)); 1748 break; 1749 } |
|
1536 case TARGET_MSG_HELP: 1537 { 1538 /* 1539 * XXX Handle BDR, Abort, Abort Tag, and transfer negotiations. 1540 */ 1541 restart_sequencer(ahc); 1542 return; 1543 } --- 722 unchanged lines hidden (view full) --- 2266 break; 2267 } 2268 case MSG_TYPE_TARGET_MSGIN: 2269 { 2270 int msgdone; 2271 int msgout_request; 2272 2273 if (ahc->msgout_len == 0) | 1750 case TARGET_MSG_HELP: 1751 { 1752 /* 1753 * XXX Handle BDR, Abort, Abort Tag, and transfer negotiations. 1754 */ 1755 restart_sequencer(ahc); 1756 return; 1757 } --- 722 unchanged lines hidden (view full) --- 2480 break; 2481 } 2482 case MSG_TYPE_TARGET_MSGIN: 2483 { 2484 int msgdone; 2485 int msgout_request; 2486 2487 if (ahc->msgout_len == 0) |
2274 panic("Target REQINIT with no active message"); | 2488 panic("Target MSGIN with no active message"); |
2275 2276 /* 2277 * If we interrupted a mesgout session, the initiator 2278 * will not know this until our first REQ. So, we 2279 * only honor mesgout requests after we've sent our 2280 * first byte. 2281 */ 2282 if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0 --- 161 unchanged lines hidden (view full) --- 2444 * the entire message is availible and has been 2445 * handled, return TRUE indicating that we have 2446 * parsed an entire message. 2447 * 2448 * In the case of extended messages, we accept the length 2449 * byte outright and perform more checking once we know the 2450 * extended message type. 2451 */ | 2489 2490 /* 2491 * If we interrupted a mesgout session, the initiator 2492 * will not know this until our first REQ. So, we 2493 * only honor mesgout requests after we've sent our 2494 * first byte. 2495 */ 2496 if ((ahc_inb(ahc, SCSISIGI) & ATNI) != 0 --- 161 unchanged lines hidden (view full) --- 2658 * the entire message is availible and has been 2659 * handled, return TRUE indicating that we have 2660 * parsed an entire message. 2661 * 2662 * In the case of extended messages, we accept the length 2663 * byte outright and perform more checking once we know the 2664 * extended message type. 2665 */ |
2452 if (ahc->msgin_buf[0] == MSG_MESSAGE_REJECT) { | 2666 switch (ahc->msgin_buf[0]) { 2667 case MSG_MESSAGE_REJECT: |
2453 response = ahc_handle_msg_reject(ahc, devinfo); | 2668 response = ahc_handle_msg_reject(ahc, devinfo); |
2669 /* FALLTHROUGH */ 2670 case MSG_NOOP: |
|
2454 done = TRUE; | 2671 done = TRUE; |
2455 } else if (ahc->msgin_buf[0] == MSG_NOOP) { 2456 done = TRUE; 2457 } else if (ahc->msgin_buf[0] != MSG_EXTENDED) { 2458 reject = TRUE; 2459 } else if (ahc->msgin_index >= 2) { | 2672 break; 2673 case MSG_IGN_WIDE_RESIDUE: 2674 { 2675 struct ahc_target_tinfo *tinfo; 2676 2677 tinfo = &ahc->transinfo[devinfo->target_offset]; 2678 /* Wait for the whole message */ 2679 if (ahc->msgin_index >= 1) { 2680 if (ahc->msgin_buf[1] != 1 2681 || tinfo->current.width == MSG_EXT_WDTR_BUS_8_BIT) { 2682 reject = TRUE; 2683 done = TRUE; 2684 } else 2685 ahc_handle_ign_wide_residue(ahc, devinfo); 2686 } 2687 } 2688 case MSG_EXTENDED: 2689 { 2690 /* Wait for enough of the message to begin validation */ 2691 if (ahc->msgin_index < 2) 2692 break; |
2460 switch (ahc->msgin_buf[2]) { 2461 case MSG_EXT_SDTR: 2462 { 2463 struct ahc_syncrate *syncrate; 2464 u_int period; 2465 u_int offset; 2466 u_int saved_offset; 2467 --- 63 unchanged lines hidden (view full) --- 2531 * and acting on this message. 2532 * 2533 * Add one to MSG_EXT_WDTR_LEN to account for 2534 * the extended message preamble. 2535 */ 2536 if (ahc->msgin_index < (MSG_EXT_WDTR_LEN + 1)) 2537 break; 2538 | 2693 switch (ahc->msgin_buf[2]) { 2694 case MSG_EXT_SDTR: 2695 { 2696 struct ahc_syncrate *syncrate; 2697 u_int period; 2698 u_int offset; 2699 u_int saved_offset; 2700 --- 63 unchanged lines hidden (view full) --- 2764 * and acting on this message. 2765 * 2766 * Add one to MSG_EXT_WDTR_LEN to account for 2767 * the extended message preamble. 2768 */ 2769 if (ahc->msgin_index < (MSG_EXT_WDTR_LEN + 1)) 2770 break; 2771 |
2539 if (devinfo->role == ROLE_TARGET) { | 2772 /* 2773 * Due to a problem with sync/wide transfers 2774 * on the aic7880 only allow this on Ultra2 2775 * controllers for the moment. 2776 */ 2777 if (devinfo->role == ROLE_TARGET 2778 && (ahc->features & AHC_ULTRA2) == 0) { |
2540 reject = TRUE; 2541 break; 2542 } 2543 2544 bus_width = ahc->msgin_buf[3]; 2545 if (ahc_sent_msg(ahc, MSG_EXT_WDTR, /*full*/TRUE)) { 2546 /* 2547 * Don't send a WDTR back to the --- 78 unchanged lines hidden (view full) --- 2626 break; 2627 } 2628 default: 2629 /* Unknown extended message. Reject it. */ 2630 reject = TRUE; 2631 break; 2632 } 2633 } | 2779 reject = TRUE; 2780 break; 2781 } 2782 2783 bus_width = ahc->msgin_buf[3]; 2784 if (ahc_sent_msg(ahc, MSG_EXT_WDTR, /*full*/TRUE)) { 2785 /* 2786 * Don't send a WDTR back to the --- 78 unchanged lines hidden (view full) --- 2865 break; 2866 } 2867 default: 2868 /* Unknown extended message. Reject it. */ 2869 reject = TRUE; 2870 break; 2871 } 2872 } |
2873 case MSG_ABORT: 2874 case MSG_ABORT_TAG: 2875 case MSG_BUS_DEV_RESET: 2876 case MSG_CLEAR_QUEUE: 2877 case MSG_TERM_IO_PROC: 2878 /* Target mode messages */ 2879 if (devinfo->role != ROLE_TARGET) 2880 reject = TRUE; 2881 break; 2882 default: 2883 reject = TRUE; 2884 break; 2885 } |
|
2634 2635 if (reject) { 2636 /* 2637 * Assert attention and setup to 2638 * reject the message. 2639 */ 2640 ahc->msgout_index = 0; 2641 ahc->msgout_len = 1; --- 5 unchanged lines hidden (view full) --- 2647 if (done && !response) 2648 /* Clear the outgoing message buffer */ 2649 ahc->msgout_len = 0; 2650 2651 return (done); 2652} 2653 2654static void | 2886 2887 if (reject) { 2888 /* 2889 * Assert attention and setup to 2890 * reject the message. 2891 */ 2892 ahc->msgout_index = 0; 2893 ahc->msgout_len = 1; --- 5 unchanged lines hidden (view full) --- 2899 if (done && !response) 2900 /* Clear the outgoing message buffer */ 2901 ahc->msgout_len = 0; 2902 2903 return (done); 2904} 2905 2906static void |
2907ahc_handle_ign_wide_residue(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) 2908{ 2909 u_int scb_index; 2910 struct scb *scb; 2911 2912 scb_index = ahc_inb(ahc, SCB_TAG); 2913 scb = ahc->scb_data->scbarray[scb_index]; 2914 if ((ahc_inb(ahc, SEQ_FLAGS) & DPHASE) == 0 2915 || (scb->ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_IN) { 2916 /* 2917 * Ignore the message if we haven't 2918 * seen an appropriate data phase yet. 2919 */ 2920 } else { 2921 /* 2922 * If the residual occurred on the last 2923 * transfer and the transfer request was 2924 * expected to end on an odd count, do 2925 * nothing. Otherwise, subtract a byte 2926 * and update the residual count accordingly. 2927 */ 2928 u_int resid_sgcnt; 2929 2930 resid_sgcnt = ahc_inb(ahc, SCB_RESID_SGCNT); 2931 if (resid_sgcnt == 0 2932 && ahc_inb(ahc, DATA_COUNT_ODD) == 1) { 2933 /* 2934 * If the residual occurred on the last 2935 * transfer and the transfer request was 2936 * expected to end on an odd count, do 2937 * nothing. 2938 */ 2939 } else { 2940 u_int data_cnt; 2941 u_int data_addr; 2942 u_int sg_index; 2943 2944 data_cnt = (ahc_inb(ahc, SCB_RESID_DCNT + 2) << 16) 2945 | (ahc_inb(ahc, SCB_RESID_DCNT + 1) << 8) 2946 | (ahc_inb(ahc, SCB_RESID_DCNT)); 2947 2948 data_addr = (ahc_inb(ahc, SHADDR + 3) << 24) 2949 | (ahc_inb(ahc, SHADDR + 2) << 16) 2950 | (ahc_inb(ahc, SHADDR + 1) << 8) 2951 | (ahc_inb(ahc, SHADDR)); 2952 2953 data_cnt += 1; 2954 data_addr -= 1; 2955 2956 sg_index = scb->sg_count - resid_sgcnt; 2957 2958 /* 2959 * scb->ahc_dma starts with the second S/G entry. 2960 */ 2961 if (sg_index-- != 0 2962 && (scb->ahc_dma[sg_index].len < data_cnt)) { 2963 u_int sg_addr; 2964 2965 data_cnt = 1; 2966 data_addr = scb->ahc_dma[sg_index - 1].addr 2967 + scb->ahc_dma[sg_index - 1].len - 1; 2968 2969 sg_addr = scb->ahc_dmaphys 2970 + (sg_index * sizeof(*scb->ahc_dma)); 2971 ahc_outb(ahc, SG_NEXT + 3, sg_addr >> 24); 2972 ahc_outb(ahc, SG_NEXT + 2, sg_addr >> 16); 2973 ahc_outb(ahc, SG_NEXT + 1, sg_addr >> 8); 2974 ahc_outb(ahc, SG_NEXT, sg_addr); 2975 } 2976 2977 ahc_outb(ahc, SCB_RESID_DCNT + 2, data_cnt >> 16); 2978 ahc_outb(ahc, SCB_RESID_DCNT + 1, data_cnt >> 8); 2979 ahc_outb(ahc, SCB_RESID_DCNT, data_cnt); 2980 2981 ahc_outb(ahc, SHADDR + 3, data_addr >> 24); 2982 ahc_outb(ahc, SHADDR + 2, data_addr >> 16); 2983 ahc_outb(ahc, SHADDR + 1, data_addr >> 8); 2984 ahc_outb(ahc, SHADDR, data_addr); 2985 } 2986 } 2987} 2988 2989static void |
|
2655ahc_handle_devreset(struct ahc_softc *ahc, int target, char channel, 2656 cam_status status, ac_code acode, char *message, 2657 int verbose_only) 2658{ 2659 struct ahc_devinfo devinfo; 2660 struct cam_path *path; 2661 int found; 2662 int error; --- 596 unchanged lines hidden (view full) --- 3259 /* 3260 * If we are not configured for target mode, someone 3261 * is really confused to be sending this to us. 3262 */ 3263 if ((ahc->flags & AHC_TARGETMODE) == 0) 3264 return (CAM_REQ_INVALID); 3265 3266 /* Range check target and lun */ | 2990ahc_handle_devreset(struct ahc_softc *ahc, int target, char channel, 2991 cam_status status, ac_code acode, char *message, 2992 int verbose_only) 2993{ 2994 struct ahc_devinfo devinfo; 2995 struct cam_path *path; 2996 int found; 2997 int error; --- 596 unchanged lines hidden (view full) --- 3594 /* 3595 * If we are not configured for target mode, someone 3596 * is really confused to be sending this to us. 3597 */ 3598 if ((ahc->flags & AHC_TARGETMODE) == 0) 3599 return (CAM_REQ_INVALID); 3600 3601 /* Range check target and lun */ |
3267 if (cam_sim_bus(sim) == 0) 3268 our_id = ahc->our_id; 3269 else 3270 our_id = ahc->our_id_b; 3271 if (ccb->ccb_h.target_id > ((ahc->features & AHC_WIDE) ? 15 : 7) 3272 || ((ahc->features & AHC_MULTI_TID) == 0 3273 && (ccb->ccb_h.target_id != our_id))) 3274 return (CAM_TID_INVALID); | |
3275 | 3602 |
3276 if (ccb->ccb_h.target_lun > 8) 3277 return (CAM_LUN_INVALID); | 3603 /* 3604 * Handle the 'black hole' device that sucks up 3605 * requests to unattached luns on enabled targets. 3606 */ 3607 if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD 3608 && ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) { 3609 *tstate = NULL; 3610 *lstate = ahc->black_hole; 3611 } else { 3612 if (cam_sim_bus(sim) == 0) 3613 our_id = ahc->our_id; 3614 else 3615 our_id = ahc->our_id_b; 3616 if (ccb->ccb_h.target_id > ((ahc->features & AHC_WIDE) ? 15 : 7) 3617 || ((ahc->features & AHC_MULTI_TID) == 0 3618 && (ccb->ccb_h.target_id != our_id))) 3619 return (CAM_TID_INVALID); |
3278 | 3620 |
3279 *tstate = ahc->enabled_targets[ccb->ccb_h.target_id]; 3280 *lstate = NULL; 3281 if (*tstate != NULL) 3282 *lstate = (*tstate)->enabled_luns[ccb->ccb_h.target_lun]; | 3621 if (ccb->ccb_h.target_lun > 8) 3622 return (CAM_LUN_INVALID); |
3283 | 3623 |
3624 *tstate = ahc->enabled_targets[ccb->ccb_h.target_id]; 3625 *lstate = NULL; 3626 if (*tstate != NULL) 3627 *lstate = 3628 (*tstate)->enabled_luns[ccb->ccb_h.target_lun]; 3629 } 3630 |
|
3284 if (notfound_failure != 0 && *lstate == NULL) 3285 return (CAM_PATH_INVALID); 3286 3287 return (CAM_REQ_CMP); 3288} 3289 3290static void 3291ahc_action(struct cam_sim *sim, union ccb *ccb) --- 16 unchanged lines hidden (view full) --- 3308 { 3309 struct tmode_tstate *tstate; 3310 cam_status status; 3311 3312 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, 3313 &lstate, TRUE); 3314 3315 if (status != CAM_REQ_CMP) { | 3631 if (notfound_failure != 0 && *lstate == NULL) 3632 return (CAM_PATH_INVALID); 3633 3634 return (CAM_REQ_CMP); 3635} 3636 3637static void 3638ahc_action(struct cam_sim *sim, union ccb *ccb) --- 16 unchanged lines hidden (view full) --- 3655 { 3656 struct tmode_tstate *tstate; 3657 cam_status status; 3658 3659 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, 3660 &lstate, TRUE); 3661 3662 if (status != CAM_REQ_CMP) { |
3316 ccb->ccb_h.status = status; 3317 xpt_done(ccb); 3318 break; | 3663 if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) { 3664 /* Response from the black hole device */ 3665 tstate = NULL; 3666 lstate = ahc->black_hole; 3667 } else { 3668 ccb->ccb_h.status = status; 3669 xpt_done(ccb); 3670 break; 3671 } |
3319 } 3320 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) { 3321 SLIST_INSERT_HEAD(&lstate->accept_tios, &ccb->ccb_h, 3322 sim_links.sle); 3323 ccb->ccb_h.status = CAM_REQ_INPROG; 3324 break; 3325 } 3326 --- 110 unchanged lines hidden (view full) --- 3437 /* Clear notification state */ 3438 } 3439 SLIST_INSERT_HEAD(&lstate->immed_notifies, &ccb->ccb_h, 3440 sim_links.sle); 3441 ccb->ccb_h.status = CAM_REQ_INPROG; 3442 break; 3443 } 3444 case XPT_EN_LUN: /* Enable LUN as a target */ | 3672 } 3673 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) { 3674 SLIST_INSERT_HEAD(&lstate->accept_tios, &ccb->ccb_h, 3675 sim_links.sle); 3676 ccb->ccb_h.status = CAM_REQ_INPROG; 3677 break; 3678 } 3679 --- 110 unchanged lines hidden (view full) --- 3790 /* Clear notification state */ 3791 } 3792 SLIST_INSERT_HEAD(&lstate->immed_notifies, &ccb->ccb_h, 3793 sim_links.sle); 3794 ccb->ccb_h.status = CAM_REQ_INPROG; 3795 break; 3796 } 3797 case XPT_EN_LUN: /* Enable LUN as a target */ |
3445 { 3446 struct tmode_tstate *tstate; 3447 struct tmode_lstate *lstate; 3448 struct ccb_en_lun *cel; 3449 cam_status status; 3450 int target; 3451 int lun; 3452 3453 status = ahc_find_tmode_devs(ahc, sim, ccb, &tstate, &lstate, 3454 /* notfound_failure*/FALSE); 3455 3456 if (status != CAM_REQ_CMP) { 3457 ccb->ccb_h.status = status; 3458 xpt_done(ccb); 3459 break; 3460 } 3461 3462 cel = &ccb->cel; 3463 target = ccb->ccb_h.target_id; 3464 lun = ccb->ccb_h.target_lun; 3465 if (cel->enable != 0) { 3466 u_int scsiseq; 3467 3468 /* Are we already enabled?? */ 3469 if (lstate != NULL) { 3470 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA; 3471 xpt_done(ccb); 3472 break; 3473 } 3474 3475 if (cel->grp6_len != 0 3476 || cel->grp7_len != 0) { 3477 /* 3478 * Don't (yet?) support vendor 3479 * specific commands. 3480 */ 3481 ccb->ccb_h.status = CAM_REQ_INVALID; 3482 xpt_done(ccb); 3483 break; 3484 } 3485 3486 /* 3487 * Seems to be okay. 3488 * Setup our data structures. 3489 */ 3490 if (tstate == NULL) { 3491 tstate = malloc(sizeof(*tstate), 3492 M_DEVBUF, M_NOWAIT); 3493 if (tstate == NULL) { 3494 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 3495 xpt_done(ccb); 3496 break; 3497 } 3498 bzero(tstate, sizeof(*tstate)); 3499 ahc->enabled_targets[target] = tstate; 3500 } 3501 lstate = malloc(sizeof(*lstate), M_DEVBUF, M_NOWAIT); 3502 if (lstate == NULL) { 3503 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 3504 xpt_done(ccb); 3505 break; 3506 } 3507 bzero(lstate, sizeof(*lstate)); 3508 SLIST_INIT(&lstate->accept_tios); 3509 SLIST_INIT(&lstate->immed_notifies); 3510 tstate->enabled_luns[lun] = lstate; 3511 pause_sequencer(ahc); 3512 if ((ahc->features & AHC_MULTI_TID) != 0) { 3513 u_int16_t targid_mask; 3514 3515 targid_mask = ahc_inb(ahc, TARGID) 3516 | (ahc_inb(ahc, TARGID + 1) << 8); 3517 3518 targid_mask |= (0x01 << target); 3519 ahc_outb(ahc, TARGID, targid_mask); 3520 ahc_outb(ahc, TARGID+1, (targid_mask >> 8)); 3521 } 3522 /* Allow select-in operations */ 3523 scsiseq = ahc_inb(ahc, SCSISEQ_TEMPLATE); 3524 scsiseq |= ENSELI; 3525 ahc_outb(ahc, SCSISEQ_TEMPLATE, scsiseq); 3526 scsiseq = ahc_inb(ahc, SCSISEQ); 3527 scsiseq |= ENSELI; 3528 ahc_outb(ahc, SCSISEQ, scsiseq); 3529 unpause_sequencer(ahc, /*always?*/FALSE); 3530 ccb->ccb_h.status = CAM_REQ_CMP; 3531 xpt_print_path(ccb->ccb_h.path); 3532 printf("Lun now enabled for target mode\n"); 3533 xpt_done(ccb); 3534 break; 3535 } else { 3536 struct ccb_hdr *elm; 3537 3538 /* XXX Fully Implement Disable */ 3539 if (lstate == NULL) { 3540 ccb->ccb_h.status = CAM_LUN_INVALID; 3541 xpt_done(ccb); 3542 break; 3543 } 3544 3545 ccb->ccb_h.status = CAM_REQ_CMP; 3546 LIST_FOREACH(elm, &ahc->pending_ccbs, sim_links.le) { 3547 if (elm->func_code == XPT_CONT_TARGET_IO 3548 && !xpt_path_comp(elm->path, ccb->ccb_h.path)){ 3549 printf("CTIO pending\n"); 3550 ccb->ccb_h.status = CAM_REQ_INVALID; 3551 break; 3552 } 3553 } 3554 3555 if (SLIST_FIRST(&lstate->accept_tios) != NULL) { 3556 printf("ATIOs pending\n"); 3557 ccb->ccb_h.status = CAM_REQ_INVALID; 3558 } 3559 3560 if (SLIST_FIRST(&lstate->immed_notifies) != NULL) { 3561 printf("INOTs pending\n"); 3562 ccb->ccb_h.status = CAM_REQ_INVALID; 3563 } 3564 3565 if (ccb->ccb_h.status == CAM_REQ_CMP) { 3566 int i, empty; 3567 3568 free(lstate, M_DEVBUF); 3569 tstate->enabled_luns[lun] = NULL; 3570 3571 /* Can we clean up the target too? */ 3572 for (empty = 1, i = 0; i < 8; i++) 3573 if (tstate->enabled_luns[i] != NULL) { 3574 empty = 0; 3575 break; 3576 } 3577 if (empty) { 3578 printf("Target Empty\n"); 3579 free(tstate, M_DEVBUF); 3580 ahc->enabled_targets[target] = NULL; 3581 pause_sequencer(ahc); 3582 if (ahc->features & AHC_MULTI_TID) { 3583 u_int16_t targid_mask; 3584 3585 targid_mask = 3586 ahc_inb(ahc, TARGID) 3587 | (ahc_inb(ahc, TARGID + 1) 3588 << 8); 3589 3590 targid_mask &= (0x01 << target); 3591 ahc_outb(ahc, TARGID, 3592 targid_mask); 3593 ahc_outb(ahc, TARGID+1, 3594 (targid_mask >> 8)); 3595 } 3596 3597 for (empty = 1, i = 0; i < 16; i++) 3598 if (ahc->enabled_targets[i] 3599 != NULL) { 3600 empty = 0; 3601 break; 3602 } 3603 if (empty) { 3604 /* Disallow select-in */ 3605 u_int scsiseq; 3606 3607 printf("No targets\n"); 3608 scsiseq = 3609 ahc_inb(ahc, 3610 SCSISEQ_TEMPLATE); 3611 scsiseq &= ~ENSELI; 3612 ahc_outb(ahc, SCSISEQ_TEMPLATE, 3613 scsiseq); 3614 scsiseq = ahc_inb(ahc, SCSISEQ); 3615 scsiseq &= ~ENSELI; 3616 ahc_outb(ahc, SCSISEQ, scsiseq); 3617 } 3618 unpause_sequencer(ahc, 3619 /*always?*/FALSE); 3620 } 3621 } 3622 xpt_done(ccb); 3623 break; 3624 } | 3798 ahc_handle_en_lun(ahc, sim, ccb); 3799 xpt_done(ccb); |
3625 break; | 3800 break; |
3626 } | |
3627 case XPT_ABORT: /* Abort the specified CCB */ 3628 { 3629 ahc_abort_ccb(ahc, sim, ccb); 3630 break; 3631 } 3632 case XPT_SET_TRAN_SETTINGS: 3633 { 3634 struct ahc_devinfo devinfo; --- 1780 unchanged lines hidden --- | 3801 case XPT_ABORT: /* Abort the specified CCB */ 3802 { 3803 ahc_abort_ccb(ahc, sim, ccb); 3804 break; 3805 } 3806 case XPT_SET_TRAN_SETTINGS: 3807 { 3808 struct ahc_devinfo devinfo; --- 1780 unchanged lines hidden --- |