xref: /titanic_51/usr/src/boot/lib/libstand/read.c (revision 976852c7c99379de5f63105094194b9024a54029)
14a5d661aSToomas Soome /*	$NetBSD: read.c,v 1.8 1997/01/22 00:38:12 cgd Exp $	*/
24a5d661aSToomas Soome 
34a5d661aSToomas Soome /*-
44a5d661aSToomas Soome  * Copyright (c) 1993
54a5d661aSToomas Soome  *	The Regents of the University of California.  All rights reserved.
64a5d661aSToomas Soome  *
74a5d661aSToomas Soome  * This code is derived from software contributed to Berkeley by
84a5d661aSToomas Soome  * The Mach Operating System project at Carnegie-Mellon University.
94a5d661aSToomas Soome  *
104a5d661aSToomas Soome  * Redistribution and use in source and binary forms, with or without
114a5d661aSToomas Soome  * modification, are permitted provided that the following conditions
124a5d661aSToomas Soome  * are met:
134a5d661aSToomas Soome  * 1. Redistributions of source code must retain the above copyright
144a5d661aSToomas Soome  *    notice, this list of conditions and the following disclaimer.
154a5d661aSToomas Soome  * 2. Redistributions in binary form must reproduce the above copyright
164a5d661aSToomas Soome  *    notice, this list of conditions and the following disclaimer in the
174a5d661aSToomas Soome  *    documentation and/or other materials provided with the distribution.
184a5d661aSToomas Soome  * 4. Neither the name of the University nor the names of its contributors
194a5d661aSToomas Soome  *    may be used to endorse or promote products derived from this software
204a5d661aSToomas Soome  *    without specific prior written permission.
214a5d661aSToomas Soome  *
224a5d661aSToomas Soome  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
234a5d661aSToomas Soome  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
244a5d661aSToomas Soome  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
254a5d661aSToomas Soome  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
264a5d661aSToomas Soome  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
274a5d661aSToomas Soome  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
284a5d661aSToomas Soome  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
294a5d661aSToomas Soome  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
304a5d661aSToomas Soome  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
314a5d661aSToomas Soome  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
324a5d661aSToomas Soome  * SUCH DAMAGE.
334a5d661aSToomas Soome  *
344a5d661aSToomas Soome  *	@(#)read.c	8.1 (Berkeley) 6/11/93
354a5d661aSToomas Soome  *
364a5d661aSToomas Soome  *
374a5d661aSToomas Soome  * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
384a5d661aSToomas Soome  * All Rights Reserved.
394a5d661aSToomas Soome  *
404a5d661aSToomas Soome  * Author: Alessandro Forin
414a5d661aSToomas Soome  *
424a5d661aSToomas Soome  * Permission to use, copy, modify and distribute this software and its
434a5d661aSToomas Soome  * documentation is hereby granted, provided that both the copyright
444a5d661aSToomas Soome  * notice and this permission notice appear in all copies of the
454a5d661aSToomas Soome  * software, derivative works or modified versions, and any portions
464a5d661aSToomas Soome  * thereof, and that both notices appear in supporting documentation.
474a5d661aSToomas Soome  *
484a5d661aSToomas Soome  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
494a5d661aSToomas Soome  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
504a5d661aSToomas Soome  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
514a5d661aSToomas Soome  *
524a5d661aSToomas Soome  * Carnegie Mellon requests users of this software to return to
534a5d661aSToomas Soome  *
544a5d661aSToomas Soome  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
554a5d661aSToomas Soome  *  School of Computer Science
564a5d661aSToomas Soome  *  Carnegie Mellon University
574a5d661aSToomas Soome  *  Pittsburgh PA 15213-3890
584a5d661aSToomas Soome  *
594a5d661aSToomas Soome  * any improvements or extensions that they make and grant Carnegie the
604a5d661aSToomas Soome  * rights to redistribute these changes.
614a5d661aSToomas Soome  */
624a5d661aSToomas Soome 
634a5d661aSToomas Soome #include <sys/cdefs.h>
644a5d661aSToomas Soome __FBSDID("$FreeBSD$");
654a5d661aSToomas Soome 
664a5d661aSToomas Soome #include <sys/param.h>
674a5d661aSToomas Soome #include "stand.h"
684a5d661aSToomas Soome 
694a5d661aSToomas Soome ssize_t
704a5d661aSToomas Soome read(int fd, void *dest, size_t bcount)
714a5d661aSToomas Soome {
724a5d661aSToomas Soome     struct open_file	*f = &files[fd];
734a5d661aSToomas Soome     size_t		resid;
744a5d661aSToomas Soome 
754a5d661aSToomas Soome     if ((unsigned)fd >= SOPEN_MAX || !(f->f_flags & F_READ)) {
764a5d661aSToomas Soome 	errno = EBADF;
774a5d661aSToomas Soome 	return (-1);
784a5d661aSToomas Soome     }
794a5d661aSToomas Soome     if (f->f_flags & F_RAW) {
804a5d661aSToomas Soome 	twiddle(8);
814a5d661aSToomas Soome 	errno = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
82*976852c7SToomas Soome 	    btodb(f->f_offset), bcount, dest, &resid);
834a5d661aSToomas Soome 	if (errno)
844a5d661aSToomas Soome 	    return (-1);
854a5d661aSToomas Soome 	f->f_offset += resid;
864a5d661aSToomas Soome 	return (resid);
874a5d661aSToomas Soome     }
884a5d661aSToomas Soome 
894a5d661aSToomas Soome     /*
904a5d661aSToomas Soome      * Optimise reads from regular files using a readahead buffer.
914a5d661aSToomas Soome      * If the request can't be satisfied from the current buffer contents,
924a5d661aSToomas Soome      * check to see if it should be bypassed, or refill the buffer and complete
934a5d661aSToomas Soome      * the request.
944a5d661aSToomas Soome      */
954a5d661aSToomas Soome     resid = bcount;
964a5d661aSToomas Soome     for (;;) {
974a5d661aSToomas Soome 	size_t	ccount, cresid;
984a5d661aSToomas Soome 	/* how much can we supply? */
994a5d661aSToomas Soome 	ccount = imin(f->f_ralen, resid);
1004a5d661aSToomas Soome 	if (ccount > 0) {
1014a5d661aSToomas Soome 	    bcopy(f->f_rabuf + f->f_raoffset, dest, ccount);
1024a5d661aSToomas Soome 	    f->f_raoffset += ccount;
1034a5d661aSToomas Soome 	    f->f_ralen -= ccount;
1044a5d661aSToomas Soome 	    resid -= ccount;
1054a5d661aSToomas Soome 	    if (resid == 0)
1064a5d661aSToomas Soome 		return(bcount);
1074a5d661aSToomas Soome 	    dest = (char *)dest + ccount;
1084a5d661aSToomas Soome 	}
1094a5d661aSToomas Soome 
1104a5d661aSToomas Soome 	/* will filling the readahead buffer again not help? */
1114a5d661aSToomas Soome 	if (resid >= SOPEN_RASIZE) {
1124a5d661aSToomas Soome 	    /* bypass the rest of the request and leave the buffer empty */
1134a5d661aSToomas Soome 	    if ((errno = (f->f_ops->fo_read)(f, dest, resid, &cresid)))
1144a5d661aSToomas Soome 		    return (-1);
1154a5d661aSToomas Soome 	    return(bcount - cresid);
1164a5d661aSToomas Soome 	}
1174a5d661aSToomas Soome 
1184a5d661aSToomas Soome 	/* fetch more data */
1194a5d661aSToomas Soome 	if ((errno = (f->f_ops->fo_read)(f, f->f_rabuf, SOPEN_RASIZE, &cresid)))
1204a5d661aSToomas Soome 	    return (-1);
1214a5d661aSToomas Soome 	f->f_raoffset = 0;
1224a5d661aSToomas Soome 	f->f_ralen = SOPEN_RASIZE - cresid;
1234a5d661aSToomas Soome 	/* no more data, return what we had */
1244a5d661aSToomas Soome 	if (f->f_ralen == 0)
1254a5d661aSToomas Soome 	    return(bcount - resid);
1264a5d661aSToomas Soome     }
1274a5d661aSToomas Soome }
128