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