in FlashPoint.c [2275:2564]
static void FPT_ssel(u32 port, unsigned char p_card)
{
unsigned char auto_loaded, i, target, *theCCB;
u32 cdb_reg;
struct sccb_card *CurrCard;
struct sccb *currSCCB;
struct sccb_mgr_tar_info *currTar_Info;
unsigned char lastTag, lun;
CurrCard = &FPT_BL_Card[p_card];
currSCCB = CurrCard->currentSCCB;
target = currSCCB->TargID;
currTar_Info = &FPT_sccbMgrTbl[p_card][target];
lastTag = CurrCard->tagQ_Lst;
ARAM_ACCESS(port);
if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
currSCCB->ControlByte &= ~F_USE_CMD_Q;
if (((CurrCard->globalFlags & F_CONLUN_IO) &&
((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
lun = currSCCB->Lun;
else
lun = 0;
if (CurrCard->globalFlags & F_TAG_STARTED) {
if (!(currSCCB->ControlByte & F_USE_CMD_Q)) {
if ((currTar_Info->TarLUN_CA == 0)
&& ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
== TAG_Q_TRYING)) {
if (currTar_Info->TarTagQ_Cnt != 0) {
currTar_Info->TarLUNBusy[lun] = 1;
FPT_queueSelectFail(CurrCard, p_card);
SGRAM_ACCESS(port);
return;
}
else {
currTar_Info->TarLUNBusy[lun] = 1;
}
}
/*End non-tagged */
else {
currTar_Info->TarLUNBusy[lun] = 1;
}
}
/*!Use cmd Q Tagged */
else {
if (currTar_Info->TarLUN_CA == 1) {
FPT_queueSelectFail(CurrCard, p_card);
SGRAM_ACCESS(port);
return;
}
currTar_Info->TarLUNBusy[lun] = 1;
} /*else use cmd Q tagged */
}
/*if glob tagged started */
else {
currTar_Info->TarLUNBusy[lun] = 1;
}
if ((((CurrCard->globalFlags & F_CONLUN_IO) &&
((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
|| (!(currSCCB->ControlByte & F_USE_CMD_Q)))) {
if (CurrCard->discQCount >= QUEUE_DEPTH) {
currTar_Info->TarLUNBusy[lun] = 1;
FPT_queueSelectFail(CurrCard, p_card);
SGRAM_ACCESS(port);
return;
}
for (i = 1; i < QUEUE_DEPTH; i++) {
if (++lastTag >= QUEUE_DEPTH)
lastTag = 1;
if (CurrCard->discQ_Tbl[lastTag] == NULL) {
CurrCard->tagQ_Lst = lastTag;
currTar_Info->LunDiscQ_Idx[lun] = lastTag;
CurrCard->discQ_Tbl[lastTag] = currSCCB;
CurrCard->discQCount++;
break;
}
}
if (i == QUEUE_DEPTH) {
currTar_Info->TarLUNBusy[lun] = 1;
FPT_queueSelectFail(CurrCard, p_card);
SGRAM_ACCESS(port);
return;
}
}
auto_loaded = 0;
WR_HARPOON(port + hp_select_id, target);
WR_HARPOON(port + hp_gp_reg_3, target); /* Use by new automation logic */
if (currSCCB->OperationCode == RESET_COMMAND) {
WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
(currSCCB->
Sccb_idmsg & ~DISC_PRIV)));
WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP);
currSCCB->Sccb_scsimsg = TARGET_RESET;
WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
auto_loaded = 1;
currSCCB->Sccb_scsistat = SELECT_BDR_ST;
if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
currTar_Info->TarSyncCtrl = 0;
currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
}
if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
}
FPT_sssyncv(port, target, NARROW_SCSI, currTar_Info);
FPT_SccbMgrTableInitTarget(p_card, target);
}
else if (currSCCB->Sccb_scsistat == ABORT_ST) {
WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
(currSCCB->
Sccb_idmsg & ~DISC_PRIV)));
WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT +
(((unsigned
char)(currSCCB->
ControlByte &
TAG_TYPE_MASK)
>> 6) | (unsigned char)
0x20)));
WRW_HARPOON((port + SYNC_MSGS + 2),
(MPM_OP + AMSG_OUT + currSCCB->Sccb_tag));
WRW_HARPOON((port + SYNC_MSGS + 4), (BRH_OP + ALWAYS + NP));
WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
auto_loaded = 1;
}
else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
auto_loaded = FPT_siwidn(port, p_card);
currSCCB->Sccb_scsistat = SELECT_WN_ST;
}
else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
== SYNC_SUPPORTED)) {
auto_loaded = FPT_sisyncn(port, p_card, 0);
currSCCB->Sccb_scsistat = SELECT_SN_ST;
}
if (!auto_loaded) {
if (currSCCB->ControlByte & F_USE_CMD_Q) {
CurrCard->globalFlags |= F_TAG_STARTED;
if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
== TAG_Q_REJECT) {
currSCCB->ControlByte &= ~F_USE_CMD_Q;
/* Fix up the start instruction with a jump to
Non-Tag-CMD handling */
WRW_HARPOON((port + ID_MSG_STRT),
BRH_OP + ALWAYS + NTCMD);
WRW_HARPOON((port + NON_TAG_ID_MSG),
(MPM_OP + AMSG_OUT +
currSCCB->Sccb_idmsg));
WR_HARPOON(port + hp_autostart_3,
(SELECT + SELCHK_STRT));
/* Setup our STATE so we know what happened when
the wheels fall off. */
currSCCB->Sccb_scsistat = SELECT_ST;
currTar_Info->TarLUNBusy[lun] = 1;
}
else {
WRW_HARPOON((port + ID_MSG_STRT),
(MPM_OP + AMSG_OUT +
currSCCB->Sccb_idmsg));
WRW_HARPOON((port + ID_MSG_STRT + 2),
(MPM_OP + AMSG_OUT +
(((unsigned char)(currSCCB->
ControlByte &
TAG_TYPE_MASK)
>> 6) | (unsigned char)0x20)));
for (i = 1; i < QUEUE_DEPTH; i++) {
if (++lastTag >= QUEUE_DEPTH)
lastTag = 1;
if (CurrCard->discQ_Tbl[lastTag] ==
NULL) {
WRW_HARPOON((port +
ID_MSG_STRT + 6),
(MPM_OP + AMSG_OUT +
lastTag));
CurrCard->tagQ_Lst = lastTag;
currSCCB->Sccb_tag = lastTag;
CurrCard->discQ_Tbl[lastTag] =
currSCCB;
CurrCard->discQCount++;
break;
}
}
if (i == QUEUE_DEPTH) {
currTar_Info->TarLUNBusy[lun] = 1;
FPT_queueSelectFail(CurrCard, p_card);
SGRAM_ACCESS(port);
return;
}
currSCCB->Sccb_scsistat = SELECT_Q_ST;
WR_HARPOON(port + hp_autostart_3,
(SELECT + SELCHK_STRT));
}
}
else {
WRW_HARPOON((port + ID_MSG_STRT),
BRH_OP + ALWAYS + NTCMD);
WRW_HARPOON((port + NON_TAG_ID_MSG),
(MPM_OP + AMSG_OUT + currSCCB->Sccb_idmsg));
currSCCB->Sccb_scsistat = SELECT_ST;
WR_HARPOON(port + hp_autostart_3,
(SELECT + SELCHK_STRT));
}
theCCB = (unsigned char *)&currSCCB->Cdb[0];
cdb_reg = port + CMD_STRT;
for (i = 0; i < currSCCB->CdbLength; i++) {
WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
cdb_reg += 2;
theCCB++;
}
if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
}
/* auto_loaded */
WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
WR_HARPOON(port + hp_xferstat, 0x00);
WRW_HARPOON((port + hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT));
if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED)) {
WR_HARPOON(port + hp_scsictrl_0,
(SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
} else {
/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
auto_loaded |= AUTO_IMMED; */
auto_loaded = AUTO_IMMED;
DISABLE_AUTO(port);
WR_HARPOON(port + hp_autostart_3, auto_loaded);
}
SGRAM_ACCESS(port);
}