diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2008-09-30 23:40:17 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2008-09-30 23:40:17 +0000 |
commit | e84f34e41ca9ffc2e22c1acdc1160f858489d841 (patch) | |
tree | 39d962cf8ca5c11830cdcd90b2a5ebf93d020bdd | |
parent | 49b35fc38919654308f8fbaa6a21fbf7cf26ba56 (diff) |
provide a scsi probe hook that checks if an atapi device is plugged into
sas mpi variants. this lets the midlayer know it should send the right
sized commands to the device.
this will make the cd drive work on the sun enterprise m4000 and related
machines.
reported by James Hsieh at sun.
-rw-r--r-- | sys/dev/ic/mpi.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/sys/dev/ic/mpi.c b/sys/dev/ic/mpi.c index 5435432f1c4..254e6a298be 100644 --- a/sys/dev/ic/mpi.c +++ b/sys/dev/ic/mpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpi.c,v 1.95 2008/09/30 23:36:19 dlg Exp $ */ +/* $OpenBSD: mpi.c,v 1.96 2008/09/30 23:40:16 dlg Exp $ */ /* * Copyright (c) 2005, 2006 David Gwynne <dlg@openbsd.org> @@ -58,13 +58,14 @@ struct cfdriver mpi_cd = { int mpi_scsi_cmd(struct scsi_xfer *); void mpi_scsi_cmd_done(struct mpi_ccb *); void mpi_minphys(struct buf *bp); +int mpi_scsi_probe(struct scsi_link *); int mpi_scsi_ioctl(struct scsi_link *, u_long, caddr_t, int, struct proc *); struct scsi_adapter mpi_switch = { mpi_scsi_cmd, mpi_minphys, - NULL, + mpi_scsi_probe, NULL, mpi_scsi_ioctl }; @@ -1388,6 +1389,56 @@ mpi_minphys(struct buf *bp) } int +mpi_scsi_probe(struct scsi_link *link) +{ + struct mpi_softc *sc = link->adapter_softc; + struct mpi_ecfg_hdr ehdr; + struct mpi_cfg_sas_dev_pg0 pg0; + u_int32_t address; + + if (sc->sc_porttype != MPI_PORTFACTS_PORTTYPE_SAS || link->lun != 0) + return (0); + + address = MPI_CFG_SAS_DEV_ADDR_BUS | link->target; + + if (mpi_ecfg_header(sc, MPI_CONFIG_REQ_EXTPAGE_TYPE_SAS_DEVICE, 0, + address, &ehdr) != 0) + return (EIO); + + if (mpi_ecfg_page(sc, address, &ehdr, 1, &pg0, sizeof(pg0)) != 0) { + /* the device probably doesnt exist if the page fetch fails */ + return (ENXIO); + } + + DPRINTF(MPI_D_MISC, "%s: mpi_scsi_probe sas dev pg 0 for target %d:\n", + DEVNAME(sc), link->target); + DPRINTF(MPI_D_MISC, "%s: slot: 0x%04x enc_handle: 0x%04x\n", + DEVNAME(sc), letoh16(pg0.slot), letoh16(pg0.enc_handle)); + DPRINTF(MPI_D_MISC, "%s: sas_addr: 0x%016llx\n", DEVNAME(sc), + letoh64(pg0.sas_addr)); + DPRINTF(MPI_D_MISC, "%s: parent_dev_handle: 0x%04x phy_num: 0x%02x " + "access_status: 0x%02x\n", DEVNAME(sc), + letoh16(pg0.parent_dev_handle), pg0.phy_num, pg0.access_status); + DPRINTF(MPI_D_MISC, "%s: dev_handle: 0x%04x " + "bus: 0x%02x target: 0x%02x\n", DEVNAME(sc), + letoh16(pg0.dev_handle), pg0.bus, pg0.target); + DPRINTF(MPI_D_MISC, "%s: device_info: 0x%08x\n", DEVNAME(sc), + letoh32(pg0.device_info)); + DPRINTF(MPI_D_MISC, "%s: flags: 0x%04x physical_port: 0x%02x\n", + DEVNAME(sc), letoh16(pg0.flags), pg0.physical_port); + + if (ISSET(letoh32(pg0.device_info), + MPI_CFG_SAS_DEV_0_DEVINFO_ATAPI_DEVICE)) { + DPRINTF(MPI_D_MISC, "%s: target %d is an ATAPI device\n", + DEVNAME(sc), link->target); + link->flags |= SDEV_ATAPI; + link->quirks |= SDEV_ONLYBIG; + } + + return (0); +} + +int mpi_scsi_ioctl(struct scsi_link *a, u_long b, caddr_t c, int d, struct proc *e) { return (ENOTTY); |