summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/mpi.c112
-rw-r--r--sys/dev/ic/mpireg.h58
-rw-r--r--sys/dev/ic/mpivar.h7
3 files changed, 90 insertions, 87 deletions
diff --git a/sys/dev/ic/mpi.c b/sys/dev/ic/mpi.c
index efa0f3d073a..70132a157bc 100644
--- a/sys/dev/ic/mpi.c
+++ b/sys/dev/ic/mpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpi.c,v 1.55 2006/07/06 00:55:03 dlg Exp $ */
+/* $OpenBSD: mpi.c,v 1.56 2006/07/06 09:04:45 dlg Exp $ */
/*
* Copyright (c) 2005, 2006 David Gwynne <dlg@openbsd.org>
@@ -322,7 +322,7 @@ mpi_run_ppr(struct mpi_softc *sc)
struct mpi_cfg_hdr hdr;
struct mpi_cfg_spi_port_pg0 pg;
struct scsi_link *link;
- int i, r, tries;
+ int i, tries;
if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_SCSI_SPI_PORT, 0, 0x0,
&hdr) != 0) {
@@ -342,16 +342,11 @@ mpi_run_ppr(struct mpi_softc *sc)
if (link == NULL)
continue;
- /* is this a RAID device? */
- tries = 0;
- for (r = 0; r < sc->sc_ioc_pg2->max_vols; r++)
- if (i == sc->sc_ioc_pg2->raid_vol[r].vol_id) {
- DNPRINTF(MPI_D_PPR, "%s: mpi_run_ppr scsibus "
- "%d ioc %d target %d RAID\n", DEVNAME(sc),
- sc->sc_link.scsibus, sc->sc_ioc_number, i);
- /* XXX fan out ppr */
- }
+ /* do not ppr volumes */
+ if (link->flags & SDEV_VIRTUAL)
+ continue;
+ tries = 0;
while (mpi_ppr(sc, link, pg.min_period, pg.max_offset,
tries) == EAGAIN)
tries++;
@@ -2015,71 +2010,78 @@ void
mpi_get_raid(struct mpi_softc *sc)
{
struct mpi_cfg_hdr hdr;
- struct mpi_cfg_raid_vol *raidvol;
+ struct mpi_cfg_ioc_pg2 *vol_page;
+ struct mpi_cfg_raid_vol *vol_list, *vol;
+ size_t pagelen;
+ u_int32_t capabilities;
+ struct scsi_link *link;
int i;
DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid\n", DEVNAME(sc));
if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_IOC, 2, 0, &hdr) != 0) {
- DNPRINTF(MPI_D_PPR, "%s: mpi_get_raid unable to fetch header"
+ DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to fetch header"
"for IOC page 2\n", DEVNAME(sc));
return;
}
- /* make page length bytes instead of dwords */
- sc->sc_ioc_pg2 = malloc(hdr.page_length * 4, M_DEVBUF, M_WAITOK);
- if (mpi_cfg_page(sc, 0, &hdr, 1, sc->sc_ioc_pg2,
- hdr.page_length * 4) != 0) {
+ pagelen = hdr.page_length * 4; /* dwords to bytes */
+ vol_page = malloc(pagelen, M_TEMP, M_WAITOK);
+ if (vol_page == NULL) {
+ DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to allocate "
+ "space for ioc config page 2\n", DEVNAME(sc));
+ return;
+ }
+ vol_list = (struct mpi_cfg_raid_vol *)(vol_page + 1);
+
+ if (mpi_cfg_page(sc, 0, &hdr, 1, vol_page, pagelen) != 0) {
DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to fetch IOC "
"page 2\n", DEVNAME(sc));
- return;
+ goto out;
}
- DNPRINTF(MPI_D_RAID, "%s: capabilities: %x active vols %d "
- "max vols: %d\n", DEVNAME(sc),
- letoh32(sc->sc_ioc_pg2->capabilities),
- sc->sc_ioc_pg2->no_active_vols, sc->sc_ioc_pg2->max_vols);
- DNPRINTF(MPI_D_RAID, "%s: active phys disks: %d max disks: %d\n",
- DEVNAME(sc), sc->sc_ioc_pg2->no_active_phys_disks,
- sc->sc_ioc_pg2->max_phys_disks);
+ capabilities = letoh32(vol_page->capabilities);
+
+ DNPRINTF(MPI_D_RAID, "%s: capabilities: 0x08%x\n", DEVNAME(sc),
+ letoh32(vol_page->capabilities));
+ DNPRINTF(MPI_D_RAID, "%s: active_vols: %d max_vols: %d "
+ "active_physdisks: %d max_physdisks: %d\n", DEVNAME(sc),
+ vol_page->active_vols, vol_page->max_vols,
+ vol_page->active_physdisks, vol->max_physdisks);
/* don't walk list if there are no RAID capability */
- if (letoh32(sc->sc_ioc_pg2->capabilities) == 0xdeadbeef)
- return;
+ if (capabilities == 0xdeadbeef) {
+ printf("%s: deadbeef in raid configuration\n", DEVNAME(sc));
+ goto out;
+ }
- for (i = 0; i < sc->sc_ioc_pg2->max_vols; i++) {
- raidvol = &sc->sc_ioc_pg2->raid_vol[i];
- DNPRINTF(MPI_D_RAID, "%s: id: %#02x bus: %d ioc: %d page: %d "
- "type: %#02x flags: %#02x\n", DEVNAME(sc), raidvol->vol_id,
- raidvol->vol_bus, raidvol->vol_ioc, raidvol->vol_page,
- raidvol->vol_type, raidvol->flags);
+ if ((capabilities & MPI_CFG_IOC_2_CAPABILITIES_RAID) == 0 ||
+ (vol_page->active_vols == 0))
+ goto out;
- }
+ sc->sc_flags |= MPI_F_RAID;
- /* reuse hdr */
- if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_IOC, 3, 0, &hdr) != 0) {
- DNPRINTF(MPI_D_PPR, "%s: mpi_get_raid unable to fetch header"
- "for IOC page 3\n", DEVNAME(sc));
- return;
- }
+ for (i = 0; i < vol_page->active_vols; i++) {
+ vol = &vol_list[i];
- /* make page length bytes instead of dwords */
- sc->sc_ioc_pg3 = malloc(hdr.page_length * 4, M_DEVBUF, M_WAITOK);
- if (mpi_cfg_page(sc, 0, &hdr, 1, sc->sc_ioc_pg3,
- hdr.page_length * 4) != 0) {
- DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to fetch IOC "
- "page 3\n", DEVNAME(sc));
- return;
- }
+ DNPRINTF(MPI_D_RAID, "%s: id: %d bus: %d ioc: %d pg: %d\n",
+ DEVNAME(sc), vol->vol_id, vol->vol_bus, vol->vol_ioc,
+ vol->vol_page);
+ DNPRINTF(MPI_D_RAID, "%s: type: 0x%02x flags: 0x%02x\n",
+ DEVNAME(sc), vol->vol_type, vol->flags);
- for (i = 0; i < sc->sc_ioc_pg3->no_phys_disks; i++) {
- DNPRINTF(MPI_D_RAID, "%s: id: %#02x bus: %d ioc: %d "
- "num: %#02x\n", DEVNAME(sc),
- sc->sc_ioc_pg3->phys_disks[i].phys_disk_id,
- sc->sc_ioc_pg3->phys_disks[i].phys_disk_bus,
- sc->sc_ioc_pg3->phys_disks[i].phys_disk_ioc,
- sc->sc_ioc_pg3->phys_disks[i].phys_disk_num);
+ if (vol->vol_ioc != sc->sc_ioc_number || vol->vol_bus != 0)
+ continue;
+
+ link = sc->sc_scsibus->sc_link[vol->vol_id][0];
+ if (link == NULL)
+ continue;
+
+ link->flags |= SDEV_VIRTUAL;
}
+
+out:
+ free(vol_page, M_TEMP);
}
int
diff --git a/sys/dev/ic/mpireg.h b/sys/dev/ic/mpireg.h
index 461deb9754d..a7bf6b7615c 100644
--- a/sys/dev/ic/mpireg.h
+++ b/sys/dev/ic/mpireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpireg.h,v 1.24 2006/07/01 13:23:14 dlg Exp $ */
+/* $OpenBSD: mpireg.h,v 1.25 2006/07/06 09:04:45 dlg Exp $ */
/*
* Copyright (c) 2005 David Gwynne <dlg@openbsd.org>
@@ -1007,6 +1007,28 @@ struct mpi_cfg_manufacturing_pg0 {
char board_tracer_number[16];
} __packed;
+struct mpi_cfg_ioc_pg2 {
+ struct mpi_cfg_hdr config_header;
+
+ u_int32_t capabilities;
+#define MPI_CFG_IOC_2_CAPABILITIES_IS (1<<0)
+#define MPI_CFG_IOC_2_CAPABILITIES_IME (1<<1)
+#define MPI_CFG_IOC_2_CAPABILITIES_IM (1<<2)
+#define MPI_CFG_IOC_2_CAPABILITIES_RAID ( \
+ MPI_CFG_IOC_2_CAPABILITIES_IS | MPI_CFG_IOC_2_CAPABILITIES_IME | \
+ MPI_CFG_IOC_2_CAPABILITIES_IM)
+#define MPI_CFG_IOC_2_CAPABILITIES_SES (1<<29)
+#define MPI_CFG_IOC_2_CAPABILITIES_SAFTE (1<<30)
+#define MPI_CFG_IOC_2_CAPABILITIES_XCHANNEL (1<<31)
+
+ u_int8_t active_vols;
+ u_int8_t max_vols;
+ u_int8_t active_physdisks;
+ u_int8_t physdisks;
+
+ /* followed by a list of mpi_cf_raid_vol structs */
+} __packed;
+
struct mpi_cfg_raid_vol {
u_int8_t vol_id;
u_int8_t vol_bus;
@@ -1014,48 +1036,30 @@ struct mpi_cfg_raid_vol {
u_int8_t vol_page;
u_int8_t vol_type;
-#define MPI_CFG_RAID_TYPE_RAID_IS (1<<0) /* RAID 0 */
-#define MPI_CFG_RAID_TYPE_RAID_IME (1<<1) /* RAID 1 */
-#define MPI_CFG_RAID_TYPE_RAID_IM (1<<2) /* RAID 1 */
-#define MPI_CFG_RAID_TYPE_RAID5 (1<<3)
-#define MPI_CFG_RAID_TYPE_RAID6 (1<<4)
-#define MPI_CFG_RAID_TYPE_RAID10 (1<<5)
-#define MPI_CFG_RAID_TYPE_RAID50 (1<<6)
-#define MPI_CFG_RAID_TYPE_UNKNOWN (0xff)
+#define MPI_CFG_RAID_TYPE_RAID_IS (0x00)
+#define MPI_CFG_RAID_TYPE_RAID_IME (0x01)
+#define MPI_CFG_RAID_TYPE_RAID_IM (0x02)
u_int8_t flags;
-#define MPI_CFG_RAID_VOL_ACTIVE (0<<3)
#define MPI_CFG_RAID_VOL_INACTIVE (1<<3)
u_int16_t reserved;
} __packed;
-struct mpi_cfg_ioc_pg2 {
+struct mpi_cfg_ioc_pg3 {
struct mpi_cfg_hdr config_header;
- u_int32_t capabilities;
+ u_int8_t no_phys_disks;
+ u_int8_t reserved[3];
- u_int8_t no_active_vols;
- u_int8_t max_vols;
- u_int8_t no_active_phys_disks;
- u_int8_t max_phys_disks;
- struct mpi_cfg_raid_vol raid_vol[1]; /* length is stored in header */
+ /* followed by a list of mpi_cf_raid_physdisk structs */
} __packed;
-struct mpi_cfg_raid_pd {
+struct mpi_cfg_raid_physdisk {
u_int8_t phys_disk_id;
u_int8_t phys_disk_bus;
u_int8_t phys_disk_ioc;
u_int8_t phys_disk_num;
} __packed;
-struct mpi_cfg_ioc_pg3 {
- struct mpi_cfg_hdr config_header;
-
- u_int8_t no_phys_disks;
- u_int8_t reserved[3];
-
- struct mpi_cfg_raid_pd phys_disks[1]; /* length stored in header */
-} __packed;
-
struct mpi_cfg_fc_port_pg0 {
struct mpi_cfg_hdr config_header;
diff --git a/sys/dev/ic/mpivar.h b/sys/dev/ic/mpivar.h
index e019923e1ed..51111dda0b4 100644
--- a/sys/dev/ic/mpivar.h
+++ b/sys/dev/ic/mpivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpivar.h,v 1.16 2006/07/06 00:55:03 dlg Exp $ */
+/* $OpenBSD: mpivar.h,v 1.17 2006/07/06 09:04:45 dlg Exp $ */
/*
* Copyright (c) 2005 David Gwynne <dlg@openbsd.org>
@@ -96,6 +96,7 @@ struct mpi_softc {
int sc_flags;
#define MPI_F_VMWARE (1<<0)
+#define MPI_F_RAID (1<<1)
struct scsibus_softc *sc_scsibus;
@@ -120,10 +121,6 @@ struct mpi_softc {
struct mpi_ccb_list sc_ccb_free;
struct mpi_dmamem *sc_replies;
-
- /* RAID pages */
- struct mpi_cfg_ioc_pg2 *sc_ioc_pg2;
- struct mpi_cfg_ioc_pg3 *sc_ioc_pg3;
};
int mpi_attach(struct mpi_softc *);