aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/xsysace.c
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@secretlab.ca>2009-03-09 13:42:24 +0100
committerJens Axboe <jens.axboe@oracle.com>2009-03-14 21:06:52 +0100
commitbfbd442f69ec9c58590ffc6e93ac8d6809caa48b (patch)
treea59b1df605fe80e923d11935a13894cc09ca5e33 /drivers/block/xsysace.c
parent059ea3318c8ede71851a52b4359fbf1ab0cec301 (diff)
downloadkernel_samsung_espresso10-bfbd442f69ec9c58590ffc6e93ac8d6809caa48b.zip
kernel_samsung_espresso10-bfbd442f69ec9c58590ffc6e93ac8d6809caa48b.tar.gz
kernel_samsung_espresso10-bfbd442f69ec9c58590ffc6e93ac8d6809caa48b.tar.bz2
Fix Xilinx SystemACE driver to handle empty CF slot
The SystemACE driver does not handle an empty CF slot gracefully. An empty CF slot ends up hanging the system. This patch adds a check for the CF state and stops trying to process requests if the slot is empty. Signed-off-by: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/block/xsysace.c')
-rw-r--r--drivers/block/xsysace.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 381d686..119be34 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -489,6 +489,28 @@ static void ace_fsm_dostate(struct ace_device *ace)
ace->fsm_state, ace->id_req_count);
#endif
+ /* Verify that there is actually a CF in the slot. If not, then
+ * bail out back to the idle state and wake up all the waiters */
+ status = ace_in32(ace, ACE_STATUS);
+ if ((status & ACE_STATUS_CFDETECT) == 0) {
+ ace->fsm_state = ACE_FSM_STATE_IDLE;
+ ace->media_change = 1;
+ set_capacity(ace->gd, 0);
+ dev_info(ace->dev, "No CF in slot\n");
+
+ /* Drop all pending requests */
+ while ((req = elv_next_request(ace->queue)) != NULL)
+ end_request(req, 0);
+
+ /* Drop back to IDLE state and notify waiters */
+ ace->fsm_state = ACE_FSM_STATE_IDLE;
+ ace->id_result = -EIO;
+ while (ace->id_req_count) {
+ complete(&ace->id_completion);
+ ace->id_req_count--;
+ }
+ }
+
switch (ace->fsm_state) {
case ACE_FSM_STATE_IDLE:
/* See if there is anything to do */