Browse Source

Merge pull request #189 from BlueSCSI/wifiMerge

Wifi merge
Eric Helgeson 1 năm trước cách đây
mục cha
commit
be2d0d9efd
2 tập tin đã thay đổi với 99 bổ sung24 xóa
  1. 92 24
      lib/SCSI2SD/src/firmware/network.c
  2. 7 0
      lib/SCSI2SD/src/firmware/network.h

+ 92 - 24
lib/SCSI2SD/src/firmware/network.c

@@ -104,6 +104,12 @@ int scsiNetworkCommand()
 
 	DBGMSG_F("------ in scsiNetworkCommand with command 0x%02x (size %d)", command, size);
 
+	// Rather than duplicating code, this just diverts a 'fake' read request to make the gvpscsi.device happy on the Amiga
+	if ((scsiDev.cdb[0] == SCSI_NETWORK_WIFI_CMD) && (scsiDev.cdb[1] == SCSI_NETWORK_WIFI_CMD_ALTREAD)) {
+		// Redirect the command as a READ.
+		command = 0x08;
+	}
+
 	switch (command) {
 	case 0x08:
 		// read(6)
@@ -156,26 +162,62 @@ int scsiNetworkCommand()
 
 			DBGMSG_BUF(scsiDev.data, scsiDev.dataLen);
 		}
+		// Patches around the weirdness on the Amiga SCSI devices
+		if ((scsiDev.cdb[0] == SCSI_NETWORK_WIFI_CMD) && (scsiDev.cdb[1] == SCSI_NETWORK_WIFI_CMD_ALTREAD)) {
+			scsiDev.data[2] = scsiDev.cdb[2];    // for me really
+			int extra = 0;
+			if (scsiDev.cdb[2] == AMIGASCSI_PATCH_24BYTE_BLOCKSIZE) {
+				if (scsiDev.dataLen<90) scsiDev.dataLen = 90;
+				int missing = (scsiDev.dataLen-90) % 24;
+				if (missing) {
+					scsiDev.dataLen += 24 - missing;
+					if (scsiDev.dataLen>NETWORK_PACKET_MAX_SIZE) {
+						extra = scsiDev.dataLen - NETWORK_PACKET_MAX_SIZE;
+						scsiDev.dataLen = NETWORK_PACKET_MAX_SIZE;
+					}
+				}
+				scsiEnterPhase(DATA_IN);
+				scsiWrite(scsiDev.data, scsiDev.dataLen);
+				while (!scsiIsWriteFinished(NULL))
+				{
+					platform_poll();
+				}
+				scsiFinishWrite();
+			} else {
+				extra = scsiDev.dataLen;     // F9 means send in ONE transaction
+				if (extra) scsiEnterPhase(DATA_IN);
+			}
 
-		// DaynaPort driver needs a delay between reading the initial packet size and the data so manually do two transfers
-		scsiEnterPhase(DATA_IN);
-		scsiWrite(scsiDev.data, 6);
-		while (!scsiIsWriteFinished(NULL))
-		{
-			platform_poll();
-		}
-		scsiFinishWrite();
-
-		if (scsiDev.dataLen > 6)
-		{
-			s2s_delay_us(80);
-
-			scsiWrite(scsiDev.data + 6, scsiDev.dataLen - 6);
+			if (extra) {
+				// Just write the extra data to make the padding work for such a large packet
+				scsiWrite(scsiDev.data, extra);
+				while (!scsiIsWriteFinished(NULL))
+				{
+					platform_poll();
+				}
+				scsiFinishWrite();
+			}
+		} else {
+			// DaynaPort driver needs a delay between reading the initial packet size and the data so manually do two transfers
+			scsiEnterPhase(DATA_IN);
+			scsiWrite(scsiDev.data, 6);
 			while (!scsiIsWriteFinished(NULL))
 			{
 				platform_poll();
 			}
 			scsiFinishWrite();
+
+			if (scsiDev.dataLen > 6)
+			{
+				s2s_delay_us(80);
+
+				scsiWrite(scsiDev.data + 6, scsiDev.dataLen - 6);
+				while (!scsiIsWriteFinished(NULL))
+				{
+					platform_poll();
+				}
+				scsiFinishWrite();
+			}
 		}
 
 		scsiDev.status = GOOD;
@@ -311,6 +353,17 @@ int scsiNetworkCommand()
 			// return wi-fi scan results
 			if (!platform_network_wifi_scan_finished())
 			{
+				scsiDev.target->sense.code = ILLEGAL_REQUEST;
+				scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
+				scsiDev.status = CHECK_CONDITION;
+				scsiDev.phase = STATUS;
+				break;
+			}
+
+			if (unlikely(size < 2))
+			{
+				scsiDev.target->sense.code = ILLEGAL_REQUEST;
+				scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
 				scsiDev.status = CHECK_CONDITION;
 				scsiDev.phase = STATUS;
 				break;
@@ -325,17 +378,23 @@ int scsiNetworkCommand()
 			}
 
 			if (nets) {
-				int size = sizeof(struct wifi_network_entry) * nets;
-				if (size + 2 > sizeof(scsiDev.data))
+				unsigned int netsize = sizeof(struct wifi_network_entry) * nets;
+				if (netsize + 2 > sizeof(scsiDev.data))
 				{
 					log_f("WARNING: wifi_network_list is bigger than scsiDev.data, truncating");
-					size = sizeof(scsiDev.data) - 2;
-					size -= (size % (sizeof(struct wifi_network_entry)));
+					netsize = sizeof(scsiDev.data) - 2;
+					netsize -= (netsize % (sizeof(struct wifi_network_entry)));
 				}
-				scsiDev.data[0] = (size >> 8) & 0xff;
-				scsiDev.data[1] = size & 0xff;
-				memcpy(scsiDev.data + 2, wifi_network_list, size);
-				scsiDev.dataLen = size + 2;
+				if (netsize + 2 > size)
+				{
+					log_f("WARNING: wifi_network_list is bigger than requested dataLen, truncating");
+					netsize = size - 2;
+					netsize -= (netsize % (sizeof(struct wifi_network_entry)));
+				}
+				scsiDev.data[0] = (netsize >> 8) & 0xff;
+				scsiDev.data[1] = netsize & 0xff;
+				memcpy(scsiDev.data + 2, wifi_network_list, netsize);
+				scsiDev.dataLen = netsize + 2;
 			}
 			else
 			{
@@ -396,6 +455,14 @@ int scsiNetworkCommand()
 			scsiDev.phase = STATUS;
 			break;
 		}
+
+		case SCSI_NETWORK_WIFI_CMD_GETMACADDRESS:
+			// Update for the gvpscsi.device on the Amiga as it doesn't like 0x09 command being called! - NOTE this only sends 6 bytes back
+			memcpy(scsiDev.data, scsiDev.boardCfg.wifiMACAddress, sizeof(scsiDev.boardCfg.wifiMACAddress));
+			memset(scsiDev.data + sizeof(scsiDev.boardCfg.wifiMACAddress), 0, sizeof(scsiDev.data) - sizeof(scsiDev.boardCfg.wifiMACAddress));
+
+			scsiDev.dataLen = 6;
+			scsiDev.phase = DATA_IN;
 		}
 		break;
 
