summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2005-07-18 01:29:02 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2005-07-18 01:29:02 +0000
commit55c922539f00e75ede1934fecab3da3ce9080b32 (patch)
treea70f0b54bf032de17a3fe9f0f6bdc7ad6414e794 /sys
parent3b8831a47bf63a5a45f9fa405c3d6073348d03aa (diff)
Rip out all previous bio code because it sucked. Replaced all ioctl code in
ami(4) and bio(4). Note that this will break trees where userland and kernel are not in sync. ok dlg@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/biovar.h187
-rw-r--r--sys/dev/ic/ami.c481
-rw-r--r--sys/dev/ic/amireg.h4
-rw-r--r--sys/dev/ic/amivar.h3
4 files changed, 527 insertions, 148 deletions
diff --git a/sys/dev/biovar.h b/sys/dev/biovar.h
index da1bcec337d..410ef126d28 100644
--- a/sys/dev/biovar.h
+++ b/sys/dev/biovar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: biovar.h,v 1.5 2005/04/06 02:11:25 marco Exp $ */
+/* $OpenBSD: biovar.h,v 1.6 2005/07/18 01:29:01 marco Exp $ */
/*
* Copyright (c) 2002 Niklas Hallqvist. All rights reserved.
@@ -50,147 +50,56 @@ int bio_register(struct device *, int (*)(struct device *, u_long,
/* RAID section */
-#define BIOC_MAX_CDB 16
-#define BIOC_MAX_SENSE 32
-#define BIOC_MAX_PHYSDISK 128 /* based on FC arrays */
-#define BIOC_MAX_VIRTDISK 128 /* based on FC arrays */
-
-/* ioctl tunnel defines */
-/* SHALL be implemented */
-#define BIOCPING _IOWR('B', 32, bioc_ping)
-typedef struct _bioc_ping {
+#define BIOCINQ _IOWR('B', 32, bioc_inq)
+typedef struct _bioc_inq {
void *cookie;
- int x;
-} bioc_ping;
-/* SHALL be implemented */
-#define BIOCCAPABILITIES _IOWR('B', 33, bioc_capabilities)
-typedef struct _bioc_capabilities {
- void *cookie;
- u_int64_t ioctls; /* bit field, 1 ioctl supported */
-#define BIOC_PING 0x01
-#define BIOC_ALARM 0x02
-#define BIOC_PREP_REMOVAL 0x04
-#define BIOC_REBUILD 0x08
-#define BIOC_STATUS 0x10
-#define BIOC_SCSICMD 0x20
-#define BIOC_STARTSTOP 0x40
-#define BIOC_BLINK 0x80
- u_int32_t raid_types; /* bit field, 1 supported raid type */
-#define BIOC_RAID0 0x01
-#define BIOC_RAID1 0x02
-#define BIOC_RAID3 0x04
-#define BIOC_RAID5 0x08
-#define BIOC_RAID10 0x10
-#define BIOC_RAID01 0x20
-#define BIOC_RAID50 0x40
-} bioc_capabilities;
-
-/* OPTIONAL */
-#define BIOCALARM _IOWR('B', 34, bioc_alarm)
-typedef struct _bioc_alarm {
- void *cookie;
- u_int32_t opcode;
-#define BIOCSALARM_DISABLE 0x00
-#define BIOCSALARM_ENABLE 0x01
-#define BIOCSALARM_SILENCE 0x02
-#define BIOCGALARM_STATE 0x03
-#define BIOCSALARM_TEST 0x04
- u_int8_t state; /* only used with GET function */
-} bioc_alarm;
-
-/* OPTIONAL */
-#define BIOCSCSICMD _IOWR('B', 35, bioc_scsicmd)
-typedef struct _bioc_scsicmd {
- void *cookie;
+ int novol; /* nr of volumes */
+ int nodisk; /* nr of total disks */
+} bioc_inq;
- /* in (kernel centric) */
- u_int8_t channel;
- u_int8_t target;
- u_int8_t cdb[BIOC_MAX_CDB];
- u_int8_t cdblen;
- u_int8_t direction; /* 0 = out, 1 = in, this is userland centric */
-#define BIOC_DIROUT 0x00
-#define BIOC_DIRIN 0x01
-#define BIOC_DIRNONE 0x02
-
- /* out (kernel centric) */
- u_int8_t status;
- u_int8_t sensebuf[BIOC_MAX_SENSE];
- u_int8_t senselen;
-
- /* in & out (kernel centric) */
- void *data;
- u_int32_t datalen; /* going in it governs the maximum buffer size
- going out it contains actual bytes transfered */
-} bioc_scsicmd;
-
-/* OPTIONAL */
-#define BIOCSTARTSTOP _IOWR('B', 36, bioc_startstop)
-typedef struct _bioc_startstop {
- void *cookie;
- u_int8_t opcode;
-#define BIOCSUNIT_START 0x00
-#define BIOCSUNIT_STOP 0x01
- u_int8_t channel;
- u_int8_t target;
-} bioc_startstop;
-
-/* SHALL be implemented */
-#define BIOCSTATUS _IOWR('B', 37, bioc_status)
-typedef struct _bioc_status {
+#define BIOCDISK _IOWR('B', 33, bioc_disk)
+/* structure that represents a disk in a RAID volume */
+typedef struct _bioc_disk {
void *cookie;
- u_int8_t opcode;
-#define BIOCGSTAT_CHANGE 0x00 /* any changes since last call? */
-#define BIOCGSTAT_ALL 0x01 /* get all status */
-#define BIOCGSTAT_PHYSDISK 0x02 /* get physical disk status only */
-#define BIOCGSTAT_VIRTDISK 0x03 /* get virtual disk status only */
-#define BIOCGSTAT_BATTERY 0x04 /* get battery status only */
-#define BIOCGSTAT_ENCLOSURE 0x05 /* get enclosure status only */
-#define BIOCGSTAT_TEMPERATURE 0x06 /* get temperature status only */
- u_int8_t status; /* global status flag */
-#define BIOC_STATOK 0x00 /* status is OK */
-#define BIOC_STATDEGRAD 0x01 /* status is degraded */
-#define BIOC_STATCRIT 0x02 /* status is critical */
-#define BIOC_STATBAT 0x04 /* something wrong with battery */
-#define BIOC_STATENC 0x08 /* something wrong with enclosure */
-#define BIOC_STATTEMP 0x10 /* something is over/under heating */
- /* return fields used per request define in opcode */
- u_int8_t channels; /* max channels */
- u_int8_t buswidth; /* max physical drives per channel */
- /* filled in when called with BIOCGSTAT_PHYSDISK set */
- u_int8_t pdcount; /* physical disk counter */
- u_int8_t physdisk[BIOC_MAX_PHYSDISK];
-#define BIOC_PDUNUSED 0x00 /* disk not present */
-#define BIOC_PDONLINE 0x01 /* disk present */
-#define BIOC_PDOFFLINE 0x02 /* disk present but offline */
-#define BIOC_PDINUSE 0x04 /* critical operation in progress */
- /* filled in when called with BIOCGSTAT_VIRTDISK set */
- u_int8_t vdcount; /* virtual disk counter */
- u_int8_t virtdisk[BIOC_MAX_VIRTDISK];
-#define BIOC_VDUNUSED 0x00 /* disk not present */
-#define BIOC_VDONLINE 0x01 /* disk present */
-#define BIOC_VDOFFLINE 0x02 /* disk present but offline */
-#define BIOC_VDINUSE 0x04 /* critical operation in progress */
- /* filled in when called with BIOCGSTAT_BATTERY set */
- u_int8_t batstat; /* battery status */
-#define BIOC_BATNOTPRES 0x00 /* battery not present */
-#define BIOC_BATMISSING 0x01 /* battery removed */
-#define BIOC_BATVOLTERR 0x02 /* battery low/high power */
-#define BIOC_BATTEMP 0x04 /* battery over/under temp*/
- /* NOTYET: encloure status & temperature status */
-} bioc_status;
-
-/* OPTIONAL */
-/* depending on the controller it is handled either in userland or in kernel */
-#define BIOCBLINK _IOWR('B', 38, bioc_blink)
-typedef struct _bioc_blink {
+
+ int diskid; /* virtual disk id */
+ int status; /* current status */
+ int volid; /* associate with volume, if -1 unused */
+
+ quad_t size; /* size of the disk */
+
+ /* this is provided by the physical disks if suported */
+ char vendor[8]; /* vendor string */
+ char product[16]; /* product string */
+ char revision[4]; /* revision string */
+ char pad[4]; /* zero terminate in here */
+
+ /* XXX get this too? */
+ /* serial number */
+} bioc_disk;
+
+#define BIOCVOL _IOWR('B', 34, bioc_vol)
+/* structure that represents a RAID volume */
+typedef struct _bioc_vol {
void *cookie;
- u_int8_t opcode;
-#define BIOCSBLINK_BLINK 0x00
-#define BIOCSBLINK_UNBLINK 0x01
-#define BIOCSBLINK_ALERT 0x02
- u_int8_t channel;
- u_int8_t target;
-} bioc_blink;
+ int volid; /* volume id */
+ int status; /* current status */
+#define BIOC_SONLINE 0x00
+#define BIOC_SOFFLINE 0x01
+#define BIOC_SDEGRADED 0x02
+ quad_t size; /* size of the disk */
+ int level; /* raid level */
+ int nodisk; /* nr of drives */
+
+ /* this is provided by the RAID card */
+ char vendor[8]; /* vendor string */
+ char product[16]; /* product string */
+ char revision[4]; /* revision string */
+ char pad[4]; /* zero terminate in here */
+} bioc_vol;
+
+#define BIOC_INQ 0x01
+#define BIOC_DISK 0x02
+#define BIOC_VOL 0x04
diff --git a/sys/dev/ic/ami.c b/sys/dev/ic/ami.c
index f93c91e0c44..49e98cbbb3b 100644
--- a/sys/dev/ic/ami.c
+++ b/sys/dev/ic/ami.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ami.c,v 1.46 2005/07/03 22:31:27 krw Exp $ */
+/* $OpenBSD: ami.c,v 1.47 2005/07/18 01:29:01 marco Exp $ */
/*
* Copyright (c) 2001 Michael Shalayeff
@@ -45,7 +45,7 @@
* Theo de Raadt.
*/
-/*#define AMI_DEBUG */
+/*#define AMI_DEBUG */
#include <sys/param.h>
#include <sys/systm.h>
@@ -76,11 +76,11 @@
#define AMI_D_DMA 0x0008
#define AMI_D_IOCTL 0x0010
int ami_debug = 0
- | AMI_D_CMD
- | AMI_D_INTR
- | AMI_D_MISC
-/* | AMI_D_DMA */
-/* | AMI_D_IOCTL */
+/* | AMI_D_CMD*/
+/* | AMI_D_INTR*/
+/* | AMI_D_MISC*/
+/* | AMI_D_DMA*/
+ | AMI_D_IOCTL
;
#else
#define AMI_DPRINTF(m,a) /* m, a */
@@ -136,11 +136,19 @@ void ami_copy_internal_data(struct scsi_xfer *xs, void *v, size_t size);
int ami_inquire(struct ami_softc *sc, u_int8_t op);
#if NBIO > 0
+int ami_mgmt(struct ami_softc *, u_int8_t, u_int8_t, u_int8_t,
+ size_t, void *);
+int ami_drv_inq(struct ami_softc *, u_int8_t, u_int8_t, void *);
int ami_ioctl(struct device *, u_long, caddr_t);
+int ami_ioctl_inq(struct ami_softc *, bioc_inq *);
+int ami_ioctl_vol(struct ami_softc *, bioc_vol *);
+int ami_ioctl_disk(struct ami_softc *, bioc_disk *);
+#if 0
int ami_ioctl_alarm(struct ami_softc *, bioc_alarm *);
int ami_ioctl_startstop( struct ami_softc *, bioc_startstop *);
int ami_ioctl_status( struct ami_softc *, bioc_status *);
int ami_ioctl_passthru(struct ami_softc *, bioc_scsicmd *);
+#endif
#endif /* NBIO > 0 */
struct ami_ccb *
@@ -582,6 +590,7 @@ ami_attach(sc)
sc->sc_link.adapter = &ami_switch;
sc->sc_link.adapter_target = sc->sc_maxunits;
sc->sc_link.adapter_buswidth = sc->sc_maxunits;
+ sc->sc_state_ch = 1; /* mark state as changed */
#ifdef AMI_DEBUG
printf(": FW %s, BIOS v%s, %dMB RAM\n"
@@ -1680,6 +1689,7 @@ ami_scsi_ioctl(struct scsi_link *link, u_long cmd,
caddr_t addr, int flag, struct proc *p)
{
struct ami_softc *sc = (struct ami_softc *)link->adapter_softc;
+ /* u_int8_t target = link->target; */
if (sc->sc_ioctl)
return (sc->sc_ioctl(link->adapter_softc, cmd, addr));
@@ -1688,6 +1698,461 @@ ami_scsi_ioctl(struct scsi_link *link, u_long cmd,
}
#if NBIO > 0
+struct disk {
+ SLIST_ENTRY(disk) next;
+ bioc_disk bd;
+
+ int ch;
+ int tg;
+};
+
+struct volume {
+ SLIST_ENTRY(volume) next;
+ bioc_vol bv;
+};
+
+SLIST_HEAD(disk_list, disk);
+struct disk_list disks = SLIST_HEAD_INITIALIZER(disk);
+
+SLIST_HEAD(vol_list, volume);
+struct vol_list volumes = SLIST_HEAD_INITIALIZER(volume);
+
+int
+ami_ioctl(dev, cmd, addr)
+ struct device *dev;
+ u_long cmd;
+ caddr_t addr;
+{
+ struct ami_softc *sc = (struct ami_softc *)dev;
+ ami_lock_t lock;
+ int error = 0;
+
+ AMI_DPRINTF(AMI_D_IOCTL, ("%s: ioctl()\n", sc->sc_dev.dv_xname));
+
+ if (sc->sc_flags & AMI_BROKEN)
+ return ENODEV; /* can't do this to broken device for now */
+
+ lock = AMI_LOCK_AMI(sc);
+ if (sc->sc_flags & AMI_CMDWAIT) {
+ AMI_UNLOCK_AMI(sc, lock);
+ return EBUSY;
+ }
+
+ switch (cmd) {
+ case BIOCINQ:
+ case BIOCVOL:
+ case BIOCDISK:
+ sc->sc_flags |= AMI_CMDWAIT;
+ while (!TAILQ_EMPTY(&sc->sc_ccbq))
+ if (tsleep(&sc->sc_free_ccb, PRIBIO, "ami_ioctl",
+ 100 * 60) == EWOULDBLOCK)
+ return EWOULDBLOCK;
+ }
+
+ switch (cmd) {
+ case BIOCINQ:
+ AMI_DPRINTF(AMI_D_IOCTL, ("inquiry\n"));
+ error = ami_ioctl_inq(sc, (bioc_inq *)addr);
+ break;
+
+ case BIOCVOL:
+ AMI_DPRINTF(AMI_D_IOCTL, ("volume\n"));
+ error = ami_ioctl_vol(sc, (bioc_vol *)addr);
+ break;
+
+ case BIOCDISK:
+ AMI_DPRINTF(AMI_D_IOCTL, ("disk\n"));
+ error = ami_ioctl_disk(sc, (bioc_disk *)addr);
+ break;
+
+ default:
+ AMI_DPRINTF(AMI_D_IOCTL, ("%s: invalid ioctl\n",
+ sc->sc_dev.dv_xname));
+ error = EINVAL;
+ }
+
+ sc->sc_flags &= ~AMI_CMDWAIT;
+ wakeup(&sc->sc_ccbq);
+
+ AMI_UNLOCK_AMI(sc, lock);
+
+ return (error);
+}
+
+int
+ami_drv_inq(sc, ch, tg, inqbuf)
+ struct ami_softc *sc;
+ u_int8_t ch;
+ u_int8_t tg;
+ void *inqbuf;
+{
+ struct ami_ccb *ccb;
+ struct ami_iocmd *cmd;
+ struct ami_passthrough *ps;
+ struct scsi_inquiry_data *pp;
+ void *idata;
+ bus_dmamap_t idatamap;
+ bus_dma_segment_t idataseg[1];
+ paddr_t pa;
+ int error = 0;
+
+ if (!(idata = ami_allocmem(sc->dmat, &idatamap, idataseg, NBPG, 1,
+ "ami mgmt"))) {
+ error = ENOMEM;
+ goto bail;
+ }
+
+ pa = idataseg[0].ds_addr;
+ ps = idata;
+ pp = idata + sizeof *ps;
+
+ ccb = ami_get_ccb(sc);
+ ccb->ccb_data = NULL;
+ cmd = ccb->ccb_cmd;
+
+ cmd->acc_cmd = AMI_PASSTHRU;
+ cmd->acc_passthru.apt_data = htole32(pa);
+
+ memset(ps, 0, sizeof *ps);
+
+ ps->apt_channel = ch;
+ ps->apt_target = tg;
+ ps->apt_ncdb = sizeof(struct scsi_inquiry);
+ ps->apt_nsense = sizeof(struct scsi_sense_data);
+
+ ps->apt_cdb[0] = INQUIRY;
+ ps->apt_cdb[1] = 0;
+ ps->apt_cdb[2] = 0;
+ ps->apt_cdb[3] = 0;
+ ps->apt_cdb[4] = sizeof(struct scsi_inquiry_data); /* INQUIRY length */
+ ps->apt_cdb[5] = 0;
+
+ ps->apt_data = htole32(pa + sizeof *ps);
+ ps->apt_datalen = sizeof(struct scsi_inquiry_data);
+
+ AMI_DPRINTF(AMI_D_IOCTL, ("%s: ami_drv_inq(%p, %02x, %02x, ,%p) ",
+ sc->sc_dev.dv_xname, sc, ch, tg, inqbuf));
+
+ if (ami_cmd(ccb, BUS_DMA_WAITOK, 1) == 0) {
+ AMI_DPRINTF(AMI_D_IOCTL, ("completed\n"));
+
+ memcpy(inqbuf, pp, sizeof(struct scsi_inquiry_data));
+ }
+ else {
+ AMI_DPRINTF(AMI_D_IOCTL, ("failed\n"));
+
+ error = EINVAL;
+ }
+
+bail:
+ ami_freemem(sc->dmat, &idatamap, idataseg, NBPG, 1, "ami mgmt");
+
+ return (error);
+}
+
+int
+ami_mgmt(sc, opcode, par1, par2, size, buffer)
+ struct ami_softc *sc;
+ u_int8_t opcode;
+ u_int8_t par1;
+ u_int8_t par2;
+ size_t size;
+ void *buffer;
+{
+ struct ami_ccb *ccb;
+ struct ami_iocmd *cmd;
+ void *idata;
+ bus_dmamap_t idatamap;
+ bus_dma_segment_t idataseg[1];
+ paddr_t pa;
+ int error = 0;
+
+ if (!(idata = ami_allocmem(sc->dmat, &idatamap, idataseg, NBPG,
+ (size / NBPG) + 1, "ami mgmt"))) {
+ error = ENOMEM;
+ goto bail;
+ }
+
+ pa = idataseg[0].ds_addr;
+
+ ccb = ami_get_ccb(sc);
+ ccb->ccb_data = NULL;
+ cmd = ccb->ccb_cmd;
+
+ cmd->acc_cmd = opcode;
+ cmd->acc_io.aio_channel = par1;
+ cmd->acc_io.aio_param = par2;
+ cmd->acc_io.aio_data = htole32(pa);
+
+ AMI_DPRINTF(AMI_D_IOCTL, ("%s: ami_mgmt(%p, %02x, %02x, %02x, %d,%p) ",
+ sc->sc_dev.dv_xname, sc, opcode, par1, par2, size, buffer));
+
+ if (ami_cmd(ccb, BUS_DMA_WAITOK, 1) == 0) {
+ AMI_DPRINTF(AMI_D_IOCTL, ("completed\n"));
+
+ memcpy(buffer, idata, size);
+ }
+ else {
+ AMI_DPRINTF(AMI_D_IOCTL, ("failed\n"));
+
+ error = EINVAL;
+ }
+
+bail:;
+ ami_freemem(sc->dmat, &idatamap, idataseg, NBPG, (size / NBPG) + 1,
+ "ami mgmt");
+
+ return (error);
+}
+
+int
+ami_ioctl_inq(sc, bi)
+ struct ami_softc *sc;
+ bioc_inq *bi;
+{
+ struct scsi_inquiry_data inqbuf;
+ struct ami_big_diskarray *p; /* struct too large for stack */
+ struct volume *vol;
+ struct disk *dk;
+ int i, s, t, c;
+ int off;
+ int error = 0;
+
+ if (!sc->sc_state_ch) {
+ bi->novol = 0;
+ bi->nodisk = 0;
+ SLIST_FOREACH(vol, &volumes, next) {
+ bi->novol++;
+ bi->nodisk += vol->bv.nodisk;
+ }
+
+ return 0;
+ }
+
+ AMI_DPRINTF(AMI_D_IOCTL, ("%s: biocinq", sc->sc_dev.dv_xname));
+
+ p = malloc(sizeof *p, M_DEVBUF, M_NOWAIT);
+ if (!p) {
+ printf("%s: no memory for raw interface\n", sc->sc_dev.dv_xname);
+ return (ENOMEM);
+ }
+
+ bi->nodisk = 0;
+
+ for (c = 0; c < 4; c++) { /* FIXME get max channel from inq3 */
+ for (t = 0; t < AMI_MAX_TARGET; t++) {
+ if (!ami_drv_inq(sc, c, t, &inqbuf)) {
+ if ((inqbuf.device & SID_TYPE) != T_DIRECT)
+ /* XXX save c:t if PROC for later use */
+ continue; /* we only care about disk */
+
+ dk = malloc(sizeof(struct disk), M_DEVBUF,
+ M_NOWAIT);
+ if (!dk) {
+ /* FIXME */
+ panic("not enough memory.");
+ }
+
+ dk->ch = c;
+ dk->tg = t;
+ dk->bd.diskid = bi->nodisk;
+ dk->bd.status = 0; /* XXX xlate */
+ dk->bd.volid = -1; /* not yet claimed */
+ dk->bd.size = 0; /* GETCAP or get in 2nd pass */
+ strlcpy(dk->bd.vendor, inqbuf.vendor,
+ 8 + 16 + 4 + 1); /* vendor prod rev zero */
+
+ bi->nodisk++;
+
+ SLIST_INSERT_HEAD(&disks, dk, next);
+ }
+ else {
+ AMI_DPRINTF(AMI_D_IOCTL, ("c: %d t: %d "
+ "fail\n", c, t));
+ }
+ }
+ }
+
+ if (!ami_mgmt(sc, AMI_FCOP, AMI_FC_RDCONF, 0, sizeof *p, p)) {
+ bi->novol = p->ada_nld;
+
+ AMI_DPRINTF(AMI_D_IOCTL, ("novol: %d nodisk: %d p: %p\n",
+ bi->novol, bi->nodisk, &p));
+
+ /* setup volume list */
+ for (i = 0; i < p->ada_nld; i++) {
+ vol = malloc(sizeof(struct volume), M_DEVBUF, M_NOWAIT);
+ if (!vol) {
+ /* FIXME */
+ panic("not enough memory.");
+ }
+
+ vol->bv.volid = i;
+ vol->bv.status = 0; /* XXX translate ami status */
+ vol->bv.size = 0;
+ vol->bv.level = p->ada_ldrv[i].adl_raidlvl;
+ vol->bv.nodisk = 0;
+ /* do string ops here, question is how */
+
+ for (s = 0; s < p->ada_ldrv[i].adl_spandepth; s++) {
+ for (t = 0; t < p->ada_ldrv[i].adl_nstripes; t++) {
+ vol->bv.nodisk++;
+
+ off = p->ada_ldrv[i].adl_spans[s].ads_devs[t].add_channel * AMI_MAX_TARGET + p->ada_ldrv[i].adl_spans[s].ads_devs[t].add_target;
+ /* walk disk list and add size */
+ SLIST_FOREACH(dk, &disks, next) {
+ if (dk->ch != (p->ada_ldrv[i].adl_spans[s].ads_devs[t].add_target >> 4) || dk->tg != (p->ada_ldrv[i].adl_spans[s].ads_devs[t].add_target & 0x0f))
+ continue;
+
+ dk->bd.size = (quad_t)p->ada_pdrv[off].adp_size;
+ dk->bd.volid = i;
+
+ AMI_DPRINTF(AMI_D_IOCTL, ("\tdiskid: %d\n", dk->bd.diskid));
+ AMI_DPRINTF(AMI_D_IOCTL, ("\tstatus: %d\n", dk->bd.status));
+ AMI_DPRINTF(AMI_D_IOCTL, ("\tvolid : %d\n", dk->bd.volid));
+ AMI_DPRINTF(AMI_D_IOCTL, ("\tsize : %d\n", dk->bd.size));
+ AMI_DPRINTF(AMI_D_IOCTL, ("\tvendor: %s\n", dk->bd.vendor));
+ AMI_DPRINTF(AMI_D_IOCTL, ("\tchan : %d\n", dk->ch));
+ AMI_DPRINTF(AMI_D_IOCTL, ("\ttarget: %d\n", dk->tg));
+
+ }
+ }
+
+ switch (vol->bv.level) {
+ case 0:
+ vol->bv.size += p->ada_ldrv[i].adl_spans[s].ads_length * p->ada_ldrv[i].adl_nstripes;
+ break;
+
+ case 1:
+ vol->bv.size += p->ada_ldrv[i].adl_spans[s].ads_length;
+ break;
+
+ case 5:
+ vol->bv.size += p->ada_ldrv[i].adl_spans[s].ads_length * (p->ada_ldrv[i].adl_nstripes - 1);
+ break;
+ }
+
+ }
+
+ if (p->ada_ldrv[i].adl_spandepth > 1)
+ vol->bv.level *= 10;
+
+ vol->bv.size *= (quad_t)512;
+
+ AMI_DPRINTF(AMI_D_IOCTL, ("voldid: %d\n",
+ vol->bv.volid));
+ AMI_DPRINTF(AMI_D_IOCTL, ("status: %d\n",
+ vol->bv.status));
+ AMI_DPRINTF(AMI_D_IOCTL, ("size : %lld\n",
+ vol->bv.size));
+ AMI_DPRINTF(AMI_D_IOCTL, ("level : %d\n",
+ vol->bv.level));
+ AMI_DPRINTF(AMI_D_IOCTL, ("nodisk: %d\n",
+ vol->bv.nodisk));
+
+ SLIST_INSERT_HEAD(&volumes, vol, next);
+ }
+
+#if 0
+ printf("LD: %d %d\n", p->ada_nld, sizeof p);
+
+ for (i = 0; i < p->ada_nld; i++) {
+ printf("\tspandepth: %d\n", p->ada_ldrv[i].adl_spandepth);
+ printf("\traidlvl : %d\n", p->ada_ldrv[i].adl_raidlvl);
+ printf("\trd ahead : %d\n", p->ada_ldrv[i].adl_rdahead);
+ printf("\tstrp size: %d\n", p->ada_ldrv[i].adl_stripesz);
+ printf("\tstatus : %d\n", p->ada_ldrv[i].adl_status);
+ printf("\twr policy: %d\n", p->ada_ldrv[i].adl_wrpolicy);
+ printf("\tdirectio : %d\n", p->ada_ldrv[i].adl_directio);
+ printf("\tnr stripe: %d\n", p->ada_ldrv[i].adl_nstripes);
+ for (s = 0; s < p->ada_ldrv[i].adl_spandepth; s++) {
+ for (t = 0; t < p->ada_ldrv[i].adl_nstripes; t++) {
+ off = p->ada_ldrv[i].adl_spans[s].ads_devs[t].add_channel *
+ AMI_MAX_TARGET +
+ p->ada_ldrv[i].adl_spans[s].ads_devs[t].add_target;
+
+ printf("\t\tspan : %d\n", s);
+ printf("\t\tstart : %d\n",
+ (u_int32_t)p->ada_ldrv[i].adl_spans[s].ads_start);
+ printf("\t\tlength : %d\n",
+ (u_int32_t)p->ada_ldrv[i].adl_spans[s].ads_length);
+
+ printf("\t\t\tchannel : %02x\n",
+ p->ada_ldrv[i].adl_spans[s].ads_devs[t].add_channel);
+ printf("\t\t\ttarget : %02x\n",
+ p->ada_ldrv[i].adl_spans[s].ads_devs[t].add_target);
+ printf("\t\t\toff : %d\n");
+
+ printf("\t\t\ttype : %d\n",
+ p->ada_pdrv[off].adp_type);
+ printf("\t\t\tstatus : %d\n",
+ p->ada_pdrv[off].adp_ostatus);
+ printf("\t\t\tdepth : %d\n",
+ p->ada_pdrv[off].adp_tagdepth);
+ printf("\t\t\tsneg : %d\n",
+ p->ada_pdrv[off].adp_sneg);
+ printf("\t\t\tsize : %d\n\n",
+ (u_int32_t)p->ada_pdrv[off].adp_size);
+ }
+ }
+ }
+#endif
+ }
+ else {
+ AMI_DPRINTF(AMI_D_IOCTL, ("failed\n"));
+ error = EINVAL;
+ }
+
+ free(p, M_DEVBUF);
+
+ sc->sc_state_ch = 0; /* state normalized */
+
+ return (error);
+}
+
+int
+ami_ioctl_vol(sc, bv)
+ struct ami_softc *sc;
+ bioc_vol *bv;
+{
+ struct volume *vol;
+ int error = EINVAL;
+
+ AMI_DPRINTF(AMI_D_IOCTL, ("%s: biocvol\n", sc->sc_dev.dv_xname));
+
+ SLIST_FOREACH(vol, &volumes, next) {
+ if (bv->volid != vol->bv.volid)
+ continue;
+
+ memcpy(bv, &vol->bv, sizeof *bv);
+ error = 0;
+ }
+
+ return (error);
+}
+
+int
+ami_ioctl_disk(sc, bd)
+ struct ami_softc *sc;
+ bioc_disk *bd;
+{
+ struct disk *dk;
+ int error = EINVAL;
+
+ AMI_DPRINTF(AMI_D_IOCTL, ("%s: biocdisk\n", sc->sc_dev.dv_xname));
+
+ SLIST_FOREACH(dk, &disks, next) {
+ if (bd->diskid != dk->bd.diskid)
+ continue;
+
+ memcpy(bd, &dk->bd, sizeof *bd);
+ error = 0;
+ }
+
+ return (error);
+}
+
+#if 0
int
ami_ioctl(dev, cmd, addr)
struct device *dev;
@@ -2072,6 +2537,8 @@ ami_ioctl_passthru(sc, bp)
return (error);
}
+#endif
+
#endif /* NBIO > 0 */
#ifdef AMI_DEBUG
diff --git a/sys/dev/ic/amireg.h b/sys/dev/ic/amireg.h
index 9773c10c140..204237944e5 100644
--- a/sys/dev/ic/amireg.h
+++ b/sys/dev/ic/amireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: amireg.h,v 1.15 2005/07/14 04:41:04 marco Exp $ */
+/* $OpenBSD: amireg.h,v 1.16 2005/07/18 01:29:01 marco Exp $ */
/*
* Copyright (c) 2000 Michael Shalayeff
@@ -223,6 +223,8 @@
#define AMI_HSPDIAG 0xb1
#define AMI_GESENSEINFO 0xb2 /* get extended sense info */
#define AMI_SYSFLUSH 0xfe /* flush system */
+#define AMI_GETINQ 0xcf /* get proc & drive inquiry data */
+/* this needs to be removed when the new bioctl goes in */
#define AMI_ALARM 0x51 /* alarm functions */
#define AMI_ALARM_OFF 0x00
#define AMI_ALARM_ON 0x01
diff --git a/sys/dev/ic/amivar.h b/sys/dev/ic/amivar.h
index ae0cbc8cbcd..798e91937b0 100644
--- a/sys/dev/ic/amivar.h
+++ b/sys/dev/ic/amivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: amivar.h,v 1.11 2005/06/28 18:33:11 marco Exp $ */
+/* $OpenBSD: amivar.h,v 1.12 2005/07/18 01:29:01 marco Exp $ */
/*
* Copyright (c) 2001 Michael Shalayeff
@@ -92,6 +92,7 @@ struct ami_softc {
struct timeout sc_requeue_tmo;
struct timeout sc_poll_tmo;
int sc_dis_poll;
+ int sc_state_ch;
char sc_fwver[16];
char sc_biosver[16];