aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc
diff options
context:
space:
mode:
authorAlex Dubov <oakad@yahoo.com>2006-12-08 00:50:47 -0500
committerPierre Ossman <drzeus@drzeus.cx>2007-02-04 14:54:07 -0500
commit1289335a2ab57d00c638c3954dc86d6c4eab5606 (patch)
tree640694a63b26625a772e92ac30e0539b57511316 /drivers/mmc
parentfba68bd2dab1ac99af3c5a963ec9581cfa9f1725 (diff)
tifm_sd: alter order of the states in the command handler
Previously, stop command was issued right after BRS (block received/sent) event. Stop command completion event could interfere with the card busy event, causing miscount of the written blocks. This patch ensures that stop command issued as last action for a particular command, after DMA sompletion event and written block count verification. Signed-off-by: Alex Dubov <oakad@yahoo.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/tifm_sd.c57
1 files changed, 37 insertions, 20 deletions
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
index fa4a52886b97..f22c3968f2d4 100644
--- a/drivers/mmc/tifm_sd.c
+++ b/drivers/mmc/tifm_sd.c
@@ -17,7 +17,7 @@
17#include <asm/io.h> 17#include <asm/io.h>
18 18
19#define DRIVER_NAME "tifm_sd" 19#define DRIVER_NAME "tifm_sd"
20#define DRIVER_VERSION "0.6" 20#define DRIVER_VERSION "0.7"
21 21
22static int no_dma = 0; 22static int no_dma = 0;
23static int fixed_timeout = 0; 23static int fixed_timeout = 0;
@@ -239,50 +239,65 @@ change_state:
239 tifm_sd_fetch_resp(cmd, sock); 239 tifm_sd_fetch_resp(cmd, sock);
240 if (cmd->data) { 240 if (cmd->data) {
241 host->state = BRS; 241 host->state = BRS;
242 } else 242 } else {
243 host->state = READY; 243 host->state = READY;
244 }
244 goto change_state; 245 goto change_state;
245 } 246 }
246 break; 247 break;
247 case BRS: 248 case BRS:
248 if (tifm_sd_transfer_data(sock, host, host_status)) { 249 if (tifm_sd_transfer_data(sock, host, host_status)) {
249 if (!host->req->stop) { 250 if (cmd->data->flags & MMC_DATA_WRITE) {
250 if (cmd->data->flags & MMC_DATA_WRITE) { 251 host->state = CARD;
251 host->state = CARD; 252 } else {
253 if (no_dma) {
254 if (host->req->stop) {
255 tifm_sd_exec(host, host->req->stop);
256 host->state = SCMD;
257 } else {
258 host->state = READY;
259 }
252 } else { 260 } else {
253 host->state = 261 host->state = FIFO;
254 host->buffer ? READY : FIFO;
255 } 262 }
256 goto change_state;
257 } 263 }
258 tifm_sd_exec(host, host->req->stop); 264 goto change_state;
259 host->state = SCMD;
260 } 265 }
261 break; 266 break;
262 case SCMD: 267 case SCMD:
263 if (host_status & TIFM_MMCSD_EOC) { 268 if (host_status & TIFM_MMCSD_EOC) {
264 tifm_sd_fetch_resp(host->req->stop, sock); 269 tifm_sd_fetch_resp(host->req->stop, sock);
265 if (cmd->error) { 270 host->state = READY;
266 host->state = READY;
267 } else if (cmd->data->flags & MMC_DATA_WRITE) {
268 host->state = CARD;
269 } else {
270 host->state = host->buffer ? READY : FIFO;
271 }
272 goto change_state; 271 goto change_state;
273 } 272 }
274 break; 273 break;
275 case CARD: 274 case CARD:
275 dev_dbg(&sock->dev, "waiting for CARD, have %zd blocks\n",
276 host->written_blocks);
276 if (!(host->flags & CARD_BUSY) 277 if (!(host->flags & CARD_BUSY)
277 && (host->written_blocks == cmd->data->blocks)) { 278 && (host->written_blocks == cmd->data->blocks)) {
278 host->state = host->buffer ? READY : FIFO; 279 if (no_dma) {
280 if (host->req->stop) {
281 tifm_sd_exec(host, host->req->stop);
282 host->state = SCMD;
283 } else {
284 host->state = READY;
285 }
286 } else {
287 host->state = FIFO;
288 }
279 goto change_state; 289 goto change_state;
280 } 290 }
281 break; 291 break;
282 case FIFO: 292 case FIFO:
283 if (host->flags & FIFO_RDY) { 293 if (host->flags & FIFO_RDY) {
284 host->state = READY;
285 host->flags &= ~FIFO_RDY; 294 host->flags &= ~FIFO_RDY;
295 if (host->req->stop) {
296 tifm_sd_exec(host, host->req->stop);
297 host->state = SCMD;
298 } else {
299 host->state = READY;
300 }
286 goto change_state; 301 goto change_state;
287 } 302 }
288 break; 303 break;
@@ -340,7 +355,9 @@ static unsigned int tifm_sd_signal_irq(struct tifm_dev *sock,
340 if (host->req->stop) { 355 if (host->req->stop) {
341 if (host->state == SCMD) { 356 if (host->state == SCMD) {
342 host->req->stop->error = error_code; 357 host->req->stop->error = error_code;
343 } else if(host->state == BRS) { 358 } else if (host->state == BRS
359 || host->state == CARD
360 || host->state == FIFO) {
344 host->req->cmd->error = error_code; 361 host->req->cmd->error = error_code;
345 tifm_sd_exec(host, host->req->stop); 362 tifm_sd_exec(host, host->req->stop);
346 queue_delayed_work(sock->wq, 363 queue_delayed_work(sock->wq,