@@ -403,6 +470,7 @@ int scsiNetworkCommand()
 		handled = 0;
 	}
 
+
 	return handled;
 }
 
@@ -435,7 +503,7 @@ int scsiNetworkEnqueue(const uint8_t *buf, size_t len)
 	{
 		DBGMSG_F("%s: dropping packets in ring, write index caught up to read index", __func__);
 	}
-	
+
 	return 1;
 }
 
@@ -454,7 +522,7 @@ int scsiNetworkPurge(void)
 			scsiNetworkOutboundQueue.readIndex = 0;
 		else
 			scsiNetworkOutboundQueue.readIndex++;
-		
+
 		sent++;
 	}
 

+ 7 - 0
lib/SCSI2SD/src/firmware/network.h

@@ -30,6 +30,13 @@ extern "C" {
 #define SCSI_NETWORK_WIFI_CMD_INFO			0x04
 #define SCSI_NETWORK_WIFI_CMD_JOIN			0x05
 
+// Patches to make the DaynaPORT (or whats left of it) work on the Amiga - RobSmithDev
+#define SCSI_NETWORK_WIFI_CMD_ALTREAD       0x08   // gvpscsi.device on AMIGA doesnt like the standard version
+#define SCSI_NETWORK_WIFI_CMD_GETMACADDRESS 0x09   // gvpscsi.device on AMIGA doesnt like the standard version
+
+#define AMIGASCSI_PATCH_24BYTE_BLOCKSIZE 	0xA8   // In this mode, data written is rounded up to the nearest 24-byte boundary
+#define AMIGASCSI_PATCH_SINGLEWRITE_ONLY 	0xA9   // In this mode, data written is always ONLY as one single write command
+
 #define NETWORK_PACKET_QUEUE_SIZE   20		// must be <= 255
 #define NETWORK_PACKET_MAX_SIZE     1520