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