diff options
Diffstat (limited to 'drivers/mmc/tifm_sd.c')
-rw-r--r-- | drivers/mmc/tifm_sd.c | 57 |
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 | ||
22 | static int no_dma = 0; | 22 | static int no_dma = 0; |
23 | static int fixed_timeout = 0; | 23 | static 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, |