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