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