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*45803Sbostic * @(#)uda.c 7.11 (Berkeley) 12/16/90 723247Smckusick */ 85153Ssam 95153Ssam /* 105153Ssam * UDA50/RAxx disk device driver 115153Ssam */ 125153Ssam 13*45803Sbostic #include "sys/param.h" 14*45803Sbostic #include "sys/buf.h" 15*45803Sbostic #include "sys/disklabel.h" 169186Ssam 17*45803Sbostic #include "../include/pte.h" 1835050Skarels 19*45803Sbostic #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 28*45803Sbostic #include "../uba/udareg.h" 29*45803Sbostic #include "../uba/ubareg.h" 30*45803Sbostic #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 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; 11333764Sbostic if (rastrategy(&tio, 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 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 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); 18033408Skarels if (udcmd(func == 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 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