diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2006-11-21 11:45:37 -0500 |
---|---|---|
committer | Pierre Ossman <drzeus@drzeus.cx> | 2007-02-04 14:54:11 -0500 |
commit | 5ba593a97206fb96dc0e63f209e6ade86452844f (patch) | |
tree | 4526bc8268b3e45e417949de206c3a964d83f510 /drivers | |
parent | 55db890a838c7b37256241b1fc53d6344aa79cc0 (diff) |
mmc: Handle wbsd's stupid command list
The wbsd hardware is so incredibly brain damaged that it has an internal
list of commands that result in data transfers. The result being that
commands that aren't on this list aren't supported.
Instead of locking up, waiting for a data interrupt that will never come,
we try to fail a bit more gracefully.
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/wbsd.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index cf16e44c0301..c1dd6ad8dab3 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/mmc/wbsd.c - Winbond W83L51xD SD/MMC driver | 2 | * linux/drivers/mmc/wbsd.c - Winbond W83L51xD SD/MMC driver |
3 | * | 3 | * |
4 | * Copyright (C) 2004-2005 Pierre Ossman, All Rights Reserved. | 4 | * Copyright (C) 2004-2006 Pierre Ossman, All Rights Reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -910,6 +910,45 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
910 | */ | 910 | */ |
911 | if (cmd->data && (cmd->error == MMC_ERR_NONE)) { | 911 | if (cmd->data && (cmd->error == MMC_ERR_NONE)) { |
912 | /* | 912 | /* |
913 | * The hardware is so delightfully stupid that it has a list | ||
914 | * of "data" commands. If a command isn't on this list, it'll | ||
915 | * just go back to the idle state and won't send any data | ||
916 | * interrupts. | ||
917 | */ | ||
918 | switch (cmd->opcode) { | ||
919 | case 11: | ||
920 | case 17: | ||
921 | case 18: | ||
922 | case 20: | ||
923 | case 24: | ||
924 | case 25: | ||
925 | case 26: | ||
926 | case 27: | ||
927 | case 30: | ||
928 | case 42: | ||
929 | case 56: | ||
930 | break; | ||
931 | |||
932 | /* ACMDs. We don't keep track of state, so we just treat them | ||
933 | * like any other command. */ | ||
934 | case 51: | ||
935 | break; | ||
936 | |||
937 | default: | ||
938 | #ifdef CONFIG_MMC_DEBUG | ||
939 | printk(KERN_WARNING "%s: Data command %d is not " | ||
940 | "supported by this controller.\n", | ||
941 | mmc_hostname(host->mmc), cmd->opcode); | ||
942 | #endif | ||
943 | cmd->data->error = MMC_ERR_INVALID; | ||
944 | |||
945 | if (cmd->data->stop) | ||
946 | wbsd_send_command(host, cmd->data->stop); | ||
947 | |||
948 | goto done; | ||
949 | }; | ||
950 | |||
951 | /* | ||
913 | * Dirty fix for hardware bug. | 952 | * Dirty fix for hardware bug. |
914 | */ | 953 | */ |
915 | if (host->dma == -1) | 954 | if (host->dma == -1) |