sda_cmd.c revision 4bb7efa72ed531c10f097919636e67724ec4c25a
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * CDDL HEADER START
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The contents of this file are subject to the terms of the
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Common Development and Distribution License (the "License").
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * You may not use this file except in compliance with the License.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * See the License for the specific language governing permissions
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * and limitations under the License.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * When distributing Covered Code, include this CDDL HEADER in each
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * If applicable, add the following below this CDDL HEADER, with the
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * CDDL HEADER END
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Use is subject to license terms.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * SD card common framework. This module provides most of the common
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * functionality so that SecureDigital host adapters and client devices
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * (such as the sdcard driver) can share common code.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * NB that this file contains a fair bit of non-DDI compliant code.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * But writing a nexus driver would be impossible to do with only DDI
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * compliant interfaces.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Types and Structures.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowetypedef struct sda_cmd_impl {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Implementation private stuff.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Local Prototypes.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic int sda_cmd_ctor(void *, void *, int);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic void sda_cmd_dtor(void *, void *);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Static Variables.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#define CIP(cmdp) ((sda_cmd_impl_t *)(void *)cmdp)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Implementation.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sda_cmd_cache = kmem_cache_create("sda_cmd_cache",
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sizeof (struct sda_cmd_impl), 0, sda_cmd_ctor, sda_cmd_dtor,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe list_create(list, sizeof (struct sda_cmd_impl),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*ARGSUSED1*/
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowesda_cmd_ctor(void *cbuf, void *arg, int kmflags)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe mutex_init(&c->c_lock, NULL, MUTEX_DRIVER, NULL);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*ARGSUSED1*/
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowesda_cmd_notify(sda_cmd_t *cmdp, uint16_t flags, sda_err_t errno)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Now we need to make sure that we wake anyone waiting on this
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * command to complete, if it is complete.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Don't overwrite an earlier error.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((c->c_flags & (SDA_CMDF_BUSY | SDA_CMDF_DAT)) == 0) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe while ((c->c_flags & (SDA_CMDF_BUSY | SDA_CMDF_DAT)) != 0)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowesda_cmd_submit(sda_slot_t *slot, sda_cmd_t *cmdp, void (*done)(sda_cmd_t *))
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* checks for cases where the slot can't accept the command */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* fail it synchronously */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sda_cmd_notify(cmdp, SDA_CMDF_DAT | SDA_CMDF_BUSY, errno);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowesda_cmd_resubmit_acmd(sda_slot_t *slot, sda_cmd_t *cmdp)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowesda_cmd_alloc(sda_slot_t *slot, sda_index_t index, uint32_t argument,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return (&(c->c_public));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowesda_cmd_alloc_acmd(sda_slot_t *slot, sda_index_t index, uint32_t argument,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe c->c_argument = index == ACMD_SD_SEND_OCR ? 0 : slot->s_rca << 16;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return (&(c->c_public));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowesda_cmd_exec(sda_slot_t *slot, sda_cmd_t *cmdp, uint32_t *resp)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((cmdp->sc_rtype & Rb) || (cmdp->sc_nblks != 0)) {