199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (c) 2001 John H. Baldwin <jhb@FreeBSD.org>
199767f8919635c4928607450d9e0abb932109ceToomas Soome * All rights reserved.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Redistribution and use in source and binary forms, with or without
199767f8919635c4928607450d9e0abb932109ceToomas Soome * modification, are permitted provided that the following conditions
199767f8919635c4928607450d9e0abb932109ceToomas Soome * 1. Redistributions of source code must retain the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome * notice, this list of conditions and the following disclaimer.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome * notice, this list of conditions and the following disclaimer in the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * documentation and/or other materials provided with the distribution.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
199767f8919635c4928607450d9e0abb932109ceToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
199767f8919635c4928607450d9e0abb932109ceToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
199767f8919635c4928607450d9e0abb932109ceToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
199767f8919635c4928607450d9e0abb932109ceToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
199767f8919635c4928607450d9e0abb932109ceToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
199767f8919635c4928607450d9e0abb932109ceToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
199767f8919635c4928607450d9e0abb932109ceToomas Soome * SUCH DAMAGE.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * BIOS CD device handling for CD's that have been booted off of via no
199767f8919635c4928607450d9e0abb932109ceToomas Soome * emulation booting as defined in the El Torito standard.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Ideas and algorithms from:
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Major numbers for devices we frontend for. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args)
199767f8919635c4928607450d9e0abb932109ceToomas Soome * List of BIOS devices, translation from disk unit number to
199767f8919635c4928607450d9e0abb932109ceToomas Soome * BIOS unit number.
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int bc_read(int unit, daddr_t dblk, int blks, caddr_t dest);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int bc_init(void);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int bc_strategy(void *devdata, int flag, daddr_t dblk,
199767f8919635c4928607450d9e0abb932109ceToomas Soome size_t offset, size_t size, char *buf, size_t *rsize);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int bc_realstrategy(void *devdata, int flag, daddr_t dblk,
199767f8919635c4928607450d9e0abb932109ceToomas Soome size_t offset, size_t size, char *buf, size_t *rsize);
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Translate between BIOS device numbers and our private unit numbers.
199767f8919635c4928607450d9e0abb932109ceToomas Soome DEBUG("looking for bios device 0x%x", biosdev);
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; i < nbcinfo; i++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome DEBUG("bc unit %d is BIOS device 0x%x", i, bcinfo[i].bc_unit);
199767f8919635c4928607450d9e0abb932109ceToomas Soome * We can't quiz, we have to be told what device to use, so this functoin
199767f8919635c4928607450d9e0abb932109ceToomas Soome * doesn't do anything. Instead, the loader calls bc_add() with the BIOS
199767f8919635c4928607450d9e0abb932109ceToomas Soome * device number to add.
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (-1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (-1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome bcache_add_dev(nbcinfo); /* register cd device in bcache */
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Print information about disks
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; i < nbcinfo; i++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Attempt to open the disk described by (dev) for use by (f).
199767f8919635c4928607450d9e0abb932109ceToomas Soomebc_strategy(void *devdata, int rw, daddr_t dblk, size_t offset, size_t size,
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (bcache_strategy(&bcd, rw, dblk, offset, size, buf, rsize));
199767f8919635c4928607450d9e0abb932109ceToomas Soomebc_realstrategy(void *devdata, int rw, daddr_t dblk, size_t offset, size_t size,
199767f8919635c4928607450d9e0abb932109ceToomas Soome DEBUG("read %d from %lld to %p", blks, dblk, buf);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((blks = bc_read(unit, dblk, blks, buf)) < 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome fragsize, dblk, blks, buf + (blks * BIOSCD_SECSIZE));
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (fragsize && bc_read(unit, dblk + blks, 1, fragbuf) != 1) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome bcopy(fragbuf, buf + (blks * BIOSCD_SECSIZE), fragsize);
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Max number of sectors to bounce-buffer at a time. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* return negative value for an error, otherwise blocks read */
199767f8919635c4928607450d9e0abb932109ceToomas Soomebc_read(int unit, daddr_t dblk, int blks, caddr_t dest)
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Just in case some idiot actually tries to read -1 blocks... */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (-1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* If nothing to do, just return succcess. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Decide whether we have to bounce */
199767f8919635c4928607450d9e0abb932109ceToomas Soome * The destination buffer is above first 1MB of
199767f8919635c4928607450d9e0abb932109ceToomas Soome * physical memory so we have to arrange a suitable
199767f8919635c4928607450d9e0abb932109ceToomas Soome * bounce buffer.
199767f8919635c4928607450d9e0abb932109ceToomas Soome while (resid > 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Loop retrying the operation a couple of times. The BIOS
199767f8919635c4928607450d9e0abb932109ceToomas Soome * may also retry.
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* If retrying, reset the drive */
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* fall back to 1 sector read */
199767f8919635c4928607450d9e0abb932109ceToomas Soome DEBUG("%d sectors from %lld to %p (0x%x) %s", x, dblk, p,
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* still an error? break off */
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* hexdump(dest, (blks * BIOSCD_SECSIZE)); */
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Return a suitable dev_t value for (dev).
199767f8919635c4928607450d9e0abb932109ceToomas Soome DEBUG("unit %d BIOS device %d", unit, biosdev);
199767f8919635c4928607450d9e0abb932109ceToomas Soome * XXX: Need to examine device spec here to figure out if SCSI or
199767f8919635c4928607450d9e0abb932109ceToomas Soome * ATAPI. No idea on how to figure out device number. All we can
199767f8919635c4928607450d9e0abb932109ceToomas Soome * really pass to the kernel is what bus and device on which bus we
199767f8919635c4928607450d9e0abb932109ceToomas Soome * were booted from, which dev_t isn't well suited to since those
199767f8919635c4928607450d9e0abb932109ceToomas Soome * number don't match to unit numbers very well. We may just need
199767f8919635c4928607450d9e0abb932109ceToomas Soome * to engage in a hack where we pass -C to the boot args if we are
199767f8919635c4928607450d9e0abb932109ceToomas Soome * the boot device.
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* XXX: Assume partition 'a'. */