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; }