From owner-svn-src-user@FreeBSD.ORG Wed Jun 20 15:55:43 2012 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B38231065670; Wed, 20 Jun 2012 15:55:43 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 94CB78FC08; Wed, 20 Jun 2012 15:55:43 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q5KFthQb051947; Wed, 20 Jun 2012 15:55:43 GMT (envelope-from ae@svn.freebsd.org) Received: (from ae@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q5KFthgG051945; Wed, 20 Jun 2012 15:55:43 GMT (envelope-from ae@svn.freebsd.org) Message-Id: <201206201555.q5KFthgG051945@svn.freebsd.org> From: "Andrey V. Elsukov" Date: Wed, 20 Jun 2012 15:55:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r237323 - user/ae/bootcode/sys/boot/i386/libi386 X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 20 Jun 2012 15:55:43 -0000 Author: ae Date: Wed Jun 20 15:55:43 2012 New Revision: 237323 URL: http://svn.freebsd.org/changeset/base/237323 Log: Reimplement bd_opendisk and bd_closedisk functins using new API to get access to partition tables. Modified: user/ae/bootcode/sys/boot/i386/libi386/biosdisk.c Modified: user/ae/bootcode/sys/boot/i386/libi386/biosdisk.c ============================================================================== --- user/ae/bootcode/sys/boot/i386/libi386/biosdisk.c Wed Jun 20 15:45:50 2012 (r237322) +++ user/ae/bootcode/sys/boot/i386/libi386/biosdisk.c Wed Jun 20 15:55:43 2012 (r237323) @@ -96,6 +96,9 @@ static struct bdinfo } bdinfo [MAXBDDEV]; static int nbdinfo = 0; +#define BDSZ(od) (bdinfo[(od)->od_dkunit].bd_sectors) +#define BDSECSZ(od) (bdinfo[(od)->od_dkunit].bd_sectorsize) + static int bd_read(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest); static int bd_write(struct open_disk *od, daddr_t dblk, int blks, @@ -362,49 +365,123 @@ bd_open(struct open_file *f, ...) } static int -bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev) +diskread(void *dev, void *buf, size_t blocks, off_t offset) { - struct open_disk *od; - int error; - if (dev->d_unit >= nbdinfo) { - DEBUG("attempt to open nonexistent disk"); - return(ENXIO); - } - - od = (struct open_disk *)malloc(sizeof(struct open_disk)); - if (!od) { - DEBUG("no memory"); - return (ENOMEM); - } + return (bd_read(dev, offset, blocks, buf)); +} - /* Look up BIOS unit number, initalise open_disk structure */ - od->od_dkunit = dev->d_unit; - od->od_unit = bdinfo[od->od_dkunit].bd_unit; - od->od_flags = bdinfo[od->od_dkunit].bd_flags; - od->od_boff = 0; - error = 0; - DEBUG("open '%s', unit 0x%x slice %d partition %d", - i386_fmtdev(dev), dev->d_unit, - dev->d_kind.biosdisk.slice, dev->d_kind.biosdisk.partition); - - /* Get geometry for this open (removable device may have changed) */ - if (bd_getgeom(od)) { - DEBUG("can't get geometry"); - error = ENXIO; - goto out; - } +static int +bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev) +{ + struct open_disk *od; + struct ptable_entry part; + int error; - /* Determine disk layout. */ - error = bd_open_mbr(od, dev); - - out: - if (error) { - free(od); - } else { - *odp = od; /* return the open disk */ - } - return(error); + if (dev->d_unit >= nbdinfo) { + DEBUG("attempt to open nonexistent disk"); + return (ENXIO); + } + od = (struct open_disk *)malloc(sizeof(struct open_disk)); + if (!od) { + DEBUG("no memory"); + return (ENOMEM); + } + + /* Look up BIOS unit number, initalize open_disk structure */ + od->od_dkunit = dev->d_unit; + od->od_unit = bdinfo[od->od_dkunit].bd_unit; + od->od_ptable = bdinfo[od->od_dkunit].bd_ptable; + od->od_slice = 0; + od->od_boff = 0; + error = 0; + DEBUG("open '%s', unit 0x%x slice %d partition %d", + i386_fmtdev(dev), dev->d_unit, dev->d_kind.biosdisk.slice, + dev->d_kind.biosdisk.partition); + + /* Determine disk layout. */ + if (od->od_ptable == NULL) { + od->od_ptable = ptable_open(od, BDSZ(od), BDSECSZ(od), + diskread); + if (od->od_ptable == NULL) { + DEBUG("Can't read partition table"); + error = ENXIO; + goto out; + } + /* Save the result */ + bdinfo[od->od_dkunit].bd_ptable = od->od_ptable; + } + /* + * What we want to open: + * a whole disk: + * slice = -1 + * + * a MBR slice: + * slice = 1 .. 4 + * partition = -1 + * + * an EBR slice: + * slice = 5 .. N + * partition = -1 + * + * a GPT partition: + * slice = 1 .. N + * partition = 255 + * + * BSD partition within an MBR slice: + * slice = 1 .. N + * partition = 0 .. 19 + */ + if (dev->d_kind.biosdisk.slice > 0) { + /* Try to get information about partition */ + error = ptable_getpart(od->od_ptable, &part, + dev->d_kind.biosdisk.slice); + if (error != 0) /* Partition isn't exists */ + goto out; + /* Adjust open_disk's offset within the biosdisk */ + od->od_boff = part.start; + if (dev->d_kind.biosdisk.partition == -1 || + dev->d_kind.biosdisk.partition == 255) + goto out; /* Nothing more to do */ + + /* Try to read BSD label */ + od->od_ptable = ptable_open(od, part.end - part.start + 1, + SECSZ(od), diskread); + if (od->od_ptable == NULL) { + DEBUG("Can't read BSD label"); + error = ENXIO; + /* Keep parent partition table opened */ + goto out; + } + /* Save the slice number of the parent partition */ + od->od_slice = part.index; + error = ptable_getpart(od->od_ptable, &part, + dev->d_kind.biosdisk.partition); + if (error != 0) { + /* + * Keep parent partition table opened, but + * close this one (BSD label). + */ + ptable_close(od->od_ptable); + goto out; + } + /* Adjust open_disk's offset within the biosdisk */ + od->od_boff += part.start; + } else if (dev->d_kind.biosdisk.slice == 0) { + error = ptable_getbestpart(od->od_ptable, &part); + if (error != 0) + goto out; + /* Save the slice number of best partition to dev */ + dev->d_kind.biosdisk.slice = part.index; + od->od_boff = part.start; + } +out: + if (error != 0) { + free(od); + } else { + *odp = od; /* return the open disk */ + } + return (error); } static int @@ -421,8 +498,12 @@ bd_close(struct open_file *f) static void bd_closedisk(struct open_disk *od) { - DEBUG("open_disk %p", od); - free(od); + + DEBUG("close_disk %p", od); + /* Close only nested ptables */ + if (od->od_slice != 0 && od->od_ptable != NULL) + ptable_close(od->od_ptable); + free(od); } static int