Home | History | Annotate | Line # | Download | only in lib
      1  1.4    joerg /*	$NetBSD: riscosdisk.c,v 1.4 2011/07/17 20:54:35 joerg Exp $	*/
      2  1.1  reinoud 
      3  1.1  reinoud /*-
      4  1.2    bjh21  * Copyright (c) 2001, 2006 Ben Harris
      5  1.1  reinoud  * All rights reserved.
      6  1.1  reinoud  *
      7  1.1  reinoud  * Redistribution and use in source and binary forms, with or without
      8  1.1  reinoud  * modification, are permitted provided that the following conditions
      9  1.1  reinoud  * are met:
     10  1.1  reinoud  * 1. Redistributions of source code must retain the above copyright
     11  1.1  reinoud  *    notice, this list of conditions and the following disclaimer.
     12  1.1  reinoud  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  reinoud  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  reinoud  *    documentation and/or other materials provided with the distribution.
     15  1.1  reinoud  * 3. The name of the author may not be used to endorse or promote products
     16  1.1  reinoud  *    derived from this software without specific prior written permission.
     17  1.1  reinoud  *
     18  1.1  reinoud  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19  1.1  reinoud  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20  1.1  reinoud  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21  1.1  reinoud  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22  1.1  reinoud  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23  1.1  reinoud  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24  1.1  reinoud  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25  1.1  reinoud  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26  1.1  reinoud  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27  1.1  reinoud  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  1.1  reinoud  */
     29  1.1  reinoud 
     30  1.2    bjh21 #include <sys/types.h>
     31  1.2    bjh21 #include <sys/param.h>
     32  1.2    bjh21 #include <sys/disklabel.h>
     33  1.1  reinoud #include <lib/libsa/stand.h>
     34  1.1  reinoud #include <riscoscalls.h>
     35  1.2    bjh21 #include <riscosdisk.h>
     36  1.2    bjh21 #include <riscospart.h>
     37  1.1  reinoud 
     38  1.1  reinoud struct riscosdisk {
     39  1.2    bjh21 	void	*privword;
     40  1.1  reinoud 	int	drive;
     41  1.2    bjh21 	daddr_t	boff;
     42  1.1  reinoud };
     43  1.1  reinoud 
     44  1.2    bjh21 static void *
     45  1.2    bjh21 rodisk_getprivateword(char const *fsname)
     46  1.2    bjh21 {
     47  1.2    bjh21 	void *privword;
     48  1.2    bjh21 	char module[20];
     49  1.2    bjh21 	os_error *err;
     50  1.2    bjh21 
     51  1.2    bjh21 	/* XXX The %c dance is because libsa printf can't do %% */
     52  1.2    bjh21 	snprintf(module, sizeof(module), "FileCore%c%s", '%', fsname);
     53  1.2    bjh21 	err = xosmodule_lookup(module, NULL, NULL, NULL, &privword, NULL);
     54  1.2    bjh21 	if (err != NULL)
     55  1.2    bjh21 		return NULL;
     56  1.2    bjh21 	return privword;
     57  1.2    bjh21 }
     58  1.2    bjh21 
     59  1.1  reinoud int
     60  1.2    bjh21 rodisk_open(struct open_file *f, ... /* char const *fsname, int drive,
     61  1.2    bjh21     int partition */)
     62  1.1  reinoud {
     63  1.1  reinoud 	va_list ap;
     64  1.2    bjh21 	struct disklabel dl;
     65  1.1  reinoud 	char const *fsname;
     66  1.2    bjh21 	int drive, partition, nfd, nhd, err;
     67  1.1  reinoud 	struct riscosdisk *rd;
     68  1.2    bjh21 	void *privword;
     69  1.1  reinoud 
     70  1.1  reinoud 	va_start(ap, f);
     71  1.1  reinoud 	fsname = va_arg(ap, char const *);
     72  1.1  reinoud 	drive = va_arg(ap, int);
     73  1.2    bjh21 	partition = va_arg(ap, int);
     74  1.1  reinoud 	va_end(ap);
     75  1.1  reinoud 
     76  1.2    bjh21 	if ((privword = rodisk_getprivateword(fsname)) == NULL)
     77  1.2    bjh21 		return ECTLR;
     78  1.2    bjh21 	if (xfilecore_drives(&privword, NULL, &nfd, &nhd) != NULL)
     79  1.2    bjh21 		return ECTLR;
     80  1.2    bjh21 	if (drive < 0 ||
     81  1.2    bjh21 	    (drive < 4 && drive >= nfd) ||
     82  1.2    bjh21 	    drive >= nhd + 4)
     83  1.2    bjh21 		return EUNIT;
     84  1.2    bjh21 
     85  1.2    bjh21 	rd = alloc(sizeof(*rd));
     86  1.2    bjh21 	rd->privword = privword;
     87  1.2    bjh21 	rd->drive = drive;
     88  1.2    bjh21 	rd->boff = 0;
     89  1.2    bjh21 	f->f_devdata = rd;
     90  1.2    bjh21 	if (partition != RAW_PART) {
     91  1.2    bjh21 		err = getdisklabel_acorn(f, &dl);
     92  1.2    bjh21 		if (err != 0) {
     93  1.2    bjh21 			dealloc(rd, sizeof(*rd));
     94  1.2    bjh21 			return err;
     95  1.2    bjh21 		}
     96  1.2    bjh21 		if (partition >= dl.d_npartitions ||
     97  1.2    bjh21 		    dl.d_partitions[partition].p_size == 0) {
     98  1.2    bjh21 			dealloc(rd, sizeof(*rd));
     99  1.2    bjh21 			return EPART;
    100  1.2    bjh21 		}
    101  1.2    bjh21 		rd->boff = dl.d_partitions[partition].p_offset;
    102  1.2    bjh21 	}
    103  1.2    bjh21 	return 0;
    104  1.2    bjh21 }
    105  1.1  reinoud 
    106  1.2    bjh21 int
    107  1.2    bjh21 rodisk_close(struct open_file *f)
    108  1.2    bjh21 {
    109  1.2    bjh21 	struct riscosdisk *rd = f->f_devdata;
    110  1.1  reinoud 
    111  1.2    bjh21 	dealloc(rd, sizeof *rd);
    112  1.2    bjh21 	return 0;
    113  1.2    bjh21 }
    114  1.1  reinoud 
    115  1.2    bjh21 int
    116  1.2    bjh21 rodisk_strategy(void *devdata, int flag, daddr_t dblk, size_t size,
    117  1.2    bjh21     void *buf, size_t *rsize)
    118  1.2    bjh21 {
    119  1.2    bjh21 	struct riscosdisk *rd = devdata;
    120  1.2    bjh21 	size_t resid;
    121  1.2    bjh21 	uint32_t daddr, ndaddr;
    122  1.2    bjh21 	void *nbuf;
    123  1.2    bjh21 	os_error *err;
    124  1.2    bjh21 
    125  1.2    bjh21 	if (flag != F_READ)
    126  1.2    bjh21 		return EROFS;
    127  1.2    bjh21 
    128  1.2    bjh21 	dblk += rd->boff;
    129  1.2    bjh21 
    130  1.2    bjh21 	if (rsize) *rsize = 0;
    131  1.2    bjh21 	if (dblk < 1 << (29 - DEV_BSHIFT)) {
    132  1.2    bjh21 		daddr = (dblk * DEV_BSIZE) | (rd->drive << 29);
    133  1.2    bjh21 		if ((err = xfilecorediscop_read_sectors(0, daddr, buf, size,
    134  1.2    bjh21 		    &rd->privword, &ndaddr, &nbuf, &resid)) != NULL)
    135  1.2    bjh21 			goto eio;
    136  1.2    bjh21 	} else if (dblk < 1 << 29) {
    137  1.2    bjh21 		daddr = dblk | (rd->drive << 29);
    138  1.2    bjh21 		if ((err = xfilecoresectorop_read_sectors(0, daddr, buf, size,
    139  1.2    bjh21 		    &rd->privword, &ndaddr, &nbuf, &resid)) != NULL)
    140  1.2    bjh21 			goto eio;
    141  1.2    bjh21 	} else if (dblk < 1LL << (64 - DEV_BSHIFT)){
    142  1.2    bjh21 		struct filecore_daddr64 daddr64;
    143  1.2    bjh21 		daddr64.drive = rd->drive;
    144  1.2    bjh21 		daddr64.daddr = dblk * DEV_BSIZE;
    145  1.2    bjh21 		if ((err = xfilecorediscop64_read_sectors(0, &daddr64, buf,
    146  1.2    bjh21 		    size, NULL, &rd->privword, &ndaddr, &nbuf, &resid)) !=
    147  1.2    bjh21 		    NULL)
    148  1.2    bjh21 			goto eio;
    149  1.2    bjh21 	} else
    150  1.2    bjh21 		return EIO;
    151  1.2    bjh21 	if (rsize)
    152  1.2    bjh21 		*rsize = size - resid;
    153  1.2    bjh21 	return 0;
    154  1.2    bjh21 eio:
    155  1.2    bjh21 	printf("Error: %s\n", err->errmess);
    156  1.2    bjh21 	return EIO;
    157  1.2    bjh21 }
    158