changes to support DS5000
[unix-history] / usr / src / sys / pmax / dev / rz.c
CommitLineData
12d43ee5
KM
1/*
2 * Copyright (c) 1992 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Van Jacobson of Lawrence Berkeley Laboratory and Ralph Campbell.
7 *
8 * %sccs.include.redist.c%
9 *
10 * @(#)rz.c 7.1 (Berkeley) %G%
11 */
12
13/*
14 * SCSI CCS (Command Command Set) disk driver.
15 * NOTE: The name was changed from "sd" to "rz" for DEC compatibility.
16 * I guess I can't avoid confusion someplace.
17 */
18#include "rz.h"
19#if NRZ > 0
20
21#include "param.h"
22#include "systm.h"
23#include "buf.h"
24#include "errno.h"
25#include "dkstat.h"
26#include "disklabel.h"
27#include "malloc.h"
28
29#include "device.h"
30#include "scsi.h"
31#include "devDiskLabel.h"
32
33#include "proc.h"
34#include "uio.h"
35
36extern void printf();
37extern void bcopy();
38extern void disksort();
39extern int splbio();
40extern void splx();
41extern int physio();
42
43int rzprobe();
44void rzstrategy(), rzstart(), rzdone();
45
46struct driver rzdriver = {
47 "rz", rzprobe, rzstart, rzdone,
48};
49
50struct size {
51 u_long strtblk;
52 u_long endblk;
53 int nblocks;
54};
55
56struct rzinfo {
57 struct size part[8];
58};
59
60/*
61 * Since the SCSI standard tends to hide the disk structure, we define
62 * partitions in terms of DEV_BSIZE blocks. The default partition table
63 * (for an unlabeled disk) reserves 512K for a boot area, has an 8 meg
64 * root and 32 meg of swap. The rest of the space on the drive goes in
65 * the G partition. As usual, the C partition covers the entire disk
66 * (including the boot area).
67 */
68struct rzinfo rzdefaultpart = {
69 1024, 17408, 16384 , /* A */
70 17408, 82944, 65536 , /* B */
71 0, 0, 0 , /* C */
72 17408, 115712, 98304 , /* D */
73 115712, 218112, 102400 , /* E */
74 218112, 0, 0 , /* F */
75 82944, 0, 0 , /* G */
76 115712, 0, 0 , /* H */
77};
78
79struct rzstats {
80 long rzresets;
81 long rztransfers;
82 long rzpartials;
83};
84
85struct rz_softc {
86 struct scsi_device *sc_sd; /* physical unit info */
87 int sc_format_pid; /* process using "format" mode */
88 short sc_flags; /* see below */
89 short sc_type; /* drive type from INQUIRY cmd */
90 u_int sc_blks; /* number of blocks on device */
91 int sc_blksize; /* device block size in bytes */
92 int sc_bshift; /* convert device blocks to DEV_BSIZE */
93 u_int sc_wpms; /* average xfer rate in 16bit wds/sec */
94 struct rzinfo sc_info; /* drive partition table & label info */
95 struct rzstats sc_stats; /* statisic counts */
96 struct buf sc_tab; /* queue of pending operations */
97 struct buf sc_buf; /* buf for doing I/O */
98 struct buf sc_errbuf; /* buf for doing REQUEST_SENSE */
99 struct ScsiCmd sc_cmd; /* command for controller */
100 ScsiGroup1Cmd sc_rwcmd; /* SCSI cmd if not in "format" mode */
101 struct scsi_fmt_cdb sc_cdb; /* SCSI cmd if in "format" mode */
102 struct scsi_fmt_sense sc_sense; /* sense data from last cmd */
103} rz_softc[NRZ];
104
105/* sc_flags values */
106#define RZF_ALIVE 0x1 /* drive found and ready */
107#define RZF_SENSEINPROGRESS 0x2 /* REQUEST_SENSE command in progress */
108
109#ifdef DEBUG
110int rzdebug = 3;
111#define RZB_ERROR 0x01
112#define RZB_PARTIAL 0x02
113#define RZB_PRLABEL 0x04
114#endif
115
116#define rzunit(x) ((minor(x) >> 3) & 0x7)
117#define rzpart(x) (minor(x) & 0x7)
118#define b_cylin b_resid
119
120/*
121 * Table of scsi commands users are allowed to access via "format" mode.
122 * 0 means not legal.
123 * 1 means legal.
124 */
125static char legal_cmds[256] = {
126/***** 0 1 2 3 4 5 6 7 8 9 A B C D E F */
127/*00*/ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
128/*10*/ 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
129/*20*/ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
130/*30*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
131/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
132/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
133/*60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
134/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
135/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
136/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
137/*a0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
138/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
139/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
140/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
141/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
142/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
143};
144
145/*
146 * Test to see if device is present.
147 * Return true if found and initialized ok.
148 */
149rzprobe(sd)
150 register struct scsi_device *sd;
151{
152 register struct rz_softc *sc = &rz_softc[sd->sd_unit];
153 register int tries, i;
154 ScsiInquiryData inqbuf;
155 u_char capbuf[8];
156 ScsiClass7Sense *sp;
157
158 /* init some parameters that don't change */
159 sc->sc_sd = sd;
160 sc->sc_cmd.sd = sd;
161 sc->sc_cmd.unit = sd->sd_unit;
162 sc->sc_rwcmd.unitNumber = sd->sd_slave;
163
164 /* try to find out what type of device this is */
165 sc->sc_format_pid = 1; /* force use of sc_cdb */
166 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd);
167 scsiGroup0Cmd(SCSI_INQUIRY, sd->sd_slave, 0, sizeof(inqbuf),
168 (ScsiGroup0Cmd *)sc->sc_cdb.cdb);
169 sc->sc_buf.b_flags = B_BUSY | B_PHYS | B_READ;
170 sc->sc_buf.b_bcount = sizeof(inqbuf);
171 sc->sc_buf.b_un.b_addr = (caddr_t)&inqbuf;
172 sc->sc_buf.av_forw = (struct buf *)0;
173 sc->sc_tab.b_actf = sc->sc_tab.b_actl = &sc->sc_buf;
174 rzstart(sd->sd_unit);
175 if (biowait(&sc->sc_buf) ||
176 (i = sizeof(inqbuf) - sc->sc_buf.b_resid) < 5)
177 goto bad;
178 switch (inqbuf.type) {
179 case SCSI_DISK_TYPE: /* disk */
180 case SCSI_WORM_TYPE: /* WORM */
181 case SCSI_ROM_TYPE: /* CD-ROM */
182 case SCSI_OPTICAL_MEM_TYPE: /* Magneto-optical */
183 break;
184
185 default: /* not a disk */
186 goto bad;
187 }
188 sc->sc_type = inqbuf.type;
189
190 /* see if device is ready */
191 for (tries = 10; ; ) {
192 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd);
193 scsiGroup0Cmd(SCSI_TEST_UNIT_READY, sd->sd_slave, 0, 0,
194 (ScsiGroup0Cmd *)sc->sc_cdb.cdb);
195 sc->sc_buf.b_flags = B_BUSY | B_PHYS | B_READ;
196 sc->sc_buf.b_bcount = 0;
197 sc->sc_buf.b_un.b_addr = (caddr_t)0;
198 sc->sc_buf.av_forw = (struct buf *)0;
199 sc->sc_tab.b_actf = sc->sc_tab.b_actl = &sc->sc_buf;
200
201 sc->sc_cmd.cmd = sc->sc_cdb.cdb;
202 sc->sc_cmd.cmdlen = sc->sc_cdb.len;
203 sc->sc_cmd.buf = (caddr_t)0;
204 sc->sc_cmd.buflen = 0;
205 /* setup synchronous data transfers if the device supports it */
206 if (tries == 10 && (inqbuf.flags & SCSI_SYNC))
207 sc->sc_cmd.flags = SCSICMD_USE_SYNC;
208 else
209 sc->sc_cmd.flags = 0;
210
211 (*sc->sc_sd->sd_cdriver->d_start)(&sc->sc_cmd);
212 if (!biowait(&sc->sc_buf))
213 break;
214 if (--tries < 0)
215 goto bad;
216 if (!(sc->sc_sense.status & SCSI_STATUS_CHECKCOND))
217 goto again;
218 sp = (ScsiClass7Sense *)sc->sc_sense.sense;
219 if (sp->error7 != 0x70)
220 goto again;
221 if (sp->key == SCSI_CLASS7_UNIT_ATTN && tries != 9) {
222 /* drive recalibrating, give it a while */
223 DELAY(1000000);
224 continue;
225 }
226 if (sp->key == SCSI_CLASS7_NOT_READY) {
227 ScsiStartStopCmd *cp;
228
229 /* try to spin-up disk with start/stop command */
230 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd);
231 cp = (ScsiStartStopCmd *)sc->sc_cdb.cdb;
232 cp->command = SCSI_START_STOP;
233 cp->unitNumber = sd->sd_slave;
234 cp->immed = 0;
235 cp->loadEject = 0;
236 cp->start = 1;
237 cp->pad1 = 0;
238 cp->pad2 = 0;
239 cp->pad3 = 0;
240 cp->pad4 = 0;
241 cp->control = 0;
242 sc->sc_buf.b_flags = B_BUSY | B_PHYS | B_READ;
243 sc->sc_buf.b_bcount = 0;
244 sc->sc_buf.b_un.b_addr = (caddr_t)0;
245 sc->sc_buf.av_forw = (struct buf *)0;
246 sc->sc_tab.b_actf = sc->sc_tab.b_actl = &sc->sc_buf;
247 rzstart(sd->sd_unit);
248 if (biowait(&sc->sc_buf))
249 goto bad;
250 continue;
251 }
252 again:
253 DELAY(1000);
254 }
255
256 /* find out how big a disk this is */
257 sc->sc_cdb.len = sizeof(ScsiGroup1Cmd);
258 scsiGroup1Cmd(SCSI_READ_CAPACITY, sd->sd_slave, 0, 0,
259 (ScsiGroup1Cmd *)sc->sc_cdb.cdb);
260 sc->sc_buf.b_flags = B_BUSY | B_PHYS | B_READ;
261 sc->sc_buf.b_bcount = sizeof(capbuf);
262 sc->sc_buf.b_un.b_addr = (caddr_t)capbuf;
263 sc->sc_buf.av_forw = (struct buf *)0;
264 sc->sc_tab.b_actf = sc->sc_tab.b_actl = &sc->sc_buf;
265 rzstart(sd->sd_unit);
266 if (biowait(&sc->sc_buf) || sc->sc_buf.b_resid != 0)
267 goto bad;
268 sc->sc_blks = (capbuf[0] << 24) | (capbuf[1] << 16) |
269 (capbuf[2] << 8) | capbuf[3];
270 sc->sc_blksize = (capbuf[4] << 24) | (capbuf[5] << 16) |
271 (capbuf[6] << 8) | capbuf[7];
272
273 printf("rz%d at %s%d drive %d slave %d", sd->sd_unit,
274 sd->sd_cdriver->d_name, sd->sd_ctlr, sd->sd_drive,
275 sd->sd_slave);
276 if (inqbuf.version > 1 || i < 36)
277 printf(" type 0x%x, qual 0x%x, ver %d",
278 inqbuf.type, inqbuf.qualifier, inqbuf.version);
279 else {
280 char vid[9], pid[17], revl[5];
281
282 bcopy((caddr_t)inqbuf.vendorID, (caddr_t)vid, 8);
283 bcopy((caddr_t)inqbuf.productID, (caddr_t)pid, 16);
284 bcopy((caddr_t)inqbuf.revLevel, (caddr_t)revl, 4);
285 for (i = 8; --i > 0; )
286 if (vid[i] != ' ')
287 break;
288 vid[i+1] = 0;
289 for (i = 16; --i > 0; )
290 if (pid[i] != ' ')
291 break;
292 pid[i+1] = 0;
293 for (i = 4; --i > 0; )
294 if (revl[i] != ' ')
295 break;
296 revl[i+1] = 0;
297 printf(" %s %s rev %s", vid, pid, revl);
298 }
299 printf(", %d %d byte blocks\n", sc->sc_blks, sc->sc_blksize);
300 if (sc->sc_blksize != DEV_BSIZE) {
301 if (sc->sc_blksize < DEV_BSIZE) {
302 printf("rz%d: need %d byte blocks - drive ignored\n",
303 sd->sd_unit, DEV_BSIZE);
304 goto bad;
305 }
306 for (i = sc->sc_blksize; i > DEV_BSIZE; i >>= 1)
307 ++sc->sc_bshift;
308 sc->sc_blks <<= sc->sc_bshift;
309 }
310 sc->sc_wpms = 32 * (60 * DEV_BSIZE / 2); /* XXX */
311 sc->sc_format_pid = 0;
312 sc->sc_flags = RZF_ALIVE;
313
314 /* try to read disk label or partition table information */
315 if (rzreadlabel(sc, sd) == 0)
316 goto ok;
317
318 /*
319 * We don't have a disk label, build a default partition
320 * table with 'standard' size root & swap and everything else
321 * in the G partition.
322 */
323 sc->sc_info = rzdefaultpart;
324 /* C gets everything */
325 sc->sc_info.part[2].nblocks = sc->sc_blks;
326 sc->sc_info.part[2].endblk = sc->sc_blks;
327 /* G gets from end of B to end of disk */
328 sc->sc_info.part[6].nblocks = sc->sc_blks - sc->sc_info.part[1].endblk;
329 sc->sc_info.part[6].endblk = sc->sc_blks;
330 /*
331 * We also define the D, E and F paritions as an alternative to
332 * B and G. D is 48Mb, starts after A and is intended for swapping.
333 * E is 50Mb, starts after D and is intended for /usr. F starts
334 * after E and is what ever is left.
335 */
336 if (sc->sc_blks >= sc->sc_info.part[4].endblk) {
337 sc->sc_info.part[5].nblocks =
338 sc->sc_blks - sc->sc_info.part[4].endblk;
339 sc->sc_info.part[5].endblk = sc->sc_blks;
340 } else {
341 sc->sc_info.part[5].strtblk = 0;
342 sc->sc_info.part[3] = sc->sc_info.part[5];
343 sc->sc_info.part[4] = sc->sc_info.part[5];
344 }
345 /*
346 * H is a single partition alternative to E and F.
347 */
348 if (sc->sc_blks >= sc->sc_info.part[3].endblk) {
349 sc->sc_info.part[7].nblocks =
350 sc->sc_blks - sc->sc_info.part[3].endblk;
351 sc->sc_info.part[7].endblk = sc->sc_blks;
352 } else
353 sc->sc_info.part[7].strtblk = 0;
354
355ok:
356 sc->sc_buf.b_flags = 0;
357 return (1);
358
359bad:
360 /* doesn't exist or not a CCS device */
361 sc->sc_format_pid = 0;
362 sc->sc_buf.b_flags = 0;
363 return (0);
364}
365
366/*
367 * Try to read the disk label and fill in the partition table info.
368 */
369static int
370rzreadlabel(sc, sd)
371 register struct rz_softc *sc;
372 register struct scsi_device *sd;
373{
374 register struct size *sp;
375 Sun_DiskLabel *sunLabelPtr;
376 Dec_DiskLabel *decLabelPtr;
377 char labelBuffer[DEV_BSIZE];
378 int part, error;
379
380 /*
381 * The label of a SCSI disk normally resides in the first sector.
382 * Format and send a SCSI READ command to fetch the sector.
383 */
384 sc->sc_buf.b_flags = B_BUSY | B_PHYS | B_READ;
385 sc->sc_buf.b_bcount = sizeof(labelBuffer);
386 sc->sc_buf.b_un.b_addr = labelBuffer;
387 sc->sc_buf.b_cylin = SUN_LABEL_SECTOR;
388 sc->sc_buf.av_forw = (struct buf *)0;
389 sc->sc_tab.b_actf = sc->sc_tab.b_actl = &sc->sc_buf;
390 rzstart(sd->sd_unit);
391 if (error = biowait(&sc->sc_buf))
392 return (error);
393 sunLabelPtr = (Sun_DiskLabel *)labelBuffer;
394 if (sunLabelPtr->magic == SUN_DISK_MAGIC) {
395 /*
396 * XXX - Should really check if label is valid.
397 */
398#ifdef DEBUG
399 if (rzdebug & RZB_PRLABEL) {
400 printf("rz%d: SUN label %s\n", sd->sd_unit,
401 sunLabelPtr->asciiLabel);
402 printf(" Partitions");
403 }
404#endif
405 sp = sc->sc_info.part;
406 for (part = 0; part < DEV_NUM_DISK_PARTS; part++, sp++) {
407 sp->strtblk =
408 sunLabelPtr->map[part].cylinder *
409 sunLabelPtr->numHeads *
410 sunLabelPtr->numSectors;
411 sp->nblocks =
412 sunLabelPtr->map[part].numBlocks;
413 sp->endblk = sp->strtblk + sp->nblocks;
414#ifdef DEBUG
415 if (rzdebug & RZB_PRLABEL)
416 printf(" (%d,%d)", sp->strtblk, sp->nblocks);
417#endif
418 }
419#ifdef DEBUG
420 if (rzdebug & RZB_PRLABEL)
421 printf("\n");
422#endif
423 return (0);
424 }
425
426 /*
427 * The disk isn't in SUN or UNIX format so try Dec format.
428 * We have to read the right sector first.
429 */
430 sc->sc_buf.b_flags = B_BUSY | B_PHYS | B_READ;
431 sc->sc_buf.b_bcount = sizeof(labelBuffer);
432 sc->sc_buf.b_un.b_addr = labelBuffer;
433 sc->sc_buf.b_cylin = DEC_LABEL_SECTOR;
434 sc->sc_buf.av_forw = (struct buf *)0;
435 sc->sc_tab.b_actf = sc->sc_tab.b_actl = &sc->sc_buf;
436 rzstart(sd->sd_unit);
437 if (error = biowait(&sc->sc_buf))
438 return (error);
439 decLabelPtr = (Dec_DiskLabel *)labelBuffer;
440 if (decLabelPtr->magic == DEC_LABEL_MAGIC &&
441 decLabelPtr->isPartitioned) {
442 /*
443 * XXX - Should really check if label is valid.
444 */
445#ifdef DEBUG
446 if (rzdebug & RZB_PRLABEL) {
447 printf("rz%d: DEC label\n", sd->sd_unit);
448 printf(" Partitions");
449 }
450#endif
451 sp = sc->sc_info.part;
452 for (part = 0; part < DEV_NUM_DISK_PARTS; part++, sp++) {
453 sp->strtblk = decLabelPtr->map[part].startBlock;
454 sp->nblocks = decLabelPtr->map[part].numBlocks;
455 sp->endblk = sp->strtblk + sp->nblocks;
456#ifdef DEBUG
457 if (rzdebug & RZB_PRLABEL)
458 printf(" (%d,%d)", sp->strtblk, sp->nblocks);
459#endif
460 }
461#ifdef DEBUG
462 if (rzdebug & RZB_PRLABEL)
463 printf("\n");
464#endif
465 return (0);
466 }
467 return (EIO);
468}
469
470/*
471 * This routine is called for partial block transfers and non-aligned
472 * transfers (the latter only being possible on devices with a block size
473 * larger than DEV_BSIZE). The operation is performed in three steps
474 * using a locally allocated buffer:
475 * 1. transfer any initial partial block
476 * 2. transfer full blocks
477 * 3. transfer any final partial block
478 */
479static void
480rzlblkstrat(bp, bsize)
481 register struct buf *bp;
482 register int bsize;
483{
484 register struct buf *cbp;
485 caddr_t cbuf;
486 register int bn, resid;
487 register caddr_t addr;
488
489 cbp = (struct buf *)malloc(sizeof(struct buf), M_DEVBUF, M_WAITOK);
490 cbuf = (caddr_t)malloc(bsize, M_DEVBUF, M_WAITOK);
491 bzero((caddr_t)cbp, sizeof(*cbp));
492 cbp->b_proc = curproc;
493 cbp->b_dev = bp->b_dev;
494 bn = bp->b_blkno;
495 resid = bp->b_bcount;
496 addr = bp->b_un.b_addr;
497#ifdef DEBUG
498 if (rzdebug & RZB_PARTIAL)
499 printf("rzlblkstrat: bp %x flags %x bn %x resid %x addr %x\n",
500 bp, bp->b_flags, bn, resid, addr);
501#endif
502
503 while (resid > 0) {
504 register int boff = dbtob(bn) & (bsize - 1);
505 register int count;
506
507 if (boff || resid < bsize) {
508 rz_softc[rzunit(bp->b_dev)].sc_stats.rzpartials++;
509 count = MIN(resid, bsize - boff);
510 cbp->b_flags = B_BUSY | B_PHYS | B_READ;
511 cbp->b_blkno = bn - btodb(boff);
512 cbp->b_un.b_addr = cbuf;
513 cbp->b_bcount = bsize;
514#ifdef DEBUG
515 if (rzdebug & RZB_PARTIAL)
516 printf(" readahead: bn %x cnt %x off %x addr %x\n",
517 cbp->b_blkno, count, boff, addr);
518#endif
519 rzstrategy(cbp);
520 biowait(cbp);
521 if (cbp->b_flags & B_ERROR) {
522 bp->b_flags |= B_ERROR;
523 bp->b_error = cbp->b_error;
524 break;
525 }
526 if (bp->b_flags & B_READ) {
527 bcopy(&cbuf[boff], addr, count);
528 goto done;
529 }
530 bcopy(addr, &cbuf[boff], count);
531#ifdef DEBUG
532 if (rzdebug & RZB_PARTIAL)
533 printf(" writeback: bn %x cnt %x off %x addr %x\n",
534 cbp->b_blkno, count, boff, addr);
535#endif
536 } else {
537 count = resid & ~(bsize - 1);
538 cbp->b_blkno = bn;
539 cbp->b_un.b_addr = addr;
540 cbp->b_bcount = count;
541#ifdef DEBUG
542 if (rzdebug & RZB_PARTIAL)
543 printf(" fulltrans: bn %x cnt %x addr %x\n",
544 cbp->b_blkno, count, addr);
545#endif
546 }
547 cbp->b_flags = B_BUSY | B_PHYS | (bp->b_flags & B_READ);
548 rzstrategy(cbp);
549 biowait(cbp);
550 if (cbp->b_flags & B_ERROR) {
551 bp->b_flags |= B_ERROR;
552 bp->b_error = cbp->b_error;
553 break;
554 }
555done:
556 bn += btodb(count);
557 resid -= count;
558 addr += count;
559#ifdef DEBUG
560 if (rzdebug & RZB_PARTIAL)
561 printf(" done: bn %x resid %x addr %x\n",
562 bn, resid, addr);
563#endif
564 }
565 free(cbuf, M_DEVBUF);
566 free(cbp, M_DEVBUF);
567}
568
569void
570rzstrategy(bp)
571 register struct buf *bp;
572{
573 register int unit = rzunit(bp->b_dev);
574 register int part = rzpart(bp->b_dev);
575 register int bn, sz;
576 register struct rz_softc *sc = &rz_softc[unit];
577 register int s;
578
579 if (sc->sc_format_pid) {
580 if (sc->sc_format_pid != curproc->p_pid) {
581 bp->b_error = EPERM;
582 goto bad;
583 }
584 bp->b_cylin = 0;
585 } else {
586 bn = bp->b_blkno;
587 sz = (bp->b_bcount + (DEV_BSIZE - 1)) >> DEV_BSHIFT;
588 if (bn < 0 || bn + sz > sc->sc_info.part[part].nblocks) {
589 if (bn == sc->sc_info.part[part].nblocks) {
590 bp->b_resid = bp->b_bcount;
591 goto done;
592 }
593 bp->b_error = EINVAL;
594 goto bad;
595 }
596 /*
597 * Non-aligned or partial-block transfers handled specially.
598 */
599 s = sc->sc_blksize - 1;
600 if ((dbtob(bn) & s) || (bp->b_bcount & s)) {
601 rzlblkstrat(bp, sc->sc_blksize);
602 goto done;
603 }
604 bp->b_cylin = (bn + sc->sc_info.part[part].strtblk) >>
605 sc->sc_bshift;
606 }
607 /* don't let disksort() see sc_errbuf */
608 while (sc->sc_flags & RZF_SENSEINPROGRESS)
609 printf("SENSE\n"); /* XXX */
610 s = splbio();
611 disksort(&sc->sc_tab, bp);
612 if (sc->sc_tab.b_active == 0) {
613 sc->sc_tab.b_active = 1;
614 rzstart(unit);
615 }
616 splx(s);
617 return;
618bad:
619 bp->b_flags |= B_ERROR;
620done:
621 biodone(bp);
622}
623
624void
625rzstart(unit)
626 int unit;
627{
628 register struct rz_softc *sc = &rz_softc[unit];
629 register struct buf *bp = sc->sc_tab.b_actf;
630 register int n;
631
632 sc->sc_cmd.buf = bp->b_un.b_addr;
633 sc->sc_cmd.buflen = bp->b_bcount;
634
635 if (sc->sc_format_pid || (sc->sc_flags & RZF_SENSEINPROGRESS)) {
636 sc->sc_cmd.flags = !(bp->b_flags & B_READ) ?
637 SCSICMD_DATA_TO_DEVICE : 0;
638 sc->sc_cmd.cmd = sc->sc_cdb.cdb;
639 sc->sc_cmd.cmdlen = sc->sc_cdb.len;
640 } else {
641 if (bp->b_flags & B_READ) {
642 sc->sc_cmd.flags = 0;
643 sc->sc_rwcmd.command = SCSI_READ_EXT;
644 } else {
645 sc->sc_cmd.flags = SCSICMD_DATA_TO_DEVICE;
646 sc->sc_rwcmd.command = SCSI_WRITE_EXT;
647 }
648 sc->sc_cmd.cmd = (u_char *)&sc->sc_rwcmd;
649 sc->sc_cmd.cmdlen = sizeof(sc->sc_rwcmd);
650 n = bp->b_cylin;
651 sc->sc_rwcmd.highAddr = n >> 24;
652 sc->sc_rwcmd.midHighAddr = n >> 16;
653 sc->sc_rwcmd.midLowAddr = n >> 8;
654 sc->sc_rwcmd.lowAddr = n;
655 n = howmany(bp->b_bcount, sc->sc_blksize);
656 sc->sc_rwcmd.highBlockCount = n >> 8;
657 sc->sc_rwcmd.lowBlockCount = n;
658#ifdef DEBUG
659 if ((bp->b_bcount & (sc->sc_blksize - 1)) != 0)
660 printf("rz%d: partial block xfer -- %x bytes\n",
661 unit, bp->b_bcount);
662#endif
663 sc->sc_stats.rztransfers++;
664 if ((n = sc->sc_sd->sd_dk) >= 0) {
665 dk_busy |= 1 << n;
666 ++dk_seek[n];
667 ++dk_xfer[n];
668 dk_wds[n] += bp->b_bcount >> 6;
669 }
670 }
671
672 /* tell controller to start this command */
673 (*sc->sc_sd->sd_cdriver->d_start)(&sc->sc_cmd);
674}
675
676/*
677 * This is called by the controller driver when the command is done.
678 */
679void
680rzdone(unit, error, resid, status)
681 register int unit;
682 int error; /* error number from errno.h */
683 int resid; /* amount not transfered */
684 int status; /* SCSI status byte */
685{
686 register struct rz_softc *sc = &rz_softc[unit];
687 register struct buf *bp = sc->sc_tab.b_actf;
688 register struct scsi_device *sd = sc->sc_sd;
689 extern int cold;
690
691 if (bp == NULL) {
692 printf("rz%d: bp == NULL\n", unit);
693 return;
694 }
695 if (sd->sd_dk >= 0)
696 dk_busy &= ~(1 << sd->sd_dk);
697 if (sc->sc_flags & RZF_SENSEINPROGRESS) {
698 sc->sc_flags &= ~RZF_SENSEINPROGRESS;
699 sc->sc_tab.b_actf = bp = bp->av_forw; /* remove sc_errbuf */
700
701 if (error || (status & SCSI_STATUS_CHECKCOND)) {
702#ifdef DEBUG
703 if (rzdebug & RZB_ERROR)
704 printf("rz%d: error reading sense data: error %d scsi status 0x%x\n",
705 unit, error, status);
706#endif
707 /*
708 * We got an error during the REQUEST_SENSE,
709 * fill in no sense for data.
710 */
711 sc->sc_sense.sense[0] = 0x70;
712 sc->sc_sense.sense[2] = SCSI_CLASS7_NO_SENSE;
713 } else if (!cold
714#ifdef DEBUG
715 || (rzdebug & RZB_ERROR)
716#endif
717 ) {
718 printf("rz%d: ", unit);
719 scsiPrintSense((ScsiClass7Sense *)sc->sc_sense.sense,
720 sizeof(sc->sc_sense.sense) - resid);
721 }
722 } else if (error || (status & SCSI_STATUS_CHECKCOND)) {
723#ifdef DEBUG
724 if (rzdebug & RZB_ERROR)
725 printf("rz%d: error %d scsi status 0x%x\n",
726 unit, error, status);
727#endif
728 /* save error info */
729 sc->sc_sense.status = status;
730 bp->b_flags |= B_ERROR;
731 bp->b_error = error;
732 bp->b_resid = resid;
733
734 if (status & SCSI_STATUS_CHECKCOND) {
735 /*
736 * Start a REQUEST_SENSE command.
737 * Since we are called at interrupt time, we can't
738 * wait for the command to finish; that's why we use
739 * the sc_flags field.
740 */
741 sc->sc_flags |= RZF_SENSEINPROGRESS;
742 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd);
743 scsiGroup0Cmd(SCSI_REQUEST_SENSE, sd->sd_slave, 0,
744 sizeof(sc->sc_sense.sense),
745 (ScsiGroup0Cmd *)sc->sc_cdb.cdb);
746 sc->sc_errbuf.b_flags = B_BUSY | B_PHYS | B_READ;
747 sc->sc_errbuf.b_bcount = sizeof(sc->sc_sense.sense);
748 sc->sc_errbuf.b_un.b_addr = (caddr_t)sc->sc_sense.sense;
749 sc->sc_errbuf.av_forw = bp;
750 sc->sc_tab.b_actf = &sc->sc_errbuf;
751 rzstart(unit);
752 return;
753 }
754 } else {
755 sc->sc_sense.status = status;
756 bp->b_resid = resid;
757 }
758
759 sc->sc_tab.b_actf = bp->av_forw;
760 biodone(bp);
761 if (sc->sc_tab.b_actf)
762 rzstart(unit);
763 else
764 sc->sc_tab.b_active = 0;
765}
766
767int
768rzopen(dev, flags, mode, p)
769 dev_t dev;
770 int flags, mode;
771 struct proc *p;
772{
773 register int unit = rzunit(dev);
774 register struct rz_softc *sc = &rz_softc[unit];
775
776 if (unit >= NRZ)
777 return (ENXIO);
778 if (!(sc->sc_flags & RZF_ALIVE) || suser(p->p_ucred, &p->p_acflag))
779 return (ENXIO);
780
781 if (sc->sc_sd->sd_dk >= 0)
782 dk_wpms[sc->sc_sd->sd_dk] = sc->sc_wpms;
783 return (0);
784}
785
786rzclose(dev, flags)
787 dev_t dev;
788 int flags;
789{
790 return (0);
791}
792
793int
794rzread(dev, uio)
795 dev_t dev;
796 struct uio *uio;
797{
798 register struct rz_softc *sc = &rz_softc[rzunit(dev)];
799
800 if (sc->sc_format_pid && sc->sc_format_pid != curproc->p_pid)
801 return (EPERM);
802
803 return (physio(rzstrategy, (struct buf *)0, dev,
804 B_READ, minphys, uio));
805}
806
807int
808rzwrite(dev, uio)
809 dev_t dev;
810 struct uio *uio;
811{
812 register struct rz_softc *sc = &rz_softc[rzunit(dev)];
813
814 if (sc->sc_format_pid && sc->sc_format_pid != curproc->p_pid)
815 return (EPERM);
816
817 return (physio(rzstrategy, (struct buf *)0, dev,
818 B_WRITE, minphys, uio));
819}
820
821int
822rzioctl(dev, cmd, data, flag, p)
823 dev_t dev;
824 int cmd;
825 caddr_t data;
826 int flag;
827 struct proc *p;
828{
829 register struct rz_softc *sc = &rz_softc[rzunit(dev)];
830
831 switch (cmd) {
832 default:
833 return (EINVAL);
834
835 case SDIOCSFORMAT:
836 /* take this device into or out of "format" mode */
837 if (suser(p->p_ucred, &p->p_acflag))
838 return (EPERM);
839
840 if (*(int *)data) {
841 if (sc->sc_format_pid)
842 return (EPERM);
843 sc->sc_format_pid = p->p_pid;
844 } else
845 sc->sc_format_pid = 0;
846 return (0);
847
848 case SDIOCGFORMAT:
849 /* find out who has the device in format mode */
850 *(int *)data = sc->sc_format_pid;
851 return (0);
852
853 case SDIOCSCSICOMMAND:
854 /*
855 * Save what user gave us as SCSI cdb to use with next
856 * read or write to the char device.
857 */
858 if (sc->sc_format_pid != p->p_pid)
859 return (EPERM);
860 if (legal_cmds[((struct scsi_fmt_cdb *)data)->cdb[0]] == 0)
861 return (EINVAL);
862 bcopy(data, (caddr_t)&sc->sc_cdb, sizeof(sc->sc_cdb));
863 return (0);
864
865 case SDIOCSENSE:
866 /*
867 * return the SCSI sense data saved after the last
868 * operation that completed with "check condition" status.
869 */
870 bcopy((caddr_t)&sc->sc_sense, data, sizeof(sc->sc_sense));
871 return (0);
872
873 }
874 /*NOTREACHED*/
875}
876
877int
878rzsize(dev)
879 dev_t dev;
880{
881 register int unit = rzunit(dev);
882 register struct rz_softc *sc = &rz_softc[unit];
883
884 if (unit >= NRZ || !(sc->sc_flags & RZF_ALIVE))
885 return (-1);
886
887 return (sc->sc_info.part[rzpart(dev)].nblocks);
888}
889
890/*
891 * Non-interrupt driven, non-dma dump routine.
892 */
893int
894rzdump(dev)
895 dev_t dev;
896{
897#ifdef notdef
898 int part = rzpart(dev);
899 int unit = rzunit(dev);
900 register struct rz_softc *sc = &rz_softc[unit];
901 register struct scsi_device *sd = sc->sc_hd;
902 register daddr_t baddr;
903 register int maddr;
904 register int pages, i;
905 int stat;
906 extern int lowram;
907
908 /*
909 * Hmm... all vax drivers dump maxfree pages which is physmem minus
910 * the message buffer. Is there a reason for not dumping the
911 * message buffer? Savecore expects to read 'dumpsize' pages of
912 * dump, where dumpsys() sets dumpsize to physmem!
913 */
914 pages = physmem;
915
916 /* is drive ok? */
917 if (unit >= NRZ || (sc->sc_flags & RZF_ALIVE) == 0)
918 return (ENXIO);
919 /* dump parameters in range? */
920 if (dumplo < 0 || dumplo >= sc->sc_info.part[part].nblocks)
921 return (EINVAL);
922 if (dumplo + ctod(pages) > sc->sc_info.part[part].nblocks)
923 pages = dtoc(sc->sc_info.part[part].nblocks - dumplo);
924 maddr = lowram;
925 baddr = dumplo + sc->sc_info.part[part].strtblk;
926 /* scsi bus idle? */
927 if (!scsireq(&sc->sc_dq)) {
928 scsireset(sd->sd_ctlr);
929 sc->sc_stats.rzresets++;
930 printf("[ drive %d reset ] ", unit);
931 }
932 for (i = 0; i < pages; i++) {
933#define NPGMB (1024*1024/NBPG)
934 /* print out how many Mbs we have dumped */
935 if (i && (i % NPGMB) == 0)
936 printf("%d ", i / NPGMB);
937#undef NPBMG
938 mapin(mmap, (u_int)vmmap, btop(maddr), PG_URKR|PG_CI|PG_V);
939 stat = scsi_tt_write(sd->sd_ctlr, sd->sd_drive, sd->sd_slave,
940 vmmap, NBPG, baddr, sc->sc_bshift);
941 if (stat) {
942 printf("rzdump: scsi write error 0x%x\n", stat);
943 return (EIO);
944 }
945 maddr += NBPG;
946 baddr += ctod(1);
947 }
948 return (0);
949#else notdef
950 return (ENXIO);
951#endif notdef
952}
953#endif