1 /* $NetBSD: scimci.c,v 1.2 2012/01/21 19:44:29 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 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.2 2012/01/21 19:44:29 nonaka 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); 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