~ubuntu-branches/ubuntu/trusty/linux-linaro-omap/trusty

« back to all changes in this revision

Viewing changes to drivers/mmc/core/core.c

  • Committer: Package Import Robot
  • Author(s): John Rigby, John Rigby
  • Date: 2011-09-26 10:44:23 UTC
  • Revision ID: package-import@ubuntu.com-20110926104423-57i0gl3v99b3lkfg
Tags: 3.0.0-1007.9
[ John Rigby ]

Enable crypto modules and remove crypto-modules from
exclude-module files
LP: #826021

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <linux/log2.h>
24
24
#include <linux/regulator/consumer.h>
25
25
#include <linux/pm_runtime.h>
26
 
#include <linux/fault-inject.h>
27
 
#include <linux/random.h>
28
26
 
29
27
#include <linux/mmc/card.h>
30
28
#include <linux/mmc/host.h>
84
82
        flush_workqueue(workqueue);
85
83
}
86
84
 
87
 
#ifdef CONFIG_FAIL_MMC_REQUEST
88
 
 
89
 
static DECLARE_FAULT_ATTR(fail_mmc_request);
90
 
 
91
 
static int __init setup_fail_mmc_request(char *str)
92
 
{
93
 
        return setup_fault_attr(&fail_mmc_request, str);
94
 
}
95
 
__setup("fail_mmc_request=", setup_fail_mmc_request);
96
 
 
97
 
static void mmc_should_fail_request(struct mmc_host *host,
98
 
                                    struct mmc_request *mrq)
99
 
{
100
 
        struct mmc_command *cmd = mrq->cmd;
101
 
        struct mmc_data *data = mrq->data;
102
 
        static const int data_errors[] = {
103
 
                -ETIMEDOUT,
104
 
                -EILSEQ,
105
 
                -EIO,
106
 
        };
107
 
 
108
 
        if (!data)
109
 
                return;
110
 
 
111
 
        if (cmd->error || data->error || !host->make_it_fail ||
112
 
            !should_fail(&fail_mmc_request, data->blksz * data->blocks))
113
 
                return;
114
 
 
115
 
        data->error = data_errors[random32() % ARRAY_SIZE(data_errors)];
116
 
        data->bytes_xfered = (random32() % (data->bytes_xfered >> 9)) << 9;
117
 
}
118
 
 
119
 
static int __init fail_mmc_request_debugfs(void)
120
 
{
121
 
        return init_fault_attr_dentries(&fail_mmc_request,
122
 
                                        "fail_mmc_request");
123
 
}
124
 
 
125
 
late_initcall(fail_mmc_request_debugfs);
126
 
 
127
 
#else /* CONFIG_FAIL_MMC_REQUEST */
128
 
 
129
 
static void mmc_should_fail_request(struct mmc_host *host,
130
 
                                    struct mmc_request *mrq)
131
 
{
132
 
}
133
 
 
134
 
#endif /* CONFIG_FAIL_MMC_REQUEST */
135
 
 
136
 
 
137
85
/**
138
86
 *      mmc_request_done - finish processing an MMC request
139
87
 *      @host: MMC host which completed request
160
108
                cmd->error = 0;
161
109
                host->ops->request(host, mrq);
162
110
        } else {
163
 
                mmc_should_fail_request(host, mrq);
164
 
 
165
111
                led_trigger_event(host->led, LED_OFF);
166
112
 
167
113
                pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n",
252
198
 
253
199
static void mmc_wait_done(struct mmc_request *mrq)
254
200
{
255
 
        complete(&mrq->completion);
256
 
}
257
 
 
258
 
static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
259
 
{
260
 
        init_completion(&mrq->completion);
261
 
        mrq->done = mmc_wait_done;
262
 
        mmc_start_request(host, mrq);
263
 
}
264
 
 
265
 
static void mmc_wait_for_req_done(struct mmc_host *host,
266
 
                                  struct mmc_request *mrq)
267
 
{
268
 
        wait_for_completion(&mrq->completion);
269
 
}
270
 
 
271
 
/**
272
 
 *      mmc_pre_req - Prepare for a new request
273
 
 *      @host: MMC host to prepare command
274
 
 *      @mrq: MMC request to prepare for
275
 
 *      @is_first_req: true if there is no previous started request
276
 
 *                     that may run in parellel to this call, otherwise false
277
 
 *
278
 
 *      mmc_pre_req() is called in prior to mmc_start_req() to let
279
 
 *      host prepare for the new request. Preparation of a request may be
280
 
 *      performed while another request is running on the host.
281
 
 */
