Deleted Added
full compact
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 ---