2 * Copyright (C) 2010 Nathan Whitehorn
3 * Copyright (C) 2011 glevand <geoffrey.levand@mail.ru>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer,
11 * without modification, immediately at the beginning of the file.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
31 #include <sys/param.h>
32 #include <sys/module.h>
33 #include <sys/systm.h>
34 #include <sys/kernel.h>
38 #include <sys/kthread.h>
40 #include <sys/malloc.h>
41 #include <sys/mutex.h>
46 #include <machine/pio.h>
47 #include <machine/bus.h>
48 #include <machine/platform.h>
49 #include <machine/resource.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>
61 #include "ps3-hvcall.h"
63 #define PS3CDROM_LOCK_INIT(_sc) \
64 mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), "ps3cdrom", \
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);
72 #define PS3CDROM_MAX_XFERS 3
74 #define LV1_STORAGE_SEND_ATAPI_COMMAND 0x01
76 struct ps3cdrom_softc
;
78 struct ps3cdrom_xfer
{
79 TAILQ_ENTRY(ps3cdrom_xfer
) x_queue
;
80 struct ps3cdrom_softc
*x_sc
;
82 bus_dmamap_t x_dmamap
;
86 TAILQ_HEAD(ps3cdrom_xferq
, ps3cdrom_xfer
);
88 struct ps3cdrom_softc
{
97 struct resource
*sc_irq
;
100 bus_dma_tag_t sc_dmatag
;
102 struct cam_sim
*sc_sim
;
103 struct cam_path
*sc_path
;
105 struct ps3cdrom_xfer sc_xfer
[PS3CDROM_MAX_XFERS
];
106 struct ps3cdrom_xferq sc_active_xferq
;
107 struct ps3cdrom_xferq sc_free_xferq
;
111 NON_DATA_PROTO
= 0x00,
112 PIO_DATA_IN_PROTO
= 0x01,
113 PIO_DATA_OUT_PROTO
= 0x02,
117 enum lv1_ata_in_out
{
122 struct lv1_atapi_cmd
{
127 uint32_t proto
; /* enum lv1_ata_proto */
128 uint32_t in_out
; /* enum lv1_ata_in_out */
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
);
138 static void ps3cdrom_intr(void *arg
);
140 static void ps3cdrom_transfer(void *arg
, bus_dma_segment_t
*segs
, int nsegs
,
143 static int ps3cdrom_decode_lv1_status(uint64_t status
,
144 u_int8_t
*sense_key
, u_int8_t
*asc
, u_int8_t
*ascq
);
147 ps3cdrom_probe(device_t dev
)
149 if (ps3bus_get_bustype(dev
) != PS3_BUSTYPE_STORAGE
||
150 ps3bus_get_devtype(dev
) != PS3_DEVTYPE_CDROM
)
153 device_set_desc(dev
, "Playstation 3 CDROM");
155 return (BUS_PROBE_SPECIFIC
);
159 ps3cdrom_attach(device_t dev
)
161 struct ps3cdrom_softc
*sc
= device_get_softc(dev
);
162 struct cam_devq
*devq
;
163 struct ps3cdrom_xfer
*xp
;
164 struct ccb_setasync csa
;
169 PS3CDROM_LOCK_INIT(sc
);
171 /* Setup interrupt handler */
174 sc
->sc_irq
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
, &sc
->sc_irqid
,
177 device_printf(dev
, "Could not allocate IRQ\n");
179 goto fail_destroy_lock
;
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
);
186 device_printf(dev
, "Could not setup IRQ\n");
188 goto fail_release_intr
;
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
);
198 device_printf(dev
, "Could not create DMA tag\n");
200 goto fail_teardown_intr
;
203 /* Setup transfer queues */
205 TAILQ_INIT(&sc
->sc_active_xferq
);
206 TAILQ_INIT(&sc
->sc_free_xferq
);
208 for (i
= 0; i
< PS3CDROM_MAX_XFERS
; i
++) {
209 xp
= &sc
->sc_xfer
[i
];
212 err
= bus_dmamap_create(sc
->sc_dmatag
, BUS_DMA_COHERENT
,
215 device_printf(dev
, "Could not create DMA map (%d)\n",
217 goto fail_destroy_dmamap
;
220 TAILQ_INSERT_TAIL(&sc
->sc_free_xferq
, xp
, x_queue
);
225 devq
= cam_simq_alloc(PS3CDROM_MAX_XFERS
- 1);
227 device_printf(dev
, "Could not allocate SIM queue\n");
229 goto fail_destroy_dmatag
;
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,
236 device_printf(dev
, "Could not allocate SIM\n");
239 goto fail_destroy_dmatag
;
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");
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");
260 goto fail_unregister_xpt_bus
;
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 strncpy(cpi
->sim_vid
, "FreeBSD", SIM_IDLEN
);
424 strncpy(cpi
->hba_vid
, "Sony", HBA_IDLEN
);
425 strncpy(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
,
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
));
512 scsi_set_sense_data(&ccb
->csio
.sense_data
,
513 /*sense_format*/ SSD_TYPE_NONE
,
519 ccb
->csio
.sense_len
= SSD_FULL_SIZE
;
520 ccb
->ccb_h
.status
= CAM_SCSI_STATUS_ERROR
|
524 if ((ccb
->ccb_h
.flags
& CAM_DIR_MASK
) != CAM_DIR_NONE
)
525 ccb
->csio
.resid
= ccb
->csio
.dxfer_len
;
528 if (ccb
->ccb_h
.flags
& CAM_DIR_IN
)
529 bus_dmamap_sync(sc
->sc_dmatag
, xp
->x_dmamap
,
530 BUS_DMASYNC_POSTREAD
);
532 bus_dmamap_unload(sc
->sc_dmatag
, xp
->x_dmamap
);
535 TAILQ_REMOVE(&sc
->sc_active_xferq
, xp
, x_queue
);
536 TAILQ_INSERT_TAIL(&sc
->sc_free_xferq
, xp
, x_queue
);
541 "Could not find transfer with tag 0x%016lx\n", tag
);
548 ps3cdrom_transfer(void *arg
, bus_dma_segment_t
*segs
, int nsegs
, int error
)
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
;
556 uint64_t start_sector
, block_count
;
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
));
563 PS3CDROM_ASSERT_LOCKED(sc
);
566 device_printf(dev
, "Could not load DMA map (%d)\n", error
);
569 TAILQ_INSERT_TAIL(&sc
->sc_free_xferq
, xp
, x_queue
);
570 ccb
->ccb_h
.status
= CAM_SCSI_STATUS_ERROR
;
575 cdb
= (ccb
->ccb_h
.flags
& CAM_CDB_POINTER
) ?
576 ccb
->csio
.cdb_io
.cdb_ptr
:
577 ccb
->csio
.cdb_io
.cdb_bytes
;
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
));
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];
590 err
= lv1_storage_read(devid
, 0 /* region id */,
591 start_sector
, block_count
, 0 /* flags */, segs
[0].ds_addr
,
593 bus_dmamap_sync(sc
->sc_dmatag
, xp
->x_dmamap
,
594 BUS_DMASYNC_POSTREAD
);
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];
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
);
610 struct lv1_atapi_cmd atapi_cmd
;
612 bzero(&atapi_cmd
, sizeof(atapi_cmd
));
613 atapi_cmd
.pktlen
= 12;
614 bcopy(cdb
, atapi_cmd
.pkt
, ccb
->csio
.cdb_len
);
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
;
625 atapi_cmd
.proto
= NON_DATA_PROTO
;
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
;
633 if (ccb
->ccb_h
.flags
& CAM_DIR_OUT
)
634 bus_dmamap_sync(sc
->sc_dmatag
, xp
->x_dmamap
,
635 BUS_DMASYNC_PREWRITE
);
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
,
647 device_printf(dev
, "ATAPI command 0x%02x failed (%d)\n",
650 bus_dmamap_unload(sc
->sc_dmatag
, xp
->x_dmamap
);
653 TAILQ_INSERT_TAIL(&sc
->sc_free_xferq
, xp
, x_queue
);
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
,
660 /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST
,
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
;
670 CAM_DEBUG(ccb
->ccb_h
.path
, CAM_DEBUG_TRACE
,
671 ("ATAPI command 0x%02x tag 0x%016lx submitted\n ", cdb
[0],
674 TAILQ_INSERT_TAIL(&sc
->sc_active_xferq
, xp
, x_queue
);
675 ccb
->ccb_h
.status
|= CAM_SIM_QUEUED
;
680 ps3cdrom_decode_lv1_status(uint64_t status
, u_int8_t
*sense_key
, u_int8_t
*asc
,
683 if (((status
>> 24) & 0xff) != SCSI_STATUS_CHECK_COND
)
686 *sense_key
= (status
>> 16) & 0xff;
687 *asc
= (status
>> 8) & 0xff;
688 *ascq
= status
& 0xff;
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
),
700 static driver_t ps3cdrom_driver
= {
703 sizeof(struct ps3cdrom_softc
),
706 static devclass_t ps3cdrom_devclass
;
708 DRIVER_MODULE(ps3cdrom
, ps3bus
, ps3cdrom_driver
, ps3cdrom_devclass
, 0, 0);
709 MODULE_DEPEND(ps3cdrom
, cam
, 1, 1, 1);