1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (C) 2010 Nathan Whitehorn 5 * Copyright (C) 2011 glevand <geoffrey.levand@mail.ru> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer, 13 * without modification, immediately at the beginning of the file. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 #include <sys/param.h> 32 #include <sys/module.h> 33 #include <sys/systm.h> 34 #include <sys/kernel.h> 35 #include <sys/ata.h> 36 #include <sys/bus.h> 37 #include <sys/conf.h> 38 #include <sys/kthread.h> 39 #include <sys/lock.h> 40 #include <sys/malloc.h> 41 #include <sys/mutex.h> 42 43 #include <vm/vm.h> 44 #include <vm/pmap.h> 45 46 #include <machine/pio.h> 47 #include <machine/bus.h> 48 #include <machine/platform.h> 49 #include <machine/resource.h> 50 #include <sys/bus.h> 51 #include <sys/rman.h> 52 53 #include <cam/cam.h> 54 #include <cam/cam_ccb.h> 55 #include <cam/cam_sim.h> 56 #include <cam/cam_xpt_sim.h> 57 #include <cam/cam_debug.h> 58 #include <cam/scsi/scsi_all.h> 59 60 #include "ps3bus.h" 61 #include "ps3-hvcall.h" 62 63 #define PS3CDROM_LOCK_INIT(_sc) \ 64 mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), "ps3cdrom", \ 65 MTX_DEF) 66 #define PS3CDROM_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); 67 #define PS3CDROM_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 68 #define PS3CDROM_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 69 #define PS3CDROM_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); 70 #define PS3CDROM_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); 71 72 #define PS3CDROM_MAX_XFERS 3 73 74 #define LV1_STORAGE_SEND_ATAPI_COMMAND 0x01 75 76 struct ps3cdrom_softc; 77 78 struct ps3cdrom_xfer { 79 TAILQ_ENTRY(ps3cdrom_xfer) x_queue; 80 struct ps3cdrom_softc *x_sc; 81 union ccb *x_ccb; 82 bus_dmamap_t x_dmamap; 83 uint64_t x_tag; 84 }; 85 86 TAILQ_HEAD(ps3cdrom_xferq, ps3cdrom_xfer); 87 88 struct ps3cdrom_softc { 89 device_t sc_dev; 90 91 struct mtx sc_mtx; 92 93 uint64_t sc_blksize; 94 uint64_t sc_nblocks; 95 96 int sc_irqid; 97 struct resource *sc_irq; 98 void *sc_irqctx; 99 100 bus_dma_tag_t sc_dmatag; 101 102 struct cam_sim *sc_sim; 103 struct cam_path *sc_path; 104 105 struct ps3cdrom_xfer sc_xfer[PS3CDROM_MAX_XFERS]; 106 struct ps3cdrom_xferq sc_active_xferq; 107 struct ps3cdrom_xferq sc_free_xferq; 108 }; 109 110 enum lv1_ata_proto { 111 NON_DATA_PROTO = 0x00, 112 PIO_DATA_IN_PROTO = 0x01, 113 PIO_DATA_OUT_PROTO = 0x02, 114 DMA_PROTO = 0x03 115 }; 116 117 enum lv1_ata_in_out { 118 DIR_WRITE = 0x00, 119 DIR_READ = 0x01 120 }; 121 122 struct lv1_atapi_cmd { 123 uint8_t pkt[32]; 124 uint32_t pktlen; 125 uint32_t nblocks; 126 uint32_t blksize; 127 uint32_t proto; /* enum lv1_ata_proto */ 128 uint32_t in_out; /* enum lv1_ata_in_out */ 129 uint64_t buf; 130 uint32_t arglen; 131 }; 132 133 static void ps3cdrom_action(struct cam_sim *sim, union ccb *ccb); 134 static void ps3cdrom_poll(struct cam_sim *sim); 135 static void ps3cdrom_async(void *callback_arg, u_int32_t code, 136 struct cam_path* path, void *arg); 137 138 static void ps3cdrom_intr(void *arg); 139 140 static void ps3cdrom_transfer(void *arg, bus_dma_segment_t *segs, int nsegs, 141 int error); 142 143 static int ps3cdrom_decode_lv1_status(uint64_t status, 144 u_int8_t *sense_key, u_int8_t *asc, u_int8_t *ascq); 145 146 static int 147 ps3cdrom_probe(device_t dev) 148 { 149 if (ps3bus_get_bustype(dev) != PS3_BUSTYPE_STORAGE || 150 ps3bus_get_devtype(dev) != PS3_DEVTYPE_CDROM) 151 return (ENXIO); 152 153 device_set_desc(dev, "Playstation 3 CDROM"); 154 155 return (BUS_PROBE_SPECIFIC); 156 } 157 158 static int 159 ps3cdrom_attach(device_t dev) 160 { 161 struct ps3cdrom_softc *sc = device_get_softc(dev); 162 struct cam_devq *devq; 163 struct ps3cdrom_xfer *xp; 164 struct ccb_setasync csa; 165 int i, err; 166 167 sc->sc_dev = dev; 168 169 PS3CDROM_LOCK_INIT(sc); 170 171 /* Setup interrupt handler */ 172 173 sc->sc_irqid = 0; 174 sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irqid, 175 RF_ACTIVE); 176 if (!sc->sc_irq) { 177 device_printf(dev, "Could not allocate IRQ\n"); 178 err = ENXIO; 179 goto fail_destroy_lock; 180 } 181 182 err = bus_setup_intr(dev, sc->sc_irq, 183 INTR_TYPE_CAM | INTR_MPSAFE | INTR_ENTROPY, 184 NULL, ps3cdrom_intr, sc, &sc->sc_irqctx); 185 if (err) { 186 device_printf(dev, "Could not setup IRQ\n"); 187 err = ENXIO; 188 goto fail_release_intr; 189 } 190 191 /* Setup DMA */ 192 193 err = bus_dma_tag_create(bus_get_dma_tag(dev), 4096, 0, 194 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 195 BUS_SPACE_UNRESTRICTED, 1, PAGE_SIZE, 0, 196 busdma_lock_mutex, &sc->sc_mtx, &sc->sc_dmatag); 197 if (err) { 198 device_printf(dev, "Could not create DMA tag\n"); 199 err = ENXIO; 200 goto fail_teardown_intr; 201 } 202 203 /* Setup transfer queues */ 204 205 TAILQ_INIT(&sc->sc_active_xferq); 206 TAILQ_INIT(&sc->sc_free_xferq); 207 208 for (i = 0; i < PS3CDROM_MAX_XFERS; i++) { 209 xp = &sc->sc_xfer[i]; 210 xp->x_sc = sc; 211 212 err = bus_dmamap_create(sc->sc_dmatag, BUS_DMA_COHERENT, 213 &xp->x_dmamap); 214 if (err) { 215 device_printf(dev, "Could not create DMA map (%d)\n", 216 err); 217 goto fail_destroy_dmamap; 218 } 219 220 TAILQ_INSERT_TAIL(&sc->sc_free_xferq, xp, x_queue); 221 } 222 223 /* Setup CAM */ 224 225 devq = cam_simq_alloc(PS3CDROM_MAX_XFERS - 1); 226 if (!devq) { 227 device_printf(dev, "Could not allocate SIM queue\n"); 228 err = ENOMEM; 229 goto fail_destroy_dmatag; 230 } 231 232 sc->sc_sim = cam_sim_alloc(ps3cdrom_action, ps3cdrom_poll, "ps3cdrom", 233 sc, device_get_unit(dev), &sc->sc_mtx, PS3CDROM_MAX_XFERS - 1, 0, 234 devq); 235 if (!sc->sc_sim) { 236 device_printf(dev, "Could not allocate SIM\n"); 237 cam_simq_free(devq); 238 err = ENOMEM; 239 goto fail_destroy_dmatag; 240 } 241 242 /* Setup XPT */ 243 244 PS3CDROM_LOCK(sc); 245 246 err = xpt_bus_register(sc->sc_sim, dev, 0); 247 if (err != CAM_SUCCESS) { 248 device_printf(dev, "Could not register XPT bus\n"); 249 err = ENXIO; 250 PS3CDROM_UNLOCK(sc); 251 goto fail_free_sim; 252 } 253 254 err = xpt_create_path(&sc->sc_path, NULL, cam_sim_path(sc->sc_sim), 255 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); 256 if (err != CAM_REQ_CMP) { 257 device_printf(dev, "Could not create XPT path\n"); 258 err = ENOMEM; 259 PS3CDROM_UNLOCK(sc); 260 goto fail_unregister_xpt_bus; 261 } 262 263 memset(&csa, 0, sizeof(csa)); 264 xpt_setup_ccb(&csa.ccb_h, sc->sc_path, 5); 265 csa.ccb_h.func_code = XPT_SASYNC_CB; 266 csa.event_enable = AC_LOST_DEVICE; 267 csa.callback = ps3cdrom_async; 268 csa.callback_arg = sc->sc_sim; 269 xpt_action((union ccb *) &csa); 270 271 CAM_DEBUG(sc->sc_path, CAM_DEBUG_TRACE, 272 ("registered SIM for ps3cdrom%d\n", device_get_unit(dev))); 273 274 PS3CDROM_UNLOCK(sc); 275 276 return (BUS_PROBE_SPECIFIC); 277 278 fail_unregister_xpt_bus: 279 280 xpt_bus_deregister(cam_sim_path(sc->sc_sim)); 281 282 fail_free_sim: 283 284 cam_sim_free(sc->sc_sim, TRUE); 285 286 fail_destroy_dmamap: 287 288 while ((xp = TAILQ_FIRST(&sc->sc_free_xferq))) { 289 TAILQ_REMOVE(&sc->sc_free_xferq, xp, x_queue); 290 bus_dmamap_destroy(sc->sc_dmatag, xp->x_dmamap); 291 } 292 293 fail_destroy_dmatag: 294 295 bus_dma_tag_destroy(sc->sc_dmatag); 296 297 fail_teardown_intr: 298 299 bus_teardown_intr(dev, sc->sc_irq, sc->sc_irqctx); 300 301 fail_release_intr: 302 303 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irqid, sc->sc_irq); 304 305 fail_destroy_lock: 306 307 PS3CDROM_LOCK_DESTROY(sc); 308 309 return (err); 310 } 311 312 static int 313 ps3cdrom_detach(device_t dev) 314 { 315 struct ps3cdrom_softc *sc = device_get_softc(dev); 316 int i; 317 318 xpt_async(AC_LOST_DEVICE, sc->sc_path, NULL); 319 xpt_free_path(sc->sc_path); 320 xpt_bus_deregister(cam_sim_path(sc->sc_sim)); 321 cam_sim_free(sc->sc_sim, TRUE); 322 323 for (i = 0; i < PS3CDROM_MAX_XFERS; i++) 324 bus_dmamap_destroy(sc->sc_dmatag, sc->sc_xfer[i].x_dmamap); 325 326 bus_dma_tag_destroy(sc->sc_dmatag); 327 328 bus_teardown_intr(dev, sc->sc_irq, sc->sc_irqctx); 329 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irqid, sc->sc_irq); 330 331 PS3CDROM_LOCK_DESTROY(sc); 332 333 return (0); 334 } 335 336 static void 337 ps3cdrom_action(struct cam_sim *sim, union ccb *ccb) 338 { 339 struct ps3cdrom_softc *sc = (struct ps3cdrom_softc *)cam_sim_softc(sim); 340 device_t dev = sc->sc_dev; 341 struct ps3cdrom_xfer *xp; 342 int err; 343 344 PS3CDROM_ASSERT_LOCKED(sc); 345 346 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 347 ("function code 0x%02x\n", ccb->ccb_h.func_code)); 348 349 switch (ccb->ccb_h.func_code) { 350 case XPT_SCSI_IO: 351 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) 352 break; 353 354 if(ccb->ccb_h.target_id > 0) { 355 ccb->ccb_h.status = CAM_TID_INVALID; 356 break; 357 } 358 359 if(ccb->ccb_h.target_lun > 0) { 360 ccb->ccb_h.status = CAM_LUN_INVALID; 361 break; 362 } 363 364 xp = TAILQ_FIRST(&sc->sc_free_xferq); 365 366 KASSERT(xp != NULL, ("no free transfers")); 367 368 xp->x_ccb = ccb; 369 370 TAILQ_REMOVE(&sc->sc_free_xferq, xp, x_queue); 371 372 err = bus_dmamap_load_ccb(sc->sc_dmatag, xp->x_dmamap, 373 ccb, ps3cdrom_transfer, xp, 0); 374 if (err && err != EINPROGRESS) { 375 device_printf(dev, "Could not load DMA map (%d)\n", 376 err); 377 378 xp->x_ccb = NULL; 379 TAILQ_INSERT_TAIL(&sc->sc_free_xferq, xp, x_queue); 380 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; 381 break; 382 } 383 return; 384 case XPT_SET_TRAN_SETTINGS: 385 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 386 break; 387 case XPT_GET_TRAN_SETTINGS: 388 { 389 struct ccb_trans_settings *cts = &ccb->cts; 390 391 cts->protocol = PROTO_SCSI; 392 cts->protocol_version = SCSI_REV_2; 393 cts->transport = XPORT_SPI; 394 cts->transport_version = 2; 395 cts->proto_specific.valid = 0; 396 cts->xport_specific.valid = 0; 397 ccb->ccb_h.status = CAM_REQ_CMP; 398 break; 399 } 400 case XPT_RESET_BUS: 401 case XPT_RESET_DEV: 402 ccb->ccb_h.status = CAM_REQ_CMP; 403 break; 404 case XPT_CALC_GEOMETRY: 405 cam_calc_geometry(&ccb->ccg, 1); 406 break; 407 case XPT_PATH_INQ: 408 { 409 struct ccb_pathinq *cpi = &ccb->cpi; 410 411 cpi->version_num = 1; 412 cpi->hba_inquiry = 0; 413 cpi->target_sprt = 0; 414 cpi->hba_inquiry = PI_SDTR_ABLE; 415 cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN | PIM_NO_6_BYTE; 416 cpi->hba_eng_cnt = 0; 417 bzero(cpi->vuhba_flags, sizeof(cpi->vuhba_flags)); 418 cpi->max_target = 0; 419 cpi->max_lun = 0; 420 cpi->initiator_id = 7; 421 cpi->bus_id = cam_sim_bus(sim); 422 cpi->unit_number = cam_sim_unit(sim); 423 cpi->base_transfer_speed = 150000; 424 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 425 strlcpy(cpi->hba_vid, "Sony", HBA_IDLEN); 426 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 427 cpi->transport = XPORT_SPI; 428 cpi->transport_version = 2; 429 cpi->protocol = PROTO_SCSI; 430 cpi->protocol_version = SCSI_REV_2; 431 cpi->maxio = PAGE_SIZE; 432 cpi->ccb_h.status = CAM_REQ_CMP; 433 break; 434 } 435 default: 436 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 437 ("unsupported function code 0x%02x\n", 438 ccb->ccb_h.func_code)); 439 ccb->ccb_h.status = CAM_REQ_INVALID; 440 break; 441 } 442 443 xpt_done(ccb); 444 } 445 446 static void 447 ps3cdrom_poll(struct cam_sim *sim) 448 { 449 ps3cdrom_intr(cam_sim_softc(sim)); 450 } 451 452 static void 453 ps3cdrom_async(void *callback_arg, u_int32_t code, 454 struct cam_path* path, void *arg) 455 { 456 switch (code) { 457 case AC_LOST_DEVICE: 458 xpt_print_path(path); 459 break; 460 default: 461 break; 462 } 463 } 464 465 static void 466 ps3cdrom_intr(void *arg) 467 { 468 struct ps3cdrom_softc *sc = (struct ps3cdrom_softc *) arg; 469 device_t dev = sc->sc_dev; 470 uint64_t devid = ps3bus_get_device(dev); 471 struct ps3cdrom_xfer *xp; 472 union ccb *ccb; 473 u_int8_t *cdb, sense_key, asc, ascq; 474 uint64_t tag, status; 475 476 if (lv1_storage_get_async_status(devid, &tag, &status) != 0) 477 return; 478 479 PS3CDROM_LOCK(sc); 480 481 /* Find transfer with the returned tag */ 482 483 TAILQ_FOREACH(xp, &sc->sc_active_xferq, x_queue) { 484 if (xp->x_tag == tag) 485 break; 486 } 487 488 if (xp) { 489 ccb = xp->x_ccb; 490 cdb = (ccb->ccb_h.flags & CAM_CDB_POINTER) ? 491 ccb->csio.cdb_io.cdb_ptr : 492 ccb->csio.cdb_io.cdb_bytes; 493 494 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 495 ("ATAPI command 0x%02x tag 0x%016lx completed (0x%016lx)\n", 496 cdb[0], tag, status)); 497 498 if (!status) { 499 ccb->csio.scsi_status = SCSI_STATUS_OK; 500 ccb->csio.resid = 0; 501 ccb->ccb_h.status = CAM_REQ_CMP; 502 } else { 503 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; 504 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; 505 506 if (!ps3cdrom_decode_lv1_status(status, &sense_key, 507 &asc, &ascq)) { 508 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 509 ("sense key 0x%02x asc 0x%02x ascq 0x%02x\n", 510 sense_key, asc, ascq)); 511 512 scsi_set_sense_data(&ccb->csio.sense_data, 513 /*sense_format*/ SSD_TYPE_NONE, 514 /*current_error*/ 1, 515 sense_key, 516 asc, 517 ascq, 518 SSD_ELEM_NONE); 519 ccb->csio.sense_len = SSD_FULL_SIZE; 520 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR | 521 CAM_AUTOSNS_VALID; 522 } 523 524 if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) 525 ccb->csio.resid = ccb->csio.dxfer_len; 526 } 527 528 if (ccb->ccb_h.flags & CAM_DIR_IN) 529 bus_dmamap_sync(sc->sc_dmatag, xp->x_dmamap, 530 BUS_DMASYNC_POSTREAD); 531 532 bus_dmamap_unload(sc->sc_dmatag, xp->x_dmamap); 533 534 xp->x_ccb = NULL; 535 TAILQ_REMOVE(&sc->sc_active_xferq, xp, x_queue); 536 TAILQ_INSERT_TAIL(&sc->sc_free_xferq, xp, x_queue); 537 538 xpt_done(ccb); 539 } else { 540 device_printf(dev, 541 "Could not find transfer with tag 0x%016lx\n", tag); 542 } 543 544 PS3CDROM_UNLOCK(sc); 545 } 546 547 static void 548 ps3cdrom_transfer(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 549 { 550 struct ps3cdrom_xfer *xp = (struct ps3cdrom_xfer *) arg; 551 struct ps3cdrom_softc *sc = xp->x_sc; 552 device_t dev = sc->sc_dev; 553 uint64_t devid = ps3bus_get_device(dev); 554 union ccb *ccb = xp->x_ccb; 555 u_int8_t *cdb; 556 uint64_t start_sector, block_count; 557 int err; 558 559 KASSERT(nsegs == 1 || nsegs == 0, 560 ("ps3cdrom_transfer: invalid number of DMA segments %d", nsegs)); 561 KASSERT(error == 0, ("ps3cdrom_transfer: DMA error %d", error)); 562 563 PS3CDROM_ASSERT_LOCKED(sc); 564 565 if (error) { 566 device_printf(dev, "Could not load DMA map (%d)\n", error); 567 568 xp->x_ccb = NULL; 569 TAILQ_INSERT_TAIL(&sc->sc_free_xferq, xp, x_queue); 570 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; 571 xpt_done(ccb); 572 return; 573 } 574 575 cdb = (ccb->ccb_h.flags & CAM_CDB_POINTER) ? 576 ccb->csio.cdb_io.cdb_ptr : 577 ccb->csio.cdb_io.cdb_bytes; 578 579 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 580 ("ATAPI command 0x%02x cdb_len %d dxfer_len %d\n ", cdb[0], 581 ccb->csio.cdb_len, ccb->csio.dxfer_len)); 582 583 switch (cdb[0]) { 584 case READ_10: 585 KASSERT(nsegs == 1, ("ps3cdrom_transfer: no data to read")); 586 start_sector = (cdb[2] << 24) | (cdb[3] << 16) | 587 (cdb[4] << 8) | cdb[5]; 588 block_count = (cdb[7] << 8) | cdb[8]; 589 590 err = lv1_storage_read(devid, 0 /* region id */, 591 start_sector, block_count, 0 /* flags */, segs[0].ds_addr, 592 &xp->x_tag); 593 bus_dmamap_sync(sc->sc_dmatag, xp->x_dmamap, 594 BUS_DMASYNC_POSTREAD); 595 break; 596 case WRITE_10: 597 KASSERT(nsegs == 1, ("ps3cdrom_transfer: no data to write")); 598 start_sector = (cdb[2] << 24) | (cdb[3] << 16) | 599 (cdb[4] << 8) | cdb[5]; 600 block_count = (cdb[7] << 8) | cdb[8]; 601 602 bus_dmamap_sync(sc->sc_dmatag, xp->x_dmamap, 603 BUS_DMASYNC_PREWRITE); 604 err = lv1_storage_write(devid, 0 /* region id */, 605 start_sector, block_count, 0 /* flags */, 606 segs[0].ds_addr, &xp->x_tag); 607 break; 608 default: 609 { 610 struct lv1_atapi_cmd atapi_cmd; 611 612 bzero(&atapi_cmd, sizeof(atapi_cmd)); 613 atapi_cmd.pktlen = 12; 614 bcopy(cdb, atapi_cmd.pkt, ccb->csio.cdb_len); 615 616 if (ccb->ccb_h.flags & CAM_DIR_IN) { 617 atapi_cmd.in_out = DIR_READ; 618 atapi_cmd.proto = (ccb->csio.dxfer_len >= 2048) ? 619 DMA_PROTO : PIO_DATA_IN_PROTO; 620 } else if (ccb->ccb_h.flags & CAM_DIR_OUT) { 621 atapi_cmd.in_out = DIR_WRITE; 622 atapi_cmd.proto = (ccb->csio.dxfer_len >= 2048) ? 623 DMA_PROTO : PIO_DATA_OUT_PROTO; 624 } else { 625 atapi_cmd.proto = NON_DATA_PROTO; 626 } 627 628 atapi_cmd.nblocks = atapi_cmd.arglen = 629 (nsegs == 0) ? 0 : segs[0].ds_len; 630 atapi_cmd.blksize = 1; 631 atapi_cmd.buf = (nsegs == 0) ? 0 : segs[0].ds_addr; 632 633 if (ccb->ccb_h.flags & CAM_DIR_OUT) 634 bus_dmamap_sync(sc->sc_dmatag, xp->x_dmamap, 635 BUS_DMASYNC_PREWRITE); 636 637 err = lv1_storage_send_device_command(devid, 638 LV1_STORAGE_SEND_ATAPI_COMMAND, vtophys(&atapi_cmd), 639 sizeof(atapi_cmd), atapi_cmd.buf, atapi_cmd.arglen, 640 &xp->x_tag); 641 642 break; 643 } 644 } 645 646 if (err) { 647 device_printf(dev, "ATAPI command 0x%02x failed (%d)\n", 648 cdb[0], err); 649 650 bus_dmamap_unload(sc->sc_dmatag, xp->x_dmamap); 651 652 xp->x_ccb = NULL; 653 TAILQ_INSERT_TAIL(&sc->sc_free_xferq, xp, x_queue); 654 655 bzero(&ccb->csio.sense_data, sizeof(ccb->csio.sense_data)); 656 /* Invalid field in parameter list */ 657 scsi_set_sense_data(&ccb->csio.sense_data, 658 /*sense_format*/ SSD_TYPE_NONE, 659 /*current_error*/ 1, 660 /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 661 /*asc*/ 0x26, 662 /*ascq*/ 0x00, 663 SSD_ELEM_NONE); 664 665 ccb->csio.sense_len = SSD_FULL_SIZE; 666 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; 667 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID; 668 xpt_done(ccb); 669 } else { 670 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 671 ("ATAPI command 0x%02x tag 0x%016lx submitted\n ", cdb[0], 672 xp->x_tag)); 673 674 TAILQ_INSERT_TAIL(&sc->sc_active_xferq, xp, x_queue); 675 ccb->ccb_h.status |= CAM_SIM_QUEUED; 676 } 677 } 678 679 static int 680 ps3cdrom_decode_lv1_status(uint64_t status, u_int8_t *sense_key, u_int8_t *asc, 681 u_int8_t *ascq) 682 { 683 if (((status >> 24) & 0xff) != SCSI_STATUS_CHECK_COND) 684 return -1; 685 686 *sense_key = (status >> 16) & 0xff; 687 *asc = (status >> 8) & 0xff; 688 *ascq = status & 0xff; 689 690 return (0); 691 } 692 693 static device_method_t ps3cdrom_methods[] = { 694 DEVMETHOD(device_probe, ps3cdrom_probe), 695 DEVMETHOD(device_attach, ps3cdrom_attach), 696 DEVMETHOD(device_detach, ps3cdrom_detach), 697 {0, 0}, 698 }; 699 700 static driver_t ps3cdrom_driver = { 701 "ps3cdrom", 702 ps3cdrom_methods, 703 sizeof(struct ps3cdrom_softc), 704 }; 705 706 DRIVER_MODULE(ps3cdrom, ps3bus, ps3cdrom_driver, 0, 0); 707 MODULE_DEPEND(ps3cdrom, cam, 1, 1, 1); 708