xref: /illumos-gate/usr/src/uts/common/io/sdcard/impl/sda_slot.c (revision 4eaa471005973e11a6110b69fe990530b3b95a38)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * SD card slot support.
28  *
29  * NB that this file contains a fair bit of non-DDI compliant code.
30  * But writing a nexus driver would be impossible to do with only DDI
31  * compliant interfaces.
32  */
33 
34 #include <sys/types.h>
35 #include <sys/sysmacros.h>
36 #include <sys/cpuvar.h>
37 #include <sys/cmn_err.h>
38 #include <sys/varargs.h>
39 #include <sys/ddi.h>
40 #include <sys/sunddi.h>
41 #include <sys/sunndi.h>
42 #include <sys/sdcard/sda_impl.h>
43 
44 
45 /*
46  * Prototypes.
47  */
48 
49 static void sda_slot_insert(void *);
50 static sda_err_t sda_slot_check_response(sda_cmd_t *);
51 static void sda_slot_handle_detect(sda_slot_t *);
52 static void sda_slot_handle_transfer(sda_slot_t *, sda_err_t);
53 static void sda_slot_handle_fault(sda_slot_t *, sda_fault_t);
54 static void sda_slot_abort(sda_slot_t *, sda_err_t);
55 static void sda_slot_halt(sda_slot_t *);
56 static void sda_slot_thread(void *);
57 static void sda_slot_vprintf(sda_slot_t *, int, const char *, va_list);
58 
59 /*
60  * Static Variables.
61  */
62 
63 static struct {
64 	sda_fault_t	fault;
65 	const char	*msg;
66 } sda_slot_faults[] = {
67 	{ SDA_FAULT_TIMEOUT,	"Data transfer timed out" },
68 	{ SDA_FAULT_ACMD12,	"Auto CMD12 failure" },
69 	{ SDA_FAULT_CRC7,	"CRC7 failure on CMD/DAT line" },
70 	{ SDA_FAULT_PROTO,	"SD/MMC protocol signaling error" },
71 	{ SDA_FAULT_INIT,	"Card initialization failure" },
72 	{ SDA_FAULT_HOST,	"Internal host or slot failure" },
73 	{ SDA_FAULT_CURRENT,	"Current overlimit detected" },
74 	{ SDA_FAULT_RESET,	"Failed to reset slot" },
75 	{ SDA_FAULT_NONE,	NULL },	/* sentinel, must be last! */
76 };
77 
78 /*
79  * Internal implementation.
80  */
81 
82 /*
83  * These allow for recursive entry.  This is necessary to facilitate
84  * simpler locking with things like the fault handler, where a caller
85  * might already be "holding" the slot.
86  *
87  * This is modeled in part after ndi_devi_enter and ndi_devi_exit.
88  */
89 void
90 sda_slot_enter(sda_slot_t *slot)
91 {
92 	kt_did_t	self = ddi_get_kt_did();
93 	mutex_enter(&slot->s_lock);
94 	if (slot->s_owner == self) {
95 		slot->s_circular++;
96 	} else {
97 		while ((slot->s_owner != 0) && (slot->s_owner != self)) {
98 			cv_wait(&slot->s_cv, &slot->s_lock);
99 		}
100 		slot->s_owner = self;
101 		slot->s_circular++;
102 	}
103 	mutex_exit(&slot->s_lock);
104 }
105 
106 void
107 sda_slot_exit(sda_slot_t *slot)
108 {
109 	ASSERT(sda_slot_owned(slot));
110 
111 	mutex_enter(&slot->s_lock);
112 	slot->s_circular--;
113 	if (slot->s_circular == 0) {
114 		slot->s_owner = 0;
115 		cv_broadcast(&slot->s_cv);
116 	}
117 	mutex_exit(&slot->s_lock);
118 }
119 
120 boolean_t
121 sda_slot_owned(sda_slot_t *slot)
122 {
123 	return (slot->s_owner == ddi_get_kt_did());
124 }
125 
126 sda_err_t
127 sda_slot_check_response(sda_cmd_t *cmdp)
128 {
129 	uint32_t	errs;
130 	switch (cmdp->sc_rtype & 0xf) {
131 	case R1:
132 		if ((errs = (cmdp->sc_response[0] & R1_ERRS)) != 0) {
133 			if (errs & (R1_WP_VIOLATION | R1_CSD_OVERWRITE)) {
134 				return (SDA_EWPROTECT);
135 			}
136 			if (errs & (R1_ADDRESS_ERROR | R1_BLOCK_LEN_ERROR |
137 			    R1_OUT_OF_RANGE | R1_ERASE_PARAM)) {
138 				return (SDA_EINVAL);
139 			}
140 			return (SDA_EIO);
141 		}
142 		break;
143 	case R5:
144 		if ((errs = (cmdp->sc_response[0] & R5_ERRS)) != 0) {
145 			return (SDA_EIO);
146 		}
147 		break;
148 	}
149 	return (SDA_EOK);
150 }
151 
152 void
153 sda_slot_halt(sda_slot_t *slot)
154 {
155 	sda_slot_enter(slot);
156 	slot->s_ops.so_halt(slot->s_prv);
157 	/* We need to wait 1 msec for power down. */
158 	drv_usecwait(1000);
159 	sda_slot_exit(slot);
160 }
161 
162 void
163 sda_slot_reset(sda_slot_t *slot)
164 {
165 	sda_slot_enter(slot);
166 	if (slot->s_ops.so_reset(slot->s_prv) != 0) {
167 		sda_slot_fault(slot, SDA_FAULT_RESET);
168 	}
169 	sda_slot_exit(slot);
170 }
171 
172 int
173 sda_slot_power_on(sda_slot_t *slot)
174 {
175 	int		rv;
176 	uint32_t	ocr;
177 
178 	sda_slot_enter(slot);
179 
180 	/*
181 	 * Get the voltage supplied by the host.  Note that we expect
182 	 * hosts will include a range of 2.7-3.7 in their supported
183 	 * voltage ranges.  The spec does not allow for hosts that
184 	 * cannot supply a voltage in this range, yet.
185 	 */
186 	if ((rv = sda_getprop(slot, SDA_PROP_OCR, &ocr)) != 0) {
187 		sda_slot_err(slot, "Failed to get host OCR (%d)", rv);
188 		goto done;
189 	}
190 	if ((ocr & OCR_HI_MASK) == 0) {
191 		sda_slot_err(slot, "Host does not support standard voltages.");
192 		rv = ENOTSUP;
193 		goto done;
194 	}
195 
196 	/*
197 	 * We prefer 3.3V, 3.0V, and failing that, just use the
198 	 * maximum that the host supports.  3.3V is preferable,
199 	 * because it is the typical common voltage that just about
200 	 * everything supports.  Otherwise we just pick the highest
201 	 * supported voltage.  This facilitates initial power up.
202 	 */
203 	if (ocr & OCR_32_33V) {
204 		slot->s_cur_ocr = OCR_32_33V;
205 	} else if (ocr & OCR_29_30V) {
206 		slot->s_cur_ocr = OCR_29_30V;
207 	} else {
208 		slot->s_cur_ocr = (1U << (ddi_fls(ocr) - 1));
209 	}
210 
211 	/*
212 	 * Turn on the power.
213 	 */
214 	if ((rv = sda_setprop(slot, SDA_PROP_OCR, slot->s_cur_ocr)) != 0) {
215 		sda_slot_err(slot, "Failed to set OCR %x (%d)",
216 		    slot->s_cur_ocr, rv);
217 		goto done;
218 	}
219 
220 	sda_slot_exit(slot);
221 
222 	/*
223 	 * Wait 250 msec (per spec) for power ramp to complete.
224 	 */
225 	delay(drv_usectohz(250000));
226 	return (0);
227 
228 done:
229 	sda_slot_exit(slot);
230 	return (rv);
231 }
232 
233 void
234 sda_slot_power_off(sda_slot_t *slot)
235 {
236 	sda_slot_enter(slot);
237 	(void) sda_setprop(slot, SDA_PROP_OCR, 0);
238 	/* XXX: FMA: on failure this should cause a fault to be generated */
239 	/* spec requires voltage to stay low for at least 1 msec */
240 	drv_usecwait(1000);
241 	sda_slot_exit(slot);
242 }
243 
244 void
245 sda_slot_insert(void *arg)
246 {
247 	sda_slot_t	*slot = arg;
248 
249 	if (sda_init_card(slot) != SDA_EOK) {
250 		/*
251 		 * Remove power from the slot.  If a more severe fault
252 		 * occurred, then a manual reset with cfgadm will be needed.
253 		 */
254 		sda_slot_err(slot, "Unable to initialize card!");
255 		sda_slot_enter(slot);
256 		sda_slot_power_off(slot);
257 		sda_slot_abort(slot, SDA_ENODEV);
258 		sda_slot_exit(slot);
259 		sda_nexus_remove(slot);
260 
261 	} else {
262 		sda_nexus_insert(slot);
263 	}
264 
265 	slot->s_stamp = ddi_get_time();
266 	slot->s_intransit = 0;
267 }
268 
269 void
270 sda_slot_mem_reset(sda_slot_t *slot, sda_err_t errno)
271 {
272 	sda_cmd_t	*cmdp;
273 
274 	sda_slot_enter(slot);
275 	cmdp = list_head(&slot->s_cmdlist);
276 	while (cmdp != NULL) {
277 		sda_cmd_t	*next;
278 		next = list_next(&slot->s_cmdlist, cmdp);
279 		if (cmdp->sc_flags & SDA_CMDF_MEM) {
280 			list_remove(&slot->s_cmdlist, cmdp);
281 			sda_cmd_notify(cmdp, 0, errno);
282 			mutex_enter(&slot->s_evlock);
283 			list_insert_tail(&slot->s_abortlist, cmdp);
284 			mutex_exit(&slot->s_evlock);
285 		}
286 		cmdp = next;
287 	}
288 	sda_slot_exit(slot);
289 
290 	/* wake up to process the abort list */
291 	sda_slot_wakeup(slot);
292 }
293 
294 void
295 sda_slot_abort(sda_slot_t *slot, sda_err_t errno)
296 {
297 	sda_cmd_t	*cmdp;
298 
299 	ASSERT(sda_slot_owned(slot));
300 
301 	if ((cmdp = slot->s_xfrp) != NULL) {
302 		slot->s_xfrp = NULL;
303 		sda_cmd_notify(cmdp, SDA_CMDF_BUSY | SDA_CMDF_DAT, errno);
304 	}
305 	while ((cmdp = list_head(&slot->s_cmdlist)) != NULL) {
306 		list_remove(&slot->s_cmdlist, cmdp);
307 		sda_cmd_notify(cmdp, 0, errno);
308 		mutex_enter(&slot->s_evlock);
309 		list_insert_tail(&slot->s_abortlist, cmdp);
310 		mutex_exit(&slot->s_evlock);
311 	}
312 
313 	sda_slot_wakeup(slot);
314 }
315 
316 void
317 sda_slot_handle_transfer(sda_slot_t *slot, sda_err_t errno)
318 {
319 	sda_cmd_t	*cmdp;
320 
321 	sda_slot_enter(slot);
322 
323 	if ((cmdp = slot->s_xfrp) != NULL) {
324 
325 		slot->s_xfrp = NULL;
326 		slot->s_xfrtmo = 0;
327 		(void) sda_setprop(slot, SDA_PROP_LED, 0);
328 		sda_slot_exit(slot);
329 
330 		sda_slot_wakeup(slot);
331 
332 		sda_cmd_notify(cmdp, SDA_CMDF_DAT, errno);
333 	} else {
334 		sda_slot_exit(slot);
335 	}
336 }
337 
338 void
339 sda_slot_handle_fault(sda_slot_t *slot, sda_fault_t fault)
340 {
341 	const char	*msg;
342 	int		i;
343 
344 	sda_slot_enter(slot);
345 
346 	if ((fault == SDA_FAULT_TIMEOUT) && (slot->s_init)) {
347 		/*
348 		 * Timeouts during initialization are quite normal.
349 		 */
350 		sda_slot_exit(slot);
351 		return;
352 	}
353 
354 	slot->s_failed = B_TRUE;
355 	sda_slot_abort(slot, SDA_EFAULT);
356 
357 	msg = "Unknown fault (%d)";
358 	for (i = 0; sda_slot_faults[i].msg != NULL; i++) {
359 		if (sda_slot_faults[i].fault == fault) {
360 			msg = sda_slot_faults[i].msg;
361 			break;
362 		}
363 	}
364 
365 	/*
366 	 * FMA would be a better choice here.
367 	 */
368 	sda_slot_err(slot, msg, fault);
369 
370 	/*
371 	 * Shut down the slot.  Interaction from userland via cfgadm
372 	 * can revive it.
373 	 *
374 	 * FMA can help here.
375 	 */
376 	sda_slot_halt(slot);
377 
378 	sda_slot_exit(slot);
379 }
380 
381 void
382 sda_slot_handle_detect(sda_slot_t *slot)
383 {
384 	uint32_t	inserted;
385 
386 	sda_slot_enter(slot);
387 
388 	slot->s_stamp = ddi_get_time();
389 	slot->s_intransit = 1;
390 	slot->s_flags = 0;
391 	slot->s_rca = 0;
392 	slot->s_ready = B_FALSE;
393 
394 	sda_getprop(slot, SDA_PROP_INSERTED, &inserted);
395 	slot->s_inserted = (inserted != 0);
396 
397 	if (slot->s_inserted && !slot->s_failed) {
398 		/*
399 		 * We need to initialize the card, so we only support
400 		 * hipri commands for now.
401 		 */
402 		slot->s_init = B_TRUE;
403 
404 		/*
405 		 * Card insertion occurred.  We have to run this on
406 		 * another task, to avoid deadlock as the task may
407 		 * need to dispatch commands.
408 		 */
409 		(void) ddi_taskq_dispatch(slot->s_hp_tq, sda_slot_insert, slot,
410 		    DDI_SLEEP);
411 	} else {
412 
413 		/*
414 		 * Nuke in-flight commands.
415 		 */
416 		sda_slot_abort(slot, SDA_ENODEV);
417 
418 		/*
419 		 * Restart the slot (incl. power cycle).  This gets the
420 		 * slot to a known good state.
421 		 */
422 		sda_slot_reset(slot);
423 
424 		sda_nexus_remove(slot);
425 
426 		slot->s_intransit = 0;
427 	}
428 	sda_slot_exit(slot);
429 
430 	sda_slot_wakeup(slot);
431 }
432 
433 void
434 sda_slot_transfer(sda_slot_t *slot, sda_err_t errno)
435 {
436 	mutex_enter(&slot->s_evlock);
437 	slot->s_errno = errno;
438 	slot->s_xfrdone = B_TRUE;
439 	cv_broadcast(&slot->s_evcv);
440 	mutex_exit(&slot->s_evlock);
441 }
442 
443 void
444 sda_slot_detect(sda_slot_t *slot)
445 {
446 	mutex_enter(&slot->s_evlock);
447 	slot->s_detect = B_TRUE;
448 	cv_broadcast(&slot->s_evcv);
449 	mutex_exit(&slot->s_evlock);
450 }
451 
452 void
453 sda_slot_fault(sda_slot_t *slot, sda_fault_t fault)
454 {
455 	mutex_enter(&slot->s_evlock);
456 	slot->s_fault = fault;
457 	cv_broadcast(&slot->s_evcv);
458 	mutex_exit(&slot->s_evlock);
459 }
460 
461 void
462 sda_slot_wakeup(sda_slot_t *slot)
463 {
464 	mutex_enter(&slot->s_evlock);
465 	slot->s_wake = B_TRUE;
466 	cv_broadcast(&slot->s_evcv);
467 	mutex_exit(&slot->s_evlock);
468 }
469 
470 void
471 sda_slot_init(sda_slot_t *slot)
472 {
473 	mutex_init(&slot->s_lock, NULL, MUTEX_DRIVER, NULL);
474 	cv_init(&slot->s_cv, NULL, CV_DRIVER, NULL);
475 	mutex_init(&slot->s_evlock, NULL, MUTEX_DRIVER, NULL);
476 	cv_init(&slot->s_evcv, NULL, CV_DRIVER, NULL);
477 
478 	sda_cmd_list_init(&slot->s_cmdlist);
479 	sda_cmd_list_init(&slot->s_abortlist);
480 }
481 
482 void
483 sda_slot_fini(sda_slot_t *slot)
484 {
485 	sda_cmd_list_fini(&slot->s_cmdlist);
486 	sda_cmd_list_fini(&slot->s_abortlist);
487 	mutex_destroy(&slot->s_lock);
488 	mutex_destroy(&slot->s_evlock);
489 	cv_destroy(&slot->s_cv);
490 	cv_destroy(&slot->s_evcv);
491 }
492 
493 void
494 sda_slot_attach(sda_slot_t *slot)
495 {
496 	sda_host_t	*h = slot->s_hostp;
497 	char		name[16];
498 	uint32_t	cap;
499 
500 	/*
501 	 * We have two taskqs.  The first taskq is used for
502 	 * card initialization.
503 	 *
504 	 * The second is used for the main processing loop.
505 	 *
506 	 * The reason for a separate taskq is that initialization
507 	 * needs to acquire locks which may be held by the slot
508 	 * thread, or by device driver context... use of the separate
509 	 * taskq breaks the deadlock.  Additionally, the
510 	 * initialization task may need to sleep quite a while during
511 	 * card initialization.
512 	 */
513 
514 	sda_slot_enter(slot);
515 
516 	(void) snprintf(name, sizeof (name), "slot_%d_hp_tq",
517 	    slot->s_slot_num);
518 	slot->s_hp_tq = ddi_taskq_create(h->h_dip, name, 1,
519 	    TASKQ_DEFAULTPRI, 0);
520 	if (slot->s_hp_tq == NULL) {
521 		/* Generally, this failure should never occur */
522 		sda_slot_err(slot, "Unable to create hotplug slot taskq");
523 		sda_slot_exit(slot);
524 		return;
525 	}
526 
527 	/* create the main processing thread */
528 	(void) snprintf(name, sizeof (name), "slot_%d_main_tq",
529 	    slot->s_slot_num);
530 	slot->s_main_tq = ddi_taskq_create(h->h_dip, name, 1,
531 	    TASKQ_DEFAULTPRI, 0);
532 	if (slot->s_main_tq == NULL) {
533 		/* Generally, this failure should never occur */
534 		sda_slot_err(slot, "Unable to create main slot taskq");
535 		sda_slot_exit(slot);
536 		return;
537 	}
538 	(void) ddi_taskq_dispatch(slot->s_main_tq, sda_slot_thread, slot,
539 	    DDI_SLEEP);
540 
541 	/*
542 	 * Determine slot capabilities.
543 	 */
544 	slot->s_caps = 0;
545 
546 	if ((sda_getprop(slot, SDA_PROP_CAP_NOPIO, &cap) == 0) && (cap != 0)) {
547 		slot->s_caps |= SLOT_CAP_NOPIO;
548 	}
549 	if ((sda_getprop(slot, SDA_PROP_CAP_4BITS, &cap) == 0) && (cap != 0)) {
550 		slot->s_caps |= SLOT_CAP_4BITS;
551 	}
552 	if ((sda_getprop(slot, SDA_PROP_CAP_HISPEED, &cap) == 0) &&
553 	    (cap != 0)) {
554 		slot->s_caps |= SLOT_CAP_HISPEED;
555 	}
556 
557 	/* make sure that the host is started up */
558 	if (slot->s_ops.so_reset(slot->s_prv) != 0) {
559 		sda_slot_fault(slot, SDA_FAULT_RESET);
560 	}
561 
562 	sda_slot_exit(slot);
563 }
564 
565 void
566 sda_slot_detach(sda_slot_t *slot)
567 {
568 	/*
569 	 * Shut down the thread.
570 	 */
571 	mutex_enter(&slot->s_evlock);
572 	slot->s_detach = B_TRUE;
573 	cv_broadcast(&slot->s_evcv);
574 	mutex_exit(&slot->s_evlock);
575 
576 	/*
577 	 * Nuke the taskqs. We do this after stopping the background
578 	 * thread to avoid deadlock.
579 	 */
580 	if (slot->s_main_tq)
581 		ddi_taskq_destroy(slot->s_main_tq);
582 	if (slot->s_hp_tq)
583 		ddi_taskq_destroy(slot->s_hp_tq);
584 }
585 
586 void
587 sda_slot_suspend(sda_slot_t *slot)
588 {
589 	mutex_enter(&slot->s_evlock);
590 	slot->s_suspend = B_TRUE;
591 	cv_broadcast(&slot->s_evcv);
592 	mutex_exit(&slot->s_evlock);
593 	ddi_taskq_wait(slot->s_main_tq);
594 }
595 
596 void
597 sda_slot_resume(sda_slot_t *slot)
598 {
599 	mutex_enter(&slot->s_evlock);
600 	slot->s_suspend = B_FALSE;
601 	/*
602 	 * A card change event may have occurred, and in any case we need
603 	 * to reinitialize the card.
604 	 */
605 	slot->s_detect = B_TRUE;
606 	mutex_exit(&slot->s_evlock);
607 
608 	/* Start up a new instance of the main processing task. */
609 	(void) ddi_taskq_dispatch(slot->s_main_tq, sda_slot_thread, slot,
610 	    DDI_SLEEP);
611 }
612 
613 void
614 sda_slot_thread(void *arg)
615 {
616 	sda_slot_t	*slot = arg;
617 
618 	for (;;) {
619 		sda_cmd_t	*cmdp;
620 		boolean_t	datline;
621 		sda_err_t	rv;
622 
623 		mutex_enter(&slot->s_evlock);
624 
625 		/*
626 		 * Process any abort list first.
627 		 */
628 		if ((cmdp = list_head(&slot->s_abortlist)) != NULL) {
629 			list_remove(&slot->s_abortlist, cmdp);
630 			mutex_exit(&slot->s_evlock);
631 			/*
632 			 * EOK used here, to avoid clobbering previous
633 			 * error code.
634 			 */
635 			sda_cmd_notify(cmdp, SDA_CMDF_BUSY | SDA_CMDF_DAT,
636 			    SDA_EOK);
637 			continue;
638 		}
639 
640 		if (slot->s_detach) {
641 			/* Parent is detaching the slot, bail out. */
642 			break;
643 		}
644 
645 		if ((slot->s_suspend) && (slot->s_xfrp == NULL)) {
646 			/*
647 			 * Host wants to suspend, but don't do it if
648 			 * we have a transfer outstanding.
649 			 */
650 			break;
651 		}
652 
653 		if (slot->s_detect) {
654 			slot->s_detect = B_FALSE;
655 			mutex_exit(&slot->s_evlock);
656 
657 			sda_slot_handle_detect(slot);
658 			continue;
659 		}
660 
661 		if (slot->s_xfrdone) {
662 			sda_err_t	errno;
663 
664 			errno = slot->s_errno;
665 			slot->s_errno = SDA_EOK;
666 			slot->s_xfrdone = B_FALSE;
667 			mutex_exit(&slot->s_evlock);
668 
669 			sda_slot_handle_transfer(slot, errno);
670 			continue;
671 		}
672 
673 		if (slot->s_fault != SDA_FAULT_NONE) {
674 			sda_fault_t	fault;
675 
676 			fault = slot->s_fault;
677 			slot->s_fault = SDA_FAULT_NONE;
678 			mutex_exit(&slot->s_evlock);
679 
680 			sda_slot_handle_fault(slot, fault);
681 			continue;
682 		}
683 
684 		if (slot->s_reap) {
685 			/*
686 			 * Do not sleep while holding the evlock.  If this
687 			 * fails, we'll just try again the next cycle.
688 			 */
689 			(void) ddi_taskq_dispatch(slot->s_hp_tq,
690 			    sda_nexus_reap, slot, DDI_NOSLEEP);
691 		}
692 
693 		if ((slot->s_xfrp != NULL) && (gethrtime() > slot->s_xfrtmo)) {
694 			/*
695 			 * The device stalled processing the data request.
696 			 * At this point, we really have no choice but to
697 			 * nuke the request, and flag a fault.
698 			 */
699 			mutex_exit(&slot->s_evlock);
700 			sda_slot_handle_transfer(slot, SDA_ETIME);
701 			sda_slot_fault(slot, SDA_FAULT_TIMEOUT);
702 			continue;
703 		}
704 
705 		/*
706 		 * If the slot has suspended, then we can't process
707 		 * any new commands yet.
708 		 */
709 		if ((slot->s_suspend) || (!slot->s_wake)) {
710 
711 			/*
712 			 * We use a timed wait if we are waiting for a
713 			 * data transfer to complete, or if we might
714 			 * need to reap child nodes.  Otherwise we
715 			 * avoid the timed wait to avoid waking CPU
716 			 * (power savings.)
717 			 */
718 
719 			if ((slot->s_xfrp != NULL) || (slot->s_reap)) {
720 				/* Wait 3 sec (reap attempts). */
721 				(void) cv_timedwait(&slot->s_evcv,
722 				    &slot->s_evlock,
723 				    ddi_get_lbolt() + drv_usectohz(3000000));
724 			} else {
725 				(void) cv_wait(&slot->s_evcv, &slot->s_evlock);
726 			}
727 
728 			mutex_exit(&slot->s_evlock);
729 			continue;
730 		}
731 
732 		slot->s_wake = B_FALSE;
733 
734 		/*
735 		 * Possibly reap child nodes.
736 		 */
737 		if (slot->s_reap) {
738 			slot->s_reap = B_FALSE;
739 			mutex_exit(&slot->s_evlock);
740 			sda_nexus_reap(slot);
741 		} else {
742 			mutex_exit(&slot->s_evlock);
743 		}
744 
745 		/*
746 		 * We're awake now, so look for work to do.  First
747 		 * acquire access to the slot.
748 		 */
749 		sda_slot_enter(slot);
750 
751 
752 		/*
753 		 * If no more commands to process, go back to sleep.
754 		 */
755 		if ((cmdp = list_head(&slot->s_cmdlist)) == NULL) {
756 			sda_slot_exit(slot);
757 			continue;
758 		}
759 
760 		/*
761 		 * If the current command is not an initialization
762 		 * command, but we are initializing, go back to sleep.
763 		 * (This happens potentially during a card reset or
764 		 * suspend/resume cycle, where the card has not been
765 		 * removed, but a reset is in progress.)
766 		 */
767 		if (slot->s_init && !(cmdp->sc_flags & SDA_CMDF_INIT)) {
768 			sda_slot_exit(slot);
769 			continue;
770 		}
771 
772 		datline = ((cmdp->sc_flags & SDA_CMDF_DAT) != 0);
773 
774 		if (datline) {
775 			/*
776 			 * If the current command has a data phase
777 			 * while a transfer is in progress, then go
778 			 * back to sleep.
779 			 */
780 			if (slot->s_xfrp != NULL) {
781 				sda_slot_exit(slot);
782 				continue;
783 			}
784 
785 			/*
786 			 * Note that APP_CMD doesn't have a data phase,
787 			 * although the associated ACMD might.
788 			 */
789 			if (cmdp->sc_index != CMD_APP_CMD) {
790 				slot->s_xfrp = cmdp;
791 				/*
792 				 * All commands should complete in
793 				 * less than 5 seconds.  The worst
794 				 * case is actually somewhere around 4
795 				 * seconds, but that is when the clock
796 				 * is only 100 kHz.
797 				 */
798 				slot->s_xfrtmo = gethrtime() +
799 				    5000000000ULL;
800 				(void) sda_setprop(slot, SDA_PROP_LED, 1);
801 			}
802 		}
803 
804 		/*
805 		 * We're committed to dispatching this command now,
806 		 * so remove it from the list.
807 		 */
808 		list_remove(&slot->s_cmdlist, cmdp);
809 
810 		/*
811 		 * There could be more commands after this one, so we
812 		 * mark ourself so we stay awake for another cycle.
813 		 */
814 		sda_slot_wakeup(slot);
815 
816 		/*
817 		 * Submit the command.  Note that we are holding the
818 		 * slot lock here, so it is critical that the caller
819 		 * *not* call back up into the framework.  The caller
820 		 * must break context.  But doing it this way prevents
821 		 * a critical race on card removal.
822 		 *
823 		 * Note that we don't resubmit memory to the device if
824 		 * it isn't flagged as ready (e.g. if the wrong device
825 		 * was inserted!)
826 		 */
827 		if ((!slot->s_ready) && (cmdp->sc_flags & SDA_CMDF_MEM)) {
828 			rv = SDA_ENODEV;
829 			if (!slot->s_warn) {
830 				sda_slot_err(slot,
831 				    "Device removed while in use.  "
832 				    "Please reinsert!");
833 				slot->s_warn = B_TRUE;
834 			}
835 		} else {
836 			rv = slot->s_ops.so_cmd(slot->s_prv, cmdp);
837 		}
838 		if (rv == SDA_EOK)
839 			rv = sda_slot_check_response(cmdp);
840 
841 		if (rv == SDA_EOK) {
842 			/*
843 			 * If APP_CMD completed properly, then
844 			 * resubmit with ACMD index.  Note wake was
845 			 * already set above.
846 			 */
847 			if (cmdp->sc_index == CMD_APP_CMD) {
848 				if ((cmdp->sc_response[0] & R1_APP_CMD) == 0) {
849 					sda_slot_log(slot, "APP_CMD not set!");
850 				}
851 				sda_cmd_resubmit_acmd(slot, cmdp);
852 				sda_slot_exit(slot);
853 
854 				continue;
855 			}
856 
857 		} else if (datline) {
858 			/*
859 			 * If an error occurred and we were expecting
860 			 * a transfer phase, we have to clean up.
861 			 */
862 			(void) sda_setprop(slot, SDA_PROP_LED, 0);
863 			slot->s_xfrp = NULL;
864 			slot->s_xfrtmo = 0;
865 
866 			/*
867 			 * And notify any waiter.
868 			 */
869 			sda_slot_exit(slot);
870 			sda_cmd_notify(cmdp, SDA_CMDF_BUSY | SDA_CMDF_DAT, rv);
871 			continue;
872 		}
873 
874 		/*
875 		 * Wake any waiter.
876 		 */
877 		sda_slot_exit(slot);
878 		sda_cmd_notify(cmdp, SDA_CMDF_BUSY, rv);
879 	}
880 
881 	mutex_exit(&slot->s_evlock);
882 }
883 
884 void
885 sda_slot_vprintf(sda_slot_t *s, int level, const char *fmt, va_list ap)
886 {
887 	char		msgbuf[256];
888 	const char	*pfx, *sfx;
889 
890 	if (level == CE_CONT) {
891 		pfx = "!";
892 		sfx = "\n";
893 	} else {
894 		pfx = sfx = "";
895 	}
896 
897 	if (s != NULL) {
898 		dev_info_t	*dip = s->s_hostp->h_dip;
899 
900 		(void) snprintf(msgbuf, sizeof (msgbuf),
901 		    "%s%s%d: slot %d: %s%s", pfx,
902 		    ddi_driver_name(dip), ddi_get_instance(dip),
903 		    s->s_slot_num, fmt, sfx);
904 	} else {
905 		(void) snprintf(msgbuf, sizeof (msgbuf), "%ssda: %s%s",
906 		    pfx, fmt, sfx);
907 	}
908 	vcmn_err(level, msgbuf, ap);
909 }
910 
911 void
912 sda_slot_err(sda_slot_t *s, const char *fmt, ...)
913 {
914 	va_list	ap;
915 
916 	va_start(ap, fmt);
917 	sda_slot_vprintf(s, CE_WARN, fmt, ap);
918 	va_end(ap);
919 }
920 
921 void
922 sda_slot_log(sda_slot_t *s, const char *fmt, ...)
923 {
924 	va_list	ap;
925 
926 	va_start(ap, fmt);
927 	sda_slot_vprintf(s, CE_CONT, fmt, ap);
928 	va_end(ap);
929 }
930