|  | @@ -477,6 +477,8 @@ static void doReserveRelease()
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +static uint32_t resetUntil = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  static void scsiReset()
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	scsiDev.rstCount++;
 | 
	
	
		
			
				|  | @@ -515,6 +517,7 @@ static void scsiReset()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	scsiDev.postDataOutHook = NULL;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	// Sleep to allow the bus to settle down a bit.
 | 
	
		
			
				|  |  |  	// We must be ready again within the "Reset to selection time" of
 | 
	
		
			
				|  |  |  	// 250ms.
 | 
	
	
		
			
				|  | @@ -523,7 +526,7 @@ static void scsiReset()
 | 
	
		
			
				|  |  |  	// in which case TERMPWR cannot be supplied, and reset will ALWAYS
 | 
	
		
			
				|  |  |  	// be true. Therefore, the sleep here must be slow to avoid slowing
 | 
	
		
			
				|  |  |  	// USB comms
 | 
	
		
			
				|  |  | -	s2s_delay_ms(1); // 1ms.
 | 
	
		
			
				|  |  | +	resetUntil = s2s_getTime_ms() + 2; // At least 1ms.
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void enter_SelectionPhase()
 | 
	
	
		
			
				|  | @@ -646,6 +649,9 @@ static void process_SelectionPhase()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void process_MessageOut()
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | +	int wasNeedSyncNegotiationAck = scsiDev.needSyncNegotiationAck;
 | 
	
		
			
				|  |  | +	scsiDev.needSyncNegotiationAck = 0; // Successful on -most- messages.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	scsiEnterPhase(MESSAGE_OUT);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	scsiDev.atnFlag = 0;
 | 
	
	
		
			
				|  | @@ -716,11 +722,10 @@ static void process_MessageOut()
 | 
	
		
			
				|  |  |  		// Message Reject
 | 
	
		
			
				|  |  |  		// Oh well.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		if (scsiDev.needSyncNegotiationAck)
 | 
	
		
			
				|  |  | +		if (wasNeedSyncNegotiationAck)
 | 
	
		
			
				|  |  |  		{
 | 
	
		
			
				|  |  |  			scsiDev.target->syncOffset = 0;
 | 
	
		
			
				|  |  |  			scsiDev.target->syncPeriod = 0;
 | 
	
		
			
				|  |  | -			scsiDev.needSyncNegotiationAck = 0;
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	else if (scsiDev.msgOut == 0x08)
 | 
	
	
		
			
				|  | @@ -732,6 +737,12 @@ static void process_MessageOut()
 | 
	
		
			
				|  |  |  		// Message Parity Error
 | 
	
		
			
				|  |  |  		// Go back and re-send the last message.
 | 
	
		
			
				|  |  |  		scsiDev.phase = MESSAGE_IN;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		if (wasNeedSyncNegotiationAck)
 | 
	
		
			
				|  |  | +		{
 | 
	
		
			
				|  |  | +			scsiDev.target->syncOffset = 0;
 | 
	
		
			
				|  |  | +			scsiDev.target->syncPeriod = 0;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	else if (scsiDev.msgOut & 0x80) // 0x80 -> 0xFF
 | 
	
		
			
				|  |  |  	{
 | 
	
	
		
			
				|  | @@ -778,9 +789,16 @@ static void process_MessageOut()
 | 
	
		
			
				|  |  |  			scsiEnterPhase(MESSAGE_IN);
 | 
	
		
			
				|  |  |  			static const uint8_t WDTR[] = {0x01, 0x02, 0x03, 0x00};
 | 
	
		
			
				|  |  |  			scsiWrite(WDTR, sizeof(WDTR));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			// SDTR becomes invalidated.
 | 
	
		
			
				|  |  | +			scsiDev.target->syncOffset = 0;
 | 
	
		
			
				|  |  | +			scsiDev.target->syncPeriod = 0;
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		else if (extmsg[0] == 1 && msgLen == 3) // Synchronous data request
 | 
	
		
			
				|  |  |  		{
 | 
	
		
			
				|  |  | +			int oldPeriod = scsiDev.target->syncPeriod;
 | 
	
		
			
				|  |  | +			int oldOffset = scsiDev.target->syncOffset;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  			int transferPeriod = extmsg[1];
 | 
	
		
			
				|  |  |  			int offset = extmsg[2];
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -836,10 +854,17 @@ static void process_MessageOut()
 | 
	
		
			
				|  |  |  				}
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -			scsiEnterPhase(MESSAGE_IN);
 | 
	
		
			
				|  |  | -			uint8_t SDTR[] = {0x01, 0x03, 0x01, scsiDev.target->syncPeriod, scsiDev.target->syncOffset};
 | 
	
		
			
				|  |  | -			scsiWrite(SDTR, sizeof(SDTR));
 | 
	
		
			
				|  |  | -			scsiDev.needSyncNegotiationAck = 1; // Check if this message is rejected.
 | 
	
		
			
				|  |  | +			if (transferPeriod != oldPeriod ||
 | 
	
		
			
				|  |  | +				scsiDev.target->syncPeriod != oldPeriod ||
 | 
	
		
			
				|  |  | +				offset != oldOffset ||
 | 
	
		
			
				|  |  | +				scsiDev.target->syncOffset != oldOffset ||
 | 
	
		
			
				|  |  | +				!wasNeedSyncNegotiationAck) // Don't get into infinite loops negotiating.
 | 
	
		
			
				|  |  | +			{
 | 
	
		
			
				|  |  | +				scsiEnterPhase(MESSAGE_IN);
 | 
	
		
			
				|  |  | +				uint8_t SDTR[] = {0x01, 0x03, 0x01, scsiDev.target->syncPeriod, scsiDev.target->syncOffset};
 | 
	
		
			
				|  |  | +				scsiWrite(SDTR, sizeof(SDTR));
 | 
	
		
			
				|  |  | +				scsiDev.needSyncNegotiationAck = 1; // Check if this message is rejected.
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		else
 | 
	
		
			
				|  |  |  		{
 | 
	
	
		
			
				|  | @@ -864,6 +889,12 @@ static void process_MessageOut()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void scsiPoll(void)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | +	if (resetUntil != 0 && resetUntil > s2s_getTime_ms())
 | 
	
		
			
				|  |  | +	{
 | 
	
		
			
				|  |  | +		return;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	resetUntil = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	if (unlikely(scsiDev.resetFlag))
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  |  		scsiReset();
 |