4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * CDDL HEADER START
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * The contents of this file are subject to the terms of the
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * Common Development and Distribution License (the "License").
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * You may not use this file except in compliance with the License.
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * or http://www.opensolaris.org/os/licensing.
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * See the License for the specific language governing permissions
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * and limitations under the License.
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * When distributing Covered Code, include this CDDL HEADER in each
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * If applicable, add the following below this CDDL HEADER, with the
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * fields enclosed by brackets "[]" replaced with your own identifying
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * information: Portions Copyright [yyyy] [name of copyright owner]
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * CDDL HEADER END
3f7d54a6b84904c8f4d8daa4c7b577bede7df8b9Garrett D'Amore * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * SD card common framework. This module provides most of the common
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * functionality so that SecureDigital host adapters and client devices
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * (such as the sdcard driver) can share common code.
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * Types and Structures.
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * Implementation private stuff.
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * Local Prototypes.
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amorestatic int sda_cmd_ctor(void *, void *, int);
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amorestatic void sda_cmd_dtor(void *, void *);
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * Static Variables.
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore#define CIP(cmdp) ((sda_cmd_impl_t *)(void *)cmdp)
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * Implementation.
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore sda_cmd_cache = kmem_cache_create("sda_cmd_cache",
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore sizeof (struct sda_cmd_impl), 0, sda_cmd_ctor, sda_cmd_dtor,
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore list_create(list, sizeof (struct sda_cmd_impl),
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amoresda_cmd_ctor(void *cbuf, void *arg, int kmflags)
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore mutex_init(&c->c_lock, NULL, MUTEX_DRIVER, NULL);
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amoresda_cmd_notify(sda_cmd_t *cmdp, uint16_t flags, sda_err_t errno)
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * Now we need to make sure that we wake anyone waiting on this
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * command to complete, if it is complete.
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore * Don't overwrite an earlier error.
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore if ((c->c_flags & (SDA_CMDF_BUSY | SDA_CMDF_DAT)) == 0) {
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore while ((c->c_flags & (SDA_CMDF_BUSY | SDA_CMDF_DAT)) != 0)
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amoresda_cmd_submit(sda_slot_t *slot, sda_cmd_t *cmdp, void (*done)(sda_cmd_t *))
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore /* checks for cases where the slot can't accept the command */
3f7d54a6b84904c8f4d8daa4c7b577bede7df8b9Garrett D'Amore * We have to return failure conditions asynchronously.
3f7d54a6b84904c8f4d8daa4c7b577bede7df8b9Garrett D'Amore * What we do in this case is mark the command failed,
3f7d54a6b84904c8f4d8daa4c7b577bede7df8b9Garrett D'Amore * and move it to the abortlist so that the slot thread
3f7d54a6b84904c8f4d8daa4c7b577bede7df8b9Garrett D'Amore * will execute the failure notification asynchronously.
3f7d54a6b84904c8f4d8daa4c7b577bede7df8b9Garrett D'Amore * NB: using 0 for flags ensures that we don't execute
3f7d54a6b84904c8f4d8daa4c7b577bede7df8b9Garrett D'Amore * the notification callback yet, we're just stashing
3f7d54a6b84904c8f4d8daa4c7b577bede7df8b9Garrett D'Amore /* Initialization commands go to the head of the class */
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amoresda_cmd_resubmit_acmd(sda_slot_t *slot, sda_cmd_t *cmdp)
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amoresda_cmd_alloc(sda_slot_t *slot, sda_index_t index, uint32_t argument,
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore c = kmem_cache_alloc(sda_cmd_cache, kmflag);
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore return (&(c->c_public));
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amoresda_cmd_alloc_acmd(sda_slot_t *slot, sda_index_t index, uint32_t argument,
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore c = kmem_cache_alloc(sda_cmd_cache, kmflag);
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore c->c_argument = index == ACMD_SD_SEND_OCR ? 0 : slot->s_rca << 16;
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore return (&(c->c_public));
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amoresda_cmd_exec(sda_slot_t *slot, sda_cmd_t *cmdp, uint32_t *resp)
4bb7efa72ed531c10f097919636e67724ec4c25aGarrett D'Amore if ((cmdp->sc_rtype & Rb) || (cmdp->sc_nblks != 0)) {