I think I found what the problem was.
SD.begin() calls (among others) Sd2Card.init(), and inside init()'s code I found this lines of code (file Sd2Card.cpp):
that change the contents of the SPI Control and SPI Status registers respectively.
Later on, and because microSD card is on board, control goes to "fail" which simply calls chipSelectHigh() and returns false, but does not revert the contents of the SPI registers.
One solution to work-around this and still leave the library code untouched is to preserve the contents of the spi register and revert them in case of failure. This is how I fixed it in my sketch:
void setup() {
Serial.begin(9600);
// disable W5100 while setting up SD
pinMode(10,OUTPUT);
digitalWrite(10,HIGH);
uint8_t spcr = SPCR;
uint8_t spsr = SPSR;
if (! SD.begin(4)) {
Serial.println(F("Error cannot initialize SD card!"));
SPCR = spcr;
SPSR = spsr;
}
}
Now I can still try to check if SD card is present, and still keep the Ethernet i/o fast.