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