}\r
}\r
\r
- if ((scsiDev.status == GOOD) && (control & 0x01))\r
+ if ((scsiDev.status == GOOD) && (control & 0x01) &&\r
+ scsiDev.target->cfg->quirks != S2S_CFG_QUIRKS_XEBEC)\r
{\r
// Linked command.\r
scsiDev.status = INTERMEDIATE;\r
message = MSG_COMMAND_COMPLETE;\r
}\r
\r
- if (scsiDev.target->cfg->quirks == S2S_CFG_QUIRKS_OMTI)\r
+ if (scsiDev.target->cfg->quirks == S2S_CFG_QUIRKS_XEBEC)\r
+ {\r
+ // More non-standardness. Expects 2 status bytes (really status + msg)\r
+ // 00 d 000 err 0\r
+ // d == disk number\r
+ // ERR = 1 if error.\r
+ if (scsiDev.status == GOOD)\r
+ {\r
+ scsiWriteByte(scsiDev.cdb[1] & 0x20);\r
+ }\r
+ else\r
+ {\r
+ scsiWriteByte((scsiDev.cdb[1] & 0x20) | 0x2);\r
+ }\r
+ s2s_delay_us(10); // Seems to need a delay before changing phase bits.\r
+ }\r
+ else if (scsiDev.target->cfg->quirks == S2S_CFG_QUIRKS_OMTI)\r
{\r
scsiDev.status |= (scsiDev.target->targetId & 0x03) << 5;\r
+ scsiWriteByte(scsiDev.status);\r
+ }\r
+ else\r
+ {\r
+ scsiWriteByte(scsiDev.status);\r
}\r
-\r
- scsiWriteByte(scsiDev.status);\r
\r
scsiDev.lastStatus = scsiDev.status;\r
scsiDev.lastSense = scsiDev.target->sense.code;\r
// Prefer LUN's set by IDENTIFY messages for newer hosts.\r
if (scsiDev.lun < 0)\r
{\r
- scsiDev.lun = scsiDev.cdb[1] >> 5;\r
+ if (command == 0xE0 || command == 0xE4) // XEBEC s1410\r
+ {\r
+ scsiDev.lun = 0;\r
+ }\r
+ else\r
+ {\r
+ scsiDev.lun = scsiDev.cdb[1] >> 5;\r
+ }\r
+ }\r
+\r
+\r
+ // For Philips P2000C with Xebec S1410 SASI/MFM adapter\r
+ // http://bitsavers.trailing-edge.com/pdf/xebec/104524C_S1410Man_Aug83.pdf\r
+ if ((scsiDev.lun > 0) && (scsiDev.boardCfg.flags & S2S_CFG_MAP_LUNS_TO_IDS))\r
+ {\r
+ int tgtIndex;\r
+ for (tgtIndex = 0; tgtIndex < S2S_MAX_TARGETS; ++tgtIndex)\r
+ {\r
+ if (scsiDev.targets[tgtIndex].targetId == scsiDev.lun)\r
+ {\r
+ scsiDev.target = &scsiDev.targets[tgtIndex];\r
+ scsiDev.lun = 0;\r
+ break;\r
+ }\r
+ }\r
}\r
\r
control = scsiDev.cdb[scsiDev.cdbLen - 1];\r
scsiDev.target->sense.asc = SCSI_PARITY_ERROR;\r
enter_Status(CHECK_CONDITION);\r
}\r
- else if ((control & 0x02) && ((control & 0x01) == 0))\r
+ else if ((control & 0x02) && ((control & 0x01) == 0) &&\r
+ // used for head step options on xebec.\r
+ likely(scsiDev.target->cfg->quirks != S2S_CFG_QUIRKS_XEBEC))\r
{\r
// FLAG set without LINK flag.\r
scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
// REQUEST SENSE\r
uint32_t allocLength = scsiDev.cdb[4];\r
\r
- // As specified by the SASI and SCSI1 standard.\r
- // Newer initiators won't be specifying 0 anyway.\r
- if (allocLength == 0) allocLength = 4;\r
-\r
- memset(scsiDev.data, 0, 256); // Max possible alloc length\r
- scsiDev.data[0] = 0xF0;\r
- scsiDev.data[2] = scsiDev.target->sense.code & 0x0F;\r
-\r
- scsiDev.data[3] = transfer.lba >> 24;\r
- scsiDev.data[4] = transfer.lba >> 16;\r
- scsiDev.data[5] = transfer.lba >> 8;\r
- scsiDev.data[6] = transfer.lba;\r
+ if (scsiDev.target->cfg->quirks == S2S_CFG_QUIRKS_XEBEC)\r
+ {\r
+ // Completely non-standard\r
+ allocLength = 4;\r
+ if (scsiDev.target->sense.code == NO_SENSE)\r
+ scsiDev.data[0] = 0;\r
+ else if (scsiDev.target->sense.code == ILLEGAL_REQUEST)\r
+ scsiDev.data[0] = 0x20; // Illegal command\r
+ else if (scsiDev.target->sense.code == NOT_READY)\r
+ scsiDev.data[0] = 0x04; // Drive not ready\r
+ else\r
+ scsiDev.data[0] = 0x11; // Uncorrectable data error\r
\r
- // Additional bytes if there are errors to report\r
- scsiDev.data[7] = 10; // additional length\r
- scsiDev.data[12] = scsiDev.target->sense.asc >> 8;\r
- scsiDev.data[13] = scsiDev.target->sense.asc;\r
+ scsiDev.data[1] = (scsiDev.cdb[1] & 0x20) | ((transfer.lba >> 16) & 0x1F);\r
+ scsiDev.data[2] = transfer.lba >> 8;\r
+ scsiDev.data[3] = transfer.lba;\r
+ }\r
+ else\r
+ {\r
+ // As specified by the SASI and SCSI1 standard.\r
+ // Newer initiators won't be specifying 0 anyway.\r
+ if (allocLength == 0) allocLength = 4;\r
+\r
+ memset(scsiDev.data, 0, 256); // Max possible alloc length\r
+ scsiDev.data[0] = 0xF0;\r
+ scsiDev.data[2] = scsiDev.target->sense.code & 0x0F;\r
+\r
+ scsiDev.data[3] = transfer.lba >> 24;\r
+ scsiDev.data[4] = transfer.lba >> 16;\r
+ scsiDev.data[5] = transfer.lba >> 8;\r
+ scsiDev.data[6] = transfer.lba;\r
+\r
+ // Additional bytes if there are errors to report\r
+ scsiDev.data[7] = 10; // additional length\r
+ scsiDev.data[12] = scsiDev.target->sense.asc >> 8;\r
+ scsiDev.data[13] = scsiDev.target->sense.asc;\r
+ }\r
\r
// Silently truncate results. SCSI-2 spec 8.2.14.\r
enter_DataIn(allocLength);\r
{\r
scsiWriteBuffer();\r
}\r
+ else if (command == 0x0f &&\r
+ scsiDev.target->cfg->quirks == S2S_CFG_QUIRKS_XEBEC)\r
+ {\r
+ scsiWriteSectorBuffer();\r
+ }\r
else if (command == 0x3C)\r
{\r
scsiReadBuffer();\r
// The Mac Plus boot-time (ie. rom code) selection abort time\r
// is < 1ms and must have no delay (standard suggests 250ms abort time)\r
// Most newer SCSI2 hosts don't care either way.\r
- if (scsiDev.boardCfg.selectionDelay == 255) // auto\r
+ if (scsiDev.target->cfg->quirks == S2S_CFG_QUIRKS_XEBEC)\r
+ {\r
+ s2s_delay_ms(1); // Simply won't work if set to 0.\r
+ }\r
+ else if (scsiDev.boardCfg.selectionDelay == 255) // auto\r
{\r
if (scsiDev.compatMode < COMPAT_SCSI2)\r
{\r
// SCSI1/SASI initiators may not set their own ID.\r
scsiDev.initiatorId = (selStatus >> 3) & 0x7;\r
\r
- while (likely(!scsiDev.resetFlag) && scsiStatusSEL())\r
+ // Wait until the end of the selection phase.\r
+ uint32_t selTimerBegin = s2s_getTime_ms();\r
+ while (likely(!scsiDev.resetFlag))\r
{\r
- // Wait until the end of the selection phase.\r
+ if (!scsiStatusSEL())\r
+ {\r
+ break;\r
+ }\r
+ else if (s2s_elapsedTime_ms(selTimerBegin) >= 10 &&\r
+ scsiDev.target->cfg->quirks == S2S_CFG_QUIRKS_XEBEC)\r
+ {\r
+ // XEBEC hosts may not bother releasing SEL at all until\r
+ // just before the command ends.\r
+ break;\r
+ }\r
+ else if (s2s_elapsedTime_ms(selTimerBegin) >= 250)\r
+ {\r
+ *SCSI_CTRL_BSY = 0;\r
+ scsiDev.resetFlag = 1;\r
+ break;\r
+ }\r
}\r
\r
scsiDev.phase = COMMAND;\r