more reformatting
[unix-history] / usr / src / sys / tahoe / stand / hd.c
CommitLineData
2839b724
KB
1/*
2 * Stand alone driver for the HDC controller
3b94e226 3 *
62e6d4ba 4 * @(#)hd.c 7.4 (Berkeley) %G%
2839b724 5 */
3b94e226
KB
6#define KERNEL
7
8#include "machine/mtpr.h"
9#include "param.h"
10#include "systm.h"
11#include "buf.h"
12#include "time.h"
13#include "inode.h"
14#include "fs.h"
15#include "ioctl.h"
16#include "tahoevba/dsk.h"
17#include "tahoevba/dskio.h"
18#include "tahoevba/hdc.h"
19#include "saio.h"
20
21#define NHD 4
22#define NDRIVE 8 /* drives per controller */
23#define HDSLAVE(x) ((x) % NDRIVE)
24#define HDCTLR(x) ((x) / NDRIVE)
25
26#define HDREG(x) (ctlr_addr->x) /* standalone io to an hdc register */
27#define HID_HDC 0x01 /* hvme_id for HDC */
2839b724
KB
28
29/*
30 * hdc controller table. It contains information about the hdc controller.
31 */
2839b724
KB
32typedef struct {
33 int ctlr; /* controller number (0-15) */
34 hdc_regs_type *registers; /* base address of hdc io registers */
35 hdc_mid_type mid; /* the module id is read to here */
d1de3d34 36 master_mcb_type master_mcb; /* the master mcb for this hdc */
2839b724
KB
37 mcb_type mcb; /* an mcb for i/o to the controller */
38} hdctlr_type;
39
40hdctlr_type hdc_ctlr[HDC_MAXCTLR][HDC_MAXBUS];
41
42/*
43 * hdc unit table. It contains information about the hdc drive.
44 * Some information is obtained from the profile prom and geometry block.
45 */
2839b724 46typedef struct {
d1de3d34
KB
47 par_tab partition[GB_MAXPART]; /* partition definitions */
48 int ctlr; /* the controller number (0-15) */
49 int slave; /* the slave number (0-4) */
50 int unit; /* the unit number (0-31) */
51 int id; /* identifies the disk model */
52 int cylinders; /* number of logical cylinders */
53 int heads; /* number of logical heads */
54 int sectors; /* number of logical sectors/track */
55 int phys_cylinders; /* number of physical cylinders */
56 int phys_heads; /* number of physical heads */
57 int phys_sectors; /* number of physical sectors/track */
58 int def_cyl; /* logical cylinder of drive def */
59 int def_cyl_count; /* number of logical def cylinders */
60 int diag_cyl; /* logical cylinder of diag area */
61 int diag_cyl_count; /* number of logical diag cylinders */
62 int rpm; /* disk rpm */
63 int bytes_per_sec; /* bytes/sector -vendorflaw conversn*/
64 int format; /* format program is active */
65 u_long phio_data[HDC_PHIO_SIZE]; /* data for physical io */
2839b724
KB
66} hdunit_type;
67
d1de3d34 68hdunit_type hdc_unit [HDC_MAXDRIVE] [HDC_MAXCTLR] [HDC_MAXBUS];
2839b724
KB
69
70/*************************************************************************
71* Procedure: hdopen
72*
d1de3d34
KB
73* Description: The hdc open routine. Initializes the hdc and reads the
74* hdc status and the geometry block.
2839b724 75*
d1de3d34
KB
76* Returns: 0 open was successful
77* -1 this is not an hdc controller
2839b724 78**************************************************************************/
2839b724 79hdopen(io)
d1de3d34 80 register struct iob *io; /* i/o block */
2839b724
KB
81{
82 mcb_type *mcb; /* an mcb to send commands to hdc */
83 hdunit_type *hu; /* disk unit information table */
84 hdctlr_type *hc; /* hdc ctlr information table */
85 hdc_mid_type *id; /* the hdc module id */
d1de3d34 86 geometry_sector geometry; /* the geometry block sector */
2839b724
KB
87 geometry_block *geo; /* the geometry block */
88 drive_stat_type status; /* the hdc status is read to here */
d1de3d34 89 long ctlr; /* the controller number */
3b94e226 90 long junk; /* badaddr will write junk here */
d1de3d34
KB
91 int par; /* partition number */
92 int drive; /* the drive number */
93 int bus; /* the bus number */
94 int i; /* temp */
2839b724 95 hdc_regs_type *ctlr_addr; /* hdc i/o registers */
2839b724 96
d1de3d34
KB
97 par = io->i_boff; /* io->i_part; */
98 bus = 0; /* io->i_bus; */
99 ctlr = HDCTLR(io->i_unit); /* io->i_ctlr; */
100 drive = HDSLAVE(io->i_unit); /* io->i_drive; */
2839b724
KB
101 hu = &hdc_unit[drive][ctlr][bus];
102 hc = &hdc_ctlr[ctlr][bus];
103 mcb = &hc->mcb;
104
105 /*
106 * Validate the device specification
107 */
3b94e226
KB
108 if (ctlr >= HDC_MAXCTLR) {
109 printf("invalid controller number\n");
d1de3d34 110 return(ENXIO);
3b94e226 111 }
d1de3d34 112 if (drive < 0 || drive > HDC_MAXDRIVE - 1) {
2839b724 113 printf("hdc: bad drive number.\n");
d1de3d34 114 return(EUNIT);
2839b724
KB
115 }
116 if (par < 0 || par > 7) {
117 printf("hdc: bad partition number.\n");
d1de3d34 118 return(EUNIT);
2839b724 119 }
3b94e226 120 ctlr_addr = (hdc_regs_type *)(bus == 0 ?
2839b724 121 0xC0000000 | ctlr << 24 | HDC_MID << 16 :
3b94e226 122 0x80000000 | ctlr << 24 | HDC_MID << 16);
2839b724
KB
123
124 /*
125 * Init drive structure.
126 */
2839b724
KB
127 hu->slave = drive;
128 hc->registers = ctlr_addr;
129
130 /*
131 * Insure that this is an hdc, then reset the hdc.
132 */
3b94e226
KB
133 junk = 0;
134 if (wbadaddr(&ctlr_addr->module_id_reg, 4, &junk)) {
d1de3d34
KB
135 printf("hd%d: %x: invalid csr\n", ctlr, (u_int)ctlr_addr);
136 return(ENXIO);
3b94e226 137 }
2839b724
KB
138 HDREG(soft_reset_reg) = 0;
139 DELAY(1000000);
140
141 /*
d1de3d34
KB
142 * Read in the hdc module id word. The controller is bad if the
143 * hdc's writeable control store is not loaded or if the hdc failed
144 * the functional integrity test for any reason.
2839b724 145 */
2839b724 146 id = &hc->mid;
d1de3d34 147 HDREG(module_id_reg) = (u_long)id;
2839b724 148 DELAY(10000);
3b94e226 149 mtpr(PADC, 0);
d1de3d34
KB
150 if (id->module_id != (u_char)HDC_MID) {
151 printf("hdc: Controller bad module id: id = %x\n",
152 id->module_id);
153 return(-1);
2839b724 154 }
d1de3d34
KB
155 if (id->code_rev == (u_char)0xFF) {
156 printf("hdc: Controller micro-code is not loaded.\n");
157 return(ENXIO);
2839b724 158 }
d1de3d34
KB
159 if (id->fit != (u_char)0xFF) {
160 printf("hdc: Controller FIT test failed: error= %x\n",
161 id->fit);
162 return(ENXIO);
2839b724
KB
163 }
164
165 /*
166 * Read the drive status. Save important info.
167 */
2839b724
KB
168 mcb->command = HCMD_STATUS;
169 mcb->drive = drive;
170 mcb->cyl = 0;
171 mcb->head = 0;
172 mcb->sector = 0;
d1de3d34
KB
173 mcb->chain[0].lwc = (long)sizeof(drive_stat_type) / 4;
174 mcb->chain[0].ta = (long)&status;
2839b724 175 if (hdmcb(mcb, io))
d1de3d34 176 return(EIO);
2839b724
KB
177 hu->cylinders = status.max_cyl+1;
178 hu->heads = status.max_head+1;
179 hu->sectors = status.max_sector+1;
180 hu->def_cyl = status.def_cyl;
181 hu->def_cyl_count = status.def_cyl_count;
182 hu->diag_cyl = status.diag_cyl;
183 hu->diag_cyl_count = status.diag_cyl_count;
184 hu->phys_cylinders = status.max_phys_cyl+1;
185 hu->phys_heads = status.max_phys_head+1;
186 hu->phys_sectors = status.max_phys_sector+1;
187 hu->bytes_per_sec = status.bytes_per_sec;
188 hu->id = status.id;
189 hu->rpm = status.rpm;
190 hu->partition[HDC_DEFPART].start=
191 hu->def_cyl * hu->sectors * hu->heads / HDC_SPB;
192 hu->partition[HDC_DEFPART].length =
193 hu->def_cyl_count * hu->sectors * hu->heads / HDC_SPB;
d1de3d34 194 io->i_boff = hu->partition[HDC_DEFPART].start; /* default */
2839b724
KB
195
196 /*
197 * Report drive down if anything in the drive status is bad.
198 * If fault condition, reading geo will try to clear the fault.
199 */
2839b724
KB
200 if (status.drs & DRS_FAULT)
201 printf("hdc: clearing drive fault.\n");
d1de3d34 202 if (!(status.drs & DRS_ONLINE)) {
2839b724 203 printf("hdc: drive is not online.\n");
d1de3d34 204 return(EIO);
2839b724
KB
205 }
206
207 /*
208 * Read the geometry block (at head=0 sector=0 of the drive
209 * definition cylinder), validate it (must have the correct
210 * version number, header, and checksum).
211 */
2839b724
KB
212 geo = &geometry.geometry_block;
213 mcb->command = HCMD_READ;
214 mcb->drive = drive;
215 mcb->cyl = status.def_cyl;
216 mcb->head = 0;
217 mcb->sector = 0;
218 mcb->chain[0].lwc = sizeof(geometry_sector) / 4;
d1de3d34 219 mcb->chain[0].ta = (long)&geometry;
2839b724
KB
220 if (hdmcb(mcb, io)) {
221 printf("hdc: could not read geometry block\n");
d1de3d34 222 return(EIO);
2839b724
KB
223 }
224 io->i_boff = 0;
d1de3d34 225 if (geo->version > 64000 || geo->version < 0) {
2839b724 226 printf("hdc: bad geometry block version#\n");
d1de3d34 227 return(ENXIO);
2839b724 228 }
d1de3d34 229 if (strcmp(&geo->id[0], GB_ID) != 0) {
2839b724 230 printf("hdc: bad geometry block header\n");
d1de3d34 231 return(ENXIO);
2839b724 232 }
d1de3d34 233 GB_CHECKSUM(geo, i);
2839b724
KB
234 if (geometry.checksum != i) {
235 printf("hdc: bad geometry block checksum\n");
d1de3d34 236 return(ENXIO);
2839b724
KB
237 }
238
239 /*
240 * Set the partition start/size info.
241 * Note: this info was already defaulted to be the disk
242 * definition partition.
243 */
d1de3d34 244 if (par != HDC_DEFPART)
3b94e226 245 if (geo->partition[par].length == 0) {
2839b724 246 printf("hdc: null partition\n");
d1de3d34 247 return(ENXIO);
3b94e226 248 }
2839b724
KB
249 else {
250 hu->partition[par].start = geo->partition[par].start;
251 hu->partition[par].length = geo->partition[par].length;
252 io->i_boff = hu->partition[par].start;
253 }
d1de3d34 254 return(0);
2839b724
KB
255}
256
257/*************************************************************************
258* Procedure: hdstrategy
259*
d1de3d34
KB
260* Description: The hdc strategy routine. This routine does the disk
261* reads/writes. If this is the format program, read/writes
262* are forced to be within the disk definition partition.
2839b724 263*
d1de3d34 264* Returns: The number of bytes transfered.
2839b724 265**************************************************************************/
d1de3d34
KB
266hdstrategy(io, cmd)
267 register struct iob *io; /* i/o block */
268 int cmd; /* i/o operation to perform */
2839b724
KB
269{
270 mcb_type *mcb; /* mcb to send to the hdc */
271 hdunit_type *hu; /* disk unit information table */
272 hdctlr_type *hc; /* hdc ctlr information table */
273 long err; /* error code */
274 long sector; /* sector number for i/o */
d1de3d34
KB
275 int partstart; /* block number of partition start */
276 int partlen; /* number of blocks in partition */
277 int bytes; /* number of bytes to transfer */
2839b724 278 int bus; /* bus number */
d1de3d34
KB
279 int ctlr; /* the controller number */
280 int drive; /* the drive number */
2839b724 281
d1de3d34
KB
282 bus = 0; /* io->i_bus; */
283 ctlr = HDCTLR(io->i_unit); /* io->i_ctlr; */
284 drive = HDSLAVE(io->i_unit); /* io->i_drive; */
2839b724
KB
285 hu = &hdc_unit[drive][ctlr][bus];
286 hc = &hdc_ctlr[ctlr][bus];
287
288 /*
289 * Only the format program can access the disk definition tracks.
290 */
d1de3d34
KB
291 if (io->i_boff == HDC_DEFPART && !hu->format) {
292 printf("hdc: partition 7 is protected\n");
293 return(0);
294 }
2839b724
KB
295
296 /*
297 * Insure the transfer fits in the partition.
298 * Set and validate transfer size.
299 */
d1de3d34
KB
300 partstart = hu->partition[io->i_boff].start;
301 partlen = hu->partition[io->i_boff].length;
302 if (io->i_bn < partstart || io->i_bn >= partstart + partlen)
303 return(0);
304 bytes = MIN(io->i_cc, DEV_BSIZE * (partstart + partlen-io->i_bn));
2839b724 305 if (io->i_cc & 3) {
d1de3d34
KB
306 printf("hdc: i/o not a longword multiple\n");
307 return(0);
2839b724
KB
308 }
309
310 /*
311 * Set up the mcb and send it to the hdc.
312 */
2839b724
KB
313 mcb = &hc->mcb;
314 sector = io->i_bn * HDC_SPB;
d1de3d34 315 mcb->command = (cmd == READ) ? HCMD_READ : HCMD_WRITE;
2839b724
KB
316 mcb->drive = hu->slave;
317 mcb->cyl = sector / (hu->sectors * hu->heads);
d1de3d34 318 mcb->head = (sector / hu->sectors) % hu->heads;
2839b724 319 mcb->sector = sector % hu->sectors;
d1de3d34 320 mcb->chain[0].ta = (u_long)io->i_ma;
2839b724
KB
321 mcb->chain[0].lwc = (bytes + 3) / 4;
322 err = hdmcb(mcb, io);
323 io->i_error = err;
d1de3d34 324 return(err ? 0 : bytes);
2839b724
KB
325}
326
327/*************************************************************************
328* Procedure: hdioctl
329*
d1de3d34 330* Description: ioctl routine.
2839b724 331*
d1de3d34
KB
332* Returns: 0 no errors
333* non-0 error
2839b724 334**************************************************************************/
2839b724 335hdioctl(io, command, arg)
d1de3d34
KB
336 struct iob *io; /* i/o block */
337 int command; /* The ioctl commmand */
338 int arg; /* Data. Format depends on ioctl */
2839b724 339{
2839b724 340 register int i;
d1de3d34
KB
341 mcb_type *mcb;
342 hdunit_type *hu; /* disk unit information table */
343 hdctlr_type *hc; /* hdc ctlr information table */
344 int bus; /* bus number */
345 int ctlr; /* the controller number */
346 int drive; /* the drive number */
347
348 bus = 0; /* io->i_bus; */
349 ctlr = HDCTLR(io->i_unit); /* io->i_ctlr; */
350 drive = HDSLAVE(io->i_unit); /* io->i_drive; */
2839b724
KB
351 hu = &hdc_unit[drive][ctlr][bus];
352 hc = &hdc_ctlr[ctlr][bus];
353
354 switch (command) {
355
356 case DSKIOCFORMAT: {
357
358 /*
359 * Format a disk track. The received argument is a pointer
360 * to a "formatop" structure describing the track to format.
361 *
362 * Set up a buffer with each longword corresponding to a
363 * sector on the track; a 1 means no flaw, a 0 means a flaw.
364 * Send an mcb to the hdc to format the track.
365 */
366
367 register struct formatop *track;
368
369 if (!hu->format)
370 return(1);
d1de3d34 371 track = (struct formatop *)arg;
2839b724 372 mcb = &hc->mcb;
d1de3d34 373 for (i = 0; i < hu->phys_sectors; i++)
2839b724 374 hu->phio_data[i] = 1;
d1de3d34
KB
375 for (i = 0; i < track->flaw_count; i++)
376 hu->phio_data[track->flaw[i]] = 0;
2839b724
KB
377 mcb->command = HCMD_FORMAT;
378 mcb->drive = hu->slave;
d1de3d34 379 mcb->chain[0].ta = (u_long)hu->phio_data;
2839b724
KB
380 mcb->chain[0].lwc = hu->phys_sectors;
381 mcb->cyl = track->cylinder;
382 mcb->head = track->head;
383 mcb->sector = 0;
384 if (hdmcb(mcb, io))
d1de3d34 385 return(EIO);
2839b724
KB
386 break;
387 }
388
389 case DSKIOCCERTIFY: {
390
391 /*
392 * Certify a disk track. The received argument is a pointer
393 * to a "formatop" structure describing the track to certify.
394 *
395 * Send an mcb to the hdc to certify the track.
396 * The controller returns data in which each longword
397 * corresponds to a sector on the track; a 1 means no flaw,
398 * a 0 means a flaw.
399 */
400
401 register struct formatop *track;
402
403 if (!hu->format)
d1de3d34
KB
404 return(1);
405 track = (struct formatop *)arg;
2839b724
KB
406 mcb = &hc->mcb;
407 mcb->command = HCMD_CERTIFY;
408 mcb->drive = hu->slave;
d1de3d34 409 mcb->chain[0].ta = (u_long)hu->phio_data;
2839b724
KB
410 mcb->chain[0].lwc = hu->phys_sectors;
411 mcb->cyl = track->cylinder;
412 mcb->head = track->head;
413 mcb->sector = 0;
414 if (hdmcb(mcb, io))
d1de3d34 415 return(EIO);
2839b724 416 track->flaw_count = 0;
d1de3d34
KB
417 for (i = 0; i < hu->phys_sectors; i++) {
418 if (track->flaw_count >= MAXVFLAW)
419 break;
420 if (hu->phio_data[i] == 0) {
2839b724
KB
421 track->flaw[track->flaw_count] = i;
422 track->flaw_count++;
423 }
424 }
425 break;
426 }
427
428 case DSKIOCVERIFY: {
429
430 /*
431 * Verify a disk track. The received argument is a pointer
432 * to a "formatop" structure describing the track to verify.
433 */
434
435 register struct formatop *track;
436
437 if (!hu->format)
438 return(1);
d1de3d34 439 track = (struct formatop *)arg;
2839b724
KB
440 mcb = &hc->mcb;
441 mcb->command = HCMD_VERIFY;
442 mcb->drive = hu->slave;
443 mcb->chain[0].ta = 0;
444 mcb->chain[0].lwc = 0;
445 mcb->cyl = track->cylinder;
446 mcb->head = track->head;
447 mcb->sector = 0;
448 if (hdmcb(mcb, io))
d1de3d34 449 return(EIO);
2839b724
KB
450 break;
451 }
452
453 case DSKIOCFORMATCTL: {
454
455 /*
456 * This ioctl provides special format control.
457 * Currently the valid arguments are:
458 *
d1de3d34 459 * arg = 0 disable formatting;
2839b724 460 *
d1de3d34
KB
461 * arg = 1 enable formatting (allow privileged access);
462 * formatting must not already be enabled;
463 * For formatting, change to use partition 7.
2839b724
KB
464 */
465
d1de3d34
KB
466 if (arg < 0 || arg > 1)
467 return(1);
468 if (arg == 1) {
469 if (hu->format)
470 return(1);
2839b724 471 /* If not already formatting.... */
d1de3d34 472 hu->format = 1;
3b94e226 473 /* io->i_part = HDC_DEFPART; */
2839b724
KB
474 io->i_boff = hu->partition[HDC_DEFPART].start;
475 }
476 else
d1de3d34 477 hu->format = 0;
2839b724
KB
478 break;
479 }
480
481 case DSKIOCSTATUS: {
482
483 /*
484 * Return info about the disk. Caller's parameter is a
485 * pointer to a dsk_status structure.
486 */
487
488 register dsk_status *status;
489
d1de3d34
KB
490 status = (dsk_status *)arg;
491 status->id = hu->id;
492 status->drive_status = 0;
493 status->rpm = hu->rpm;
2839b724 494 status->bytes_per_sec = hu->bytes_per_sec;
d1de3d34
KB
495 status->cylinders = hu->cylinders;
496 status->heads = hu->heads;
497 status->sectors = hu->sectors;
498 status->phys_cylinders = hu->phys_cylinders;
499 status->phys_heads = hu->phys_heads;
500 status->phys_sectors = hu->phys_sectors;
501 status->diag_cyl = hu->diag_cyl;
502 status->diag_cylinders = hu->diag_cyl_count;
503 status->def_cyl = hu->def_cyl;
504 status->def_cylinders = hu->def_cyl_count;
2839b724
KB
505 break;
506 }
507
508 case DSKIOCVENDORFLAW: {
509
510 /*
511 * Return vendor flaw info.
512 *
513 * Read in the vendor data (data for each track is at
514 * relative sector 0 of the track); then copy the
515 * vendor flaw data to the caller's buffer.
516 */
517
518 register vflaw_type *vflaw;
519 register struct flaw *vendor;
520
521 if (!hu->format)
522 return(1);
d1de3d34 523 vflaw = (vflaw_type *)arg;
2839b724
KB
524 mcb = &hc->mcb;
525 mcb->command = HCMD_VENDOR;
526 mcb->drive = hu->slave;
527 mcb->chain[0].lwc = HDC_VDATA_SIZE;
d1de3d34 528 mcb->chain[0].ta = (u_long)hu->phio_data;
2839b724
KB
529 mcb->cyl = vflaw->cylinder;
530 mcb->head = vflaw->head;
531 mcb->sector = 0;
532 if (hdmcb(mcb, io))
d1de3d34
KB
533 return(EIO);
534 vendor = (struct flaw *)&hu->phio_data[0];
535 for (i = 0; i < MAXVFLAW; i++) {
2839b724
KB
536 vflaw->flaw[i].offset = vendor[i].offset;
537 vflaw->flaw[i].length = vendor[i].length;
538 }
539 break;
540 }
541 }
d1de3d34 542 return(0);
2839b724
KB
543}
544
545/*************************************************************************
546* Procedure: hdmcb
547*
d1de3d34 548* Description: Internal routine used to send mcb's to the hdc.
2839b724 549*
d1de3d34
KB
550* Returns: 0 normal
551* non-zero error occurred
2839b724 552**************************************************************************/
2839b724 553hdmcb(mcb, io)
d1de3d34
KB
554 register mcb_type *mcb; /* mcb to send to the hdc */
555 register struct iob *io; /* i/o block */
2839b724 556{
d1de3d34
KB
557 master_mcb_type *master_mcb; /* the hdc's master mcb */
558 hdctlr_type *hc; /* hdc ctlr information table */
559 hdc_regs_type *ctlr_addr; /* pointer to hdc i/o registers */
560 int timeout; /* used to timeout the mcb */
561 int bus; /* bus number */
562 int ctlr; /* the controller number */
563 int i, end;
564 u_int *ptr;
565
566 bus = 0; /* io->i_bus; */
567 ctlr = HDCTLR(io->i_unit); /* io->i_ctlr; */
2839b724
KB
568 hc = &hdc_ctlr[ctlr][bus];
569
570 mcb->interrupt = FALSE;
571 mcb->priority = 0;
572 mcb->forw_phaddr = 0;
573 mcb->context = 0;
574 mcb->reserved[0] = 0;
575 mcb->reserved[1] = 0;
576 master_mcb = &hc->master_mcb;
d1de3d34 577 master_mcb->forw_phaddr = (long)&mcb->forw_phaddr;
2839b724
KB
578 master_mcb->mcs = 0;
579 master_mcb->interrupt = 0;
d1de3d34
KB
580 master_mcb->reserve1 = 0;
581 master_mcb->reserve2 = 0;
582 master_mcb->context = 0;
2839b724 583 master_mcb->mcl = MCL_IMMEDIATE;
d1de3d34
KB
584 for (i = 0; i < HDC_XSTAT_SIZE; i++)
585 master_mcb->xstatus[i] = 0;
586 ctlr_addr = hc->registers;
587 HDREG(master_mcb_reg) = (u_long)master_mcb;
2839b724 588 timeout = 15000;
d1de3d34 589 for (;;) {
2839b724 590 DELAY(1000);
3b94e226 591 mtpr(PADC, 0);
d1de3d34
KB
592 if (master_mcb->mcs & MCS_DONE &&
593 !(master_mcb->mcs & MCS_FATALERROR))
594 return(0);
2839b724 595 timeout--;
d1de3d34
KB
596 if (timeout > 0 && !(master_mcb->mcs & MCS_FATALERROR))
597 continue;
598 if (master_mcb->mcs & MCS_FATALERROR)
2839b724
KB
599 printf("hdc: controller fatal error\n");
600 else
601 printf("hdc: controller timed out\n");
602
603 printf("mmcb: ");
d1de3d34
KB
604 ptr = (u_int *)master_mcb;
605 for (i = 0; i < 8; i++)
606 printf(" %x", ptr[i]);
607 for (i = 7 + HDC_XSTAT_SIZE; i > 7; i--) {
2839b724 608 end = i;
d1de3d34
KB
609 if (ptr[i] != 0)
610 break;
2839b724 611 }
d1de3d34
KB
612 for (i = 8; i <= end; i++)
613 printf(" %x", ptr[i]);
2839b724
KB
614 printf("\n");
615
616 printf("mcb: ");
d1de3d34
KB
617 ptr = (u_int *)&mcb->forw_phaddr;
618 for (i = 0; i < 6; i++)
619 printf(" %x", ptr[i]);
620 for (i = 6; i < 72; i += 2) {
2839b724 621 printf(" %x %x", ptr[i], ptr[i+1]);
d1de3d34
KB
622 if (!(ptr[i] & 0x80000000))
623 break;
2839b724
KB
624 }
625 printf("\n");
626 return(1);
627 }
628}