1 /*- 2 * Copyright (c) 2013 Ilya Bakulin. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 */ 25 26 #include <sys/param.h> 27 #include <sys/module.h> 28 #include <sys/kernel.h> 29 #include <sys/malloc.h> 30 #include <sys/systm.h> 31 #include <sys/lock.h> 32 #include <sys/mutex.h> 33 #include <sys/bus.h> 34 #include <sys/endian.h> 35 #include <sys/sysctl.h> 36 37 #include <cam/cam.h> 38 #include <cam/cam_ccb.h> 39 #include <cam/cam_debug.h> 40 #include <cam/cam_sim.h> 41 #include <cam/cam_xpt_sim.h> 42 #include <cam/scsi/scsi_all.h> 43 44 static int is_sdio_mode = 1; 45 46 struct mmcnull_softc { 47 device_t dev; 48 struct mtx sc_mtx; 49 50 struct cam_devq *devq; 51 struct cam_sim *sim; 52 struct cam_path *path; 53 54 struct callout tick; 55 union ccb *cur_ccb; 56 }; 57 58 static void mmcnull_identify(driver_t *, device_t); 59 static int mmcnull_probe(device_t); 60 static int mmcnull_attach(device_t); 61 static int mmcnull_detach(device_t); 62 static void mmcnull_action_sd(struct cam_sim *, union ccb *); 63 static void mmcnull_action_sdio(struct cam_sim *, union ccb *); 64 static void mmcnull_intr_sd(void *xsc); 65 static void mmcnull_intr_sdio(void *xsc); 66 static void mmcnull_poll(struct cam_sim *); 67 68 static void 69 mmcnull_identify(driver_t *driver, device_t parent) 70 { 71 device_t child; 72 73 if (resource_disabled("mmcnull", 0)) 74 return; 75 76 if (device_get_unit(parent) != 0) 77 return; 78 79 /* Avoid duplicates. */ 80 if (device_find_child(parent, "mmcnull", -1)) 81 return; 82 83 child = BUS_ADD_CHILD(parent, 20, "mmcnull", 0); 84 if (child == NULL) { 85 device_printf(parent, "add MMCNULL child failed\n"); 86 return; 87 } 88 } 89 90 91 static int 92 mmcnull_probe(device_t dev) 93 { 94 device_set_desc(dev, "Emulated MMC controller"); 95 return (BUS_PROBE_DEFAULT); 96 } 97 98 static int 99 mmcnull_attach(device_t dev) 100 { 101 struct mmcnull_softc *sc; 102 sim_action_func action_func; 103 104 sc = device_get_softc(dev); 105 sc->dev = dev; 106 107 mtx_init(&sc->sc_mtx, "mmcnullmtx", NULL, MTX_DEF); 108 109 if ((sc->devq = cam_simq_alloc(1)) == NULL) 110 return (ENOMEM); 111 112 if (is_sdio_mode) 113 action_func = mmcnull_action_sdio; 114 else 115 action_func = mmcnull_action_sd; 116 sc->sim = cam_sim_alloc(action_func, mmcnull_poll, "mmcnull", sc, 117 device_get_unit(dev), &sc->sc_mtx, 1, 1, 118 sc->devq); 119 120 if (sc->sim == NULL) { 121 cam_simq_free(sc->devq); 122 device_printf(dev, "cannot allocate CAM SIM\n"); 123 return (EINVAL); 124 } 125 126 mtx_lock(&sc->sc_mtx); 127 if (xpt_bus_register(sc->sim, dev, 0) != 0) { 128 device_printf(dev, 129 "cannot register SCSI pass-through bus\n"); 130 cam_sim_free(sc->sim, FALSE); 131 cam_simq_free(sc->devq); 132 mtx_unlock(&sc->sc_mtx); 133 return (EINVAL); 134 } 135 mtx_unlock(&sc->sc_mtx); 136 137 callout_init_mtx(&sc->tick, &sc->sc_mtx, 0); /* Callout to emulate interrupts */ 138 139 device_printf(dev, "attached OK\n"); 140 141 return (0); 142 } 143 144 static int 145 mmcnull_detach(device_t dev) 146 { 147 struct mmcnull_softc *sc; 148 149 sc = device_get_softc(dev); 150 151 if (sc == NULL) 152 return (EINVAL); 153 154 if (sc->sim != NULL) { 155 mtx_lock(&sc->sc_mtx); 156 xpt_bus_deregister(cam_sim_path(sc->sim)); 157 cam_sim_free(sc->sim, FALSE); 158 mtx_unlock(&sc->sc_mtx); 159 } 160 161 if (sc->devq != NULL) 162 cam_simq_free(sc->devq); 163 164 callout_drain(&sc->tick); 165 mtx_destroy(&sc->sc_mtx); 166 167 device_printf(dev, "detached OK\n"); 168 return (0); 169 } 170 171 /* 172 * The interrupt handler 173 * This implementation calls it via callout(9) 174 * with the mutex already taken 175 */ 176 static void 177 mmcnull_intr_sd(void *xsc) { 178 struct mmcnull_softc *sc; 179 union ccb *ccb; 180 struct ccb_mmcio *mmcio; 181 182 sc = (struct mmcnull_softc *) xsc; 183 mtx_assert(&sc->sc_mtx, MA_OWNED); 184 185 ccb = sc->cur_ccb; 186 mmcio = &ccb->mmcio; 187 device_printf(sc->dev, "mmcnull_intr: MMC command = %d\n", 188 mmcio->cmd.opcode); 189 190 switch (mmcio->cmd.opcode) { 191 case MMC_GO_IDLE_STATE: 192 device_printf(sc->dev, "Reset device\n"); 193 break; 194 case SD_SEND_IF_COND: 195 mmcio->cmd.resp[0] = 0x1AA; // To match mmc_xpt expectations :-) 196 break; 197 case MMC_APP_CMD: 198 mmcio->cmd.resp[0] = R1_APP_CMD; 199 break; 200 case SD_SEND_RELATIVE_ADDR: 201 case MMC_SELECT_CARD: 202 mmcio->cmd.resp[0] = 0x1 << 16; 203 break; 204 case ACMD_SD_SEND_OP_COND: 205 mmcio->cmd.resp[0] = 0xc0ff8000; 206 mmcio->cmd.resp[0] |= MMC_OCR_CARD_BUSY; 207 break; 208 case MMC_ALL_SEND_CID: 209 /* Note: this is a real CID from Wandboard int mmc */ 210 mmcio->cmd.resp[0] = 0x1b534d30; 211 mmcio->cmd.resp[1] = 0x30303030; 212 mmcio->cmd.resp[2] = 0x10842806; 213 mmcio->cmd.resp[3] = 0x5700e900; 214 break; 215 case MMC_SEND_CSD: 216 /* Note: this is a real CSD from Wandboard int mmc */ 217 mmcio->cmd.resp[0] = 0x400e0032; 218 mmcio->cmd.resp[1] = 0x5b590000; 219 mmcio->cmd.resp[2] = 0x751f7f80; 220 mmcio->cmd.resp[3] = 0x0a404000; 221 break; 222 case MMC_READ_SINGLE_BLOCK: 223 case MMC_READ_MULTIPLE_BLOCK: 224 strcpy(mmcio->cmd.data->data, "WTF?!"); 225 break; 226 default: 227 device_printf(sc->dev, "mmcnull_intr_sd: unknown command\n"); 228 mmcio->cmd.error = 1; 229 } 230 ccb->ccb_h.status = CAM_REQ_CMP; 231 232 sc->cur_ccb = NULL; 233 xpt_done(ccb); 234 } 235 236 static void 237 mmcnull_intr_sdio_newintr(void *xsc) { 238 struct mmcnull_softc *sc; 239 struct cam_path *dpath; 240 241 sc = (struct mmcnull_softc *) xsc; 242 mtx_assert(&sc->sc_mtx, MA_OWNED); 243 device_printf(sc->dev, "mmcnull_intr_sdio_newintr()\n"); 244 245 /* Our path */ 246 if (xpt_create_path(&dpath, NULL, cam_sim_path(sc->sim), 0, 0) != CAM_REQ_CMP) { 247 device_printf(sc->dev, "mmcnull_intr_sdio_newintr(): cannot create path\n"); 248 return; 249 } 250 xpt_async(AC_UNIT_ATTENTION, dpath, NULL); 251 xpt_free_path(dpath); 252 } 253 254 static void 255 mmcnull_intr_sdio(void *xsc) { 256 struct mmcnull_softc *sc; 257 union ccb *ccb; 258 struct ccb_mmcio *mmcio; 259 260 sc = (struct mmcnull_softc *) xsc; 261 mtx_assert(&sc->sc_mtx, MA_OWNED); 262 263 ccb = sc->cur_ccb; 264 mmcio = &ccb->mmcio; 265 device_printf(sc->dev, "mmcnull_intr: MMC command = %d\n", 266 mmcio->cmd.opcode); 267 268 switch (mmcio->cmd.opcode) { 269 case MMC_GO_IDLE_STATE: 270 device_printf(sc->dev, "Reset device\n"); 271 break; 272 case SD_SEND_IF_COND: 273 mmcio->cmd.resp[0] = 0x1AA; // To match mmc_xpt expectations :-) 274 break; 275 case MMC_APP_CMD: 276 mmcio->cmd.resp[0] = R1_APP_CMD; 277 break; 278 case IO_SEND_OP_COND: 279 mmcio->cmd.resp[0] = 0x12345678; 280 mmcio->cmd.resp[0] |= ~ R4_IO_MEM_PRESENT; 281 break; 282 case SD_SEND_RELATIVE_ADDR: 283 case MMC_SELECT_CARD: 284 mmcio->cmd.resp[0] = 0x1 << 16; 285 break; 286 case ACMD_SD_SEND_OP_COND: 287 /* TODO: steal valid OCR from somewhere :-) */ 288 mmcio->cmd.resp[0] = 0x123; 289 mmcio->cmd.resp[0] |= MMC_OCR_CARD_BUSY; 290 break; 291 case MMC_ALL_SEND_CID: 292 mmcio->cmd.resp[0] = 0x1234; 293 mmcio->cmd.resp[1] = 0x5678; 294 mmcio->cmd.resp[2] = 0x9ABC; 295 mmcio->cmd.resp[3] = 0xDEF0; 296 break; 297 case MMC_READ_SINGLE_BLOCK: 298 case MMC_READ_MULTIPLE_BLOCK: 299 strcpy(mmcio->cmd.data->data, "WTF?!"); 300 break; 301 case SD_IO_RW_DIRECT: 302 device_printf(sc->dev, "Scheduling interrupt generation...\n"); 303 callout_reset(&sc->tick, hz / 10, mmcnull_intr_sdio_newintr, sc); 304 break; 305 default: 306 device_printf(sc->dev, "mmcnull_intr_sdio: unknown command\n"); 307 } 308 ccb->ccb_h.status = CAM_REQ_CMP; 309 310 sc->cur_ccb = NULL; 311 xpt_done(ccb); 312 } 313 314 /* 315 * This is a MMC IO handler 316 * It extracts MMC command from CCB and sends it 317 * to the h/w 318 */ 319 static void 320 mmcnull_handle_mmcio(struct cam_sim *sim, union ccb *ccb) 321 { 322 struct mmcnull_softc *sc; 323 struct ccb_mmcio *mmcio; 324 325 sc = cam_sim_softc(sim); 326 mmcio = &ccb->mmcio; 327 ccb->ccb_h.status = CAM_REQ_INPROG; 328 sc->cur_ccb = ccb; 329 330 /* Real h/w will wait for the interrupt */ 331 if (is_sdio_mode) 332 callout_reset(&sc->tick, hz / 10, mmcnull_intr_sdio, sc); 333 else 334 callout_reset(&sc->tick, hz / 10, mmcnull_intr_sd, sc); 335 } 336 337 static void 338 mmcnull_action_sd(struct cam_sim *sim, union ccb *ccb) 339 { 340 struct mmcnull_softc *sc; 341 342 sc = cam_sim_softc(sim); 343 if (sc == NULL) { 344 ccb->ccb_h.status = CAM_SEL_TIMEOUT; 345 xpt_done(ccb); 346 return; 347 } 348 349 mtx_assert(&sc->sc_mtx, MA_OWNED); 350 351 device_printf(sc->dev, "action: func_code %0x\n", ccb->ccb_h.func_code); 352 353 switch (ccb->ccb_h.func_code) { 354 case XPT_PATH_INQ: 355 { 356 struct ccb_pathinq *cpi; 357 358 cpi = &ccb->cpi; 359 cpi->version_num = 1; 360 cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE | PI_WIDE_16; 361 cpi->target_sprt = 0; 362 cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN; 363 cpi->hba_eng_cnt = 0; 364 cpi->max_target = 0; 365 cpi->max_lun = 0; 366 cpi->initiator_id = 1; 367 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 368 strncpy(cpi->hba_vid, "FreeBSD Foundation", HBA_IDLEN); 369 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 370 cpi->unit_number = cam_sim_unit(sim); 371 cpi->bus_id = cam_sim_bus(sim); 372 cpi->base_transfer_speed = 100; /* XXX WTF? */ 373 cpi->protocol = PROTO_MMCSD; 374 cpi->protocol_version = SCSI_REV_0; 375 cpi->transport = XPORT_MMCSD; 376 cpi->transport_version = 0; 377 378 cpi->ccb_h.status = CAM_REQ_CMP; 379 break; 380 } 381 case XPT_GET_TRAN_SETTINGS: 382 { 383 struct ccb_trans_settings *cts = &ccb->cts; 384 struct ccb_trans_settings_mmc *mcts; 385 mcts = &ccb->cts.proto_specific.mmc; 386 387 device_printf(sc->dev, "Got XPT_GET_TRAN_SETTINGS\n"); 388 389 cts->protocol = PROTO_MMCSD; 390 cts->protocol_version = 0; 391 cts->transport = XPORT_MMCSD; 392 cts->transport_version = 0; 393 cts->xport_specific.valid = 0; 394 mcts->host_f_max = 12000000; 395 mcts->host_f_min = 200000; 396 mcts->host_ocr = 1; /* Fix this */ 397 ccb->ccb_h.status = CAM_REQ_CMP; 398 break; 399 } 400 case XPT_SET_TRAN_SETTINGS: 401 device_printf(sc->dev, "Got XPT_SET_TRAN_SETTINGS, should update IOS...\n"); 402 ccb->ccb_h.status = CAM_REQ_CMP; 403 break; 404 case XPT_RESET_BUS: 405 device_printf(sc->dev, "Got XPT_RESET_BUS, ACK it...\n"); 406 ccb->ccb_h.status = CAM_REQ_CMP; 407 break; 408 case XPT_MMC_IO: 409 /* 410 * Here is the HW-dependent part of 411 * sending the command to the underlying h/w 412 * At some point in the future an interrupt comes. 413 * Then the request will be marked as completed. 414 */ 415 device_printf(sc->dev, "Got XPT_MMC_IO\n"); 416 mmcnull_handle_mmcio(sim, ccb); 417 return; 418 break; 419 case XPT_RESET_DEV: 420 /* This is sent by `camcontrol reset`*/ 421 device_printf(sc->dev, "Got XPT_RESET_DEV\n"); 422 ccb->ccb_h.status = CAM_REQ_CMP; 423 break; 424 default: 425 device_printf(sc->dev, "Func code %d is unknown\n", ccb->ccb_h.func_code); 426 ccb->ccb_h.status = CAM_REQ_INVALID; 427 break; 428 } 429 xpt_done(ccb); 430 return; 431 } 432 433 static void 434 mmcnull_action_sdio(struct cam_sim *sim, union ccb *ccb) { 435 mmcnull_action_sd(sim, ccb); 436 } 437 438 static void 439 mmcnull_poll(struct cam_sim *sim) 440 { 441 return; 442 } 443 444 445 static device_method_t mmcnull_methods[] = { 446 /* Device interface */ 447 DEVMETHOD(device_identify, mmcnull_identify), 448 DEVMETHOD(device_probe, mmcnull_probe), 449 DEVMETHOD(device_attach, mmcnull_attach), 450 DEVMETHOD(device_detach, mmcnull_detach), 451 DEVMETHOD_END 452 }; 453 454 static driver_t mmcnull_driver = { 455 "mmcnull", mmcnull_methods, sizeof(struct mmcnull_softc) 456 }; 457 458 DRIVER_MODULE(mmcnull, isa, mmcnull_driver, 0, 0); 459