f12d0b617b8a53fe5dc9b091de9de3a1478527c9
* Copyright (c) 1982, 1986 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
* @(#)uda.c 7.4 (Berkeley) %G%
* UDA50/RAxx disk device driver
#include "../machine/pte.h"
#define NRA 8 /* max. unit number on controller */
#define SECTSIZ 512 /* sector size in bytes */
* Unused, but needed in udareg.h
#include "../vaxuba/udareg.h"
#include "../vaxuba/ubareg.h"
u_short udastd
[] = { 0772150 };
* Per-controller structures use dimension MAXNUBA,
* as only one controller per UNIBUS is supported.
struct udadevice
*udaddr
[MAXNUBA
] = { 0 };
struct uda1ca uda1_ca
; /* communications area */
struct mscp uda1_rsp
; /* response packet */
struct mscp uda1_cmd
; /* command packet */
struct uda1
*ud_ubaddr
[MAXNUBA
]; /* Unibus address of uda structure */
struct disklabel ralabel
[MAXNUBA
* NRA
];
static int ratype
[MAXNUBA
* NRA
];
register struct mscp
*mp
;
register struct disklabel
*lp
, *dlp
;
register struct udadevice
*addr
;
register struct uda1
*ubaddr
;
static int udainit
[MAXNUBA
];
udaddr
[uba
] = (struct udadevice
*)ubamem(unit
, udastd
[0]);
if (badaddr((char *)addr
, sizeof(short))) {
printf("nonexistent device\n");
if (ud_ubaddr
[uba
] == 0) {
* Initialize cudbuf.i_unit so that controllers
* on UNIBUSes other than 0 can be used.
cudbuf
.i_ma
= (caddr_t
)&uda1
;
cudbuf
.i_cc
= sizeof(uda1
);
ud_ubaddr
[uba
] = (struct uda1
*)ubasetup(&cudbuf
, 2);
while ((addr
->udasa
& UDA_STEP1
) == 0)
while ((addr
->udasa
& UDA_STEP2
) == 0)
addr
->udasa
= (short)&ubaddr
->uda1_ca
.ca_rspdsc
;
while ((addr
->udasa
& UDA_STEP3
) == 0)
(short)(((int)&ubaddr
->uda1_ca
.ca_rspdsc
) >> 16);
while ((addr
->udasa
& UDA_STEP4
) == 0)
uda1
.uda1_ca
.ca_rspdsc
= (long)&ubaddr
->uda1_rsp
.mscp_cmdref
;
uda1
.uda1_ca
.ca_cmddsc
= (long)&ubaddr
->uda1_cmd
.mscp_cmdref
;
/* uda1.uda1_cmd.mscp_cntflgs = 0; */
if (udcmd(M_OP_SETCTLRC
, io
) == 0) {
printf("ra: open error, SETCTLRC\n");
uda1
.uda1_cmd
.mscp_unit
= UNITTODRIVE(unit
);
if (udcmd(M_OP_ONLINE
, io
) == 0) {
printf("ra: open error, ONLINE\n");
if (rastrategy(&tio
, READ
) != SECTSIZ
) {
printf("can't read disk label\n");
dlp
= (struct disklabel
*)(lbuf
+ LABELOFFSET
);
if (dlp
->d_magic
!= DISKMAGIC
|| dlp
->d_magic2
!= DISKMAGIC
) {
printf("ra%d: unlabeled\n", unit
);
if ((unsigned)io
->i_boff
>= lp
->d_npartitions
||
(io
->i_boff
= lp
->d_partitions
[io
->i_boff
].p_offset
) == -1) {
printf("ra: bad partition\n");
register struct mscp
*mp
;
uda1
.uda1_cmd
.mscp_opcode
= op
;
uda1
.uda1_cmd
.mscp_msglen
= MSCP_MSGLEN
;
uda1
.uda1_rsp
.mscp_msglen
= MSCP_MSGLEN
;
uda1
.uda1_ca
.ca_rspdsc
|= MSCP_OWN
|MSCP_INT
;
uda1
.uda1_ca
.ca_cmddsc
|= MSCP_OWN
|MSCP_INT
;
i
= udaddr
[UNITTOUBA(io
->i_unit
)]->udaip
;
if (uda1
.uda1_ca
.ca_cmdint
)
uda1
.uda1_ca
.ca_cmdint
= 0;
if (uda1
.uda1_ca
.ca_rspint
== 0)
uda1
.uda1_ca
.ca_rspint
= 0;
if (mp
->mscp_opcode
== (op
| M_OP_END
))
printf("unexpected mscp response (type 0x%x) ignored",
MSCP_MSGTYPE(mp
->mscp_msgtc
));
uda1
.uda1_ca
.ca_rspdsc
|= MSCP_OWN
| MSCP_INT
;
if ((mp
->mscp_status
&M_ST_MASK
) != M_ST_SUCCESS
)
if (mp
->mscp_opcode
== (M_OP_ONLINE
|M_OP_END
))
ratype
[io
->i_unit
] = mp
->mscp_onle
.onle_drivetype
;
register struct mscp
*mp
;
ubinfo
= ubasetup(io
, 1);
mp
->mscp_unit
= UNITTODRIVE(io
->i_unit
);
mp
->mscp_seq
.seq_lbn
= io
->i_bn
;
mp
->mscp_seq
.seq_bytecount
= io
->i_cc
;
mp
->mscp_seq
.seq_buffer
= (ubinfo
& 0x3ffff) | (((ubinfo
>>28)&0xf)<<24);
if ((mp
= udcmd(func
== READ
? M_OP_READ
: M_OP_WRITE
, io
)) == 0) {
printf("ra: I/O error\n");
u_long ra25_off
[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 };
u_long rx50_off
[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
u_long rd52_off
[] = { 0, 15884, 0, 0, 0, 0, 25650, 0 };
u_long rd53_off
[] = { 0, 15884, 0, 0, 0, 33440, 49324, 15884 };
u_long ra60_off
[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
u_long ra80_off
[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
u_long ra81_off
[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 };
u_long ra81_off
[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 };
u_long ra81_off
[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 };
ra25_off
, /* 2 = rc25 removable */
ra25_off
, /* 3 = rc25 fixed */
#define NOFFS (sizeof(ra_off)/sizeof(int))
register struct disklabel
*lp
;
register struct partition
*pp
;
if ((unsigned)i
>= NOFFS
|| (off
= ra_off
[i
]) == 0) {
printf("ra%d: ra type %d unsupported\n", io
->i_unit
, i
);
for (pp
= lp
->d_partitions
, i
= 0; i
< 8; pp
++, i
++)