1 /* $OpenBSD: sdmmc_scsi.c,v 1.40 2017/04/06 17:00:53 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* A SCSI adapter emulation to access SD/MMC memory cards */ 20 21 #include <sys/param.h> 22 #include <sys/buf.h> 23 #include <sys/device.h> 24 #include <sys/malloc.h> 25 #include <sys/proc.h> 26 #include <sys/systm.h> 27 28 #include <scsi/scsi_all.h> 29 #include <scsi/scsi_disk.h> 30 #include <scsi/scsiconf.h> 31 32 #include <dev/sdmmc/sdmmc_scsi.h> 33 #include <dev/sdmmc/sdmmcvar.h> 34 35 #define SDMMC_SCSIID_HOST 0x00 36 #define SDMMC_SCSIID_MAX 0x0f 37 38 #define SDMMC_SCSI_MAXCMDS 8 39 40 struct sdmmc_scsi_target { 41 struct sdmmc_function *card; 42 }; 43 44 struct sdmmc_ccb { 45 struct sdmmc_scsi_softc *ccb_scbus; 46 struct scsi_xfer *ccb_xs; 47 int ccb_flags; 48 #define SDMMC_CCB_F_ERR 0x0001 49 u_int32_t ccb_blockno; 50 u_int32_t ccb_blockcnt; 51 volatile enum { 52 SDMMC_CCB_FREE, 53 SDMMC_CCB_READY, 54 SDMMC_CCB_QUEUED 55 } ccb_state; 56 struct sdmmc_command ccb_cmd; 57 struct sdmmc_task ccb_task; 58 TAILQ_ENTRY(sdmmc_ccb) ccb_link; 59 }; 60 61 TAILQ_HEAD(sdmmc_ccb_list, sdmmc_ccb); 62 63 struct sdmmc_scsi_softc { 64 struct scsi_adapter sc_adapter; 65 struct scsi_link sc_link; 66 struct device *sc_child; 67 struct sdmmc_scsi_target *sc_tgt; 68 int sc_ntargets; 69 struct sdmmc_ccb *sc_ccbs; /* allocated ccbs */ 70 int sc_nccbs; 71 struct sdmmc_ccb_list sc_ccb_freeq; /* free ccbs */ 72 struct sdmmc_ccb_list sc_ccb_runq; /* queued ccbs */ 73 struct mutex sc_ccb_mtx; 74 struct scsi_iopool sc_iopool; 75 }; 76 77 int sdmmc_alloc_ccbs(struct sdmmc_scsi_softc *, int); 78 void sdmmc_free_ccbs(struct sdmmc_scsi_softc *); 79 void *sdmmc_ccb_alloc(void *); 80 void sdmmc_ccb_free(void *, void *); 81 82 void sdmmc_scsi_cmd(struct scsi_xfer *); 83 void sdmmc_inquiry(struct scsi_xfer *); 84 void sdmmc_start_xs(struct sdmmc_softc *, struct sdmmc_ccb *); 85 void sdmmc_complete_xs(void *); 86 void sdmmc_done_xs(struct sdmmc_ccb *); 87 void sdmmc_stimeout(void *); 88 void sdmmc_scsi_minphys(struct buf *, struct scsi_link *); 89 90 #ifdef SDMMC_DEBUG 91 #define DPRINTF(s) printf s 92 #else 93 #define DPRINTF(s) /**/ 94 #endif 95 96 void 97 sdmmc_scsi_attach(struct sdmmc_softc *sc) 98 { 99 struct sdmmc_attach_args saa; 100 struct sdmmc_scsi_softc *scbus; 101 struct sdmmc_function *sf; 102 103 rw_assert_wrlock(&sc->sc_lock); 104 105 scbus = malloc(sizeof *scbus, M_DEVBUF, M_WAITOK | M_ZERO); 106 107 scbus->sc_tgt = mallocarray(sizeof(*scbus->sc_tgt), 108 (SDMMC_SCSIID_MAX+1), M_DEVBUF, M_WAITOK | M_ZERO); 109 110 /* 111 * Each card that sent us a CID in the identification stage 112 * gets a SCSI ID > 0, whether it is a memory card or not. 113 */ 114 scbus->sc_ntargets = 1; 115 SIMPLEQ_FOREACH(sf, &sc->sf_head, sf_list) { 116 if (scbus->sc_ntargets >= SDMMC_SCSIID_MAX+1) 117 break; 118 scbus->sc_tgt[scbus->sc_ntargets].card = sf; 119 scbus->sc_ntargets++; 120 } 121 122 /* Preallocate some CCBs and initialize the CCB lists. */ 123 if (sdmmc_alloc_ccbs(scbus, SDMMC_SCSI_MAXCMDS) != 0) { 124 printf("%s: can't allocate ccbs\n", sc->sc_dev.dv_xname); 125 goto free_sctgt; 126 } 127 128 sc->sc_scsibus = scbus; 129 130 scbus->sc_adapter.scsi_cmd = sdmmc_scsi_cmd; 131 scbus->sc_adapter.scsi_minphys = sdmmc_scsi_minphys; 132 133 scbus->sc_link.adapter_target = SDMMC_SCSIID_HOST; 134 scbus->sc_link.adapter_buswidth = scbus->sc_ntargets; 135 scbus->sc_link.adapter_softc = sc; 136 scbus->sc_link.luns = 1; 137 scbus->sc_link.openings = 1; 138 scbus->sc_link.adapter = &scbus->sc_adapter; 139 scbus->sc_link.pool = &scbus->sc_iopool; 140 141 bzero(&saa, sizeof(saa)); 142 saa.scsi_link = &scbus->sc_link; 143 144 scbus->sc_child = config_found(&sc->sc_dev, &saa, scsiprint); 145 if (scbus->sc_child == NULL) { 146 printf("%s: can't attach scsibus\n", sc->sc_dev.dv_xname); 147 goto free_ccbs; 148 } 149 return; 150 151 free_ccbs: 152 sc->sc_scsibus = NULL; 153 sdmmc_free_ccbs(scbus); 154 free_sctgt: 155 free(scbus->sc_tgt, M_DEVBUF, 156 sizeof(*scbus->sc_tgt) * (SDMMC_SCSIID_MAX+1)); 157 free(scbus, M_DEVBUF, sizeof *scbus); 158 } 159 160 void 161 sdmmc_scsi_detach(struct sdmmc_softc *sc) 162 { 163 struct sdmmc_scsi_softc *scbus; 164 struct sdmmc_ccb *ccb; 165 int s; 166 167 rw_assert_wrlock(&sc->sc_lock); 168 169 scbus = sc->sc_scsibus; 170 if (scbus == NULL) 171 return; 172 173 /* Complete all open scsi xfers. */ 174 s = splbio(); 175 for (ccb = TAILQ_FIRST(&scbus->sc_ccb_runq); ccb != NULL; 176 ccb = TAILQ_FIRST(&scbus->sc_ccb_runq)) 177 sdmmc_stimeout(ccb); 178 splx(s); 179 180 if (scbus->sc_child != NULL) 181 config_detach(scbus->sc_child, DETACH_FORCE); 182 183 if (scbus->sc_tgt != NULL) 184 free(scbus->sc_tgt, M_DEVBUF, 185 sizeof(*scbus->sc_tgt) * (SDMMC_SCSIID_MAX+1)); 186 187 sdmmc_free_ccbs(scbus); 188 free(scbus, M_DEVBUF, sizeof *scbus); 189 sc->sc_scsibus = NULL; 190 } 191 192 /* 193 * CCB management 194 */ 195 196 int 197 sdmmc_alloc_ccbs(struct sdmmc_scsi_softc *scbus, int nccbs) 198 { 199 struct sdmmc_ccb *ccb; 200 int i; 201 202 scbus->sc_ccbs = mallocarray(nccbs, sizeof(struct sdmmc_ccb), 203 M_DEVBUF, M_NOWAIT); 204 if (scbus->sc_ccbs == NULL) 205 return 1; 206 scbus->sc_nccbs = nccbs; 207 208 TAILQ_INIT(&scbus->sc_ccb_freeq); 209 TAILQ_INIT(&scbus->sc_ccb_runq); 210 mtx_init(&scbus->sc_ccb_mtx, IPL_BIO); 211 scsi_iopool_init(&scbus->sc_iopool, scbus, sdmmc_ccb_alloc, 212 sdmmc_ccb_free); 213 214 for (i = 0; i < nccbs; i++) { 215 ccb = &scbus->sc_ccbs[i]; 216 ccb->ccb_scbus = scbus; 217 ccb->ccb_state = SDMMC_CCB_FREE; 218 ccb->ccb_flags = 0; 219 ccb->ccb_xs = NULL; 220 221 TAILQ_INSERT_TAIL(&scbus->sc_ccb_freeq, ccb, ccb_link); 222 } 223 return 0; 224 } 225 226 void 227 sdmmc_free_ccbs(struct sdmmc_scsi_softc *scbus) 228 { 229 if (scbus->sc_ccbs != NULL) { 230 free(scbus->sc_ccbs, M_DEVBUF, 231 scbus->sc_nccbs * sizeof(struct sdmmc_ccb)); 232 scbus->sc_ccbs = NULL; 233 } 234 } 235 236 void * 237 sdmmc_ccb_alloc(void *xscbus) 238 { 239 struct sdmmc_scsi_softc *scbus = xscbus; 240 struct sdmmc_ccb *ccb; 241 242 mtx_enter(&scbus->sc_ccb_mtx); 243 ccb = TAILQ_FIRST(&scbus->sc_ccb_freeq); 244 if (ccb != NULL) { 245 TAILQ_REMOVE(&scbus->sc_ccb_freeq, ccb, ccb_link); 246 ccb->ccb_state = SDMMC_CCB_READY; 247 } 248 mtx_leave(&scbus->sc_ccb_mtx); 249 250 return ccb; 251 } 252 253 void 254 sdmmc_ccb_free(void *xscbus, void *xccb) 255 { 256 struct sdmmc_scsi_softc *scbus = xscbus; 257 struct sdmmc_ccb *ccb = xccb; 258 int s; 259 260 s = splbio(); 261 if (ccb->ccb_state == SDMMC_CCB_QUEUED) 262 TAILQ_REMOVE(&scbus->sc_ccb_runq, ccb, ccb_link); 263 splx(s); 264 265 ccb->ccb_state = SDMMC_CCB_FREE; 266 ccb->ccb_flags = 0; 267 ccb->ccb_xs = NULL; 268 269 mtx_enter(&scbus->sc_ccb_mtx); 270 TAILQ_INSERT_TAIL(&scbus->sc_ccb_freeq, ccb, ccb_link); 271 mtx_leave(&scbus->sc_ccb_mtx); 272 } 273 274 /* 275 * SCSI command emulation 276 */ 277 278 /* XXX move to some sort of "scsi emulation layer". */ 279 static void 280 sdmmc_scsi_decode_rw(struct scsi_xfer *xs, u_int32_t *blocknop, 281 u_int32_t *blockcntp) 282 { 283 struct scsi_rw *rw; 284 struct scsi_rw_big *rwb; 285 286 if (xs->cmdlen == 6) { 287 rw = (struct scsi_rw *)xs->cmd; 288 *blocknop = _3btol(rw->addr) & (SRW_TOPADDR << 16 | 0xffff); 289 *blockcntp = rw->length ? rw->length : 0x100; 290 } else { 291 rwb = (struct scsi_rw_big *)xs->cmd; 292 *blocknop = _4btol(rwb->addr); 293 *blockcntp = _2btol(rwb->length); 294 } 295 } 296 297 void 298 sdmmc_scsi_cmd(struct scsi_xfer *xs) 299 { 300 struct scsi_link *link = xs->sc_link; 301 struct sdmmc_softc *sc = link->adapter_softc; 302 struct sdmmc_scsi_softc *scbus = sc->sc_scsibus; 303 struct sdmmc_scsi_target *tgt = &scbus->sc_tgt[link->target]; 304 struct scsi_read_cap_data rcd; 305 u_int32_t blockno; 306 u_int32_t blockcnt; 307 struct sdmmc_ccb *ccb; 308 309 if (link->target >= scbus->sc_ntargets || tgt->card == NULL || 310 link->lun != 0) { 311 DPRINTF(("%s: sdmmc_scsi_cmd: no target %d\n", 312 DEVNAME(sc), link->target)); 313 /* XXX should be XS_SENSE and sense filled out */ 314 xs->error = XS_DRIVER_STUFFUP; 315 scsi_done(xs); 316 return; 317 } 318 319 DPRINTF(("%s: scsi cmd target=%d opcode=%#x proc=\"%s\" (poll=%#x)\n", 320 DEVNAME(sc), link->target, xs->cmd->opcode, curproc ? 321 curproc->p_p->ps_comm : "", xs->flags & SCSI_POLL)); 322 323 xs->error = XS_NOERROR; 324 325 switch (xs->cmd->opcode) { 326 case READ_COMMAND: 327 case READ_BIG: 328 case WRITE_COMMAND: 329 case WRITE_BIG: 330 /* Deal with I/O outside the switch. */ 331 break; 332 333 case INQUIRY: 334 sdmmc_inquiry(xs); 335 return; 336 337 case TEST_UNIT_READY: 338 case START_STOP: 339 case SYNCHRONIZE_CACHE: 340 scsi_done(xs); 341 return; 342 343 case READ_CAPACITY: 344 bzero(&rcd, sizeof rcd); 345 _lto4b(tgt->card->csd.capacity - 1, rcd.addr); 346 _lto4b(tgt->card->csd.sector_size, rcd.length); 347 bcopy(&rcd, xs->data, MIN(xs->datalen, sizeof rcd)); 348 scsi_done(xs); 349 return; 350 351 default: 352 DPRINTF(("%s: unsupported scsi command %#x\n", 353 DEVNAME(sc), xs->cmd->opcode)); 354 xs->error = XS_DRIVER_STUFFUP; 355 scsi_done(xs); 356 return; 357 } 358 359 /* A read or write operation. */ 360 sdmmc_scsi_decode_rw(xs, &blockno, &blockcnt); 361 362 if (blockno >= tgt->card->csd.capacity || 363 blockno + blockcnt > tgt->card->csd.capacity) { 364 DPRINTF(("%s: out of bounds %u-%u >= %u\n", DEVNAME(sc), 365 blockno, blockcnt, tgt->card->csd.capacity)); 366 xs->error = XS_DRIVER_STUFFUP; 367 scsi_done(xs); 368 return; 369 } 370 371 ccb = xs->io; 372 373 ccb->ccb_xs = xs; 374 ccb->ccb_blockcnt = blockcnt; 375 ccb->ccb_blockno = blockno; 376 377 sdmmc_start_xs(sc, ccb); 378 } 379 380 void 381 sdmmc_inquiry(struct scsi_xfer *xs) 382 { 383 struct scsi_link *link = xs->sc_link; 384 struct sdmmc_softc *sc = link->adapter_softc; 385 struct sdmmc_scsi_softc *scbus = sc->sc_scsibus; 386 struct sdmmc_scsi_target *tgt = &scbus->sc_tgt[link->target]; 387 struct scsi_inquiry_data inq; 388 struct scsi_inquiry *cdb = (struct scsi_inquiry *)xs->cmd; 389 char vendor[sizeof(inq.vendor) + 1]; 390 char product[sizeof(inq.product) + 1]; 391 char revision[sizeof(inq.revision) + 1]; 392 393 if (xs->cmdlen != sizeof(*cdb)) { 394 xs->error = XS_DRIVER_STUFFUP; 395 goto done; 396 } 397 398 if (ISSET(cdb->flags, SI_EVPD)) { 399 xs->error = XS_DRIVER_STUFFUP; 400 goto done; 401 } 402 403 memset(vendor, 0, sizeof(vendor)); 404 memset(product, 0, sizeof(product)); 405 memset(revision, 0, sizeof(revision)); 406 switch (tgt->card->cid.mid) { 407 case 0x02: 408 case 0x45: 409 strlcpy(vendor, "Sandisk", sizeof(vendor)); 410 break; 411 case 0x11: 412 strlcpy(vendor, "Toshiba", sizeof(vendor)); 413 break; 414 case 0x13: 415 strlcpy(vendor, "Micron", sizeof(vendor)); 416 break; 417 case 0x15: 418 strlcpy(vendor, "Samsung", sizeof(vendor)); 419 break; 420 case 0x70: 421 strlcpy(vendor, "Kingston", sizeof(vendor)); 422 break; 423 default: 424 strlcpy(vendor, "SD/MMC", sizeof(vendor)); 425 break; 426 } 427 strlcpy(product, tgt->card->cid.pnm, sizeof(product)); 428 snprintf(revision, sizeof(revision), "%04X", tgt->card->cid.rev); 429 430 memset(&inq, 0, sizeof inq); 431 inq.device = T_DIRECT; 432 inq.dev_qual2 = SID_REMOVABLE; 433 inq.version = 2; 434 inq.response_format = 2; 435 inq.additional_length = 32; 436 memcpy(inq.vendor, vendor, sizeof(inq.vendor)); 437 memcpy(inq.product, product, sizeof(inq.product)); 438 memcpy(inq.revision, revision, sizeof(inq.revision)); 439 440 memcpy(xs->data, &inq, MIN(xs->datalen, sizeof(inq))); 441 442 done: 443 scsi_done(xs); 444 } 445 446 void 447 sdmmc_start_xs(struct sdmmc_softc *sc, struct sdmmc_ccb *ccb) 448 { 449 struct sdmmc_scsi_softc *scbus = sc->sc_scsibus; 450 struct scsi_xfer *xs = ccb->ccb_xs; 451 int s; 452 453 timeout_set(&xs->stimeout, sdmmc_stimeout, ccb); 454 sdmmc_init_task(&ccb->ccb_task, sdmmc_complete_xs, ccb); 455 456 s = splbio(); 457 TAILQ_INSERT_TAIL(&scbus->sc_ccb_runq, ccb, ccb_link); 458 ccb->ccb_state = SDMMC_CCB_QUEUED; 459 splx(s); 460 461 if (ISSET(xs->flags, SCSI_POLL)) { 462 sdmmc_complete_xs(ccb); 463 return; 464 } 465 466 timeout_add_msec(&xs->stimeout, xs->timeout); 467 sdmmc_add_task(sc, &ccb->ccb_task); 468 } 469 470 void 471 sdmmc_complete_xs(void *arg) 472 { 473 struct sdmmc_ccb *ccb = arg; 474 struct scsi_xfer *xs = ccb->ccb_xs; 475 struct scsi_link *link = xs->sc_link; 476 struct sdmmc_softc *sc = link->adapter_softc; 477 struct sdmmc_scsi_softc *scbus = sc->sc_scsibus; 478 struct sdmmc_scsi_target *tgt = &scbus->sc_tgt[link->target]; 479 int error; 480 int s; 481 482 DPRINTF(("%s: scsi cmd target=%d opcode=%#x proc=\"%s\" (poll=%#x)" 483 " complete\n", DEVNAME(sc), link->target, xs->cmd->opcode, 484 curproc ? curproc->p_p->ps_comm : "", xs->flags & SCSI_POLL)); 485 486 s = splbio(); 487 488 if (ISSET(xs->flags, SCSI_DATA_IN)) 489 error = sdmmc_mem_read_block(tgt->card, ccb->ccb_blockno, 490 xs->data, ccb->ccb_blockcnt * DEV_BSIZE); 491 else 492 error = sdmmc_mem_write_block(tgt->card, ccb->ccb_blockno, 493 xs->data, ccb->ccb_blockcnt * DEV_BSIZE); 494 495 if (error != 0) 496 xs->error = XS_DRIVER_STUFFUP; 497 498 sdmmc_done_xs(ccb); 499 splx(s); 500 } 501 502 void 503 sdmmc_done_xs(struct sdmmc_ccb *ccb) 504 { 505 struct scsi_xfer *xs = ccb->ccb_xs; 506 #ifdef SDMMC_DEBUG 507 struct scsi_link *link = xs->sc_link; 508 struct sdmmc_softc *sc = link->adapter_softc; 509 #endif 510 511 timeout_del(&xs->stimeout); 512 513 DPRINTF(("%s: scsi cmd target=%d opcode=%#x proc=\"%s\" (error=%#x)" 514 " done\n", DEVNAME(sc), link->target, xs->cmd->opcode, 515 curproc ? curproc->p_p->ps_comm : "", xs->error)); 516 517 xs->resid = 0; 518 519 if (ISSET(ccb->ccb_flags, SDMMC_CCB_F_ERR)) 520 xs->error = XS_DRIVER_STUFFUP; 521 522 scsi_done(xs); 523 } 524 525 void 526 sdmmc_stimeout(void *arg) 527 { 528 struct sdmmc_ccb *ccb = arg; 529 int s; 530 531 s = splbio(); 532 ccb->ccb_flags |= SDMMC_CCB_F_ERR; 533 if (sdmmc_task_pending(&ccb->ccb_task)) { 534 sdmmc_del_task(&ccb->ccb_task); 535 sdmmc_done_xs(ccb); 536 } 537 splx(s); 538 } 539 540 void 541 sdmmc_scsi_minphys(struct buf *bp, struct scsi_link *sl) 542 { 543 struct sdmmc_softc *sc = sl->adapter_softc; 544 struct sdmmc_scsi_softc *scbus = sc->sc_scsibus; 545 struct sdmmc_scsi_target *tgt = &scbus->sc_tgt[sl->target]; 546 struct sdmmc_function *sf = tgt->card; 547 548 /* limit to max. transfer size supported by card/host */ 549 if (sc->sc_max_xfer != 0 && 550 bp->b_bcount > sf->csd.sector_size * sc->sc_max_xfer) 551 bp->b_bcount = sf->csd.sector_size * sc->sc_max_xfer; 552 553 minphys(bp); 554 } 555