summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2006-07-06 09:22:00 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2006-07-06 09:22:00 +0000
commit4c30427ba1d0e45fa6f30e7652ac9b2fc2ab08d4 (patch)
treea375622a7c65fb041ecce4ad2e25b2869f16021e /sys/dev/ic
parentcc8013991fd3163afa7e24d7b9e389bbd12c8efb (diff)
after walking the attached devices and running ppr against them, then fetch
the ioc page 3 for a list of all the physical disks behind any configured volumes and run ppr against them too. raid volumes on scsi mpi is fast now.
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/mpi.c93
1 files changed, 77 insertions, 16 deletions
diff --git a/sys/dev/ic/mpi.c b/sys/dev/ic/mpi.c
index 70132a157bc..84ae178b783 100644
--- a/sys/dev/ic/mpi.c
+++ b/sys/dev/ic/mpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpi.c,v 1.56 2006/07/06 09:04:45 dlg Exp $ */
+/* $OpenBSD: mpi.c,v 1.57 2006/07/06 09:21:59 dlg Exp $ */
/*
* Copyright (c) 2005, 2006 David Gwynne <dlg@openbsd.org>
@@ -82,7 +82,7 @@ int mpi_poll(struct mpi_softc *, struct mpi_ccb *, int);
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);
+ struct mpi_cfg_raid_physdisk *, int, int, int);
int mpi_inq(struct mpi_softc *, u_int16_t, int);
void mpi_timeout_xs(void *);
@@ -320,7 +320,10 @@ void
mpi_run_ppr(struct mpi_softc *sc)
{
struct mpi_cfg_hdr hdr;
- struct mpi_cfg_spi_port_pg0 pg;
+ struct mpi_cfg_spi_port_pg0 port_pg;
+ struct mpi_cfg_ioc_pg3 *physdisk_pg;
+ struct mpi_cfg_raid_physdisk *physdisk_list, *physdisk;
+ size_t pagelen;
struct scsi_link *link;
int i, tries;
@@ -331,7 +334,7 @@ mpi_run_ppr(struct mpi_softc *sc)
return;
}
- if (mpi_cfg_page(sc, 0x0, &hdr, 1, &pg, sizeof(pg)) != 0) {
+ if (mpi_cfg_page(sc, 0x0, &hdr, 1, &port_pg, sizeof(port_pg)) != 0) {
DNPRINTF(MPI_D_PPR, "%s: mpi_run_ppr unable to fetch page\n",
DEVNAME(sc));
return;
@@ -347,20 +350,70 @@ mpi_run_ppr(struct mpi_softc *sc)
continue;
tries = 0;
- while (mpi_ppr(sc, link, pg.min_period, pg.max_offset,
- tries) == EAGAIN)
+ while (mpi_ppr(sc, link, NULL, port_pg.min_period,
+ port_pg.max_offset, tries) == EAGAIN)
tries++;
}
+
+ if ((sc->sc_flags & MPI_F_RAID) == 0)
+ return;
+
+ if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_IOC, 3, 0x0,
+ &hdr) != 0) {
+ DNPRINTF(MPI_D_RAID|MPI_D_PPR, "%s: mpi_run_ppr unable to "
+ "fetch ioc pg 3 header\n", DEVNAME(sc));
+ return;
+ }
+
+ pagelen = hdr.page_length * 4; /* dwords to bytes */
+ physdisk_pg = malloc(pagelen, M_TEMP, M_WAITOK);
+ if (physdisk_pg == NULL) {
+ DNPRINTF(MPI_D_RAID|MPI_D_PPR, "%s: mpi_run_ppr unable to "
+ "allocate ioc pg 3\n", DEVNAME(sc));
+ return;
+ }
+ physdisk_list = (struct mpi_cfg_raid_physdisk *)(physdisk_pg + 1);
+
+ if (mpi_cfg_page(sc, 0, &hdr, 1, physdisk_pg, pagelen) != 0) {
+ DNPRINTF(MPI_D_PPR|MPI_D_PPR, "%s: mpi_run_ppr unable to "
+ "fetch ioc page 3\n", DEVNAME(sc));
+ goto out;
+ }
+
+ DNPRINTF(MPI_D_PPR|MPI_D_PPR, "%s: no_phys_disks: %d\n", DEVNAME(sc),
+ physdisk_pg->no_phys_disks);
+
+ for (i = 0; i < physdisk_pg->no_phys_disks; i++) {
+ physdisk = &physdisk_list[i];
+
+ DNPRINTF(MPI_D_PPR|MPI_D_PPR, "%s: id: %d bus: %d ioc: %d "
+ "num: %d\n", DEVNAME(sc), physdisk->phys_disk_id,
+ physdisk->phys_disk_bus, physdisk->phys_disk_ioc,
+ physdisk->phys_disk_num);
+
+ if (physdisk->phys_disk_ioc != sc->sc_ioc_number)
+ continue;
+
+ tries = 0;
+ while (mpi_ppr(sc, NULL, physdisk, port_pg.min_period,
+ port_pg.max_offset, tries) == EAGAIN)
+ tries++;
+ }
+
+out:
+ free(physdisk_pg, M_TEMP);
}
int
-mpi_ppr(struct mpi_softc *sc, struct scsi_link *link, int period, int offset,
- int try)
+mpi_ppr(struct mpi_softc *sc, struct scsi_link *link,
+ struct mpi_cfg_raid_physdisk *physdisk, int period, int offset, int try)
{
struct mpi_cfg_hdr hdr0, hdr1;
struct mpi_cfg_spi_dev_pg0 pg0;
struct mpi_cfg_spi_dev_pg1 pg1;
u_int32_t address;
+ int id;
+ int raid = 0;
DNPRINTF(MPI_D_PPR, "%s: mpi_ppr period: %d offset: %d try: %d "
"link quirks: 0x%x\n", DEVNAME(sc), period, offset, try,
@@ -369,10 +422,18 @@ mpi_ppr(struct mpi_softc *sc, struct scsi_link *link, int period, int offset,
if (try >= 3)
return (EIO);
- if ((link->inqdata.device & SID_TYPE) == T_PROCESSOR)
- return (EIO);
+ if (physdisk == NULL) {
+ if ((link->inqdata.device & SID_TYPE) == T_PROCESSOR)
+ return (EIO);
- address = link->target;
+ address = link->target;
+ id = link->target;
+ } else {
+ raid = 1;
+ address = (physdisk->phys_disk_bus << 8) |
+ (physdisk->phys_disk_id);
+ id = physdisk->phys_disk_num;
+ }
if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_SCSI_SPI_DEV, 0,
address, &hdr0) != 0) {
@@ -417,7 +478,7 @@ mpi_ppr(struct mpi_softc *sc, struct scsi_link *link, int period, int offset,
pg1.req_period = period;
pg1.req_params2 &= ~MPI_CFG_SPI_DEV_1_REQPARAMS_WIDTH;
- if (!(link->quirks & SDEV_NOSYNC)) {
+ if (raid || !(link->quirks & SDEV_NOSYNC)) {
pg1.req_params2 |= MPI_CFG_SPI_DEV_1_REQPARAMS_WIDTH_WIDE;
switch (try) {
@@ -465,7 +526,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 (mpi_inq(sc, link->target, 0) != 0) {
+ if (mpi_inq(sc, id, raid) != 0) {
DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to do inquiry against "
"target %d\n", DEVNAME(sc), link->target);
return (EIO);
@@ -521,9 +582,9 @@ mpi_ppr(struct mpi_softc *sc, struct scsi_link *link, int period, int offset,
break;
}
- printf("%s: target %d %s at %dMHz width %dbit offset %d "
- "QAS %d DT %d IU %d\n", DEVNAME(sc), link->target,
- period ? "Sync" : "Async", period,
+ printf("%s: %s %d %s at %dMHz width %dbit offset %d "
+ "QAS %d DT %d IU %d\n", DEVNAME(sc), raid ? "phys disk" : "target",
+ id, period ? "Sync" : "Async", period,
(pg0.neg_params2 & MPI_CFG_SPI_DEV_0_NEGPARAMS_WIDTH_WIDE) ? 16 : 8,
pg0.neg_offset,
(pg0.neg_params1 & MPI_CFG_SPI_DEV_0_NEGPARAMS_QAS) ? 1 : 0,