- Main Page
- Related Pages
- Data Structures
- Files

- File List
- Globals

# drivers/sdmmc/probe.c

Go to the documentation of this file.

    00001
    00045 #include <bitops.h>
    00046 #include <byteorder.h>
    00047 #include <debug.h>
    00048 #include <delay.h>
    00049 #include <errno.h>
    00050 #include <stdbool.h>
    00051 #include <string.h>
    00052 #include <util.h>
    00053 #include <workqueue.h>
    00054 #include <delayed_work.h>
    00055 #include <malloc.h>
    00056 #include <sdmmc/sdmmc.h>
    00057 #include <buffer.h>
    00058 #include "protocol.h"
    00059 #include <app/timer.h>
    00060 #include <app/workqueue.h>
    00061 #include <board/sdmmc.h>
    00062
    00063 #ifdef BOARD_SDMMC_POWER_RAMP_UP_US
    00064 # define POWER_RAMP_UP_US       BOARD_SDMMC_POWER_RAMP_UP_US
    00065 #else
    00066 # define POWER_RAMP_UP_US       0
    00067 #endif
    00068
    00069 struct sdmmc_probe_data {
    00070         bool                    running;
    00071         int                     state;
    00072         struct sdmmc_slot       *slot;
    00073         struct workqueue_item   work;
    00074         struct delayed_work     dwork;
    00075         struct sdmmc_request    req;
    00076         int                     i;
    00077         struct buffer           *buf;
    00079         void                    (*event)(struct sdmmc_slot *slot, void *context);
    00080         void                    *context;
    00081 };
    00082
    00083 enum {
    00084         SDMMC_PROBE_STATE_INIT,
    00085         SDMMC_PROBE_STATE_INITSEQ,
    00086         SDMMC_PROBE_STATE_GO_IDLE,
    00087         SDMMC_PROBE_STATE_WAIT_SWITCH,
    00088         SDMMC_PROBE_STATE_SEND_IF_COND,
    00089         SDMMC_PROBE_STATE_DETECT_SD_ACMD,
    00090         SDMMC_PROBE_STATE_DETECT_SD_CMD,
    00091         SDMMC_PROBE_STATE_DETECT_SD_DONE,
    00092         SDMMC_PROBE_STATE_SD_APP_COND_LOOP,
    00093         SDMMC_PROBE_STATE_SD_APP_COND_CMD,
    00094         SDMMC_PROBE_STATE_SD_SEND_CID,
    00095         SDMMC_PROBE_STATE_SD_SET_RELADDR,
    00096         SDMMC_PROBE_STATE_SD_SEND_CSD,
    00097         SDMMC_PROBE_STATE_SD_SELECT_CARD,
    00098         SDMMC_PROBE_STATE_SD_SEND_SCR_ACMD,
    00099         SDMMC_PROBE_STATE_SD_SEND_SCR_CMD,
    00100         SDMMC_PROBE_STATE_SD_FUNC_CHECK,
    00101         SDMMC_PROBE_STATE_SD_FUNC_SWITCH,
    00102         SDMMC_PROBE_STATE_SD_FUNC_DONE,
    00103         SDMMC_PROBE_STATE_SD_DESELECT_CARD,
    00104         SDMMC_PROBE_STATE_SD_RESEND_CSD,
    00105         SDMMC_PROBE_STATE_SD_RESELECT_CARD,
    00106         SDMMC_PROBE_STATE_SD_SET_BUS_WIDTH_ACMD,
    00107         SDMMC_PROBE_STATE_SD_SET_BUS_WIDTH_CMD,
    00108         SDMMC_PROBE_STATE_SD_SET_BUS_WIDTH_DONE,
    00109         SDMMC_PROBE_STATE_SD_SET_CLK,
    00110         SDMMC_PROBE_STATE_SD_SET_BLOCK_LEN,
    00111         SDMMC_PROBE_STATE_SD_FINAL,
    00112         SDMMC_PROBE_STATE_DETECT_MMC,
    00113         SDMMC_PROBE_STATE_SEND_STATUS,
    00114         SDMMC_PROBE_STATE_CHECK_STATUS,
    00115 };
    00116
    00117 static void sdmmc_probe_callback(struct sdmmc_request *req)
    00118 {
    00119         struct sdmmc_probe_data *pdata = req->context;
    00120
    00121         workqueue_add_item(&sdmmc_workqueue, &pdata->work);
    00122 }
    00123
    00124 static void sdmmc_probe_engine(void *data)
    00125 {
    00126         struct sdmmc_probe_data *pdata = data;
    00127         struct sdmmc_slot       *slot = pdata->slot;
    00128         struct sdmmc_request    *req = &pdata->req;
    00129         uint32_t                *tmp;
    00130         int                     ret;
    00131
    00132         dbg_verbose("probe slot%u state=%d\n", slot->id, pdata->state);
    00133
    00134         /* Always init request to make sure data reference is removed */
    00135         sdmmc_req_init(req);
    00136
    00137         switch (pdata->state) {
    00138         case SDMMC_PROBE_STATE_INIT:
    00139                 if (!test_bit(SDMMC_SLOT_CARD_DETECT, &slot->flags)) {
    00140                         pdata->running = false;
    00141                         clear_bit(SDMMC_SLOT_CARD_PRESENT, &slot->flags);
    00142                         if (pdata->event)
    00143                                 pdata->event(slot, pdata->context);
    00144                         return;
    00145                 }
    00146                 sdmmc_slot_power_up(slot);
    00147                 sdmmc_req_prep_callback(req, sdmmc_probe_callback, pdata);
    00148                 if (POWER_RAMP_UP_US > 0) {
    00149                         /* Delay to give power the chance to ramp up */
    00150                         delayed_work_run_us(&pdata->dwork, &pdata->work,
    00151                                         POWER_RAMP_UP_US);
    00152                         pdata->state = SDMMC_PROBE_STATE_INITSEQ;
    00153                         return;
    00154                 }
    00155                 /* fall through */
    00156         case SDMMC_PROBE_STATE_INITSEQ:
    00157                 /* Run the 74 cycle initialization sequence */
    00158                 sdmmc_slot_set_f_max(slot, SDMMC_F_OD);
    00159                 sdmmc_req_prep_cmd(req, 0, 0, 0);
    00160                 set_bit(SDMMC_REQ_INITSEQ, &req->flags);
    00161                 pdata->state = SDMMC_PROBE_STATE_GO_IDLE;
    00162                 break;
    00163         case SDMMC_PROBE_STATE_GO_IDLE:
    00164                 sdmmc_req_prep_cmd(req, SDMMC_GO_IDLE_STATE, 0,
    00165                                 SDMMC_RSP_NONE | SDMMC_CMD_OPD);
    00166                 pdata->state = SDMMC_PROBE_STATE_WAIT_SWITCH;
    00167                 break;
    00168         case SDMMC_PROBE_STATE_WAIT_SWITCH:
    00169                 if (req->status)
    00170                         goto failure;
    00171                 /* The card might have got a switch function and in such a
    00172                  * case we need to apply a delay for it to switch back.
    00173                  * Same as for switch function (8 cycles).
    00174                  */
    00175                 delayed_work_run_us(&pdata->dwork, &pdata->work, 80);
    00176                 pdata->state = SDMMC_PROBE_STATE_SEND_IF_COND;
    00177                 return;
    00178         case SDMMC_PROBE_STATE_SEND_IF_COND:
    00179                 /* Indicate to card that host is SDHC capable and
    00180                  * detect if card support HC
    00181                  */
    00182                 sdmmc_req_prep_cmd(req, SD_SEND_IF_COND,
    00183                                 SD_IF_COND_V_27_33 | SD_IF_COND_CHECK_PATTERN,
    00184                                 SDMMC_RSP_R7 | SDMMC_CMD_OPD);
    00185                 pdata->state = SDMMC_PROBE_STATE_DETECT_SD_ACMD;
    00186                 break;
    00187         case SDMMC_PROBE_STATE_DETECT_SD_ACMD:
    00188                 if (req->status) {
    00189                         clear_bit(SDMMC_SLOT_HCS, &slot->flags);
    00190                         slot->bcr = 0;
    00191                 } else {
    00192                         set_bit(SDMMC_SLOT_HCS, &slot->flags);
    00193                         slot->bcr = SDMMC_OCR_CCS;
    00194                 }
    00195                 sdmmc_req_prep_cmd(req, SDMMC_APP_CMD, 0,
    00196                                 SDMMC_RSP_R1 | SDMMC_CMD_OPD);
    00197                 pdata->state = SDMMC_PROBE_STATE_DETECT_SD_CMD;
    00198                 break;
    00199         case SDMMC_PROBE_STATE_DETECT_SD_CMD:
    00200                 if (req->status || !(req->cmd.resp[0] &
    00201                                         SDMMC_CARD_STATUS_APP_CMD)) {
    00202                         pdata->state = SDMMC_PROBE_STATE_DETECT_MMC;
    00203                         goto rerun;
    00204                 }
    00205                 sdmmc_req_prep_cmd(req, SD_SEND_OP_COND, slot->bcr,
    00206                                 SDMMC_RSP_R3 | SDMMC_CMD_OPD);
    00207                 pdata->state = SDMMC_PROBE_STATE_DETECT_SD_DONE;
    00208                 break;
    00209         case SDMMC_PROBE_STATE_DETECT_SD_DONE:
    00210                 if (req->status) {
    00211                         pdata->state = SDMMC_PROBE_STATE_DETECT_MMC;
    00212                         goto rerun;
    00213                 }
    00214                 sdmmc_card_set_type(&slot->card, SDMMC_CARD_TYPE_SD);
    00215                 slot->ocr = req->cmd.resp[0];
    00216                 slot->ocr = sdmmc_slot_set_voltage(slot, slot->ocr);
    00217                 if (test_bit(SDMMC_SLOT_HCS, &slot->flags))
    00218                         slot->ocr |= SDMMC_OCR_CCS;
    00219                 pdata->i = 0;
    00220                 /* intentionally no break */
    00221         case SDMMC_PROBE_STATE_SD_APP_COND_LOOP:
    00222                 /* Send app op cond again and loop 100 times with a 10ms
    00223                  * pause
    00224                  */
    00225                 sdmmc_req_prep_cmd(req, SDMMC_APP_CMD, 0,
    00226                                 SDMMC_RSP_R1 | SDMMC_CMD_OPD);
    00227                 pdata->state = SDMMC_PROBE_STATE_SD_APP_COND_CMD;
    00228                 break;
    00229         case SDMMC_PROBE_STATE_SD_APP_COND_CMD:
    00230                 if (req->status)
    00231                         goto failure;
    00232                 sdmmc_req_prep_cmd(req, SD_SEND_OP_COND, slot->ocr,
    00233                                 SDMMC_RSP_R3 | SDMMC_CMD_OPD);
    00234                 pdata->state = SDMMC_PROBE_STATE_SD_SEND_CID;
    00235                 break;
    00236         case SDMMC_PROBE_STATE_SD_SEND_CID:
    00237                 if (req->status)
    00238                         goto failure;
    00239                 if (!(req->cmd.resp[0] & SDMMC_OCR_POWER_UP_DONE)) {
    00240                         if (pdata->i >= 100)
    00241                                 goto failure;
    00242                         pdata->i++;
    00243                         pdata->state = SDMMC_PROBE_STATE_SD_APP_COND_LOOP;
    00244                         delayed_work_run_us(&pdata->dwork, &pdata->work,
    00245                                         10000);
    00246                         return;
    00247                 }
    00248                 if (req->cmd.resp[0] & SDMMC_OCR_CCS)
    00249                         sdmmc_card_set_type(&slot->card,
    00250                                         SDMMC_CARD_TYPE_SDHC);
    00251                 sdmmc_req_prep_cmd(req, SDMMC_ALL_SEND_CID, 0,
    00252                                 SDMMC_RSP_R2 | SDMMC_CMD_OPD);
    00253                 pdata->state = SDMMC_PROBE_STATE_SD_SET_RELADDR;
    00254                 break;
    00255         case SDMMC_PROBE_STATE_SD_SET_RELADDR:
    00256                 if (req->status)
    00257                         goto failure;
    00258                 sdmmc_decode_sd_cid(&slot->card, req->cmd.resp);
    00259                 sdmmc_req_prep_cmd(req, SDMMC_SET_RELATIVE_ADDR, 0,
    00260                                 SDMMC_RSP_R6 | SDMMC_CMD_OPD);
    00261                 pdata->state = SDMMC_PROBE_STATE_SD_SEND_CSD;
    00262                 break;
    00263         case SDMMC_PROBE_STATE_SD_SEND_CSD:
    00264                 if (req->status)
    00265                         goto failure;
    00266                 slot->card.rca = req->cmd.resp[0] & SDMMC_RCA_MASK;
    00267                 sdmmc_req_prep_cmd(req, SDMMC_SEND_CSD, slot->card.rca,
    00268                                 SDMMC_RSP_R2);
    00269                 pdata->state = SDMMC_PROBE_STATE_SD_SELECT_CARD;
    00270                 break;
    00271         case SDMMC_PROBE_STATE_SD_SELECT_CARD:
    00272                 if (req->status)
    00273                         goto failure;
    00274                 ret = sdmmc_decode_sd_csd(&slot->card, req->cmd.resp);
    00275                 if (ret) {
    00276                         dbg_error("sdmmc probe: Failed to decode CSD!\n");
    00277                         goto failure;
    00278                 }
    00279
    00280                 sdmmc_req_prep_cmd(req, SDMMC_SELECT_DESELECT_CARD,
    00281                                 slot->card.rca, SDMMC_RSP_R1B);
    00282                 pdata->state = SDMMC_PROBE_STATE_SD_SEND_SCR_ACMD;
    00283                 break;
    00284         case SDMMC_PROBE_STATE_SD_SEND_SCR_ACMD:
    00285                 if (req->status)
    00286                         goto failure;
    00287                 sdmmc_req_prep_cmd(req, SDMMC_APP_CMD, slot->card.rca,
    00288                                 SDMMC_RSP_R1);
    00289                 pdata->state = SDMMC_PROBE_STATE_SD_SEND_SCR_CMD;
    00290                 break;
    00291         case SDMMC_PROBE_STATE_SD_SEND_SCR_CMD:
    00292                 if (req->status)
    00293                         goto failure;
    00294                 sdmmc_req_prep_cmd(req, SD_SEND_SCR, 0, SDMMC_RSP_R1);
    00295                 pdata->buf = buffer_dma_alloc(8);
    00296                 if (pdata->buf == NULL) {
    00297                         dbg_error("sdmmc probe: Failed to allocate buffer "
    00298                                         "w/dma!\n");
    00299                         goto failure;
    00300                 }
    00301                 sdmmc_req_prep_data(req, pdata->buf);
    00302                 pdata->state = SDMMC_PROBE_STATE_SD_FUNC_CHECK;
    00303                 break;
    00304         case SDMMC_PROBE_STATE_SD_FUNC_CHECK:
    00305                 if (req->status) {
    00306                         buffer_dma_free(pdata->buf, pdata->buf->len);
    00307                         goto failure;
    00308                 }
    00309                 dma_sync_for_cpu(pdata->buf->addr.ptr, 8, DMA_FROM_DEVICE);
    00310                 tmp = pdata->buf->addr.ptr;
    00311                 dbg_verbose("sdmmc probe: SCR: %08x %08x\n", tmp[0], tmp[1]);
    00312                 if (!(tmp[0] & SD_SCR0_BUS_WIDTH_4BIT_MASK)) {
    00313                         pdata->state = SDMMC_PROBE_STATE_SD_SET_CLK;
    00314                         buffer_dma_free(pdata->buf, pdata->buf->len);
    00315                         goto rerun;
    00316                 }
    00317                 /* If card is version 1.0 or 1.01, it doesn't support switch
    00318                  * function.
    00319                  */
    00320                 if ((tmp[0] & SD_SCR0_SPEC_VERSION_MASK) ==
    00321                                 SD_SCR0_SPEC_VERSION_10_101) {
    00322                         pdata->state = SDMMC_PROBE_STATE_SD_SET_BUS_WIDTH_ACMD;
    00323                         buffer_dma_free(pdata->buf, pdata->buf->len);
    00324                         goto rerun;
    00325                 }
    00326                 buffer_dma_free(pdata->buf, pdata->buf->len);
    00327                 sdmmc_req_prep_cmd(req, SDMMC_SWITCH_FUNC,
    00328                                 SDMMC_SWITCH_FUNC_MODE_CHECK |
    00329                                 SDMMC_SWITCH_FUNC_HIGH_SPEED, SDMMC_RSP_R1);
    00330                 pdata->buf = buffer_dma_alloc(64);
    00331                 if (pdata->buf == NULL) {
    00332                         dbg_error("sdmmc probe: Failed to allocate buffer "
    00333                                         "w/dma!\n");
    00334                         goto failure;
    00335                 }
    00336                 sdmmc_req_prep_data(req, pdata->buf);
    00337                 pdata->state = SDMMC_PROBE_STATE_SD_FUNC_SWITCH;
    00338                 break;
    00339         case SDMMC_PROBE_STATE_SD_FUNC_SWITCH:
    00340                 if ((((uint8_t *)pdata->buf->addr.ptr)[16] & 0xf) != 1 ||
    00341                                 req->status) {
    00342                         pdata->state = SDMMC_PROBE_STATE_SD_DESELECT_CARD;
    00343                         buffer_dma_free(pdata->buf, pdata->buf->len);
    00344                         goto rerun;
    00345                 }
    00346                 dbg_verbose("sdmmc probe: Card supports high speed\n");
    00347                 sdmmc_req_prep_cmd(req, SDMMC_SWITCH_FUNC,
    00348                                 SDMMC_SWITCH_FUNC_MODE_SWITCH |
    00349                                 SDMMC_SWITCH_FUNC_G6_KEEP |
    00350                                 SDMMC_SWITCH_FUNC_G5_KEEP |
    00351                                 SDMMC_SWITCH_FUNC_G4_KEEP |
    00352                                 SDMMC_SWITCH_FUNC_G3_KEEP |
    00353                                 SDMMC_SWITCH_FUNC_G2_KEEP |
    00354                                 SDMMC_SWITCH_FUNC_HIGH_SPEED, SDMMC_RSP_R1);
    00355                 sdmmc_req_prep_data(req, pdata->buf);
    00356                 pdata->state = SDMMC_PROBE_STATE_SD_FUNC_DONE;
    00357                 break;
    00358         case SDMMC_PROBE_STATE_SD_FUNC_DONE:
    00359                 if (req->status) {
    00360                         buffer_dma_free(pdata->buf, pdata->buf->len);
    00361                         goto failure;
    00362                 }
    00363                 set_bit(SDMMC_SLOT_HIGH_SPEED, &slot->flags);
    00364                 buffer_dma_free(pdata->buf, pdata->buf->len);
    00365                 /* A 8 cycle delay is required after switch command
    00366                  * @ 200KHz clock this should be 40 uS, but we use
    00367                  * 80 to handle unprecise clock setting.
    00368                  */
    00369                 delayed_work_run_us(&pdata->dwork, &pdata->work, 80);
    00370                 pdata->state = SDMMC_PROBE_STATE_SD_DESELECT_CARD;
    00371                 return;
    00372         case SDMMC_PROBE_STATE_SD_DESELECT_CARD:
    00373                 sdmmc_req_prep_cmd(req, SDMMC_SELECT_DESELECT_CARD,
    00374                                 0, SDMMC_RSP_NONE);
    00375                 pdata->state = SDMMC_PROBE_STATE_SD_RESEND_CSD;
    00376                 break;
    00377         case SDMMC_PROBE_STATE_SD_RESEND_CSD:
    00378                 if (req->status)
    00379                         goto failure;
    00380                 sdmmc_req_prep_cmd(req, SDMMC_SEND_CSD, slot->card.rca,
    00381                                 SDMMC_RSP_R2);
    00382                 pdata->state = SDMMC_PROBE_STATE_SD_RESELECT_CARD;
    00383                 break;
    00384         case SDMMC_PROBE_STATE_SD_RESELECT_CARD:
    00385                 if (req->status)
    00386                         goto failure;
    00387                 ret = sdmmc_decode_sd_csd(&slot->card, req->cmd.resp);
    00388                 if (ret) {
    00389                         dbg_error("sdmmc probe: Failed to decode CSD!\n");
    00390                         goto failure;
    00391                 }
    00392                 sdmmc_req_prep_cmd(req, SDMMC_SELECT_DESELECT_CARD,
    00393                                 slot->card.rca, SDMMC_RSP_R1B);
    00394                 pdata->state = SDMMC_PROBE_STATE_SD_SET_BUS_WIDTH_ACMD;
    00395                 break;
    00396         case SDMMC_PROBE_STATE_SD_SET_BUS_WIDTH_ACMD:
    00397                 if (req->status)
    00398                         goto failure;
    00399                 sdmmc_req_prep_cmd(req, SDMMC_APP_CMD, slot->card.rca,
    00400                                 SDMMC_RSP_R1);
    00401                 pdata->state = SDMMC_PROBE_STATE_SD_SET_BUS_WIDTH_CMD;
    00402                 break;
    00403         case SDMMC_PROBE_STATE_SD_SET_BUS_WIDTH_CMD:
    00404                 if (req->status)
    00405                         goto failure;
    00406                 sdmmc_req_prep_cmd(req, SD_SET_BUS_WIDTH,
    00407                                 SD_ARG_SET_BUS_WIDTH_4BIT, SDMMC_RSP_R1);
    00408                 pdata->state = SDMMC_PROBE_STATE_SD_SET_BUS_WIDTH_DONE;
    00409                 break;
    00410         case SDMMC_PROBE_STATE_SD_SET_BUS_WIDTH_DONE:
    00411                 if (req->status)
    00412                         goto failure;
    00413                 sdmmc_slot_set_bus_width(slot, 4);
    00414                 /* intentionally no break */
    00415         case SDMMC_PROBE_STATE_SD_SET_CLK:
    00416                 dbg_info("sdmmc: card%u max transfer rate: %d MHz\n",
    00417                                 slot->id,
    00418                                 slot->card.csd.max_transfer_rate / 1000000);
    00419                 sdmmc_slot_set_f_max(slot, slot->card.csd.max_transfer_rate);
    00420                 /* intentionally no break */
    00421         case SDMMC_PROBE_STATE_SD_SET_BLOCK_LEN:
    00422                 sdmmc_req_prep_cmd(req, SDMMC_SET_BLOCKLEN,
    00423                                 512, SDMMC_RSP_R1);
    00424                 slot->card.block_size = 512;
    00425                 pdata->state = SDMMC_PROBE_STATE_SD_FINAL;
    00426                 break;
    00427         case SDMMC_PROBE_STATE_SD_FINAL:
    00428                 if (req->status)
    00429                         goto failure;
    00430                 pdata->state = SDMMC_PROBE_STATE_SEND_STATUS;
    00431                 goto rerun;
    00432
    00433         case SDMMC_PROBE_STATE_DETECT_MMC:
    00434                 /* TODO: MMC detection */
    00435                 goto failure;
    00436         /* send_op_cond */
    00437         /* if ok attach mmc */
    00438
    00439         /* State to stay in as long as the card is available.
    00440          * Will stop the state machine after verifying that the card
    00441          * responds to SEND_STATUS, but might be restarted by
    00442          * card detection. And in case of card removal it will
    00443          * continue with card removal procedure.
    00444          *
    00445          * Always requesting the card status upon a card event allows us
    00446          * to synchronize the with request queue and avoid nasty race
    00447          * conditions elsewhere.
    00448          */
    00449         case SDMMC_PROBE_STATE_SEND_STATUS:
    00450                 if (!test_bit(SDMMC_SLOT_CARD_DETECT, &slot->flags))
    00451                         clear_bit(SDMMC_SLOT_CARD_PRESENT, &slot->flags);
    00452                 else
    00453                         set_bit(SDMMC_SLOT_CARD_PRESENT, &slot->flags);
    00454
    00455                 sdmmc_req_prep_cmd(req, SDMMC_SEND_STATUS, slot->card.rca,
    00456                                 SDMMC_RSP_R1);
    00457                 pdata->state = SDMMC_PROBE_STATE_CHECK_STATUS;
    00458                 break;
    00459
    00460         case SDMMC_PROBE_STATE_CHECK_STATUS:
    00461                 /* Normally, we go back to the SEND_STATUS state */
    00462                 pdata->state = SDMMC_PROBE_STATE_SEND_STATUS;
    00463
    00464                 if (req->status == 0) {
    00465                         uint32_t card_status;
    00466
    00467                         if (!test_bit(SDMMC_SLOT_CARD_DETECT, &slot->flags)
    00468                                         && sdmmc_slot_is_card_present(slot))
    00469                                 /* Missed an event; retry */
    00470                                 goto rerun;
    00471
    00472                         if (pdata->event)
    00473                                 pdata->event(slot, pdata->context);
    00474
    00475                         card_status = req->cmd.resp[0];
    00476                         dbg_info("sdmmc: slot%u card status: %08x\n",
    00477                                         slot->id, card_status);
    00478                         if ((card_status & SDMMC_CURRENT_STATE_MASK)
    00479                                         == SDMMC_CURRENT_STATE_TRAN) {
    00480                                 pdata->running = false;
    00481                                 return;
    00482                         } else {
    00483                                 /*
    00484                                  * Card may have been disconnected
    00485                                  * briefly. Re-run probe sequence.
    00486                                  */
    00487                                 pdata->state = SDMMC_PROBE_STATE_INIT;
    00488                                 goto rerun;
    00489                         }
    00490                 }
    00491
    00492                 /* No response to SEND_STATUS, so it must be gone. */
    00493                 if (test_bit(SDMMC_SLOT_CARD_DETECT, &slot->flags)
    00494                                 && !sdmmc_slot_is_card_present(slot))
    00495                         /* Missed an event; retry */
    00496                         goto rerun;
    00497
    00498                 clear_bit(SDMMC_SLOT_CARD_PRESENT, &slot->flags);
    00499
    00500                 if (pdata->event)
    00501                         pdata->event(slot, pdata->context);
    00502
    00503                 sdmmc_slot_power_down(slot);
    00504                 pdata->state = SDMMC_PROBE_STATE_INIT;
    00505                 pdata->running = false;
    00506                 return;
    00507         }
    00508
    00509         pdata->slot->host->submit_req(pdata->slot->host, req);
    00510         return;
    00511
    00512 rerun:
    00513         workqueue_add_item(&sdmmc_workqueue, &pdata->work);
    00514         return;
    00515
    00516 failure:
    00517         dbg_error("sdmmc: probe failure in state %d\n", pdata->state);
    00518         sdmmc_slot_power_down(slot);
    00519         pdata->state = SDMMC_PROBE_STATE_INIT;
    00520         pdata->running = false;
    00521         clear_bit(SDMMC_SLOT_CARD_PRESENT, &slot->flags);
    00522         if (pdata->event)
    00523                 pdata->event(slot, pdata->context);
    00524         /* TODO: Retry timer? */
    00525 }
    00526
    00527 /* This must be run in sdmmc_workqueue context */
    00528 void sdmmc_probe_notify_card_detect(void *context)
    00529 {
    00530         struct sdmmc_probe_data *pdata = context;
    00531
    00532         if (!pdata->running) {
    00533                 pdata->running = true;
    00534                 workqueue_add_item(&sdmmc_workqueue, &pdata->work);
    00535         }
    00536 }
    00537
    00538 void *sdmmc_probe_init(struct sdmmc_slot *slot,
    00539                 void (*event)(struct sdmmc_slot *slot, void *context),
    00540                 void *context)
    00541 {
    00542         struct sdmmc_probe_data *pdata;
    00543
    00544         pdata = malloc(sizeof(struct sdmmc_probe_data));
    00545         if (pdata == NULL)
    00546                 return NULL;
    00547         memset(pdata, 0, sizeof(struct sdmmc_probe_data));
    00548
    00549         slot->notify_card_detect = sdmmc_probe_notify_card_detect;
    00550         slot->context = pdata;
    00551
    00552         pdata->req.slot = slot;
    00553         pdata->slot = slot;
    00554         pdata->event = event;
    00555         pdata->context = context;
    00556         workqueue_init_item(&pdata->work, sdmmc_probe_engine, pdata);
    00557         delayed_work_init(&pdata->dwork, &sdmmc_timer, &sdmmc_workqueue);
    00558
    00559         return pdata;
    00560 }
    00561