Home | History | Annotate | Line # | Download | only in boot
      1 /*	$NetBSD: tmscp.c,v 1.9 2017/05/22 16:59:32 ragge Exp $ */
      2 /*
      3  * Copyright (c) 1995 Ludd, University of Lule}, Sweden.
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27  /* All bugs are subject to removal without further notice */
     28 
     29 #define NRSP 0 /* Kludge */
     30 #define NCMD 0 /* Kludge */
     31 
     32 #include <sys/param.h>
     33 #include <sys/disklabel.h>
     34 
     35 #include <lib/libsa/stand.h>
     36 
     37 #include "../include/pte.h"
     38 #include <dev/mscp/mscp.h>
     39 #include <dev/mscp/mscpreg.h>
     40 
     41 #include "vaxstand.h"
     42 
     43 static command(int,int);
     44 
     45 /*
     46  * These routines for TMSCP tape standalone boot is very simple,
     47  * assuming a lots of thing like that we only working at one tape at
     48  * a time, no separate routines for uba driver etc..
     49  * This code is directly copied from ra disk driver.
     50  */
     51 
     52 struct ra_softc {
     53 	int udaddr;
     54 	int ubaddr;
     55 	int unit;
     56 };
     57 
     58 static volatile struct uda {
     59         struct  mscp_1ca uda_ca;           /* communications area */
     60         struct  mscp uda_rsp;     /* response packets */
     61         struct  mscp uda_cmd;     /* command packets */
     62 } uda;
     63 
     64 struct  udadevice {
     65 	short udaip;
     66 	short udasa;
     67 };
     68 
     69 static volatile struct uda *ubauda;
     70 static volatile struct udadevice *udacsr;
     71 static struct ra_softc ra_softc;
     72 static int curblock;
     73 
     74 
     75 tmscpopen(struct open_file *f, int adapt, int ctlr, int unit, int part)
     76 {
     77 	char *msg;
     78 	extern u_int tmsaddr;
     79 	volatile struct ra_softc *ra=&ra_softc;
     80 	volatile u_int *nisse;
     81 	unsigned short johan;
     82 	int i,err;
     83 
     84 	curblock = 0;
     85 	if(adapt>nuba) return(EADAPT);
     86 	if(ctlr>nuda) return(ECTLR);
     87 	ra->udaddr=uioaddr[adapt]+tmsaddr;
     88 	ra->ubaddr=(int)ubaaddr[adapt];
     89 	ra->unit=unit;
     90 	udacsr=(void*)ra->udaddr;
     91 	nisse=((u_int *)ubaaddr[adapt]) + 512;
     92 	nisse[494]=PG_V|(((u_int)&uda)>>9);
     93 	nisse[495]=nisse[494]+1;
     94 	ubauda=(void*)0x3dc00+(((u_int)(&uda))&0x1ff);
     95 
     96 	/*
     97 	 * Init of this tmscp ctlr.
     98 	 */
     99 	udacsr->udaip=0; /* Start init */
    100 	while((udacsr->udasa&MP_STEP1) == 0);
    101 	udacsr->udasa=0x8000;
    102 	while((udacsr->udasa&MP_STEP2) == 0);
    103 	johan=(((u_int)ubauda)&0xffff)+8;
    104 	udacsr->udasa=johan;
    105 	while((udacsr->udasa&MP_STEP3) == 0);
    106 	udacsr->udasa=3;
    107 	while((udacsr->udasa&MP_STEP4) == 0);
    108 	udacsr->udasa=0x0001;
    109 
    110 	uda.uda_ca.ca_rspdsc=(int)&ubauda->uda_rsp.mscp_cmdref;
    111 	uda.uda_ca.ca_cmddsc=(int)&ubauda->uda_cmd.mscp_cmdref;
    112 	uda.uda_cmd.mscp_un.un_seq.seq_addr = (long *)&uda.uda_ca.ca_cmddsc;
    113 	uda.uda_rsp.mscp_un.un_seq.seq_addr = (long *)&uda.uda_ca.ca_rspdsc;
    114 	uda.uda_cmd.mscp_vcid = 1;
    115 	uda.uda_cmd.mscp_un.un_sccc.sccc_ctlrflags = 0;
    116 
    117 	command(M_OP_SETCTLRC, 0);
    118 	uda.uda_cmd.mscp_unit=ra->unit;
    119 	command(M_OP_ONLINE, 0);
    120 
    121 	if (part) {
    122 		uda.uda_cmd.mscp_un.un_seq.seq_buffer = part;
    123 		command(M_OP_POS, 0);
    124 		uda.uda_cmd.mscp_un.un_seq.seq_buffer = 0;
    125 	}
    126 
    127 	f->f_devdata=(void *)ra;
    128 	return(0);
    129 }
    130 
    131 static
    132 command(cmd, arg)
    133 {
    134 	volatile int hej;
    135 
    136 	uda.uda_cmd.mscp_opcode = cmd;
    137 	uda.uda_cmd.mscp_modifier = arg;
    138 
    139 	uda.uda_cmd.mscp_msglen = MSCP_MSGLEN;
    140 	uda.uda_rsp.mscp_msglen = MSCP_MSGLEN;
    141 
    142 	uda.uda_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT;
    143 	uda.uda_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT;
    144 	hej = udacsr->udaip;
    145 	while (uda.uda_ca.ca_rspdsc < 0) {
    146 		if (uda.uda_ca.ca_cmdint)
    147 			uda.uda_ca.ca_cmdint = 0;
    148 	}
    149 
    150 }
    151 
    152 tmscpstrategy(struct ra_softc *ra, int func, daddr_t dblk, u_int size, char *buf, u_int *rsize)
    153 {
    154 	u_int i,j,pfnum, mapnr, nsize, bn, cn, sn, tn;
    155 	volatile struct udadevice *udadev=(void*)ra->udaddr;
    156 	volatile u_int *ptmapp = (u_int *)ra->ubaddr + 512;
    157 	volatile int hej;
    158 
    159 	pfnum=(u_int)buf>>VAX_PGSHIFT;
    160 
    161 	for(mapnr=0, nsize=size;(nsize+VAX_NBPG)>0;nsize-=VAX_NBPG)
    162 		ptmapp[mapnr++]=PG_V|pfnum++;
    163 
    164 	/*
    165 	 * First position tape. Remember where we are.
    166 	 */
    167 	if (dblk < curblock) {
    168 		uda.uda_cmd.mscp_seq.seq_bytecount = curblock - dblk;
    169 		command(M_OP_POS, 12); /* 12 == step block backward */
    170 	} else {
    171 		uda.uda_cmd.mscp_seq.seq_bytecount = dblk - curblock;
    172 		command(M_OP_POS, 4); /* 4 == step block forward */
    173 	}
    174 	curblock = size/512 + dblk;
    175 
    176 	/*
    177 	 * Read in the number of blocks we need.
    178 	 * Why doesn't read of multiple blocks work?????
    179 	 */
    180 	for (i = 0 ; i < size/512 ; i++) {
    181 		uda.uda_cmd.mscp_seq.seq_lbn = 1;
    182 		uda.uda_cmd.mscp_seq.seq_bytecount = 512;
    183 		uda.uda_cmd.mscp_seq.seq_buffer =
    184 		    (((u_int)buf) & 0x1ff) + i * 512;
    185 		uda.uda_cmd.mscp_unit = ra->unit;
    186 		command(M_OP_READ, 0);
    187 	}
    188 
    189 	*rsize=size;
    190 	return 0;
    191 }
    192