xref: /netbsd-src/sys/arch/mvme68k/stand/libsa/bugdev.c (revision ce099b40997c43048fb78bd578195f81d2456523)
1*ce099b40Smartin /*	$NetBSD: bugdev.c,v 1.12 2008/04/28 20:23:29 martin Exp $	*/
2d14981d7Schuck 
37c5210bcSpk /*-
47c5210bcSpk  * Copyright (c) 1998 The NetBSD Foundation, Inc.
5d14981d7Schuck  * All rights reserved.
6d14981d7Schuck  *
77c5210bcSpk  * This code is derived from software contributed to The NetBSD Foundation
87c5210bcSpk  * by Paul Kranenburg.
97c5210bcSpk  *
10d14981d7Schuck  * Redistribution and use in source and binary forms, with or without
11d14981d7Schuck  * modification, are permitted provided that the following conditions
12d14981d7Schuck  * are met:
13d14981d7Schuck  * 1. Redistributions of source code must retain the above copyright
14d14981d7Schuck  *    notice, this list of conditions and the following disclaimer.
15d14981d7Schuck  * 2. Redistributions in binary form must reproduce the above copyright
16d14981d7Schuck  *    notice, this list of conditions and the following disclaimer in the
17d14981d7Schuck  *    documentation and/or other materials provided with the distribution.
18d14981d7Schuck  *
197c5210bcSpk  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
207c5210bcSpk  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
217c5210bcSpk  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
227c5210bcSpk  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
237c5210bcSpk  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
247c5210bcSpk  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
257c5210bcSpk  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
267c5210bcSpk  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
277c5210bcSpk  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
287c5210bcSpk  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
297c5210bcSpk  * POSSIBILITY OF SUCH DAMAGE.
30d14981d7Schuck  */
31d14981d7Schuck 
32d14981d7Schuck #include <sys/param.h>
33d14981d7Schuck #include <sys/disklabel.h>
34d14981d7Schuck #include <machine/prom.h>
35d14981d7Schuck 
36e63501d2Sjunyoung #include <lib/libsa/stand.h>
37d14981d7Schuck #include "libsa.h"
38d14981d7Schuck 
39d305a149Sjunyoung void cputobsdlabel(struct disklabel *lp, struct cpu_disklabel *clp);
40d14981d7Schuck 
41d14981d7Schuck int errno;
42d14981d7Schuck 
43d14981d7Schuck struct bugsc_softc {
44d14981d7Schuck 	int	fd;	/* Prom file descriptor */
45d14981d7Schuck 	int	poff;	/* Partition offset */
46d14981d7Schuck 	int	psize;	/* Partition size */
47d14981d7Schuck 	short	ctrl;
48d14981d7Schuck 	short	dev;
49d14981d7Schuck } bugsc_softc[1];
50d14981d7Schuck 
51d14981d7Schuck int
devopen(struct open_file * f,const char * fname,char ** file)52d305a149Sjunyoung devopen(struct open_file *f, const char *fname, char **file)
53d14981d7Schuck {
54aec399e3Sscw 	struct bugsc_softc *pp = &bugsc_softc[0];
55aec399e3Sscw 	int	error, pn = 0;
56d14981d7Schuck 	char	*dev, *cp;
57aec399e3Sscw 	size_t	nrd;
58aec399e3Sscw 	static	int iobuf[DEV_BSIZE / sizeof(int)];
59d14981d7Schuck 	struct disklabel sdlabel;
60d14981d7Schuck 
61d14981d7Schuck 	dev = bugargs.arg_start;
62d14981d7Schuck 
63d14981d7Schuck 	/*
64d14981d7Schuck 	 * Extract partition # from boot device string.
653adf82c9Sscw 	 * The Bug command line format of this is:
663adf82c9Sscw 	 *
673adf82c9Sscw 	 *   147-Bug> bo [drive],,[<d>:][kernel_name] [options]
683adf82c9Sscw 	 *
693adf82c9Sscw 	 * Where:
703adf82c9Sscw 	 *       [drive]         The bug LUN number, eg. 0
713adf82c9Sscw 	 *       [<d>:]          <d> is partition # ('a' to 'h')
723adf82c9Sscw 	 *       [kernel_name]   Eg. netbsd or /netbsd
733adf82c9Sscw 	 *       [options]       Eg. -s
743adf82c9Sscw 	 *
753adf82c9Sscw 	 * At this time, all we need do is scan for a ':', and assume the
763adf82c9Sscw 	 * preceding letter is a partition id.
77d14981d7Schuck 	 */
783adf82c9Sscw 	for (cp = dev + 1; *cp && cp <= bugargs.arg_end; cp++) {
793adf82c9Sscw 		if ( *cp == ':' ) {
803adf82c9Sscw 			pn = *(cp - 1) - 'a';
813adf82c9Sscw 			break;
823adf82c9Sscw 		}
833adf82c9Sscw 	}
843adf82c9Sscw 
853adf82c9Sscw 	if ( pn < 0 || pn >= MAXPARTITIONS ) {
863adf82c9Sscw 		printf("Invalid partition number; defaulting to 'a'\n");
873adf82c9Sscw 		pn = 0;
88d14981d7Schuck 	}
89d14981d7Schuck 
90d14981d7Schuck 	pp->fd = bugscopen(f);
91d14981d7Schuck 
92d14981d7Schuck 	if (pp->fd < 0) {
93d14981d7Schuck 		printf("Can't open device `%s'\n", dev);
94d305a149Sjunyoung 		return ENXIO;
95d14981d7Schuck 	}
96aec399e3Sscw 	error = bugscstrategy(pp, F_READ, LABELSECTOR, DEV_BSIZE, iobuf, &nrd);
97d14981d7Schuck 	if (error)
98d305a149Sjunyoung 		return error;
99aec399e3Sscw 	if (nrd != DEV_BSIZE)
100d305a149Sjunyoung 		return EINVAL;
101d14981d7Schuck 
102aec399e3Sscw 	/*LINTED*/
103aec399e3Sscw 	cputobsdlabel(&sdlabel, (struct cpu_disklabel *)&(iobuf[0]));
104d14981d7Schuck 	pp->poff = sdlabel.d_partitions[pn].p_offset;
105d14981d7Schuck 	pp->psize = sdlabel.d_partitions[pn].p_size;
106d14981d7Schuck 
107d14981d7Schuck 	f->f_dev = devsw;
108d14981d7Schuck 	f->f_devdata = (void *)pp;
109aec399e3Sscw 	/*LINTED*/
110d14981d7Schuck 	*file = (char *)fname;
111d305a149Sjunyoung 	return 0;
112d14981d7Schuck }
113d14981d7Schuck 
114d14981d7Schuck /* silly block scale factor */
115d14981d7Schuck #define BUG_BLOCK_SIZE 256
116d14981d7Schuck #define BUG_SCALE (512/BUG_BLOCK_SIZE)
117aec399e3Sscw /*ARGSUSED*/
118d14981d7Schuck int
bugscstrategy(void * devdata,int func,daddr_t dblk,size_t size,void * buf,size_t * rsize)119d305a149Sjunyoung bugscstrategy(void *devdata, int func, daddr_t dblk, size_t size, void *buf,
120d305a149Sjunyoung 	      size_t *rsize)
121d14981d7Schuck {
122d14981d7Schuck 	struct mvmeprom_dskio dio;
123aec399e3Sscw 	struct bugsc_softc *pp = (struct bugsc_softc *)devdata;
124d14981d7Schuck 	daddr_t	blk = dblk + pp->poff;
125d14981d7Schuck 
126d14981d7Schuck 	twiddle();
127d14981d7Schuck 
128d14981d7Schuck 	dio.ctrl_lun = pp->ctrl;
129d14981d7Schuck 	dio.dev_lun = pp->dev;
130d14981d7Schuck 	dio.status = 0;
131d14981d7Schuck 	dio.pbuffer = buf;
132d14981d7Schuck 	dio.blk_num = blk * BUG_SCALE;
133d14981d7Schuck 	dio.blk_cnt = size / BUG_BLOCK_SIZE; /* assumed size in bytes */
134d14981d7Schuck 	dio.flag = 0;
135d14981d7Schuck 	dio.addr_mod = 0;
136d14981d7Schuck #ifdef DEBUG
137d14981d7Schuck 	printf("bugscstrategy: size=%d blk=%d buf=%x\n", size, blk, buf);
138d14981d7Schuck 	printf("ctrl %d dev %d\n", dio.ctrl_lun, dio.dev_lun);
139d14981d7Schuck #endif
140d14981d7Schuck 	mvmeprom_diskrd(&dio);
141d14981d7Schuck 
142d14981d7Schuck 	*rsize = dio.blk_cnt * BUG_BLOCK_SIZE;
143d14981d7Schuck #ifdef DEBUG
144d14981d7Schuck 	printf("rsize %d status %x\n", *rsize, dio.status);
145d14981d7Schuck #endif
146d14981d7Schuck 
147d14981d7Schuck 	if (dio.status)
148d305a149Sjunyoung 		return EIO;
149d305a149Sjunyoung 	return 0;
150d14981d7Schuck }
151d14981d7Schuck 
152d14981d7Schuck int
bugscopen(struct open_file * f,...)153e1ffd766She bugscopen(struct open_file *f, ...)
154d14981d7Schuck {
155a07f7c80Stsutsui 
156d14981d7Schuck #ifdef DEBUG
157d14981d7Schuck 	printf("bugscopen:\n");
158d14981d7Schuck #endif
159d14981d7Schuck 
160d14981d7Schuck 	f->f_devdata = (void *)bugsc_softc;
161d14981d7Schuck 	bugsc_softc[0].ctrl = (short)bugargs.ctrl_lun;
162d14981d7Schuck 	bugsc_softc[0].dev =  (short)bugargs.dev_lun;
163d14981d7Schuck #ifdef DEBUG
164d14981d7Schuck 	printf("using mvmebug ctrl %d dev %d\n",
165d14981d7Schuck 	    bugsc_softc[0].ctrl, bugsc_softc[0].dev);
166d14981d7Schuck #endif
167d305a149Sjunyoung 	return 0;
168d14981d7Schuck }
169d14981d7Schuck 
170aec399e3Sscw /*ARGSUSED*/
171d14981d7Schuck int
bugscclose(struct open_file * f)172d305a149Sjunyoung bugscclose(struct open_file *f)
173d14981d7Schuck {
174a07f7c80Stsutsui 
175d305a149Sjunyoung 	return EIO;
176d14981d7Schuck }
177d14981d7Schuck 
178aec399e3Sscw /*ARGSUSED*/
179d14981d7Schuck int
bugscioctl(struct open_file * f,u_long cmd,void * data)180d305a149Sjunyoung bugscioctl(struct open_file *f, u_long cmd, void *data)
181d14981d7Schuck {
182a07f7c80Stsutsui 
183d305a149Sjunyoung 	return EIO;
184d14981d7Schuck }
185d14981d7Schuck 
186d14981d7Schuck void
cputobsdlabel(struct disklabel * lp,struct cpu_disklabel * clp)187d305a149Sjunyoung cputobsdlabel(struct disklabel *lp, struct cpu_disklabel *clp)
188d14981d7Schuck {
189d14981d7Schuck 	int i;
190d14981d7Schuck 
191a07f7c80Stsutsui 	lp->d_magic   = (uint32_t)clp->magic1;
192a07f7c80Stsutsui 	lp->d_type    = (uint16_t)clp->type;
193a07f7c80Stsutsui 	lp->d_subtype = (uint16_t)clp->subtype;
194aec399e3Sscw 
195c1ab2b54Sscw 	memcpy(lp->d_typename, clp->vid_vd, 16);
196c1ab2b54Sscw 	memcpy(lp->d_packname, clp->packname, 16);
197d14981d7Schuck 
198a07f7c80Stsutsui 	lp->d_secsize        = (uint32_t)clp->cfg_psm;
199a07f7c80Stsutsui 	lp->d_nsectors       = (uint32_t)clp->cfg_spt;
200a07f7c80Stsutsui 	lp->d_ncylinders     = (uint32_t)clp->cfg_trk; /* trk is num of cyl! */
201a07f7c80Stsutsui 	lp->d_ntracks        = (uint32_t)clp->cfg_hds;
202a07f7c80Stsutsui 	lp->d_secpercyl      = (uint32_t)clp->secpercyl;
203a07f7c80Stsutsui 	lp->d_secperunit     = (uint32_t)clp->secperunit;
204a07f7c80Stsutsui 	lp->d_sparespertrack = (uint16_t)clp->sparespertrack;
205a07f7c80Stsutsui 	lp->d_sparespercyl   = (uint16_t)clp->sparespercyl;
206a07f7c80Stsutsui 	lp->d_acylinders     = (uint32_t)clp->acylinders;
207a07f7c80Stsutsui 	lp->d_rpm            = (uint16_t)clp->rpm;
208a07f7c80Stsutsui 	lp->d_interleave     = (uint16_t)clp->cfg_ilv;
209a07f7c80Stsutsui 	lp->d_trackskew      = (uint16_t)clp->cfg_sof;
210a07f7c80Stsutsui 	lp->d_cylskew        = (uint16_t)clp->cylskew;
211a07f7c80Stsutsui 	lp->d_headswitch     = (uint32_t)clp->headswitch;
212d14981d7Schuck 
213d14981d7Schuck 	/* this silly table is for winchester drives */
214d14981d7Schuck 	switch (clp->cfg_ssr) {
215d14981d7Schuck 	case 0:
216d14981d7Schuck 		lp->d_trkseek = 0;
217d14981d7Schuck 		break;
218d14981d7Schuck 	case 1:
219d14981d7Schuck 		lp->d_trkseek = 6;
220d14981d7Schuck 		break;
221d14981d7Schuck 	case 2:
222d14981d7Schuck 		lp->d_trkseek = 10;
223d14981d7Schuck 		break;
224d14981d7Schuck 	case 3:
225d14981d7Schuck 		lp->d_trkseek = 15;
226d14981d7Schuck 		break;
227d14981d7Schuck 	case 4:
228d14981d7Schuck 		lp->d_trkseek = 20;
229d14981d7Schuck 		break;
230d14981d7Schuck 	default:
231d14981d7Schuck 		lp->d_trkseek = 0;
232d14981d7Schuck 		break;
233d14981d7Schuck 	}
234a07f7c80Stsutsui 	lp->d_flags = (uint32_t)clp->flags;
235aec399e3Sscw 
236d14981d7Schuck 	for (i = 0; i < NDDATA; i++)
237a07f7c80Stsutsui 		lp->d_drivedata[i] = (uint32_t)clp->drivedata[i];
238aec399e3Sscw 
239d14981d7Schuck 	for (i = 0; i < NSPARE; i++)
240a07f7c80Stsutsui 		lp->d_spare[i] = (uint32_t)clp->spare[i];
241aec399e3Sscw 
242a07f7c80Stsutsui 	lp->d_magic2      = (uint32_t)clp->magic2;
243a07f7c80Stsutsui 	lp->d_checksum    = (uint16_t)clp->checksum;
244a07f7c80Stsutsui 	lp->d_npartitions = (uint16_t)clp->partitions;
245a07f7c80Stsutsui 	lp->d_bbsize      = (uint32_t)clp->bbsize;
246a07f7c80Stsutsui 	lp->d_sbsize      = (uint32_t)clp->sbsize;
247aec399e3Sscw 
248c1ab2b54Sscw 	memcpy(&(lp->d_partitions[0]), clp->vid_4,
249c1ab2b54Sscw 	    sizeof(struct partition) * 4);
250aec399e3Sscw 
251aec399e3Sscw 	/* CONSTCOND */
252c1ab2b54Sscw 	memcpy(&(lp->d_partitions[4]), clp->cfg_4, sizeof(struct partition)
253d14981d7Schuck 	    * ((MAXPARTITIONS < 16) ? (MAXPARTITIONS - 4) : 12));
254d14981d7Schuck }
255