scimci.c revision 1.4 1 /* $NetBSD: scimci.c,v 1.4 2021/08/07 16:18:53 thorpej Exp $ */
2
3 /*-
4 * Copyright (C) 2009 NONAKA Kimihiro <nonaka (at) netbsd.org>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 /*
29 * Serial Peripheral interface driver to access MMC card
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: scimci.c,v 1.4 2021/08/07 16:18:53 thorpej Exp $");
34
35 #include <sys/param.h>
36 #include <sys/device.h>
37 #include <sys/systm.h>
38 #include <sys/malloc.h>
39 #include <sys/kernel.h>
40 #include <sys/proc.h>
41 #include <sys/bus.h>
42 #include <sys/intr.h>
43
44 #include <sh3/devreg.h>
45 #include <sh3/pfcreg.h>
46 #include <sh3/scireg.h>
47
48 #include <dev/sdmmc/sdmmcvar.h>
49 #include <dev/sdmmc/sdmmcchip.h>
50
51 #include <evbsh3/t_sh7706lan/t_sh7706lanvar.h>
52
53 #ifdef SCIMCI_DEBUG
54 int scimci_debug = 1;
55 #define DPRINTF(n,s) do { if ((n) <= scimci_debug) printf s; } while (0)
56 #else
57 #define DPRINTF(n,s) do {} while (0)
58 #endif
59
60 static int scimci_host_reset(sdmmc_chipset_handle_t);
61 static uint32_t scimci_host_ocr(sdmmc_chipset_handle_t);
62 static int scimci_host_maxblklen(sdmmc_chipset_handle_t);
63 static int scimci_card_detect(sdmmc_chipset_handle_t);
64 static int scimci_write_protect(sdmmc_chipset_handle_t);
65 static int scimci_bus_power(sdmmc_chipset_handle_t, uint32_t);
66 static int scimci_bus_clock(sdmmc_chipset_handle_t, int);
67 static int scimci_bus_width(sdmmc_chipset_handle_t, int);
68 static void scimci_exec_command(sdmmc_chipset_handle_t,
69 struct sdmmc_command *);
70
71 static struct sdmmc_chip_functions scimci_chip_functions = {
72 /* host controller reset */
73 .host_reset = scimci_host_reset,
74
75 /* host controller capabilities */
76 .host_ocr = scimci_host_ocr,
77 .host_maxblklen = scimci_host_maxblklen,
78
79 /* card detection */
80 .card_detect = scimci_card_detect,
81
82 /* write protect */
83 .write_protect = scimci_write_protect,
84
85 /* bus power, clock frequency, width */
86 .bus_power = scimci_bus_power,
87 .bus_clock = scimci_bus_clock,
88 .bus_width = scimci_bus_width,
89
90 /* command execution */
91 .exec_command = scimci_exec_command,
92
93 /* card interrupt */
94 .card_enable_intr = NULL,
95 .card_intr_ack = NULL,
96 };
97
98 static void scimci_spi_initialize(sdmmc_chipset_handle_t);
99
100 static struct sdmmc_spi_chip_functions scimci_spi_chip_functions = {
101 .initialize = scimci_spi_initialize,
102 };
103
104 #define CSR_SET_1(reg,set,mask) \
105 do { \
106 uint8_t _r; \
107 _r = _reg_read_1((reg)); \
108 _r &= ~(mask); \
109 _r |= (set); \
110 _reg_write_1((reg), _r); \
111 } while (/*CONSTCOND*/0)
112
113 #define CSR_SET_2(reg,set,mask) \
114 do { \
115 uint16_t _r; \
116 _r = _reg_read_2((reg)); \
117 _r &= ~(mask); \
118 _r |= (set); \
119 _reg_write_2((reg), _r); \
120 } while (/*CONSTCOND*/0)
121
122 #define CSR_CLR_1(reg,clr) \
123 do { \
124 uint8_t _r; \
125 _r = _reg_read_1((reg)); \
126 _r &= ~(clr); \
127 _reg_write_1((reg), _r); \
128 } while (/*CONSTCOND*/0)
129
130 #define CSR_CLR_2(reg,clr) \
131 do { \
132 uint16_t _r; \
133 _r = _reg_read_2((reg)); \
134 _r &= ~(clr); \
135 _reg_write_2((reg), _r); \
136 } while (/*CONSTCOND*/0)
137
138 #define SCPCR_CLK_MASK 0x000C
139 #define SCPCR_CLK_IN 0x000C
140 #define SCPCR_CLK_OUT 0x0004
141 #define SCPDR_CLK 0x02
142 #define SCPCR_DAT_MASK 0x0003
143 #define SCPCR_DAT_IN 0x0003
144 #define SCPCR_DAT_OUT 0x0001
145 #define SCPDR_DAT 0x01
146 #define SCPCR_CMD_MASK 0x0030
147 #define SCPCR_CMD_IN 0x0030
148 #define SCPCR_CMD_OUT 0x0010
149 #define SCPDR_CMD 0x04
150 #define SCPCR_CS_MASK 0x00C0
151 #define SCPCR_CS_IN 0x00C0
152 #define SCPCR_CS_OUT 0x0040
153 #define SCPDR_CS 0x08
154 #define PGCR_EJECT 0x0300
155 #define PGDR_EJECT 0x10
156
157 /* SCSCR */
158 #define SCSCR_SCK_OUT 0
159 #define SCSCR_SCK_IN (SCSCR_CKE1)
160
161 #define LOW_SPEED 144
162 #define MID_SPEED 48
163 #define MMC_TIME_OVER 1000
164
165 struct scimci_softc {
166 device_t sc_dev;
167 device_t sc_sdmmc;
168 };
169
170 static int scimci_match(device_t, cfdata_t, void *);
171 static void scimci_attach(device_t, device_t, void *);
172
173 CFATTACH_DECL_NEW(scimci, sizeof(struct scimci_softc),
174 scimci_match, scimci_attach, NULL, NULL);
175
176 static void scimci_putc(int);
177 static void scimci_putc_sw(void);
178 static int scimci_getc(void);
179 static void scimci_getc_sw(void);
180 static void scimci_cmd_cfgread(struct scimci_softc *, struct sdmmc_command *);
181 static void scimci_cmd_read(struct scimci_softc *, struct sdmmc_command *);
182 static void scimci_cmd_write(struct scimci_softc *, struct sdmmc_command *);
183
184 void scimci_read_buffer(u_char *buf);
185 void scimci_write_buffer(const u_char *buf);
186
187 /*ARGSUSED*/
188 static int
189 scimci_match(device_t parent, cfdata_t cf, void *aux)
190 {
191
192 if (IS_SH7706LSR)
193 return 0;
194 return 1;
195 }
196
197 /*ARGSUSED*/
198 static void
199 scimci_attach(device_t parent, device_t self, void *aux)
200 {
201 struct scimci_softc *sc = device_private(self);
202 struct sdmmcbus_attach_args saa;
203
204 sc->sc_dev = self;
205
206 aprint_naive("\n");
207 aprint_normal(": SCI MMC controller\n");
208
209 /* Setup */
210 CSR_SET_2(SH7709_SCPCR, SCPCR_CLK_OUT | SCPCR_CMD_OUT,
211 SCPCR_CLK_MASK | SCPCR_CMD_MASK);
212 CSR_CLR_2(SH7709_SCPCR, SCPCR_CMD_MASK);
213 CSR_SET_1(SH7709_SCPDR, SCPDR_CLK | SCPDR_CMD, 0);
214 CSR_SET_2(SH7709_SCPCR, SCPCR_CS_OUT, SCPCR_CS_MASK);
215
216 SHREG_SCSCR = 0x00;
217 SHREG_SCSSR = 0x00;
218 SHREG_SCSCMR = 0xfa; /* MSB first */
219 SHREG_SCSMR = SCSMR_CA; /* clock sync mode */
220 SHREG_SCBRR = LOW_SPEED;
221 delay(1000); /* wait 1ms */
222
223 /*
224 * Attach the generic SD/MMC bus driver. (The bus driver must
225 * not invoke any chipset functions before it is attached.)
226 */
227 memset(&saa, 0, sizeof(saa));
228 saa.saa_busname = "sdmmc";
229 saa.saa_sct = &scimci_chip_functions;
230 saa.saa_spi_sct = &scimci_spi_chip_functions;
231 saa.saa_sch = sc;
232 saa.saa_clkmin = 4000 / (LOW_SPEED + 1);
233 saa.saa_clkmax = 4000 / (MID_SPEED + 1);
234 saa.saa_caps = SMC_CAPS_SPI_MODE
235 | SMC_CAPS_SINGLE_ONLY
236 | SMC_CAPS_POLL_CARD_DET;
237
238 sc->sc_sdmmc = config_found(sc->sc_dev, &saa, NULL, CFARGS_NONE);
239 if (sc->sc_sdmmc == NULL)
240 aprint_error_dev(sc->sc_dev, "couldn't attach bus\n");
241 }
242
243 /*
244 * SCI access functions
245 */
246 static void
247 scimci_putc(int c)
248 {
249
250 CSR_SET_2(SH7709_SCPCR, SCPCR_CLK_OUT, SCPCR_CLK_MASK);
251 SHREG_SCSCR = SCSCR_TE | SCSCR_SCK_OUT;
252 while ((SHREG_SCSSR & SCSSR_TDRE) == 0)
253 continue;
254 CSR_CLR_2(SH7709_SCPCR, SCPCR_CLK_MASK);
255 SHREG_SCTDR = (uint8_t)c;
256 (void) SHREG_SCSSR;
257 SHREG_SCSSR = 0;
258 }
259
260 static void
261 scimci_putc_sw(void)
262 {
263
264 while ((SHREG_SCSSR & SCSSR_TEND) == 0)
265 continue;
266
267 CSR_SET_2(SH7709_SCPCR, SCPCR_CLK_IN, 0);
268 SHREG_SCSCR |= SCSCR_SCK_IN;
269 CSR_CLR_2(SH7709_SCPCR, SCPCR_CLK_MASK);
270 SHREG_SCSMR = 0;
271 SHREG_SCSCR = SCSCR_SCK_OUT;
272 SHREG_SCSSR = 0;
273 SHREG_SCSMR = SCSMR_CA;
274 }
275
276 static int
277 scimci_getc(void)
278 {
279 int c;
280
281 SHREG_SCSCR = SCSCR_RE | SCSCR_SCK_OUT;
282 if (SHREG_SCSSR & SCSSR_ORER) {
283 SHREG_SCSSR &= ~SCSSR_ORER;
284 return -1;
285 }
286 CSR_CLR_2(SH7709_SCPCR, SCPCR_CLK_MASK);
287 while ((SHREG_SCSSR & SCSSR_RDRF) == 0)
288 continue;
289 c = SHREG_SCRDR;
290 (void) SHREG_SCSSR;
291 SHREG_SCSSR = 0;
292
293 return (uint8_t)c;
294 }
295
296 static void
297 scimci_getc_sw(void)
298 {
299
300 SHREG_SCBRR = LOW_SPEED;
301 while ((SHREG_SCSSR & SCSSR_RDRF) == 0)
302 continue;
303 (void) SHREG_SCRDR;
304
305 CSR_SET_2(SH7709_SCPCR, SCPCR_CLK_IN, 0);
306 SHREG_SCSCR |= SCSCR_SCK_IN;
307 CSR_CLR_2(SH7709_SCPCR, SCPCR_CLK_MASK);
308 SHREG_SCSMR = 0;
309 SHREG_SCSCR = SCSCR_SCK_OUT;
310 SHREG_SCSSR = 0;
311 SHREG_SCSMR = SCSMR_CA;
312 }
313
314 /*
315 * Reset the host controller. Called during initialization, when
316 * cards are removed, upon resume, and during error recovery.
317 */
318 /*ARGSUSED*/
319 static int
320 scimci_host_reset(sdmmc_chipset_handle_t sch)
321 {
322
323 return 0;
324 }
325
326 /*ARGSUSED*/
327 static uint32_t
328 scimci_host_ocr(sdmmc_chipset_handle_t sch)
329 {
330
331 return MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V;
332 }
333
334 /*ARGSUSED*/
335 static int
336 scimci_host_maxblklen(sdmmc_chipset_handle_t sch)
337 {
338
339 return 512;
340 }
341
342 /*ARGSUSED*/
343 static int
344 scimci_card_detect(sdmmc_chipset_handle_t sch)
345 {
346 uint8_t reg;
347 int s;
348
349 s = splserial();
350 CSR_SET_2(SH7709_PGCR, PGCR_EJECT, 0);
351 reg = _reg_read_1(SH7709_PGDR);
352 splx(s);
353
354 return !(reg & PGDR_EJECT);
355 }
356
357 /*ARGSUSED*/
358 static int
359 scimci_write_protect(sdmmc_chipset_handle_t sch)
360 {
361
362 return 0; /* non-protect */
363 }
364
365 /*
366 * Set or change SD bus voltage and enable or disable SD bus power.
367 * Return zero on success.
368 */
369 /*ARGSUSED*/
370 static int
371 scimci_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
372 {
373
374 if ((ocr & (MMC_OCR_3_2V_3_3V|MMC_OCR_3_3V_3_4V)) == 0)
375 return 1;
376
377 /*XXX???*/
378 return 0;
379 }
380
381 /*
382 * Set or change MMCLK frequency or disable the MMC clock.
383 * Return zero on success.
384 */
385 /*ARGSUSED*/
386 static int
387 scimci_bus_clock(sdmmc_chipset_handle_t sch, int freq)
388 {
389
390 return 0;
391 }
392
393 /*ARGSUSED*/
394 static int
395 scimci_bus_width(sdmmc_chipset_handle_t sch, int width)
396 {
397
398 if (width != 1)
399 return 1;
400 return 0;
401 }
402
403 /*ARGSUSED*/
404 static void
405 scimci_spi_initialize(sdmmc_chipset_handle_t sch)
406 {
407 int i, s;
408
409 s = splserial();
410 CSR_SET_1(SH7709_SCPDR, SCPDR_CS, 0);
411 for (i = 0; i < 20; i++)
412 scimci_putc(0xff);
413 scimci_putc_sw();
414 CSR_CLR_1(SH7709_SCPDR, SCPDR_CS);
415 splx(s);
416 }
417
418 static void
419 scimci_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
420 {
421 struct scimci_softc *sc = (struct scimci_softc *)sch;
422 uint16_t resp;
423 int timo;
424 int s;
425
426 DPRINTF(1,("%s: start cmd %d arg=%#x data=%p dlen=%d flags=%#x "
427 "proc=%p \"%s\"\n", device_xname(sc->sc_dev),
428 cmd->c_opcode, cmd->c_arg, cmd->c_data, cmd->c_datalen,
429 cmd->c_flags, curproc, curproc ? curproc->p_comm : ""));
430
431 s = splhigh();
432
433 if (cmd->c_opcode == MMC_GO_IDLE_STATE)
434 SHREG_SCBRR = LOW_SPEED;
435 else
436 SHREG_SCBRR = MID_SPEED;
437
438 scimci_putc(0xff);
439 scimci_putc(0x40 | (cmd->c_opcode & 0x3f));
440 scimci_putc((cmd->c_arg >> 24) & 0xff);
441 scimci_putc((cmd->c_arg >> 16) & 0xff);
442 scimci_putc((cmd->c_arg >> 8) & 0xff);
443 scimci_putc((cmd->c_arg >> 0) & 0xff);
444 scimci_putc((cmd->c_opcode == MMC_GO_IDLE_STATE) ? 0x95 :
445 (cmd->c_opcode == SD_SEND_IF_COND) ? 0x87 : 0); /* CRC */
446 scimci_putc(0xff);
447 scimci_putc_sw();
448
449 timo = MMC_TIME_OVER;
450 while ((resp = scimci_getc()) & 0x80) {
451 if(--timo == 0) {
452 DPRINTF(1, ("%s: response timeout\n",
453 device_xname(sc->sc_dev)));
454 scimci_getc_sw();
455 cmd->c_error = ETIMEDOUT;
456 goto out;
457 }
458 }
459 if (ISSET(cmd->c_flags, SCF_RSP_SPI_S2)) {
460 resp |= (uint16_t)scimci_getc() << 8;
461 } else if (ISSET(cmd->c_flags, SCF_RSP_SPI_B4)) {
462 cmd->c_resp[1] = (uint32_t) scimci_getc() << 24;
463 cmd->c_resp[1] |= (uint32_t) scimci_getc() << 16;
464 cmd->c_resp[1] |= (uint32_t) scimci_getc() << 8;
465 cmd->c_resp[1] |= (uint32_t) scimci_getc();
466 DPRINTF(1, ("R3 resp: %#x\n", cmd->c_resp[1]));
467 }
468 scimci_getc_sw();
469
470 cmd->c_resp[0] = resp;
471 if (resp != 0 && resp != R1_SPI_IDLE) {
472 DPRINTF(1, ("%s: response error: %#x\n",
473 device_xname(sc->sc_dev), resp));
474 cmd->c_error = EIO;
475 goto out;
476 }
477 DPRINTF(1, ("R1 resp: %#x\n", resp));
478
479 if (cmd->c_datalen > 0) {
480 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
481 /* XXX: swap in this place? */
482 if (cmd->c_opcode == MMC_SEND_CID ||
483 cmd->c_opcode == MMC_SEND_CSD) {
484 sdmmc_response res;
485 uint32_t *p = cmd->c_data;
486
487 scimci_cmd_cfgread(sc, cmd);
488 res[0] = be32toh(p[3]);
489 res[1] = be32toh(p[2]);
490 res[2] = be32toh(p[1]);
491 res[3] = be32toh(p[0]);
492 memcpy(p, &res, sizeof(res));
493 } else {
494 scimci_cmd_read(sc, cmd);
495 }
496 } else {
497 scimci_cmd_write(sc, cmd);
498 }
499 }
500
501 out:
502 SET(cmd->c_flags, SCF_ITSDONE);
503 splx(s);
504
505 DPRINTF(1,("%s: cmd %d done (flags=%#x error=%d)\n",
506 device_xname(sc->sc_dev), cmd->c_opcode, cmd->c_flags, cmd->c_error));
507 }
508
509 static void
510 scimci_cmd_cfgread(struct scimci_softc *sc, struct sdmmc_command *cmd)
511 {
512 u_char *data = cmd->c_data;
513 int timo;
514 int c;
515 int i;
516
517 /* wait data token */
518 for (timo = MMC_TIME_OVER; timo > 0; timo--) {
519 c = scimci_getc();
520 if (c < 0) {
521 aprint_error_dev(sc->sc_dev, "cfg read i/o error\n");
522 cmd->c_error = EIO;
523 return;
524 }
525 if (c != 0xff)
526 break;
527 }
528 if (timo == 0) {
529 aprint_error_dev(sc->sc_dev, "cfg read timeout\n");
530 cmd->c_error = ETIMEDOUT;
531 return;
532 }
533 if (c != 0xfe) {
534 aprint_error_dev(sc->sc_dev, "cfg read error (data=%#x)\n", c);
535 cmd->c_error = EIO;
536 return;
537 }
538
539 /* data read */
540 SHREG_SCSCR = SCSCR_RE | SCSCR_SCK_OUT;
541 data[0] = '\0'; /* XXXFIXME!!! */
542 for (i = 1 /* XXXFIXME!!!*/ ; i < cmd->c_datalen; i++) {
543 while ((SHREG_SCSSR & SCSSR_RDRF) == 0)
544 continue;
545 data[i] = SHREG_SCRDR;
546 (void) SHREG_SCSSR;
547 SHREG_SCSSR = 0;
548 }
549
550 SHREG_SCBRR = LOW_SPEED;
551 (void) scimci_getc();
552 (void) scimci_getc();
553 (void) scimci_getc();
554 scimci_getc_sw();
555
556 #ifdef SCIMCI_DEBUG
557 sdmmc_dump_data(NULL, cmd->c_data, cmd->c_datalen);
558 #endif
559 }
560
561 static void
562 scimci_cmd_read(struct scimci_softc *sc, struct sdmmc_command *cmd)
563 {
564 u_char *data = cmd->c_data;
565 int timo;
566 int c;
567 int i;
568
569 /* wait data token */
570 for (timo = MMC_TIME_OVER; timo > 0; timo--) {
571 c = scimci_getc();
572 if (c < 0) {
573 aprint_error_dev(sc->sc_dev, "read i/o error\n");
574 cmd->c_error = EIO;
575 return;
576 }
577 if (c != 0xff)
578 break;
579 }
580 if (timo == 0) {
581 aprint_error_dev(sc->sc_dev, "read timeout\n");
582 cmd->c_error = ETIMEDOUT;
583 return;
584 }
585 if (c != 0xfe) {
586 aprint_error_dev(sc->sc_dev, "read error (data=%#x)\n", c);
587 cmd->c_error = EIO;
588 return;
589 }
590
591 /* data read */
592 SHREG_SCBRR = MID_SPEED;
593 SHREG_SCSCR = SCSCR_RE | SCSCR_SCK_OUT;
594 for (i = 0; i < cmd->c_datalen; i++) {
595 while ((SHREG_SCSSR & SCSSR_RDRF) == 0)
596 continue;
597 data[i] = SHREG_SCRDR;
598 (void) SHREG_SCSSR;
599 SHREG_SCSSR = 0;
600 }
601
602 SHREG_SCBRR = LOW_SPEED;
603 (void) scimci_getc();
604 (void) scimci_getc();
605 (void) scimci_getc();
606 scimci_getc_sw();
607
608 #ifdef SCIMCI_DEBUG
609 sdmmc_dump_data(NULL, cmd->c_data, cmd->c_datalen);
610 #endif
611 }
612
613 static void
614 scimci_cmd_write(struct scimci_softc *sc, struct sdmmc_command *cmd)
615 {
616 char *data = cmd->c_data;
617 int timo;
618 int c;
619 int i;
620
621 scimci_putc(0xff);
622 scimci_putc(0xfe);
623
624 /* data write */
625 SHREG_SCBRR = MID_SPEED;
626 SHREG_SCSCR = SCSCR_TE | SCSCR_SCK_OUT;
627 for (i = 0; i < cmd->c_datalen; i++) {
628 while ((SHREG_SCSSR & SCSSR_TDRE) == 0)
629 continue;
630 SHREG_SCTDR = data[i];
631 (void) SHREG_SCSSR;
632 SHREG_SCSSR = 0;
633 }
634
635 SHREG_SCBRR = LOW_SPEED;
636 scimci_putc(0);
637 scimci_putc(0);
638 scimci_putc(0);
639 scimci_putc_sw();
640
641 for (timo = MMC_TIME_OVER; timo > 0; timo--) {
642 c = scimci_getc();
643 if (c < 0) {
644 aprint_error_dev(sc->sc_dev, "write i/o error\n");
645 cmd->c_error = EIO;
646 scimci_getc_sw();
647 return;
648 }
649 if (c == 0xff)
650 break;
651 }
652 if (timo == 0) {
653 aprint_error_dev(sc->sc_dev, "write timeout\n");
654 cmd->c_error = ETIMEDOUT;
655 }
656 scimci_getc_sw();
657 }
658