123247Smckusick /*
235050Skarels * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
323247Smckusick * All rights reserved. The Berkeley software License Agreement
423247Smckusick * specifies the terms and conditions for redistribution.
523247Smckusick *
6*49100Sbostic * @(#)uda.c 7.12 (Berkeley) 05/04/91
723247Smckusick */
85153Ssam
95153Ssam /*
105153Ssam * UDA50/RAxx disk device driver
115153Ssam */
125153Ssam
1345803Sbostic #include "sys/param.h"
1445803Sbostic #include "sys/buf.h"
1545803Sbostic #include "sys/disklabel.h"
169186Ssam
1745803Sbostic #include "../include/pte.h"
1835050Skarels
1945803Sbostic #include "stand/saio.h"
205153Ssam #include "savax.h"
215153Ssam
225153Ssam /*
2332613Sbostic * Unused, but needed in udareg.h
245153Ssam */
2532613Sbostic #define NRSP 1
2632613Sbostic #define NCMD 1
275153Ssam
2845803Sbostic #include "../uba/udareg.h"
2945803Sbostic #include "../uba/ubareg.h"
3045803Sbostic #include "../uba/ubavar.h"
3133408Skarels #include "../vax/mscp.h"
325153Ssam
3335050Skarels #define NRA 8 /* max. unit number on controller */
3435050Skarels #define SECTSIZ 512 /* sector size in bytes */
3535050Skarels
3633543Sbostic #define MAXCTLR 1 /* all addresses must be specified */
3733543Sbostic u_short udastd[MAXCTLR] = { 0772150 };
385153Ssam
3933543Sbostic struct udadevice *udaddr[MAXNUBA][MAXCTLR];
405153Ssam
4132613Sbostic struct uda1 {
4232613Sbostic struct uda1ca uda1_ca; /* communications area */
4332613Sbostic struct mscp uda1_rsp; /* response packet */
4432613Sbostic struct mscp uda1_cmd; /* command packet */
4532613Sbostic } uda1;
465153Ssam
4733543Sbostic /* Unibus address of uda structure */
4833543Sbostic struct uda1 *ud_ubaddr[MAXNUBA][MAXCTLR];
4933543Sbostic struct disklabel ralabel[MAXNUBA][MAXCTLR][NRA];
5035050Skarels static u_long ramedia[MAXNUBA][MAXCTLR][NRA];
5130547Skarels char lbuf[SECTSIZ];
525153Ssam
raopen(io)5311111Ssam raopen(io)
545153Ssam register struct iob *io;
555153Ssam {
5635050Skarels register struct disklabel *lp;
5730547Skarels register struct udadevice *addr;
5835050Skarels register struct uda1 *ubaaddr;
5933764Sbostic register int uba, unit;
6033543Sbostic static int udainit[MAXNUBA][MAXCTLR];
6133764Sbostic struct iob tio;
625153Ssam
6335050Skarels if ((u_int)(uba = io->i_adapt) >= nuba)
6435050Skarels return (EADAPT);
6533543Sbostic if ((u_int)io->i_ctlr >= MAXCTLR)
6633543Sbostic return (ECTLR);
6735050Skarels if ((u_int)(unit = io->i_unit) >= NRA)
6835050Skarels return (EUNIT);
6933543Sbostic addr = udaddr[uba][io->i_ctlr] =
7033543Sbostic (struct udadevice *)ubamem(uba, udastd[io->i_ctlr]);
7133764Sbostic if (badaddr((char *)addr, sizeof(short)))
7230547Skarels return (ENXIO);
7335050Skarels if ((ubaaddr = ud_ubaddr[uba][io->i_ctlr]) == 0) {
7433764Sbostic tio = *io;
7533764Sbostic tio.i_ma = (caddr_t)&uda1;
7633764Sbostic tio.i_cc = sizeof(uda1);
7735050Skarels ud_ubaddr[uba][io->i_ctlr] = ubaaddr =
7835050Skarels (struct uda1 *)ubasetup(&tio, 2);
795153Ssam }
8033543Sbostic if (udainit[uba][io->i_ctlr] == 0) {
8130547Skarels addr->udaip = 0;
8233764Sbostic while ((addr->udasa & UDA_STEP1) == 0);
8330547Skarels addr->udasa = UDA_ERR;
8433764Sbostic while ((addr->udasa & UDA_STEP2) == 0);
8535050Skarels addr->udasa = (int)&ubaaddr->uda1_ca.ca_rspdsc;
8633764Sbostic while ((addr->udasa & UDA_STEP3) == 0);
8735050Skarels addr->udasa = (int)&ubaaddr->uda1_ca.ca_rspdsc >> 16;
8833764Sbostic while ((addr->udasa & UDA_STEP4) == 0);
8930547Skarels addr->udasa = UDA_GO;
9035050Skarels uda1.uda1_ca.ca_rspdsc = (long)&ubaaddr->uda1_rsp.mscp_cmdref;
9135050Skarels uda1.uda1_ca.ca_cmddsc = (long)&ubaaddr->uda1_cmd.mscp_cmdref;
9232613Sbostic /* uda1.uda1_cmd.mscp_cntflgs = 0; */
9333408Skarels if (udcmd(M_OP_SETCTLRC, io)) {
9432613Sbostic printf("ra: open error, SETCTLRC\n");
9533543Sbostic return (ENXIO);
9617231Smckusick }
9733543Sbostic udainit[uba][io->i_ctlr] = 1;
9827075Skarels }
9933543Sbostic lp = &ralabel[uba][io->i_ctlr][unit];
10035050Skarels if (ramedia[uba][io->i_ctlr][unit] == 0) {
10133543Sbostic uda1.uda1_cmd.mscp_unit = unit;
10233408Skarels if (udcmd(M_OP_ONLINE, io)) {
10332613Sbostic printf("ra: open error, ONLINE\n");
10433543Sbostic return (ENXIO);
10517231Smckusick }
10635050Skarels ramedia[uba][io->i_ctlr][unit] =
10735050Skarels uda1.uda1_rsp.mscp_onle.onle_mediaid;
10830547Skarels tio = *io;
10930547Skarels tio.i_bn = LABELSECTOR;
11030547Skarels tio.i_ma = lbuf;
11130547Skarels tio.i_cc = SECTSIZ;
11230547Skarels tio.i_flgs |= F_RDDATA;
113*49100Sbostic if (rastrategy(&tio, F_READ) != SECTSIZ)
11433764Sbostic return (ERDLAB);
11533408Skarels *lp = *(struct disklabel *)(lbuf + LABELOFFSET);
11635050Skarels if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
11733764Sbostic #ifdef COMPAT_42
11830547Skarels printf("ra%d: unlabeled\n", unit);
11930547Skarels ramaptype(io, lp);
12030547Skarels #else
12133764Sbostic return (EUNLAB);
12230547Skarels #endif
12335050Skarels }
1245153Ssam }
12533543Sbostic if ((u_int)io->i_part >= lp->d_npartitions ||
12633543Sbostic (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1)
12733543Sbostic return (EPART);
12830547Skarels return (0);
1295153Ssam }
1305153Ssam
13133408Skarels int
udcmd(op,io)13230547Skarels udcmd(op, io)
1335153Ssam int op;
13430547Skarels register struct iob *io;
1355153Ssam {
13633408Skarels register struct uda1 *u = &uda1;
13732613Sbostic register struct mscp *mp;
13833764Sbostic register int i;
1395153Ssam
14033408Skarels u->uda1_cmd.mscp_opcode = op;
14133408Skarels u->uda1_cmd.mscp_msglen = MSCP_MSGLEN;
14233408Skarels u->uda1_rsp.mscp_msglen = MSCP_MSGLEN;
14333408Skarels u->uda1_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT;
14433408Skarels u->uda1_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT;
14533764Sbostic i = udaddr[io->i_adapt][io->i_ctlr]->udaip; /* start uda polling */
14635050Skarels #ifdef lint
14735050Skarels i = i;
14835050Skarels #endif
14933408Skarels mp = &u->uda1_rsp;
1505153Ssam for (;;) {
15133408Skarels if (u->uda1_ca.ca_cmdint)
15233408Skarels u->uda1_ca.ca_cmdint = 0;
15333408Skarels if (u->uda1_ca.ca_rspint == 0)
15432613Sbostic continue;
15533408Skarels u->uda1_ca.ca_rspint = 0;
15632613Sbostic if (mp->mscp_opcode == (op | M_OP_END))
1575153Ssam break;
15833408Skarels printf("unexpected rsp type %x op %x ignored\n",
15933408Skarels MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode);
16033408Skarels u->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT;
1615153Ssam }
16232613Sbostic if ((mp->mscp_status&M_ST_MASK) != M_ST_SUCCESS)
16333408Skarels return (-1);
16433408Skarels return (0);
1655153Ssam }
1665153Ssam
rastrategy(io,func)16711111Ssam rastrategy(io, func)
1685153Ssam register struct iob *io;
16935050Skarels int func;
1705153Ssam {
1715153Ssam register struct mscp *mp;
17235050Skarels register int ubinfo;
1735153Ssam
1745153Ssam ubinfo = ubasetup(io, 1);
17532613Sbostic mp = &uda1.uda1_cmd;
17633543Sbostic mp->mscp_unit = io->i_unit;
17732613Sbostic mp->mscp_seq.seq_lbn = io->i_bn;
17832613Sbostic mp->mscp_seq.seq_bytecount = io->i_cc;
17935050Skarels mp->mscp_seq.seq_buffer = UBAI_ADDR(ubinfo) | (UBAI_BDP(ubinfo) << 24);
180*49100Sbostic if (udcmd(func == F_READ ? M_OP_READ : M_OP_WRITE, io)) {
1815153Ssam printf("ra: I/O error\n");
1825153Ssam ubafree(io, ubinfo);
18335050Skarels return (-1);
1845153Ssam }
1855153Ssam ubafree(io, ubinfo);
18635050Skarels return (io->i_cc);
1875153Ssam }
18810024Ssam
18930547Skarels #ifdef COMPAT_42
19035050Skarels u_long rc25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 };
19132613Sbostic u_long rx50_off[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
19232613Sbostic u_long rd52_off[] = { 0, 15884, 0, 0, 0, 0, 25650, 0 };
19332613Sbostic u_long rd53_off[] = { 0, 15884, 0, 0, 0, 33440, 49324, 15884 };
19430547Skarels u_long ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
19535050Skarels #define ra70_off ra60_off
19630547Skarels u_long ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
19730547Skarels #ifndef UCBRA
19830547Skarels #ifdef RA_COMPAT
19930547Skarels u_long ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 };
20030547Skarels #else
20130547Skarels u_long ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 };
20230547Skarels #endif
20330547Skarels #else
20430547Skarels u_long ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 };
20530547Skarels #endif
20635050Skarels u_long ra82_off[] = { 0, 15884, 0, 375345, 391590, 699390, 375345, 83790 };
20730547Skarels
20835050Skarels struct mediamap {
20935050Skarels u_long id; /* media ID */
21035050Skarels u_long *off; /* offsets */
21135050Skarels } ra_map[] = {
21235050Skarels { MSCP_MKDRIVE2('R', 'A', 60), ra60_off },
21335050Skarels { MSCP_MKDRIVE2('R', 'A', 70), ra70_off },
21435050Skarels { MSCP_MKDRIVE2('R', 'A', 80), ra80_off },
21535050Skarels { MSCP_MKDRIVE2('R', 'A', 81), ra81_off },
21635050Skarels { MSCP_MKDRIVE2('R', 'A', 82), ra82_off },
21735050Skarels { MSCP_MKDRIVE2('R', 'C', 25), rc25_off },
21835050Skarels { MSCP_MKDRIVE3('R', 'C', 'F', 25), rc25_off },
21935050Skarels { MSCP_MKDRIVE2('R', 'D', 52), rd52_off },
22035050Skarels { MSCP_MKDRIVE2('R', 'D', 53), rd53_off },
22135050Skarels { MSCP_MKDRIVE2('R', 'X', 50), rx50_off },
22235050Skarels 0
22332613Sbostic };
22432613Sbostic
ramaptype(io,lp)22530547Skarels ramaptype(io, lp)
22630547Skarels register struct iob *io;
22730547Skarels register struct disklabel *lp;
22830547Skarels {
22930547Skarels register struct partition *pp;
23035050Skarels register u_long i;
23135050Skarels register struct mediamap *map;
23230547Skarels
23335050Skarels i = MSCP_MEDIA_DRIVE(ramedia[io->i_adapt][io->i_ctlr][io->i_unit]);
23435050Skarels for (map = ra_map; map->id != 0; map++) {
23535050Skarels if (map->id == i) {
23635050Skarels lp->d_npartitions = 8;
23735050Skarels for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++)
23835050Skarels pp->p_offset = map->off[i];
23935050Skarels return;
24035050Skarels }
24130547Skarels }
24235050Skarels printf("ra%d: media type 0x%x unsupported\n", io->i_unit, i);
24335050Skarels lp->d_npartitions = 0;
24430547Skarels }
24530547Skarels #endif
246