Fix error handling in multiple block read and multiple block write state. When an error occurs, the host still needs to send CMD_STOP_TRANSMISSION resp. the STOP_TRAN token.

git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_0@18527 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2008-09-16 06:48:38 +00:00
parent 177bb338dd
commit 8a21a2f209

View file

@ -575,7 +575,7 @@ static void send_block_prepare(void)
/* Send one block with DMA from the current write buffer, possibly preparing /* Send one block with DMA from the current write buffer, possibly preparing
* the next block within the next write buffer in the background. */ * the next block within the next write buffer in the background. */
static int send_block_send(unsigned char start_token, long timeout, static int send_block_send(unsigned char start_token, long timeout,
bool prepare_next) bool prepare_next)
{ {
int rc = 0; int rc = 0;
@ -665,6 +665,9 @@ int ata_read_sectors(IF_MV2(int drive,)
rc = receive_block(inbuf, card->read_timeout); rc = receive_block(inbuf, card->read_timeout);
if (rc) if (rc)
{ {
/* If an error occurs during multiple block reading, the
* host still needs to send CMD_STOP_TRANSMISSION */
send_cmd(CMD_STOP_TRANSMISSION, 0, &response);
rc = rc * 10 - 4; rc = rc * 10 - 4;
goto error; goto error;
} }
@ -755,15 +758,17 @@ int ata_write_sectors(IF_MV2(int drive,)
if (rc) if (rc)
{ {
rc = rc * 10 - 3; rc = rc * 10 - 3;
goto error; break;
} }
} }
rc = send_block_send(start_token, card->write_timeout, false); if (rc == 0)
if (rc)
{ {
rc = rc * 10 - 4; rc = send_block_send(start_token, card->write_timeout, false);
goto error; if (rc)
} rc = rc * 10 - 4;
}
/* If an error occurs during multiple block writing, the STOP_TRAN token
* still needs to be sent, hence the special error handling above. */
if (write_cmd == CMD_WRITE_MULTIPLE_BLOCK) if (write_cmd == CMD_WRITE_MULTIPLE_BLOCK)
{ {
@ -802,7 +807,7 @@ static void mmc_thread(void)
{ {
struct queue_event ev; struct queue_event ev;
bool idle_notified = false; bool idle_notified = false;
while (1) { while (1) {
queue_wait_w_tmo(&mmc_queue, &ev, HZ); queue_wait_w_tmo(&mmc_queue, &ev, HZ);
switch ( ev.id ) switch ( ev.id )