Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / uts / common / io / sdcard / impl / sda_host.c
blob911ac70d0ceb52a60c09094fb9e2500ccc38cb4f
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
26 * SD card host support. This is the API that host drivers access.
29 #include <sys/types.h>
30 #include <sys/conf.h>
31 #include <sys/cmn_err.h>
32 #include <sys/varargs.h>
33 #include <sys/ddi.h>
34 #include <sys/sunddi.h>
35 #include <sys/sdcard/sda.h>
36 #include <sys/sdcard/sda_impl.h>
39 * Implementation.
42 void
43 sda_host_init_ops(struct dev_ops *devops)
45 bd_mod_init(devops);
48 void
49 sda_host_fini_ops(struct dev_ops *devops)
51 bd_mod_fini(devops);
54 sda_host_t *
55 sda_host_alloc(dev_info_t *dip, int nslot, sda_ops_t *ops, ddi_dma_attr_t *dma)
57 sda_host_t *h;
59 if (ops->so_version != SDA_OPS_VERSION) {
60 return (NULL);
63 h = kmem_zalloc(sizeof (*h), KM_SLEEP);
64 h->h_nslot = nslot;
65 h->h_slots = kmem_zalloc(sizeof (sda_slot_t) * nslot, KM_SLEEP);
66 h->h_dma = dma;
67 h->h_dip = dip;
69 /* initialize each slot */
70 for (int i = 0; i < nslot; i++) {
71 sda_slot_t *slot = &h->h_slots[i];
73 slot->s_hostp = h;
74 slot->s_slot_num = i;
75 slot->s_ops = *ops;
77 sda_slot_init(slot);
80 return (h);
83 void
84 sda_host_free(sda_host_t *h)
86 for (int i = 0; i < h->h_nslot; i++) {
87 sda_slot_fini(&h->h_slots[i]);
90 kmem_free(h->h_slots, sizeof (sda_slot_t) * h->h_nslot);
91 kmem_free(h, sizeof (*h));
94 void
95 sda_host_set_private(sda_host_t *h, int num, void *private)
97 h->h_slots[num].s_prv = private;
101 sda_host_attach(sda_host_t *h)
104 * Attach slots.
106 for (int i = 0; i < h->h_nslot; i++) {
108 sda_slot_attach(&h->h_slots[i]);
111 * Initiate card detection.
113 sda_host_detect(h, i);
116 return (DDI_SUCCESS);
119 void
120 sda_host_detach(sda_host_t *h)
123 * Detach slots.
125 for (int i = 0; i < h->h_nslot; i++) {
126 sda_slot_detach(&h->h_slots[i]);
130 void
131 sda_host_suspend(sda_host_t *h)
133 for (int i = 0; i < h->h_nslot; i++) {
134 sda_slot_suspend(&h->h_slots[i]);
138 void
139 sda_host_resume(sda_host_t *h)
141 for (int i = 0; i < h->h_nslot; i++) {
142 sda_slot_resume(&h->h_slots[i]);
146 void
147 sda_host_transfer(sda_host_t *h, int num, sda_err_t errno)
149 sda_slot_transfer(&h->h_slots[num], errno);
152 void
153 sda_host_detect(sda_host_t *h, int num)
155 sda_slot_detect(&h->h_slots[num]);
158 void
159 sda_host_fault(sda_host_t *h, int num, sda_fault_t fail)
161 sda_slot_fault(&h->h_slots[num], fail);
164 void
165 sda_host_log(sda_host_t *h, int snum, const char *fmt, ...)
167 va_list ap;
169 va_start(ap, fmt);
170 if (h != NULL) {
171 sda_slot_log(&h->h_slots[snum], fmt, ap);
172 } else {
173 sda_slot_log(NULL, fmt, ap);
175 va_end(ap);