root/dev/sdmmc/sdmmc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sdmmc_match
  2. sdmmc_attach
  3. sdmmc_detach
  4. sdmmc_create_thread
  5. sdmmc_task_thread
  6. sdmmc_add_task
  7. sdmmc_del_task
  8. sdmmc_needs_discover
  9. sdmmc_discover_task
  10. sdmmc_card_attach
  11. sdmmc_card_detach
  12. sdmmc_enable
  13. sdmmc_disable
  14. sdmmc_set_bus_power
  15. sdmmc_function_alloc
  16. sdmmc_function_free
  17. sdmmc_scan
  18. sdmmc_init
  19. sdmmc_delay
  20. sdmmc_app_command
  21. sdmmc_mmc_command
  22. sdmmc_go_idle_state
  23. sdmmc_set_relative_addr
  24. sdmmc_set_bus_width
  25. sdmmc_select_card
  26. sdmmc_ioctl
  27. sdmmc_dump_command

    1 /*      $OpenBSD: sdmmc.c,v 1.12 2007/05/31 10:09:01 uwe Exp $  */
    2 
    3 /*
    4  * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  */
   18 
   19 /*
   20  * Host controller independent SD/MMC bus driver based on information
   21  * from SanDisk SD Card Product Manual Revision 2.2 (SanDisk), SDIO
   22  * Simple Specification Version 1.0 (SDIO) and the Linux "mmc" driver.
   23  */
   24 
   25 #include <sys/param.h>
   26 #include <sys/device.h>
   27 #include <sys/kernel.h>
   28 #include <sys/kthread.h>
   29 #include <sys/malloc.h>
   30 #include <sys/proc.h>
   31 #include <sys/systm.h>
   32 
   33 #include <scsi/scsi_all.h>
   34 #include <scsi/scsiconf.h>
   35 
   36 #include <dev/sdmmc/sdmmc_ioreg.h>
   37 #include <dev/sdmmc/sdmmc_scsi.h>
   38 #include <dev/sdmmc/sdmmcchip.h>
   39 #include <dev/sdmmc/sdmmcreg.h>
   40 #include <dev/sdmmc/sdmmcvar.h>
   41 
   42 #ifdef SDMMC_IOCTL
   43 #include "bio.h"
   44 #if NBIO < 1
   45 #undef SDMMC_IOCTL
   46 #endif
   47 #include <dev/biovar.h>
   48 #endif
   49 
   50 int     sdmmc_match(struct device *, void *, void *);
   51 void    sdmmc_attach(struct device *, struct device *, void *);
   52 int     sdmmc_detach(struct device *, int);
   53 void    sdmmc_create_thread(void *);
   54 void    sdmmc_task_thread(void *);
   55 void    sdmmc_discover_task(void *);
   56 void    sdmmc_card_attach(struct sdmmc_softc *);
   57 void    sdmmc_card_detach(struct sdmmc_softc *, int);
   58 int     sdmmc_enable(struct sdmmc_softc *);
   59 void    sdmmc_disable(struct sdmmc_softc *);
   60 int     sdmmc_scan(struct sdmmc_softc *);
   61 int     sdmmc_init(struct sdmmc_softc *);
   62 int     sdmmc_set_bus_width(struct sdmmc_function *);
   63 #ifdef SDMMC_IOCTL
   64 int     sdmmc_ioctl(struct device *, u_long, caddr_t);
   65 #endif
   66 
   67 #define DEVNAME(sc)     SDMMCDEVNAME(sc)
   68 
   69 #ifdef SDMMC_DEBUG
   70 int sdmmcdebug = 0;
   71 extern int sdhcdebug;   /* XXX should have a sdmmc_chip_debug() function */
   72 void sdmmc_dump_command(struct sdmmc_softc *, struct sdmmc_command *);
   73 #define DPRINTF(n,s)    do { if ((n) <= sdmmcdebug) printf s; } while (0)
   74 #else
   75 #define DPRINTF(n,s)    do {} while (0)
   76 #endif
   77 
   78 struct cfattach sdmmc_ca = {
   79         sizeof(struct sdmmc_softc), sdmmc_match, sdmmc_attach, sdmmc_detach
   80 };
   81 
   82 struct cfdriver sdmmc_cd = {
   83         NULL, "sdmmc", DV_DULL
   84 };
   85 
   86 int
   87 sdmmc_match(struct device *parent, void *match, void *aux)
   88 {
   89         struct cfdata *cf = match;
   90         struct sdmmcbus_attach_args *saa = aux;
   91 
   92         return strcmp(saa->saa_busname, cf->cf_driver->cd_name) == 0;
   93 }
   94 
   95 void
   96 sdmmc_attach(struct device *parent, struct device *self, void *aux)
   97 {
   98         struct sdmmc_softc *sc = (struct sdmmc_softc *)self;
   99         struct sdmmcbus_attach_args *saa = aux;
  100 
  101         printf("\n");
  102 
  103         sc->sct = saa->sct;
  104         sc->sch = saa->sch;
  105 
  106         SIMPLEQ_INIT(&sc->sf_head);
  107         TAILQ_INIT(&sc->sc_tskq);
  108         TAILQ_INIT(&sc->sc_intrq);
  109         sdmmc_init_task(&sc->sc_discover_task, sdmmc_discover_task, sc);
  110         sdmmc_init_task(&sc->sc_intr_task, sdmmc_intr_task, sc);
  111         lockinit(&sc->sc_lock, PRIBIO, DEVNAME(sc), 0, LK_CANRECURSE);
  112 
  113 #ifdef SDMMC_IOCTL
  114         if (bio_register(self, sdmmc_ioctl) != 0)
  115                 printf("%s: unable to register ioctl\n", DEVNAME(sc));
  116 #endif
  117 
  118         /*
  119          * Create the event thread that will attach and detach cards
  120          * and perform other lengthy operations.
  121          */
  122 #ifdef DO_CONFIG_PENDING
  123         config_pending_incr();
  124 #endif
  125         kthread_create_deferred(sdmmc_create_thread, sc);
  126 }
  127 
  128 int
  129 sdmmc_detach(struct device *self, int flags)
  130 {
  131         struct sdmmc_softc *sc = (struct sdmmc_softc *)self;
  132 
  133         sc->sc_dying = 1;
  134         while (sc->sc_task_thread != NULL) {
  135                 wakeup(&sc->sc_tskq);
  136                 tsleep(sc, PWAIT, "mmcdie", 0);
  137         }
  138         return 0;
  139 }
  140 
  141 void
  142 sdmmc_create_thread(void *arg)
  143 {
  144         struct sdmmc_softc *sc = arg;
  145 
  146         if (kthread_create(sdmmc_task_thread, sc, &sc->sc_task_thread,
  147             "%s", DEVNAME(sc)) != 0)
  148                 printf("%s: can't create task thread\n", DEVNAME(sc));
  149 
  150 #ifdef DO_CONFIG_PENDING
  151         config_pending_decr();
  152 #endif
  153 }
  154 
  155 void
  156 sdmmc_task_thread(void *arg)
  157 {
  158         struct sdmmc_softc *sc = arg;
  159         struct sdmmc_task *task;
  160         int s;
  161 
  162         sdmmc_needs_discover(&sc->sc_dev);
  163 
  164         s = splsdmmc();
  165         while (!sc->sc_dying) {
  166                 for (task = TAILQ_FIRST(&sc->sc_tskq); task != NULL;
  167                      task = TAILQ_FIRST(&sc->sc_tskq)) {
  168                         splx(s);
  169                         sdmmc_del_task(task);
  170                         task->func(task->arg);
  171                         s = splsdmmc();
  172                 }
  173                 tsleep(&sc->sc_tskq, PWAIT, "mmctsk", 0);
  174         }
  175         splx(s);
  176 
  177         if (ISSET(sc->sc_flags, SMF_CARD_PRESENT))
  178                 sdmmc_card_detach(sc, DETACH_FORCE);
  179 
  180         sc->sc_task_thread = NULL;
  181         wakeup(sc);
  182         kthread_exit(0);
  183 }
  184 
  185 void
  186 sdmmc_add_task(struct sdmmc_softc *sc, struct sdmmc_task *task)
  187 {
  188         int s;
  189 
  190         s = splsdmmc();
  191         TAILQ_INSERT_TAIL(&sc->sc_tskq, task, next);
  192         task->onqueue = 1;
  193         task->sc = sc;
  194         wakeup(&sc->sc_tskq);
  195         splx(s);
  196 }
  197 
  198 void
  199 sdmmc_del_task(struct sdmmc_task *task)
  200 {
  201         struct sdmmc_softc *sc = task->sc;
  202         int s;
  203 
  204         if (sc == NULL)
  205                 return;
  206 
  207         s = splsdmmc();
  208         task->sc = NULL;
  209         task->onqueue = 0;
  210         TAILQ_REMOVE(&sc->sc_tskq, task, next);
  211         splx(s);
  212 }
  213 
  214 void
  215 sdmmc_needs_discover(struct device *self)
  216 {
  217         struct sdmmc_softc *sc = (struct sdmmc_softc *)self;
  218 
  219         if (!sdmmc_task_pending(&sc->sc_discover_task))
  220                 sdmmc_add_task(sc, &sc->sc_discover_task);
  221 }
  222 
  223 void
  224 sdmmc_discover_task(void *arg)
  225 {
  226         struct sdmmc_softc *sc = arg;
  227 
  228         if (sdmmc_chip_card_detect(sc->sct, sc->sch)) {
  229                 if (!ISSET(sc->sc_flags, SMF_CARD_PRESENT)) {
  230                         SET(sc->sc_flags, SMF_CARD_PRESENT);
  231                         sdmmc_card_attach(sc);
  232                 }
  233         } else {
  234                 if (ISSET(sc->sc_flags, SMF_CARD_PRESENT)) {
  235                         CLR(sc->sc_flags, SMF_CARD_PRESENT);
  236                         sdmmc_card_detach(sc, DETACH_FORCE);
  237                 }
  238         }
  239 }
  240 
  241 /*
  242  * Called from process context when a card is present.
  243  */
  244 void
  245 sdmmc_card_attach(struct sdmmc_softc *sc)
  246 {
  247         DPRINTF(1,("%s: attach card\n", DEVNAME(sc)));
  248 
  249         SDMMC_LOCK(sc);
  250         CLR(sc->sc_flags, SMF_CARD_ATTACHED);
  251 
  252         /*
  253          * Power up the card (or card stack).
  254          */
  255         if (sdmmc_enable(sc) != 0) {
  256                 printf("%s: can't enable card\n", DEVNAME(sc));
  257                 goto err;
  258         }
  259 
  260         /*
  261          * Scan for I/O functions and memory cards on the bus,
  262          * allocating a sdmmc_function structure for each.
  263          */
  264         if (sdmmc_scan(sc) != 0) {
  265                 printf("%s: no functions\n", DEVNAME(sc));
  266                 goto err;
  267         }
  268 
  269         /*
  270          * Initialize the I/O functions and memory cards.
  271          */
  272         if (sdmmc_init(sc) != 0) {
  273                 printf("%s: init failed\n", DEVNAME(sc));
  274                 goto err;
  275         }
  276 
  277         /* Attach SCSI emulation for memory cards. */
  278         if (ISSET(sc->sc_flags, SMF_MEM_MODE))
  279                 sdmmc_scsi_attach(sc);
  280 
  281         /* Attach I/O function drivers. */
  282         if (ISSET(sc->sc_flags, SMF_IO_MODE))
  283                 sdmmc_io_attach(sc);
  284 
  285         SET(sc->sc_flags, SMF_CARD_ATTACHED);
  286         SDMMC_UNLOCK(sc);
  287         return;
  288 err:
  289         sdmmc_card_detach(sc, DETACH_FORCE);
  290         SDMMC_UNLOCK(sc);
  291 }
  292 
  293 /*
  294  * Called from process context with DETACH_* flags from <sys/device.h>
  295  * when cards are gone.
  296  */
  297 void
  298 sdmmc_card_detach(struct sdmmc_softc *sc, int flags)
  299 {
  300         struct sdmmc_function *sf, *sfnext;
  301 
  302         DPRINTF(1,("%s: detach card\n", DEVNAME(sc)));
  303 
  304         if (ISSET(sc->sc_flags, SMF_CARD_ATTACHED)) {
  305                 /* Detach I/O function drivers. */
  306                 if (ISSET(sc->sc_flags, SMF_IO_MODE))
  307                         sdmmc_io_detach(sc);
  308 
  309                 /* Detach the SCSI emulation for memory cards. */
  310                 if (ISSET(sc->sc_flags, SMF_MEM_MODE))
  311                         sdmmc_scsi_detach(sc);
  312 
  313                 CLR(sc->sc_flags, SMF_CARD_ATTACHED);
  314         }
  315 
  316         /* Power down. */
  317         sdmmc_disable(sc);
  318 
  319         /* Free all sdmmc_function structures. */
  320         for (sf = SIMPLEQ_FIRST(&sc->sf_head); sf != NULL; sf = sfnext) {
  321                 sfnext = SIMPLEQ_NEXT(sf, sf_list);
  322                 sdmmc_function_free(sf);
  323         }
  324         SIMPLEQ_INIT(&sc->sf_head);
  325         sc->sc_function_count = 0;
  326         sc->sc_fn0 = NULL;
  327 }
  328 
  329 int
  330 sdmmc_enable(struct sdmmc_softc *sc)
  331 {
  332         u_int32_t host_ocr;
  333         int error;
  334 
  335         /*
  336          * Calculate the equivalent of the card OCR from the host
  337          * capabilities and select the maximum supported bus voltage.
  338          */
  339         host_ocr = sdmmc_chip_host_ocr(sc->sct, sc->sch);
  340         error = sdmmc_chip_bus_power(sc->sct, sc->sch, host_ocr);
  341         if (error != 0) {
  342                 printf("%s: can't supply bus power\n", DEVNAME(sc));
  343                 goto err;
  344         }
  345 
  346         /*
  347          * Select the minimum clock frequency.
  348          */
  349         error = sdmmc_chip_bus_clock(sc->sct, sc->sch, SDMMC_SDCLK_400KHZ);
  350         if (error != 0) {
  351                 printf("%s: can't supply clock\n", DEVNAME(sc));
  352                 goto err;
  353         }
  354 
  355         /* XXX wait for card to power up */
  356         sdmmc_delay(100000);
  357 
  358         /* Initialize SD I/O card function(s). */
  359         if ((error = sdmmc_io_enable(sc)) != 0)
  360                 goto err;
  361 
  362         /* Initialize SD/MMC memory card(s). */
  363         if (ISSET(sc->sc_flags, SMF_MEM_MODE) &&
  364             (error = sdmmc_mem_enable(sc)) != 0)
  365                 goto err;
  366 
  367         /* XXX respect host and card capabilities */
  368         if (ISSET(sc->sc_flags, SMF_SD_MODE))
  369                 (void)sdmmc_chip_bus_clock(sc->sct, sc->sch,
  370                     SDMMC_SDCLK_25MHZ);
  371 
  372  err:
  373         if (error != 0)
  374                 sdmmc_disable(sc);
  375         return error;
  376 }
  377 
  378 void
  379 sdmmc_disable(struct sdmmc_softc *sc)
  380 {
  381         /* XXX complete commands if card is still present. */
  382 
  383         /* Make sure no card is still selected. */
  384         (void)sdmmc_select_card(sc, NULL);
  385 
  386         /* Turn off bus power and clock. */
  387         (void)sdmmc_chip_bus_clock(sc->sct, sc->sch, SDMMC_SDCLK_OFF);
  388         (void)sdmmc_chip_bus_power(sc->sct, sc->sch, 0);
  389 }
  390 
  391 /*
  392  * Set the lowest bus voltage supported by the card and the host.
  393  */
  394 int
  395 sdmmc_set_bus_power(struct sdmmc_softc *sc, u_int32_t host_ocr,
  396     u_int32_t card_ocr)
  397 {
  398         u_int32_t bit;
  399 
  400         /* Mask off unsupported voltage levels and select the lowest. */
  401         DPRINTF(1,("%s: host_ocr=%x ", DEVNAME(sc), host_ocr));
  402         host_ocr &= card_ocr;
  403         for (bit = 4; bit < 23; bit++) {
  404                 if (ISSET(host_ocr, 1<<bit)) {
  405                         host_ocr &= 3<<bit;
  406                         break;
  407                 }
  408         }
  409         DPRINTF(1,("card_ocr=%x new_ocr=%x\n", card_ocr, host_ocr));
  410 
  411         if (host_ocr == 0 ||
  412             sdmmc_chip_bus_power(sc->sct, sc->sch, host_ocr) != 0)
  413                 return 1;
  414         return 0;
  415 }
  416 
  417 struct sdmmc_function *
  418 sdmmc_function_alloc(struct sdmmc_softc *sc)
  419 {
  420         struct sdmmc_function *sf;
  421 
  422         MALLOC(sf, struct sdmmc_function *, sizeof *sf, M_DEVBUF,
  423             M_WAITOK);
  424         bzero(sf, sizeof *sf);
  425         sf->sc = sc;
  426         sf->number = -1;
  427         sf->cis.manufacturer = SDMMC_VENDOR_INVALID;
  428         sf->cis.product = SDMMC_PRODUCT_INVALID;
  429         sf->cis.function = SDMMC_FUNCTION_INVALID;
  430         return sf;
  431 }
  432 
  433 void
  434 sdmmc_function_free(struct sdmmc_function *sf)
  435 {
  436         FREE(sf, M_DEVBUF);
  437 }
  438 
  439 /*
  440  * Scan for I/O functions and memory cards on the bus, allocating a
  441  * sdmmc_function structure for each.
  442  */
  443 int
  444 sdmmc_scan(struct sdmmc_softc *sc)
  445 {
  446         /* Scan for I/O functions. */
  447         if (ISSET(sc->sc_flags, SMF_IO_MODE))
  448                 sdmmc_io_scan(sc);
  449 
  450         /* Scan for memory cards on the bus. */
  451         if (ISSET(sc->sc_flags, SMF_MEM_MODE))
  452                 sdmmc_mem_scan(sc);
  453 
  454         /* There should be at least one function now. */
  455         if (SIMPLEQ_EMPTY(&sc->sf_head)) {
  456                 printf("%s: can't identify card\n", DEVNAME(sc));
  457                 return 1;
  458         }
  459         return 0;
  460 }
  461 
  462 /*
  463  * Initialize all the distinguished functions of the card, be it I/O
  464  * or memory functions.
  465  */
  466 int
  467 sdmmc_init(struct sdmmc_softc *sc)
  468 {
  469         struct sdmmc_function *sf;
  470 
  471         /* Initialize all identified card functions. */
  472         SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) {
  473                 if (ISSET(sc->sc_flags, SMF_IO_MODE) &&
  474                     sdmmc_io_init(sc, sf) != 0)
  475                         printf("%s: i/o init failed\n", DEVNAME(sc));
  476 
  477                 if (ISSET(sc->sc_flags, SMF_MEM_MODE) &&
  478                     sdmmc_mem_init(sc, sf) != 0)
  479                         printf("%s: mem init failed\n", DEVNAME(sc));
  480         }
  481 
  482         /* Any good functions left after initialization? */
  483         SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) {
  484                 if (!ISSET(sf->flags, SFF_ERROR))
  485                         return 0;
  486         }
  487         /* No, we should probably power down the card. */
  488         return 1;
  489 }
  490 
  491 void
  492 sdmmc_delay(u_int usecs)
  493 {
  494         int ticks = usecs / (1000000 / hz);
  495 
  496         if (ticks > 0)
  497                 tsleep(&sdmmc_delay, PWAIT, "mmcdly", ticks);
  498         else
  499                 delay(usecs);
  500 }
  501 
  502 int
  503 sdmmc_app_command(struct sdmmc_softc *sc, struct sdmmc_command *cmd)
  504 {
  505         struct sdmmc_command acmd;
  506         int error;
  507 
  508         SDMMC_LOCK(sc);
  509 
  510         bzero(&acmd, sizeof acmd);
  511         acmd.c_opcode = MMC_APP_CMD;
  512         acmd.c_arg = 0;
  513         acmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
  514 
  515         error = sdmmc_mmc_command(sc, &acmd);
  516         if (error != 0) {
  517                 SDMMC_UNLOCK(sc);
  518                 return error;
  519         }
  520 
  521         if (!ISSET(MMC_R1(acmd.c_resp), MMC_R1_APP_CMD)) {
  522                 /* Card does not support application commands. */
  523                 SDMMC_UNLOCK(sc);
  524                 return ENODEV;
  525         }
  526 
  527         error = sdmmc_mmc_command(sc, cmd);
  528         SDMMC_UNLOCK(sc);
  529         return error;
  530 }
  531 
  532 /*
  533  * Execute MMC command and data transfers.  All interactions with the
  534  * host controller to complete the command happen in the context of
  535  * the current process.
  536  */
  537 int
  538 sdmmc_mmc_command(struct sdmmc_softc *sc, struct sdmmc_command *cmd)
  539 {
  540         int error;
  541 
  542         SDMMC_LOCK(sc);
  543 
  544         sdmmc_chip_exec_command(sc->sct, sc->sch, cmd);
  545 
  546 #ifdef SDMMC_DEBUG
  547         sdmmc_dump_command(sc, cmd);
  548 #endif
  549 
  550         error = cmd->c_error;
  551         wakeup(cmd);
  552 
  553         SDMMC_UNLOCK(sc);
  554         return error;
  555 }
  556 
  557 /*
  558  * Send the "GO IDLE STATE" command.
  559  */
  560 void
  561 sdmmc_go_idle_state(struct sdmmc_softc *sc)
  562 {
  563         struct sdmmc_command cmd;
  564 
  565         bzero(&cmd, sizeof cmd);
  566         cmd.c_opcode = MMC_GO_IDLE_STATE;
  567         cmd.c_flags = SCF_CMD_BC | SCF_RSP_R0;
  568 
  569         (void)sdmmc_mmc_command(sc, &cmd);
  570 }
  571 
  572 /*
  573  * Retrieve (SD) or set (MMC) the relative card address (RCA).
  574  */
  575 int
  576 sdmmc_set_relative_addr(struct sdmmc_softc *sc,
  577     struct sdmmc_function *sf)
  578 {
  579         struct sdmmc_command cmd;
  580 
  581         bzero(&cmd, sizeof cmd);
  582 
  583         if (ISSET(sc->sc_flags, SMF_SD_MODE)) {
  584                 cmd.c_opcode = SD_SEND_RELATIVE_ADDR;
  585                 cmd.c_flags = SCF_CMD_BCR | SCF_RSP_R6;
  586         } else {
  587                 cmd.c_opcode = MMC_SET_RELATIVE_ADDR;
  588                 cmd.c_arg = MMC_ARG_RCA(sf->rca);
  589                 cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
  590         }
  591 
  592         if (sdmmc_mmc_command(sc, &cmd) != 0)
  593                 return 1;
  594 
  595         if (ISSET(sc->sc_flags, SMF_SD_MODE))
  596                 sf->rca = SD_R6_RCA(cmd.c_resp);
  597         return 0;
  598 }
  599 
  600 /*
  601  * Switch card and host to the maximum supported bus width.
  602  */
  603 int
  604 sdmmc_set_bus_width(struct sdmmc_function *sf)
  605 {
  606         struct sdmmc_softc *sc = sf->sc;
  607         struct sdmmc_command cmd;
  608         int error;
  609 
  610         SDMMC_LOCK(sc);
  611 
  612         if (!ISSET(sc->sc_flags, SMF_SD_MODE)) {
  613                 SDMMC_UNLOCK(sc);
  614                 return EOPNOTSUPP;
  615         }
  616 
  617         if ((error = sdmmc_select_card(sc, sf)) != 0) {
  618                 SDMMC_UNLOCK(sc);
  619                 return error;
  620         }
  621 
  622         bzero(&cmd, sizeof cmd);
  623         cmd.c_opcode = SD_APP_SET_BUS_WIDTH;
  624         cmd.c_arg = SD_ARG_BUS_WIDTH_4;
  625         cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1;
  626         error = sdmmc_app_command(sc, &cmd);
  627         SDMMC_UNLOCK(sc);
  628         return error;
  629 }
  630 
  631 int
  632 sdmmc_select_card(struct sdmmc_softc *sc, struct sdmmc_function *sf)
  633 {
  634         struct sdmmc_command cmd;
  635         int error;
  636 
  637         if (sc->sc_card == sf || (sf && sc->sc_card &&
  638             sc->sc_card->rca == sf->rca)) {
  639                 sc->sc_card = sf;
  640                 return 0;
  641         }
  642 
  643         bzero(&cmd, sizeof cmd);
  644         cmd.c_opcode = MMC_SELECT_CARD;
  645         cmd.c_arg = sf == NULL ? 0 : MMC_ARG_RCA(sf->rca);
  646         cmd.c_flags = SCF_CMD_AC | (sf == NULL ? SCF_RSP_R0 : SCF_RSP_R1);
  647         error = sdmmc_mmc_command(sc, &cmd);
  648         if (error == 0 || sf == NULL)
  649                 sc->sc_card = sf;
  650         return error;
  651 }
  652 
  653 #ifdef SDMMC_IOCTL
  654 int
  655 sdmmc_ioctl(struct device *self, u_long request, caddr_t addr)
  656 {
  657         struct sdmmc_softc *sc = (struct sdmmc_softc *)self;
  658         struct sdmmc_command *ucmd;
  659         struct sdmmc_command cmd;
  660         void *data;
  661         int error;
  662 
  663         switch (request) {
  664 #ifdef SDMMC_DEBUG
  665         case SDIOCSETDEBUG:
  666                 sdmmcdebug = (((struct bio_sdmmc_debug *)addr)->debug) & 0xff;
  667                 sdhcdebug = (((struct bio_sdmmc_debug *)addr)->debug >> 8) & 0xff;
  668                 break;
  669 #endif
  670 
  671         case SDIOCEXECMMC:
  672         case SDIOCEXECAPP:
  673                 ucmd = &((struct bio_sdmmc_command *)addr)->cmd;
  674 
  675                 /* Refuse to transfer more than 512K per command. */
  676                 if (ucmd->c_datalen > 524288)
  677                         return ENOMEM;
  678 
  679                 /* Verify that the data buffer is safe to copy. */
  680                 if ((ucmd->c_datalen > 0 && ucmd->c_data == NULL) ||
  681                     (ucmd->c_datalen < 1 && ucmd->c_data != NULL) ||
  682                     ucmd->c_datalen < 0)
  683                         return EINVAL;
  684 
  685                 bzero(&cmd, sizeof cmd);
  686                 cmd.c_opcode = ucmd->c_opcode;
  687                 cmd.c_arg = ucmd->c_arg;
  688                 cmd.c_flags = ucmd->c_flags;
  689                 cmd.c_blklen = ucmd->c_blklen;
  690 
  691                 if (ucmd->c_data) {
  692                         data = malloc(ucmd->c_datalen, M_TEMP,
  693                             M_WAITOK | M_CANFAIL);
  694                         if (data == NULL)
  695                                 return ENOMEM;
  696                         if (copyin(ucmd->c_data, data, ucmd->c_datalen))
  697                                 return EFAULT;
  698 
  699                         cmd.c_data = data;
  700                         cmd.c_datalen = ucmd->c_datalen;
  701                 }
  702 
  703                 if (request == SDIOCEXECMMC)
  704                         error = sdmmc_mmc_command(sc, &cmd);
  705                 else
  706                         error = sdmmc_app_command(sc, &cmd);
  707                 if (error && !cmd.c_error)
  708                         cmd.c_error = error;
  709 
  710                 bcopy(&cmd.c_resp, ucmd->c_resp, sizeof cmd.c_resp);
  711                 ucmd->c_flags = cmd.c_flags;
  712                 ucmd->c_error = cmd.c_error;
  713 
  714                 if (ucmd->c_data && copyout(data, ucmd->c_data,
  715                     ucmd->c_datalen))
  716                         return EFAULT;
  717 
  718                 if (ucmd->c_data)
  719                         free(data, M_TEMP);
  720                 break;
  721 
  722         default:
  723                 return ENOTTY;
  724         }
  725         return 0;
  726 }
  727 #endif
  728 
  729 #ifdef SDMMC_DEBUG
  730 void
  731 sdmmc_dump_command(struct sdmmc_softc *sc, struct sdmmc_command *cmd)
  732 {
  733         int i;
  734 
  735         DPRINTF(1,("%s: cmd %u arg=%#x data=%#x dlen=%d flags=%#x "
  736             "proc=\"%s\" (error %d)\n", DEVNAME(sc), cmd->c_opcode,
  737             cmd->c_arg, cmd->c_data, cmd->c_datalen, cmd->c_flags,
  738             curproc ? curproc->p_comm : "", cmd->c_error));
  739 
  740         if (cmd->c_error || sdmmcdebug < 1)
  741                 return;
  742 
  743         printf("%s: resp=", DEVNAME(sc));
  744         if (ISSET(cmd->c_flags, SCF_RSP_136))
  745                 for (i = 0; i < sizeof cmd->c_resp; i++)
  746                         printf("%02x ", ((u_char *)cmd->c_resp)[i]);
  747         else if (ISSET(cmd->c_flags, SCF_RSP_PRESENT))
  748                 for (i = 0; i < 4; i++)
  749                         printf("%02x ", ((u_char *)cmd->c_resp)[i]);
  750         printf("\n");
  751 }
  752 #endif

/* [<][>][^][v][top][bottom][index][help] */