282
 
static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq,
283
 
                 bool is_first_req)
284
 
{
285
 
        if (host->ops->pre_req)
286
 
                host->ops->pre_req(host, mrq, is_first_req);
287
 
}
288
 
 
289
 
/**
290
 
 *      mmc_post_req - Post process a completed request
291
 
 *      @host: MMC host to post process command
292
 
 *      @mrq: MMC request to post process for
293
 
 *      @err: Error, if non zero, clean up any resources made in pre_req
294
 
 *
295
 
 *      Let the host post process a completed request. Post processing of
296
 
 *      a request may be performed while another reuqest is running.
297
 
 */
298
 
static void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq,
299
 
                         int err)
300
 
{
301
 
        if (host->ops->post_req)
302
 
                host->ops->post_req(host, mrq, err);
303
 
}
304
 
 
305
 
/**
306
 
 *      mmc_start_req - start a non-blocking request
307
 
 *      @host: MMC host to start command
308
 
 *      @areq: async request to start
309
 
 *      @error: out parameter returns 0 for success, otherwise non zero
310
 
 *
311
 
 *      Start a new MMC custom command request for a host.
312
 
 *      If there is on ongoing async request wait for completion
313
 
 *      of that request and start the new one and return.
314
 
 *      Does not wait for the new request to complete.
315
 
 *
316
 
 *      Returns the completed async request, NULL in case of none completed.
317
 
 */
318
 
struct mmc_async_req *mmc_start_req(struct mmc_host *host,
319
 
                                    struct mmc_async_req *areq, int *error)
320
 
{
321
 
        int err = 0;
322
 
        struct mmc_async_req *data = host->areq;
323
 
 
324
 
        /* Prepare a new request */
325
 
        if (areq)
326
 
                mmc_pre_req(host, areq->mrq, !host->areq);
327
 
 
328
 
        if (host->areq) {
329
 
                mmc_wait_for_req_done(host, host->areq->mrq);
330
 
                err = host->areq->err_check(host->card, host->areq);
331
 
                if (err) {
332
 
                        mmc_post_req(host, host->areq->mrq, 0);
333
 
                        if (areq)
334
 
                                mmc_post_req(host, areq->mrq, -EINVAL);
335
 
 
336
 
                        host->areq = NULL;
337
 
                        goto out;
338
 
                }
339
 
        }
340
 
 
341
 
        if (areq)
342
 
                __mmc_start_req(host, areq->mrq);
343
 
 
344
 
        if (host->areq)
345
 
                mmc_post_req(host, host->areq->mrq, 0);
346
 
 
347
 
        host->areq = areq;
348
 
 out:
349
 
        if (error)
350
 
                *error = err;
351
 
        return data;
352
 
}
353
 
EXPORT_SYMBOL(mmc_start_req);
 
201
        complete(mrq->done_data);
 
202
}
354
203
 
355
204
/**
356
205
 *      mmc_wait_for_req - start a request and wait for completion
363
212
 */
364
213
void mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
365
214
{
366
 
        __mmc_start_req(host, mrq);
367
 
        mmc_wait_for_req_done(host, mrq);
 
215
        DECLARE_COMPLETION_ONSTACK(complete);
 
216
 
 
217
        mrq->done_data = &complete;
 
218
        mrq->done = mmc_wait_done;
 
219
 
 
220
        mmc_start_request(host, mrq);
 
221
 
 
222
        wait_for_completion(&complete);
368
223
}
 
224
 
369
225
EXPORT_SYMBOL(mmc_wait_for_req);
370
226
 
371
227
/**
1389
1245
                 */
1390
1246
                timeout_clks <<= 1;
1391
1247
                timeout_us += (timeout_clks * 1000) /
1392
 
                              (card->host->ios.clock / 1000);
 
1248
                              (mmc_host_clk_rate(card->host) / 1000);
1393
1249
 
1394
1250
                erase_timeout = timeout_us / 1000;
1395
1251