LCOV - code coverage report
Current view: top level - lkbce/drivers/mmc/core - sd_ops.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 192 192 100.0 %
Date: 2017-01-25 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /*
       2             :  *  linux/drivers/mmc/core/sd_ops.h
       3             :  *
       4             :  *  Copyright 2006-2007 Pierre Ossman
       5             :  *
       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
       8             :  * the Free Software Foundation; either version 2 of the License, or (at
       9             :  * your option) any later version.
      10             :  */
      11             : 
      12             : #include <linux/types.h>
      13             : #include <linux/scatterlist.h>
      14             : 
      15             : #include <linux/mmc/host.h>
      16             : #include <linux/mmc/card.h>
      17             : #include <linux/mmc/mmc.h>
      18             : #include <linux/mmc/sd.h>
      19             : 
      20             : #include "core.h"
      21             : #include "sd_ops.h"
      22             : 
      23             : static int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
      24             : {
      25          24 :         int err;
      26          24 :         struct mmc_command cmd;
      27          24 : 
      28         168 :         BUG_ON(!host);
      29         288 :         BUG_ON(card && (card->host != host));
      30             : 
      31          48 :         cmd.opcode = MMC_APP_CMD;
      32             : 
      33          96 :         if (card) {
      34          48 :                 cmd.arg = card->rca << 16;
      35          48 :                 cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
      36             :         } else {
      37          48 :                 cmd.arg = 0;
      38          48 :                 cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_BCR;
      39             :         }
      40             : 
      41          96 :         err = mmc_wait_for_cmd(host, &cmd, 0);
      42          48 :         if (err)
      43          24 :                 return err;
      44             : 
      45             :         /* Check that card supported application commands */
      46          96 :         if (!mmc_host_is_spi(host) && !(cmd.resp[0] & R1_APP_CMD))
      47          24 :                 return -EOPNOTSUPP;
      48             : 
      49          24 :         return 0;
      50             : }
      51             : 
      52             : /**
      53             :  *      mmc_wait_for_app_cmd - start an application command and wait for
      54             :                                completion
      55             :  *      @host: MMC host to start command
      56             :  *      @card: Card to send MMC_APP_CMD to
      57             :  *      @cmd: MMC command to start
      58             :  *      @retries: maximum number of retries
      59             :  *
      60             :  *      Sends a MMC_APP_CMD, checks the card response, sends the command
      61             :  *      in the parameter and waits for it to complete. Return any error
      62             :  *      that occurred while the command was executing.  Do not attempt to
      63             :  *      parse the response.
      64             :  */
      65             : int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,
      66             :         struct mmc_command *cmd, int retries)
      67             : {
      68           6 :         struct mmc_request mrq;
      69           6 : 
      70           6 :         int i, err;
      71           6 : 
      72          42 :         BUG_ON(!cmd);
      73          36 :         BUG_ON(retries < 0);
      74             : 
      75           6 :         err = -EIO;
      76             : 
      77             :         /*
      78             :          * We have to resend MMC_APP_CMD for each attempt so
      79             :          * we cannot use the retries field in mmc_command.
      80             :          */
      81          36 :         for (i = 0;i <= retries;i++) {
      82          24 :                 memset(&mrq, 0, sizeof(struct mmc_request));
      83           6 : 
      84          12 :                 err = mmc_app_cmd(host, card);
      85          12 :                 if (err) {
      86             :                         /* no point in retrying; no APP commands allowed */
      87          18 :                         if (mmc_host_is_spi(host)) {
      88          12 :                                 if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND)
      89           6 :                                         break;
      90             :                         }
      91           6 :                         continue;
      92             :                 }
      93             : 
      94           6 :                 memset(&mrq, 0, sizeof(struct mmc_request));
      95             : 
      96           6 :                 memset(cmd->resp, 0, sizeof(cmd->resp));
      97           6 :                 cmd->retries = 0;
      98             : 
      99           6 :                 mrq.cmd = cmd;
     100           6 :                 cmd->data = NULL;
     101             : 
     102          12 :                 mmc_wait_for_req(host, &mrq);
     103             : 
     104          12 :                 err = cmd->error;
     105          12 :                 if (!cmd->error)
     106           6 :                         break;
     107             : 
     108             :                 /* no point in retrying illegal APP commands */
     109          12 :                 if (mmc_host_is_spi(host)) {
     110          12 :                         if (cmd->resp[0] & R1_SPI_ILLEGAL_COMMAND)
     111           6 :                                 break;
     112             :                 }
     113             :         }
     114             : 
     115          18 :         return err;
     116             : }
     117             : 
     118           6 : EXPORT_SYMBOL(mmc_wait_for_app_cmd);
     119             : 
     120             : int mmc_app_set_bus_width(struct mmc_card *card, int width)
     121             : {
     122           3 :         int err;
     123           3 :         struct mmc_command cmd;
     124           3 : 
     125          21 :         BUG_ON(!card);
     126          21 :         BUG_ON(!card->host);
     127             : 
     128           3 :         memset(&cmd, 0, sizeof(struct mmc_command));
     129             : 
     130           3 :         cmd.opcode = SD_APP_SET_BUS_WIDTH;
     131           3 :         cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
     132             : 
     133             :         switch (width) {
     134           9 :         case MMC_BUS_WIDTH_1:
     135           3 :                 cmd.arg = SD_BUS_WIDTH_1;
     136           3 :                 break;
     137          12 :         case MMC_BUS_WIDTH_4:
     138           3 :                 cmd.arg = SD_BUS_WIDTH_4;
     139           3 :                 break;
     140           6 :         default:
     141           6 :                 return -EINVAL;
     142             :         }
     143             : 
     144          12 :         err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES);
     145           6 :         if (err)
     146           3 :                 return err;
     147             : 
     148           3 :         return 0;
     149             : }
     150             : 
     151             : int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
     152             : {
     153           3 :         struct mmc_command cmd;
     154           6 :         int i, err = 0;
     155           3 : 
     156          21 :         BUG_ON(!host);
     157             : 
     158           3 :         memset(&cmd, 0, sizeof(struct mmc_command));
     159             : 
     160           3 :         cmd.opcode = SD_APP_OP_COND;
     161           6 :         if (mmc_host_is_spi(host))
     162           3 :                 cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */
     163             :         else
     164           3 :                 cmd.arg = ocr;
     165           3 :         cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
     166             : 
     167          15 :         for (i = 100; i; i--) {
     168          15 :                 err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES);
     169          12 :                 if (err)
     170           3 :                         break;
     171             : 
     172             :                 /* if we're just probing, do a single pass */
     173           9 :                 if (ocr == 0)
     174           3 :                         break;
     175             : 
     176             :                 /* otherwise wait until reset completes */
     177           6 :                 if (mmc_host_is_spi(host)) {
     178           6 :                         if (!(cmd.resp[0] & R1_SPI_IDLE))
     179           3 :                                 break;
     180             :                 } else {
     181           6 :                         if (cmd.resp[0] & MMC_CARD_BUSY)
     182           3 :                                 break;
     183             :                 }
     184             : 
     185           3 :                 err = -ETIMEDOUT;
     186             : 
     187           9 :                 mmc_delay(10);
     188             :         }
     189             : 
     190          24 :         if (rocr && !mmc_host_is_spi(host))
     191           6 :                 *rocr = cmd.resp[0];
     192             : 
     193           6 :         return err;
     194             : }
     195             : 
     196             : int mmc_send_if_cond(struct mmc_host *host, u32 ocr)
     197             : {
     198           3 :         struct mmc_command cmd;
     199           3 :         int err;
     200           6 :         static const u8 test_pattern = 0xAA;
     201           3 :         u8 result_pattern;
     202             : 
     203             :         /*
     204             :          * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND
     205             :          * before SD_APP_OP_COND. This command will harmlessly fail for
     206             :          * SD 1.0 cards.
     207             :          */
     208           3 :         cmd.opcode = SD_SEND_IF_COND;
     209          18 :         cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern;
     210           3 :         cmd.flags = MMC_RSP_SPI_R7 | MMC_RSP_R7 | MMC_CMD_BCR;
     211             : 
     212           6 :         err = mmc_wait_for_cmd(host, &cmd, 0);
     213           6 :         if (err)
     214           3 :                 return err;
     215             : 
     216           6 :         if (mmc_host_is_spi(host))
     217           3 :                 result_pattern = cmd.resp[1] & 0xFF;
     218             :         else
     219           3 :                 result_pattern = cmd.resp[0] & 0xFF;
     220             : 
     221           6 :         if (result_pattern != test_pattern)
     222           3 :                 return -EIO;
     223             : 
     224           3 :         return 0;
     225             : }
     226             : 
     227             : int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca)
     228             : {
     229          10 :         int err;
     230          10 :         struct mmc_command cmd;
     231          10 : 
     232          70 :         BUG_ON(!host);
     233          60 :         BUG_ON(!rca);
     234             : 
     235          10 :         memset(&cmd, 0, sizeof(struct mmc_command));
     236             : 
     237          10 :         cmd.opcode = SD_SEND_RELATIVE_ADDR;
     238          10 :         cmd.arg = 0;
     239          10 :         cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
     240             : 
     241          20 :         err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
     242          20 :         if (err)
     243          10 :                 return err;
     244             : 
     245          10 :         *rca = cmd.resp[0] >> 16;
     246             : 
     247          10 :         return 0;
     248             : }
     249             : 
     250             : int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
     251             : {
     252          18 :         int err;
     253          18 :         struct mmc_request mrq;
     254          18 :         struct mmc_command cmd;
     255          18 :         struct mmc_data data;
     256          18 :         struct scatterlist sg;
     257          18 : 
     258         126 :         BUG_ON(!card);
     259         144 :         BUG_ON(!card->host);
     260         126 :         BUG_ON(!scr);
     261          18 : 
     262             :         /* NOTE: caller guarantees scr is heap-allocated */
     263             : 
     264          36 :         err = mmc_app_cmd(card->host, card);
     265          36 :         if (err)
     266          18 :                 return err;
     267             : 
     268          18 :         memset(&mrq, 0, sizeof(struct mmc_request));
     269          18 :         memset(&cmd, 0, sizeof(struct mmc_command));
     270          18 :         memset(&data, 0, sizeof(struct mmc_data));
     271             : 
     272          18 :         mrq.cmd = &cmd;
     273          18 :         mrq.data = &data;
     274             : 
     275          18 :         cmd.opcode = SD_APP_SEND_SCR;
     276          18 :         cmd.arg = 0;
     277          18 :         cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
     278             : 
     279          18 :         data.blksz = 8;
     280          18 :         data.blocks = 1;
     281          18 :         data.flags = MMC_DATA_READ;
     282          18 :         data.sg = &sg;
     283          18 :         data.sg_len = 1;
     284             : 
     285          18 :         sg_init_one(&sg, scr, 8);
     286             : 
     287          36 :         mmc_set_data_timeout(&data, card);
     288             : 
     289          36 :         mmc_wait_for_req(card->host, &mrq);
     290             : 
     291          36 :         if (cmd.error)
     292          18 :                 return cmd.error;
     293          36 :         if (data.error)
     294          18 :                 return data.error;
     295             : 
     296          54 :         scr[0] = be32_to_cpu(scr[0]);
     297          54 :         scr[1] = be32_to_cpu(scr[1]);
     298             : 
     299          18 :         return 0;
     300             : }
     301             : 
     302             : int mmc_sd_switch(struct mmc_card *card, int mode, int group,
     303             :         u8 value, u8 *resp)
     304          27 : {
     305          27 :         struct mmc_request mrq;
     306          27 :         struct mmc_command cmd;
     307          27 :         struct mmc_data data;
     308          27 :         struct scatterlist sg;
     309          27 : 
     310         162 :         BUG_ON(!card);
     311         189 :         BUG_ON(!card->host);
     312             : 
     313             :         /* NOTE: caller guarantees resp is heap-allocated */
     314             : 
     315          27 :         mode = !!mode;
     316          27 :         value &= 0xF;
     317             : 
     318          27 :         memset(&mrq, 0, sizeof(struct mmc_request));
     319          27 :         memset(&cmd, 0, sizeof(struct mmc_command));
     320          27 :         memset(&data, 0, sizeof(struct mmc_data));
     321             : 
     322          27 :         mrq.cmd = &cmd;
     323          27 :         mrq.data = &data;
     324             : 
     325          27 :         cmd.opcode = SD_SWITCH;
     326          27 :         cmd.arg = mode << 31 | 0x00FFFFFF;
     327          27 :         cmd.arg &= ~(0xF << (group * 4));
     328          27 :         cmd.arg |= value << (group * 4);
     329          27 :         cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
     330             : 
     331          27 :         data.blksz = 64;
     332          27 :         data.blocks = 1;
     333          27 :         data.flags = MMC_DATA_READ;
     334          27 :         data.sg = &sg;
     335          27 :         data.sg_len = 1;
     336             : 
     337          27 :         sg_init_one(&sg, resp, 64);
     338             : 
     339          54 :         mmc_set_data_timeout(&data, card);
     340             : 
     341          54 :         mmc_wait_for_req(card->host, &mrq);
     342             : 
     343          54 :         if (cmd.error)
     344          27 :                 return cmd.error;
     345          54 :         if (data.error)
     346          27 :                 return data.error;
     347             : 
     348          27 :         return 0;
     349             : }
     350             : 

Generated by: LCOV version 1.10