Module Name:    src
Committed By:   jmcneill
Date:           Sat Sep 27 21:01:51 UTC 2014

Modified Files:
        src/sys/dev/ic: mpt_netbsd.c

Log Message:
implement BIOCDISK_NOVOL


To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/sys/dev/ic/mpt_netbsd.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ic/mpt_netbsd.c
diff -u src/sys/dev/ic/mpt_netbsd.c:1.28 src/sys/dev/ic/mpt_netbsd.c:1.29
--- src/sys/dev/ic/mpt_netbsd.c:1.28	Sat Sep 27 18:16:56 2014
+++ src/sys/dev/ic/mpt_netbsd.c	Sat Sep 27 21:01:51 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: mpt_netbsd.c,v 1.28 2014/09/27 18:16:56 jmcneill Exp $	*/
+/*	$NetBSD: mpt_netbsd.c,v 1.29 2014/09/27 21:01:51 jmcneill Exp $	*/
 
 /*
  * Copyright (c) 2003 Wasabi Systems, Inc.
@@ -77,7 +77,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mpt_netbsd.c,v 1.28 2014/09/27 18:16:56 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mpt_netbsd.c,v 1.29 2014/09/27 21:01:51 jmcneill Exp $");
 
 #include "bio.h"
 
@@ -112,6 +112,7 @@ static int	mpt_bio_ioctl(device_t, u_lon
 static int	mpt_bio_ioctl_inq(mpt_softc_t *, struct bioc_inq *);
 static int	mpt_bio_ioctl_vol(mpt_softc_t *, struct bioc_vol *);
 static int	mpt_bio_ioctl_disk(mpt_softc_t *, struct bioc_disk *);
+static int	mpt_bio_ioctl_disk_novol(mpt_softc_t *, struct bioc_disk *);
 static int	mpt_bio_ioctl_setstate(mpt_softc_t *, struct bioc_setstate *);
 #endif
 
@@ -1639,6 +1640,35 @@ fail:
 	return NULL;
 }
 
+static fCONFIG_PAGE_IOC_3 *
+mpt_get_cfg_page_ioc3(mpt_softc_t *mpt)
+{
+	fCONFIG_PAGE_HEADER hdr;
+	fCONFIG_PAGE_IOC_3 *ioc3;
+	int rv;
+
+	rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_IOC, 3, 0, &hdr);
+	if (rv)
+		return NULL;
+
+	ioc3 = malloc(hdr.PageLength * 4, M_DEVBUF, M_WAITOK | M_ZERO);
+	if (ioc3 == NULL)
+		return NULL;
+
+	memcpy(ioc3, &hdr, sizeof(hdr));
+
+	rv = mpt_read_cfg_page(mpt, 0, &ioc3->Header);
+	if (rv)
+		goto fail;
+
+	return ioc3;
+
+fail:
+	free(ioc3, M_DEVBUF);
+	return NULL;
+}
+
+
 static fCONFIG_PAGE_RAID_VOL_0 *
 mpt_get_cfg_page_raid_vol0(mpt_softc_t *mpt, int address)
 {
@@ -1737,6 +1767,9 @@ mpt_bio_ioctl(device_t dev, u_long cmd, 
 	case BIOCVOL:
 		error = mpt_bio_ioctl_vol(mpt, addr);
 		break;
+	case BIOCDISK_NOVOL:
+		error = mpt_bio_ioctl_disk_novol(mpt, addr);
+		break;
 	case BIOCDISK:
 		error = mpt_bio_ioctl_disk(mpt, addr);
 		break;
@@ -1758,16 +1791,23 @@ static int
 mpt_bio_ioctl_inq(mpt_softc_t *mpt, struct bioc_inq *bi)
 {	
 	fCONFIG_PAGE_IOC_2 *ioc2;
+	fCONFIG_PAGE_IOC_3 *ioc3;
 
 	ioc2 = mpt_get_cfg_page_ioc2(mpt);
 	if (ioc2 == NULL)
 		return EIO;
+	ioc3 = mpt_get_cfg_page_ioc3(mpt);
+	if (ioc3 == NULL) {
+		free(ioc2, M_DEVBUF);
+		return EIO;
+	}
 
 	strlcpy(bi->bi_dev, device_xname(mpt->sc_dev), sizeof(bi->bi_dev));
 	bi->bi_novol = ioc2->NumActiveVolumes;
-	bi->bi_nodisk = ioc2->NumActivePhysDisks;
+	bi->bi_nodisk = ioc3->NumPhysDisks;
 
 	free(ioc2, M_DEVBUF);
+	free(ioc3, M_DEVBUF);
 
 	return 0;
 }
@@ -1868,38 +1908,16 @@ fail:
 	return EINVAL;
 }
 
-static int
-mpt_bio_ioctl_disk(mpt_softc_t *mpt, struct bioc_disk *bd)
+static void
+mpt_bio_ioctl_disk_common(mpt_softc_t *mpt, struct bioc_disk *bd,
+    int address)
 {
-	fCONFIG_PAGE_IOC_2 *ioc2 = NULL;
-	fCONFIG_PAGE_RAID_VOL_0 *rvol0 = NULL;
-	fCONFIG_PAGE_IOC_2_RAID_VOL *ioc2rvol;
 	fCONFIG_PAGE_RAID_PHYS_DISK_0 *phys = NULL;
 	char vendor_id[9], product_id[17], product_rev_level[5];
-	int address;
-
-	ioc2 = mpt_get_cfg_page_ioc2(mpt);
-	if (ioc2 == NULL)
-		return EIO;
-
-	if (bd->bd_volid < 0 || bd->bd_volid >= ioc2->NumActiveVolumes)
-		goto fail;
-
-	ioc2rvol = &ioc2->RaidVolume[bd->bd_volid];
-	address = ioc2rvol->VolumeID | (ioc2rvol->VolumeBus << 8);
-
-	rvol0 = mpt_get_cfg_page_raid_vol0(mpt, address);
-	if (rvol0 == NULL)
-		goto fail;
-
-	if (bd->bd_diskid < 0 || bd->bd_diskid >= rvol0->NumPhysDisks)
-		goto fail;
-
-	address = rvol0->PhysDisk[bd->bd_diskid].PhysDiskNum;
 
 	phys = mpt_get_cfg_page_raid_phys_disk0(mpt, address);
 	if (phys == NULL)
-		goto fail;
+		return;
 
 	scsipi_strvis(vendor_id, sizeof(vendor_id),
 	    phys->InquiryData.VendorID, sizeof(phys->InquiryData.VendorID));
@@ -1940,14 +1958,71 @@ mpt_bio_ioctl_disk(mpt_softc_t *mpt, str
 		break;
 	}
 
-	free(ioc2, M_DEVBUF);
 	free(phys, M_DEVBUF);
+}
+
+static int
+mpt_bio_ioctl_disk_novol(mpt_softc_t *mpt, struct bioc_disk *bd)
+{
+	fCONFIG_PAGE_IOC_3 *ioc3 = NULL;
+	int address;
+
+	ioc3 = mpt_get_cfg_page_ioc3(mpt);
+	if (ioc3 == NULL)
+		return EIO;
+
+	if (bd->bd_diskid < 0 || bd->bd_diskid >= ioc3->NumPhysDisks)
+		goto fail;
+
+	address = ioc3->PhysDisk[bd->bd_diskid].PhysDiskNum;
+
+	mpt_bio_ioctl_disk_common(mpt, bd, address);
+
+	free(ioc3, M_DEVBUF);
+
+	return 0;
+
+fail:
+	if (ioc3) free(ioc3, M_DEVBUF);
+	return EINVAL;
+}
+
+
+static int
+mpt_bio_ioctl_disk(mpt_softc_t *mpt, struct bioc_disk *bd)
+{
+	fCONFIG_PAGE_IOC_2 *ioc2 = NULL;
+	fCONFIG_PAGE_RAID_VOL_0 *rvol0 = NULL;
+	fCONFIG_PAGE_IOC_2_RAID_VOL *ioc2rvol;
+	int address;
+
+	ioc2 = mpt_get_cfg_page_ioc2(mpt);
+	if (ioc2 == NULL)
+		return EIO;
+
+	if (bd->bd_volid < 0 || bd->bd_volid >= ioc2->NumActiveVolumes)
+		goto fail;
+
+	ioc2rvol = &ioc2->RaidVolume[bd->bd_volid];
+	address = ioc2rvol->VolumeID | (ioc2rvol->VolumeBus << 8);
+
+	rvol0 = mpt_get_cfg_page_raid_vol0(mpt, address);
+	if (rvol0 == NULL)
+		goto fail;
+
+	if (bd->bd_diskid < 0 || bd->bd_diskid >= rvol0->NumPhysDisks)
+		goto fail;
+
+	address = rvol0->PhysDisk[bd->bd_diskid].PhysDiskNum;
+
+	mpt_bio_ioctl_disk_common(mpt, bd, address);
+
+	free(ioc2, M_DEVBUF);
 
 	return 0;
 
 fail:
 	if (ioc2) free(ioc2, M_DEVBUF);
-	if (phys) free(phys, M_DEVBUF);
 	return EINVAL;
 }
 

Reply via email to