summaryrefslogtreecommitdiff
path: root/sys/dev/ic/mpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ic/mpi.c')
-rw-r--r--sys/dev/ic/mpi.c85
1 files changed, 82 insertions, 3 deletions
diff --git a/sys/dev/ic/mpi.c b/sys/dev/ic/mpi.c
index e48e64d8cd5..c5c22aabb1b 100644
--- a/sys/dev/ic/mpi.c
+++ b/sys/dev/ic/mpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpi.c,v 1.50 2006/06/29 10:43:21 dlg Exp $ */
+/* $OpenBSD: mpi.c,v 1.51 2006/06/30 08:29:42 dlg Exp $ */
/*
* Copyright (c) 2005, 2006 David Gwynne <dlg@openbsd.org>
@@ -83,6 +83,7 @@ void mpi_fc_print(struct mpi_softc *);
void mpi_run_ppr(struct mpi_softc *);
int mpi_ppr(struct mpi_softc *, struct scsi_link *,
int, int, int);
+int mpi_inq(struct mpi_softc *, u_int16_t, int);
void mpi_timeout_xs(void *);
int mpi_load_xs(struct mpi_ccb *);
@@ -371,7 +372,6 @@ mpi_ppr(struct mpi_softc *sc, struct scsi_link *link, int period, int offset,
struct mpi_cfg_hdr hdr0, hdr1;
struct mpi_cfg_spi_dev_pg0 pg0;
struct mpi_cfg_spi_dev_pg1 pg1;
- struct scsi_inquiry_data inqbuf;
u_int32_t address;
DNPRINTF(MPI_D_PPR, "%s: mpi_ppr period: %d offset: %d try: %d "
@@ -477,7 +477,7 @@ mpi_ppr(struct mpi_softc *sc, struct scsi_link *link, int period, int offset,
"conf: 0x%08x\n", DEVNAME(sc), pg1.req_params1, pg1.req_offset,
pg1.req_period, pg1.req_params2, letoh32(pg1.configuration));
- if (scsi_inquire(link, &inqbuf, SCSI_POLL) != 0) {
+ if (mpi_inq(sc, link->target, 0) != 0) {
DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to do inquiry against "
"target %d\n", DEVNAME(sc), link->target);
return (EIO);
@@ -545,6 +545,85 @@ mpi_ppr(struct mpi_softc *sc, struct scsi_link *link, int period, int offset,
return (0);
}
+int
+mpi_inq(struct mpi_softc *sc, u_int16_t target, int physdisk)
+{
+ struct mpi_ccb *ccb;
+ struct scsi_inquiry inq;
+ struct {
+ struct mpi_msg_scsi_io io;
+ struct mpi_sge sge;
+ struct scsi_inquiry_data inqbuf;
+ struct scsi_sense_data sense;
+ } __packed *bundle;
+ struct mpi_msg_scsi_io *io;
+ struct mpi_sge *sge;
+ u_int64_t addr;
+
+ DNPRINTF(MPI_D_PPR, "%s: mpi_inq\n", DEVNAME(sc));
+
+ bzero(&inq, sizeof(inq));
+ inq.opcode = INQUIRY;
+
+ ccb = mpi_get_ccb(sc);
+ if (ccb == NULL)
+ return (1);
+
+ ccb->ccb_done = mpi_empty_done;
+
+ bundle = ccb->ccb_cmd;
+ io = &bundle->io;
+ sge = &bundle->sge;
+
+ io->function = physdisk ? MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH :
+ MPI_FUNCTION_SCSI_IO_REQUEST;
+ /*
+ * bus is always 0
+ * io->bus = htole16(sc->sc_bus);
+ */
+ io->target_id = target;
+
+ io->cdb_length = sizeof(inq);
+ io->sense_buf_len = sizeof(struct scsi_sense_data);
+ io->msg_flags = MPI_SCSIIO_SENSE_BUF_ADDR_WIDTH_64;
+
+ io->msg_context = htole32(ccb->ccb_id);
+
+ /*
+ * always lun 0
+ * io->lun[0] = htobe16(link->lun);
+ */
+
+ io->direction = MPI_SCSIIO_DIR_READ;
+ io->tagging = MPI_SCSIIO_ATTR_NO_DISCONNECT;
+
+ bcopy(&inq, io->cdb, sizeof(inq));
+
+ io->data_length = htole32(sizeof(struct scsi_inquiry_data));
+
+ io->sense_buf_low_addr = htole32(ccb->ccb_cmd_dva +
+ ((u_int8_t *)&bundle->sense - (u_int8_t *)bundle));
+
+ sge->sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE | MPI_SGE_FL_SIZE_64 |
+ MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL |
+ sizeof(inq));
+
+ addr = ccb->ccb_cmd_dva +
+ ((u_int8_t *)&bundle->inqbuf - (u_int8_t *)bundle);
+ sge->sg_hi_addr = htole32((u_int32_t)(addr >> 32));
+ sge->sg_lo_addr = htole32((u_int32_t)addr);
+
+ if (mpi_poll(sc, ccb, 5000) != 0)
+ return (1);
+
+ if (ccb->ccb_reply != NULL)
+ mpi_push_reply(sc, ccb->ccb_reply_dva);
+
+ mpi_put_ccb(sc, ccb);
+
+ return (0);
+}
+
void
mpi_detach(struct mpi_softc *sc)
{