2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (C) 2010 Nathan Whitehorn
5 * Copyright (C) 2011 glevand <geoffrey.levand@mail.ru>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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.
30 #include <sys/param.h>
31 #include <sys/module.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
37 #include <sys/kthread.h>
39 #include <sys/malloc.h>
40 #include <sys/mutex.h>
45 #include <machine/pio.h>
46 #include <machine/bus.h>
47 #include <machine/platform.h>
48 #include <machine/resource.h>
53 #include <cam/cam_ccb.h>
54 #include <cam/cam_sim.h>
55 #include <cam/cam_xpt_sim.h>
56 #include <cam/cam_debug.h>
57 #include <cam/scsi/scsi_all.h>
60 #include "ps3-hvcall.h"
62 #define PS3CDROM_LOCK_INIT(_sc) \
63 mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), "ps3cdrom", \
65 #define PS3CDROM_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx);
66 #define PS3CDROM_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
67 #define PS3CDROM_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
68 #define PS3CDROM_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED);
69 #define PS3CDROM_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED);
71 #define PS3CDROM_MAX_XFERS 3
73 #define LV1_STORAGE_SEND_ATAPI_COMMAND 0x01
75 struct ps3cdrom_softc
;
77 struct ps3cdrom_xfer
{
78 TAILQ_ENTRY(ps3cdrom_xfer
) x_queue
;
79 struct ps3cdrom_softc
*x_sc
;
81 bus_dmamap_t x_dmamap
;
85 TAILQ_HEAD(ps3cdrom_xferq
, ps3cdrom_xfer
);
87 struct ps3cdrom_softc
{
96 struct resource
*sc_irq
;
99 bus_dma_tag_t sc_dmatag
;
101 struct cam_sim
*sc_sim
;
102 struct cam_path
*sc_path
;
104 struct ps3cdrom_xfer sc_xfer
[PS3CDROM_MAX_XFERS
];
105 struct ps3cdrom_xferq sc_active_xferq
;
106 struct ps3cdrom_xferq sc_free_xferq
;
110 NON_DATA_PROTO
= 0x00,
111 PIO_DATA_IN_PROTO
= 0x01,
112 PIO_DATA_OUT_PROTO
= 0x02,
116 enum lv1_ata_in_out
{
121 struct lv1_atapi_cmd
{
126 uint32_t proto
; /* enum lv1_ata_proto */
127 uint32_t in_out
; /* enum lv1_ata_in_out */
132 static void ps3cdrom_action(struct cam_sim
*sim
, union ccb
*ccb
);
133 static void ps3cdrom_poll(struct cam_sim
*sim
);
134 static void ps3cdrom_async(void *callback_arg
, u_int32_t code
,
135 struct cam_path
* path
, void *arg
);
137 static void ps3cdrom_intr(void *arg
);
139 static void ps3cdrom_transfer(void *arg
, bus_dma_segment_t
*segs
, int nsegs
,
142 static int ps3cdrom_decode_lv1_status(uint64_t status
,
143 u_int8_t
*sense_key
, u_int8_t
*asc
, u_int8_t
*ascq
);
146 ps3cdrom_probe(device_t dev
)
148 if (ps3bus_get_bustype(dev
) != PS3_BUSTYPE_STORAGE
||
149 ps3bus_get_devtype(dev
) != PS3_DEVTYPE_CDROM
)
152 device_set_desc(dev
, "Playstation 3 CDROM");
154 return (BUS_PROBE_SPECIFIC
);
158 ps3cdrom_attach(device_t dev
)
160 struct ps3cdrom_softc
*sc
= device_get_softc(dev
);
161 struct cam_devq
*devq
;
162 struct ps3cdrom_xfer
*xp
;
163 struct ccb_setasync csa
;
168 PS3CDROM_LOCK_INIT(sc
);
170 /* Setup interrupt handler */
173 sc
->sc_irq
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
, &sc
->sc_irqid
,
176 device_printf(dev
, "Could not allocate IRQ\n");
178 goto fail_destroy_lock
;
181 err
= bus_setup_intr(dev
, sc
->sc_irq
,
182 INTR_TYPE_CAM
| INTR_MPSAFE
| INTR_ENTROPY
,
183 NULL
, ps3cdrom_intr
, sc
, &sc
->sc_irqctx
);
185 device_printf(dev
, "Could not setup IRQ\n");
187 goto fail_release_intr
;
192 err
= bus_dma_tag_create(bus_get_dma_tag(dev
), 4096, 0,
193 BUS_SPACE_MAXADDR
, BUS_SPACE_MAXADDR
, NULL
, NULL
,
194 BUS_SPACE_UNRESTRICTED
, 1, PAGE_SIZE
, 0,
195 busdma_lock_mutex
, &sc
->sc_mtx
, &sc
->sc_dmatag
);
197 device_printf(dev
, "Could not create DMA tag\n");
199 goto fail_teardown_intr
;
202 /* Setup transfer queues */
204 TAILQ_INIT(&sc
->sc_active_xferq
);
205 TAILQ_INIT(&sc
->sc_free_xferq
);
207 for (i
= 0; i
< PS3CDROM_MAX_XFERS
; i
++) {
208 xp
= &sc
->sc_xfer
[i
];
211 err
= bus_dmamap_create(sc
->sc_dmatag
, BUS_DMA_COHERENT
,
214 device_printf(dev
, "Could not create DMA map (%d)\n",
216 goto fail_destroy_dmamap
;
219 TAILQ_INSERT_TAIL(&sc
->sc_free_xferq
, xp
, x_queue
);
224 devq
= cam_simq_alloc(PS3CDROM_MAX_XFERS
- 1);
226 device_printf(dev
, "Could not allocate SIM queue\n");
228 goto fail_destroy_dmatag
;
231 sc
->sc_sim
= cam_sim_alloc(ps3cdrom_action
, ps3cdrom_poll
, "ps3cdrom",
232 sc
, device_get_unit(dev
), &sc
->sc_mtx
, PS3CDROM_MAX_XFERS
- 1, 0,
235 device_printf(dev
, "Could not allocate SIM\n");
238 goto fail_destroy_dmatag
;
245 err
= xpt_bus_register(sc
->sc_sim
, dev
, 0);
246 if (err
!= CAM_SUCCESS
) {
247 device_printf(dev
, "Could not register XPT bus\n");
253 err
= xpt_create_path(&sc
->sc_path
, NULL
, cam_sim_path(sc
->sc_sim
),
254 CAM_TARGET_WILDCARD
, CAM_LUN_WILDCARD
);
255 if (err
!= CAM_REQ_CMP
) {
256 device_printf(dev
, "Could not create XPT path\n");
259 goto fail_unregister_xpt_bus
;
262 memset(&csa
, 0, sizeof(csa
));
263 xpt_setup_ccb(&csa
.ccb_h
, sc
->sc_path
, 5);
264 csa
.ccb_h
.func_code
= XPT_SASYNC_CB
;
265 csa
.event_enable
= AC_LOST_DEVICE
;
266 csa
.callback
= ps3cdrom_async
;
267 csa
.callback_arg
= sc
->sc_sim
;
268 xpt_action((union ccb
*) &csa
);
270 CAM_DEBUG(sc
->sc_path
, CAM_DEBUG_TRACE
,
271 ("registered SIM for ps3cdrom%d\n", device_get_unit(dev
)));
275 return (BUS_PROBE_SPECIFIC
);
277 fail_unregister_xpt_bus
:
279 xpt_bus_deregister(cam_sim_path(sc
->sc_sim
));
283 cam_sim_free(sc
->sc_sim
, TRUE
);
287 while ((xp
= TAILQ_FIRST(&sc
->sc_free_xferq
))) {
288 TAILQ_REMOVE(&sc
->sc_free_xferq
, xp
, x_queue
);
289 bus_dmamap_destroy(sc
->sc_dmatag
, xp
->x_dmamap
);
294 bus_dma_tag_destroy(sc
->sc_dmatag
);
298 bus_teardown_intr(dev
, sc
->sc_irq
, sc
->sc_irqctx
);
302 bus_release_resource(dev
, SYS_RES_IRQ
, sc
->sc_irqid
, sc
->sc_irq
);
306 PS3CDROM_LOCK_DESTROY(sc
);
312 ps3cdrom_detach(device_t dev
)
314 struct ps3cdrom_softc
*sc
= device_get_softc(dev
);
317 xpt_async(AC_LOST_DEVICE
, sc
->sc_path
, NULL
);
318 xpt_free_path(sc
->sc_path
);
319 xpt_bus_deregister(cam_sim_path(sc
->sc_sim
));
320 cam_sim_free(sc
->sc_sim
, TRUE
);
322 for (i
= 0; i
< PS3CDROM_MAX_XFERS
; i
++)
323 bus_dmamap_destroy(sc
->sc_dmatag
, sc
->sc_xfer
[i
].x_dmamap
);
325 bus_dma_tag_destroy(sc
->sc_dmatag
);
327 bus_teardown_intr(dev
, sc
->sc_irq
, sc
->sc_irqctx
);
328 bus_release_resource(dev
, SYS_RES_IRQ
, sc
->sc_irqid
, sc
->sc_irq
);
330 PS3CDROM_LOCK_DESTROY(sc
);
336 ps3cdrom_action(struct cam_sim
*sim
, union ccb
*ccb
)
338 struct ps3cdrom_softc
*sc
= (struct ps3cdrom_softc
*)cam_sim_softc(sim
);
339 device_t dev
= sc
->sc_dev
;
340 struct ps3cdrom_xfer
*xp
;
343 PS3CDROM_ASSERT_LOCKED(sc
);
345 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
,
346 ("function code 0x%02x\n", ccb
->ccb_h
.func_code
));
348 switch (ccb
->ccb_h
.func_code
) {
350 if ((ccb
->ccb_h
.status
& CAM_STATUS_MASK
) != CAM_REQ_INPROG
)
353 if(ccb
->ccb_h
.target_id
> 0) {
354 ccb
->ccb_h
.status
= CAM_TID_INVALID
;
358 if(ccb
->ccb_h
.target_lun
> 0) {
359 ccb
->ccb_h
.status
= CAM_LUN_INVALID
;
363 xp
= TAILQ_FIRST(&sc
->sc_free_xferq
);
365 KASSERT(xp
!= NULL
, ("no free transfers"));
369 TAILQ_REMOVE(&sc
->sc_free_xferq
, xp
, x_queue
);
371 err
= bus_dmamap_load_ccb(sc
->sc_dmatag
, xp
->x_dmamap
,
372 ccb
, ps3cdrom_transfer
, xp
, 0);
373 if (err
&& err
!= EINPROGRESS
) {
374 device_printf(dev
, "Could not load DMA map (%d)\n",
378 TAILQ_INSERT_TAIL(&sc
->sc_free_xferq
, xp
, x_queue
);
379 ccb
->ccb_h
.status
= CAM_SCSI_STATUS_ERROR
;
383 case XPT_SET_TRAN_SETTINGS
:
384 ccb
->ccb_h
.status
= CAM_FUNC_NOTAVAIL
;
386 case XPT_GET_TRAN_SETTINGS
:
388 struct ccb_trans_settings
*cts
= &ccb
->cts
;
390 cts
->protocol
= PROTO_SCSI
;
391 cts
->protocol_version
= SCSI_REV_2
;
392 cts
->transport
= XPORT_SPI
;
393 cts
->transport_version
= 2;
394 cts
->proto_specific
.valid
= 0;
395 cts
->xport_specific
.valid
= 0;
396 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
401 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
403 case XPT_CALC_GEOMETRY
:
404 cam_calc_geometry(&ccb
->ccg
, 1);
408 struct ccb_pathinq
*cpi
= &ccb
->cpi
;
410 cpi
->version_num
= 1;
411 cpi
->hba_inquiry
= 0;
412 cpi
->target_sprt
= 0;
413 cpi
->hba_inquiry
= PI_SDTR_ABLE
;
414 cpi
->hba_misc
= PIM_NOBUSRESET
| PIM_SEQSCAN
| PIM_NO_6_BYTE
;
415 cpi
->hba_eng_cnt
= 0;
416 bzero(cpi
->vuhba_flags
, sizeof(cpi
->vuhba_flags
));
419 cpi
->initiator_id
= 7;
420 cpi
->bus_id
= cam_sim_bus(sim
);
421 cpi
->unit_number
= cam_sim_unit(sim
);
422 cpi
->base_transfer_speed
= 150000;
423 strlcpy(cpi
->sim_vid
, "FreeBSD", SIM_IDLEN
);
424 strlcpy(cpi
->hba_vid
, "Sony", HBA_IDLEN
);
425 strlcpy(cpi
->dev_name
, cam_sim_name(sim
), DEV_IDLEN
);
426 cpi
->transport
= XPORT_SPI
;
427 cpi
->transport_version
= 2;
428 cpi
->protocol
= PROTO_SCSI
;
429 cpi
->protocol_version
= SCSI_REV_2
;
430 cpi
->maxio
= PAGE_SIZE
;
431 cpi
->ccb_h
.status
= CAM_REQ_CMP
;
435 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
,
436 ("unsupported function code 0x%02x\n",
437 ccb
->ccb_h
.func_code
));
438 ccb
->ccb_h
.status
= CAM_REQ_INVALID
;
446 ps3cdrom_poll(struct cam_sim
*sim
)
448 ps3cdrom_intr(cam_sim_softc(sim
));
452 ps3cdrom_async(void *callback_arg
, u_int32_t code
,
453 struct cam_path
* path
, void *arg
)
457 xpt_print_path(path
);
465 ps3cdrom_intr(void *arg
)
467 struct ps3cdrom_softc
*sc
= (struct ps3cdrom_softc
*) arg
;
468 device_t dev
= sc
->sc_dev
;
469 uint64_t devid
= ps3bus_get_device(dev
);
470 struct ps3cdrom_xfer
*xp
;
472 u_int8_t
*cdb
, sense_key
, asc
, ascq
;
473 uint64_t tag
, status
;
475 if (lv1_storage_get_async_status(devid
, &tag
, &status
) != 0)
480 /* Find transfer with the returned tag */
482 TAILQ_FOREACH(xp
, &sc
->sc_active_xferq
, x_queue
) {
483 if (xp
->x_tag
== tag
)
489 cdb
= (ccb
->ccb_h
.flags
& CAM_CDB_POINTER
) ?
490 ccb
->csio
.cdb_io
.cdb_ptr
:
491 ccb
->csio
.cdb_io
.cdb_bytes
;
493 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
,
494 ("ATAPI command 0x%02x tag 0x%016lx completed (0x%016lx)\n",
495 cdb
[0], tag
, status
));
498 ccb
->csio
.scsi_status
= SCSI_STATUS_OK
;
500 ccb
->ccb_h
.status
= CAM_REQ_CMP
;
502 ccb
->csio
.scsi_status
= SCSI_STATUS_CHECK_COND
;
503 ccb
->ccb_h
.status
= CAM_SCSI_STATUS_ERROR
;
505 if (!ps3cdrom_decode_lv1_status(status
, &sense_key
,
507 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
,
508 ("sense key 0x%02x asc 0x%02x ascq 0x%02x\n",
509 sense_key
, asc
, ascq
));
511 scsi_set_sense_data(&ccb
->csio
.sense_data
,
512 /*sense_format*/ SSD_TYPE_NONE
,
518 ccb
->csio
.sense_len
= SSD_FULL_SIZE
;
519 ccb
->ccb_h
.status
= CAM_SCSI_STATUS_ERROR
|
523 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
)
524 ccb
->csio
.resid
= ccb
->csio
.dxfer_len
;
527 if (ccb
->ccb_h
.flags
& CAM_DIR_IN
)
528 bus_dmamap_sync(sc
->sc_dmatag
, xp
->x_dmamap
,
529 BUS_DMASYNC_POSTREAD
);
531 bus_dmamap_unload(sc
->sc_dmatag
, xp
->x_dmamap
);
534 TAILQ_REMOVE(&sc
->sc_active_xferq
, xp
, x_queue
);
535 TAILQ_INSERT_TAIL(&sc
->sc_free_xferq
, xp
, x_queue
);
540 "Could not find transfer with tag 0x%016lx\n", tag
);
547 ps3cdrom_transfer(void *arg
, bus_dma_segment_t
*segs
, int nsegs
, int error
)
549 struct ps3cdrom_xfer
*xp
= (struct ps3cdrom_xfer
*) arg
;
550 struct ps3cdrom_softc
*sc
= xp
->x_sc
;
551 device_t dev
= sc
->sc_dev
;
552 uint64_t devid
= ps3bus_get_device(dev
);
553 union ccb
*ccb
= xp
->x_ccb
;
555 uint64_t start_sector
, block_count
;
558 KASSERT(nsegs
== 1 || nsegs
== 0,
559 ("ps3cdrom_transfer: invalid number of DMA segments %d", nsegs
));
560 KASSERT(error
== 0, ("ps3cdrom_transfer: DMA error %d", error
));
562 PS3CDROM_ASSERT_LOCKED(sc
);
565 device_printf(dev
, "Could not load DMA map (%d)\n", error
);
568 TAILQ_INSERT_TAIL(&sc
->sc_free_xferq
, xp
, x_queue
);
569 ccb
->ccb_h
.status
= CAM_SCSI_STATUS_ERROR
;
574 cdb
= (ccb
->ccb_h
.flags
& CAM_CDB_POINTER
) ?
575 ccb
->csio
.cdb_io
.cdb_ptr
:
576 ccb
->csio
.cdb_io
.cdb_bytes
;
578 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
,
579 ("ATAPI command 0x%02x cdb_len %d dxfer_len %d\n ", cdb
[0],
580 ccb
->csio
.cdb_len
, ccb
->csio
.dxfer_len
));
584 KASSERT(nsegs
== 1, ("ps3cdrom_transfer: no data to read"));
585 start_sector
= (cdb
[2] << 24) | (cdb
[3] << 16) |
586 (cdb
[4] << 8) | cdb
[5];
587 block_count
= (cdb
[7] << 8) | cdb
[8];
589 err
= lv1_storage_read(devid
, 0 /* region id */,
590 start_sector
, block_count
, 0 /* flags */, segs
[0].ds_addr
,
592 bus_dmamap_sync(sc
->sc_dmatag
, xp
->x_dmamap
,
593 BUS_DMASYNC_POSTREAD
);
596 KASSERT(nsegs
== 1, ("ps3cdrom_transfer: no data to write"));
597 start_sector
= (cdb
[2] << 24) | (cdb
[3] << 16) |
598 (cdb
[4] << 8) | cdb
[5];
599 block_count
= (cdb
[7] << 8) | cdb
[8];
601 bus_dmamap_sync(sc
->sc_dmatag
, xp
->x_dmamap
,
602 BUS_DMASYNC_PREWRITE
);
603 err
= lv1_storage_write(devid
, 0 /* region id */,
604 start_sector
, block_count
, 0 /* flags */,
605 segs
[0].ds_addr
, &xp
->x_tag
);
609 struct lv1_atapi_cmd atapi_cmd
;
611 bzero(&atapi_cmd
, sizeof(atapi_cmd
));
612 atapi_cmd
.pktlen
= 12;
613 bcopy(cdb
, atapi_cmd
.pkt
, ccb
->csio
.cdb_len
);
615 if (ccb
->ccb_h
.flags
& CAM_DIR_IN
) {
616 atapi_cmd
.in_out
= DIR_READ
;
617 atapi_cmd
.proto
= (ccb
->csio
.dxfer_len
>= 2048) ?
618 DMA_PROTO
: PIO_DATA_IN_PROTO
;
619 } else if (ccb
->ccb_h
.flags
& CAM_DIR_OUT
) {
620 atapi_cmd
.in_out
= DIR_WRITE
;
621 atapi_cmd
.proto
= (ccb
->csio
.dxfer_len
>= 2048) ?
622 DMA_PROTO
: PIO_DATA_OUT_PROTO
;
624 atapi_cmd
.proto
= NON_DATA_PROTO
;
627 atapi_cmd
.nblocks
= atapi_cmd
.arglen
=
628 (nsegs
== 0) ? 0 : segs
[0].ds_len
;
629 atapi_cmd
.blksize
= 1;
630 atapi_cmd
.buf
= (nsegs
== 0) ? 0 : segs
[0].ds_addr
;
632 if (ccb
->ccb_h
.flags
& CAM_DIR_OUT
)
633 bus_dmamap_sync(sc
->sc_dmatag
, xp
->x_dmamap
,
634 BUS_DMASYNC_PREWRITE
);
636 err
= lv1_storage_send_device_command(devid
,
637 LV1_STORAGE_SEND_ATAPI_COMMAND
, vtophys(&atapi_cmd
),
638 sizeof(atapi_cmd
), atapi_cmd
.buf
, atapi_cmd
.arglen
,
646 device_printf(dev
, "ATAPI command 0x%02x failed (%d)\n",
649 bus_dmamap_unload(sc
->sc_dmatag
, xp
->x_dmamap
);
652 TAILQ_INSERT_TAIL(&sc
->sc_free_xferq
, xp
, x_queue
);
654 bzero(&ccb
->csio
.sense_data
, sizeof(ccb
->csio
.sense_data
));
655 /* Invalid field in parameter list */
656 scsi_set_sense_data(&ccb
->csio
.sense_data
,
657 /*sense_format*/ SSD_TYPE_NONE
,
659 /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST
,
664 ccb
->csio
.sense_len
= SSD_FULL_SIZE
;
665 ccb
->csio
.scsi_status
= SCSI_STATUS_CHECK_COND
;
666 ccb
->ccb_h
.status
= CAM_SCSI_STATUS_ERROR
| CAM_AUTOSNS_VALID
;
669 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
,
670 ("ATAPI command 0x%02x tag 0x%016lx submitted\n ", cdb
[0],
673 TAILQ_INSERT_TAIL(&sc
->sc_active_xferq
, xp
, x_queue
);
674 ccb
->ccb_h
.status
|= CAM_SIM_QUEUED
;
679 ps3cdrom_decode_lv1_status(uint64_t status
, u_int8_t
*sense_key
, u_int8_t
*asc
,
682 if (((status
>> 24) & 0xff) != SCSI_STATUS_CHECK_COND
)
685 *sense_key
= (status
>> 16) & 0xff;
686 *asc
= (status
>> 8) & 0xff;
687 *ascq
= status
& 0xff;
692 static device_method_t ps3cdrom_methods
[] = {
693 DEVMETHOD(device_probe
, ps3cdrom_probe
),
694 DEVMETHOD(device_attach
, ps3cdrom_attach
),
695 DEVMETHOD(device_detach
, ps3cdrom_detach
),
699 static driver_t ps3cdrom_driver
= {
702 sizeof(struct ps3cdrom_softc
),
705 DRIVER_MODULE(ps3cdrom
, ps3bus
, ps3cdrom_driver
, 0, 0);
706 MODULE_DEPEND(ps3cdrom
, cam
, 1, 1, 1);