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