xref: /original-bsd/sys/news3400/iodev/sd.c (revision 95ecee29)
1 /*
2  * Copyright (c) 1992, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7  *
8  * %sccs.include.redist.c%
9  *
10  * from: $Hdr: sd.c,v 4.300 91/06/27 20:42:56 root Rel41 $ SONY
11  *
12  *	@(#)sd.c	8.2 (Berkeley) 09/23/93
13  */
14 #define	dkblock(bp)	bp->b_blkno
15 
16 /*
17  * Copyright (c) 1987-1991 by SONY Corporation.
18  */
19 
20 #include "sd.h"
21 #if NSD > 0
22 
23 #include <sys/param.h>
24 #include <sys/buf.h>
25 #include <sys/proc.h>
26 #include <sys/user.h>
27 #include <sys/dkstat.h>
28 #include <sys/uio.h>
29 #include <sys/kernel.h>
30 #include <sys/reboot.h>
31 #include <sys/ioctl.h>
32 #include <sys/systm.h>
33 #include <sys/mtio.h>
34 #include <sys/stat.h>
35 #include <sys/disklabel.h>
36 #include <vm/vm.h>
37 #include <sys/syslog.h>
38 
39 #include <ufs/ffs/fs.h>
40 
41 # include <machine/cpu.h>
42 
43 #ifdef IPC_MRX
44 # include "../iop/iopvar.h"
45 # include "../ipc/newsipc.h"
46 #endif
47 
48 #ifdef CPU_SINGLE
49 # include <news3400/hbdev/hbvar.h>
50 # include <news3400/iodev/ioptohb.h>
51 #endif
52 
53 #include <news3400/iodev/scsireg.h>
54 #include <news3400/iodev/scu.h>
55 #include <news3400/iodev/dkio.h>
56 #include <news3400/iodev/sdreg.h>
57 
58 #define	sce_sdecode	sce_hdecode
59 
60 #define	dev2unit(x)	((minor(x) & ~0x80) >> 3)
61 #define	dev2part(x)	(minor(x) & 0x7)
62 
63 /* /sys/sys/file.h */
64 #define	FREAD		00001		/* descriptor read/receive'able */
65 #define	FWRITE		00002		/* descriptor write/send'able */
66 
67 #define	PART_A		0
68 #define	PART_B		1
69 #define	PART_C		2
70 #define	PART_D		3
71 #define	PART_E		4
72 #define	PART_F		5
73 #define	PART_G		6
74 #define	PART_H		7
75 
76 #define	MAXPROBERETRY	100
77 #define	NRETRY		10
78 #define	MAXHRDERR	100
79 #define	MAXRETRYCNT	16
80 
81 #define	SDBSIZE1K	(DEV_BSIZE * 2)
82 #define	MAXSDPHYS	((NSCMAP - 1) * NBPG)
83 
84 #define	D100MSEC	100000
85 
86 #if OD_STOPTIME < 1
87 # define	OD_STOPTIME	5
88 #endif /* OD_STOPTIME < 1 */
89 
90 #define FORMAT_MODE_CORRUPTED	0x31
91 #define	ONLY_ONE	1
92 
93 /************** PARTITIONS *************************************/
94 
95 #define	PART_UNUSED	(0)
96 #define	PART_SPEC	(-1)
97 #define	PART_CALCF	(-2)
98 #define	PART_CALCG	(-3)
99 
100 struct defpart {
101 	int range_min;
102 	int range_max;
103 	int partsize[PNUM];
104 };
105 
106 struct defpart defpart_std[] = {
107 	{
108 		0,		/* range_min */
109 		20,		/* range_max */
110 
111 		  PART_SPEC,		/* A: */
112 		PART_UNUSED,		/* B: */
113 		  PART_SPEC,		/* C: */
114 		PART_UNUSED,		/* D: */
115 		PART_UNUSED,		/* E: */
116 		PART_UNUSED,		/* F: */
117 		PART_UNUSED,		/* G: */
118 		PART_UNUSED,		/* H: */
119 	},
120 	{
121 		20,		/* range_min */
122 		61,		/* range_max */
123 
124 		      15884,		/* A: */
125 		      10032,		/* B: */
126 		  PART_SPEC,		/* C: */
127 		      15884,		/* D: */
128 		PART_UNUSED,		/* E: */
129 		 PART_CALCF,		/* F: */
130 		 PART_CALCG,		/* G: */
131 		PART_UNUSED,		/* H: */
132 	},
133 	{
134 		61,		/* range_min */
135 		206,		/* range_max */
136 
137 		      15884,		/* A: */
138 		      33440,		/* B: */
139 		  PART_SPEC,		/* C: */
140 		      15884,		/* D: */
141 		      55936,		/* E: */
142 		 PART_CALCF,		/* F: */
143 		 PART_CALCG,		/* G: */
144 		PART_UNUSED,		/* H: */
145 	},
146 	{
147 		206,		/* range_min */
148 		356,		/* range_max */
149 
150 		      15884,		/* A: */
151 		      33440,		/* B: */
152 		  PART_SPEC,		/* C: */
153 		      15884,		/* D: */
154 		      55936,		/* E: */
155 		 PART_CALCF,		/* F: */
156 		 PART_CALCG,		/* G: */
157 		     291346,		/* H: */
158 	},
159 	{
160 		356,		/* range_min */
161 		99999999,	/* range_max */
162 
163 		      15884,		/* A: */
164 		      66880,		/* B: */
165 		  PART_SPEC,		/* C: */
166 		      15884,		/* D: */
167 		     307200,		/* E: */
168 		 PART_CALCF,		/* F: */
169 		 PART_CALCG,		/* G: */
170 		     291346,		/* H: */
171 	},
172 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
173 };
174 
175 /************* ADDITIONAL SENSE ERROR CODES *************************/
176 
177 struct msg_list {
178 	int	ml_code;		/* message code */
179 	int	ml_msglvl;		/* message level */
180 	char	*ml_msgstr;		/* message string */
181 };
182 
183 #define	sdskeylist	skeylist
184 
185 struct msg_list ecodelist_mo[] = {
186 	{ 0x80, 0, NULL },
187 	{ 0x81, 0, NULL },
188 	{ 0x82, 0, NULL },
189 	{ 0x83, 0, NULL },
190 
191 	{ -1,   0, NULL }
192 };
193 
194 /************** Ref. sd_var.c ********************************/
195 
196 extern struct iop/**/_ctlr *sdminfo[];
197 extern struct iop/**/_device *sddinfo[];
198 extern struct iop/**/_device *sdip[][MAXSLAVE];
199 
200 extern struct buf rsdbuf[];		/* buffer for raw I/O */
201 extern struct buf csdbuf[];		/* buffer for controll */
202 extern struct buf sdutab[];		/* per drive buffers */
203 
204 extern struct sdc_softc sdc_softc[];
205 extern struct sdd_softc sdd_softc[];
206 extern u_char sd_b_openf[][PNUM];
207 extern u_char sd_c_openf[][PNUM];
208 
209 extern struct scsi kernscsi[];
210 extern struct sdst sdstdrv[];
211 extern struct disklabel sdlabel[];
212 extern struct size sdsizedrv[][PNUM];
213 
214 extern u_char sdc_rsense[][RSEN_CNT];
215 
216 extern struct sync_param sd_sync_param[];
217 
218 extern int nsd;
219 extern int nsdc;
220 
221 /************** Ref. sddefs.c *********************************/
222 
223 extern struct sddevinfo sddevinfo[];
224 
225 /**************************************************************/
226 
227 extern struct msg_list skeylist[];
228 extern struct msg_list ecodelist[];
229 
230 extern int	boothowto;
231 extern int	rsense_msg_disp;	/* RSENSE-message display flag */
232 extern int	mo_disp_format;		/* MO format mode display flag */
233 
234 int sd_ignore_error;
235 
236 static int re_init_done;
237 
238 static u_char sdwork[2340];		/* buffer for error recovery */
239 static u_char sdtmp[DEV_BSIZE];		/* buffer for temporary */
240 #ifdef mips
241 volatile static int sdtmp_stat = 0;	/* status of sdtmp */
242 #else
243 static int sdtmp_stat = 0;		/* status of sdtmp */
244 #endif
245 
246 char	pname[] = "abcdefgh";
247 
248 struct scsi *get_scsi();
249 struct sc_map *get_sc_map();
250 struct sc_inq *get_sc_inq();
251 
252 int	sdprobe(), sdslave(), sdattach(), sddgo(), sdintr();
253 int	sdwstart, sdwatch(), sdstop();	/* Have started guardian */
254 void	sdexec();
255 
256 static sd_check(), sd_tstdrv(), sd_other_pages(), sd_err_rcv(), sd_synctr_on();
257 static disklabel2sdst(), sdst2disklabel(), sd_scu_exec();
258 
259 #ifdef CPU_SINGLE
260 struct hb_driver sdcdriver =
261     {sdprobe, sdslave, sdattach, sddgo, sdintr, "sd", sddinfo, "sdc", sdminfo};
262 #else
263 struct iop_driver sdcdriver =
264     {sdprobe, sdslave, sdattach, sddgo, "sd", sddinfo, "sdc", sdminfo};
265 #endif
266 
267 /*ARGSUSED*/
268 sdprobe(im)
269 	struct iop/**/_ctlr *im;
270 {
271 	static int sdd_init = 0;
272 	register struct sc_inq *sci;
273 	register int ctlr;
274 	register int fw;
275 	int i;
276 
277 	if (sdd_init == 0) {
278 		sdd_init++;
279 		for (i = 0; i < nsd; i++)
280 			sdd_softc[i].sdd_start = -2;
281 	}
282 
283 	sci = get_sc_inq(im->im_intr);
284 	ctlr = im->im_ctlr;
285 	/*
286 	 * Check device type
287 	 *	0x00: Direct access device.
288 	 *	0x01: Sequential access device.
289 	 *	0x04: Write-once read-multiple device.
290 	 *	0x05: Read-only Direct-access device.
291 	 *	0x7f: Specified device is nonexistent.
292 	 */
293 	fw = sdc_softc[ctlr].sdc_firmware & ~SDCFW_DEVMASK;
294 
295 	switch (sci->sci_devtype) {
296 
297 	case 0x00:
298 		/*
299 		 * Assumed that the device is HD.
300 		 *	Later, distinguish MO from HD.
301 		 */
302 		sdc_softc[ctlr].sdc_firmware = fw | SDCFW_HD;
303 		break;
304 
305 	default:
306 		/*
307 		 * device type mis-match
308 		 */
309 		return (0);
310 	}
311 
312 	/*
313 	 * Set interrupt handler routine
314 	 */
315 	if (set_inthandler(im, sdintr) == 0)
316 		return (0);
317 
318 	return (1);
319 }
320 
321 
322 /*ARGSUSED*/
323 sdslave(ii, reg, intr)
324 	register struct iop/**/_device *ii;
325 	caddr_t reg;
326 	int intr;
327 {
328 	register struct scsi *sc;
329 
330 	sc = get_scsi(intr);
331 	sdip[ii->ii_ctlr][ii->ii_slave] = ii;
332 	ii->ii_intr = intr;
333 
334 	/*
335 	 * check what the device is.
336 	 */
337 	if ((ii->ii_type = sd_check(ii, sc)) < 0)
338 		goto bad_slave;
339 
340 	/*
341 	 * set up ERROR RECOVERY PARAMETERS
342 	 */
343 	if (sd_err_rcv(ii, sc) < 0)
344 		goto bad_slave;
345 
346 	/*
347 	 * set up OTHER PARAMETERS
348 	 */
349 	if (sd_other_pages(ii, sc) < 0)
350 		goto bad_slave;
351 
352 	/*
353 	 * set up Synchronous Transfer
354 	 */
355 	sd_synctr_on(ii, sc);
356 
357 	return (1);
358 
359 bad_slave:
360 	/*
361 	 * no such slave
362 	 */
363 	ii->ii_intr = -1;
364 	return (0);
365 }
366 
367 identity_check(sci, capacity, unit)
368 	register struct sc_inq *sci;
369 	int capacity;
370 	int unit;
371 {
372 	register struct sddevinfo *sdi;
373 	register u_char *id_name;
374 	register int index;
375 	register int i;
376 	int id_pass;
377 
378 	id_name = sci->sci_vendid;
379 	while (*id_name == ' ')
380 		id_name++;
381 
382 	index = UNKNOWN_DISK;
383 	id_pass = 0;
384 	for (sdi = sddevinfo; sdi->id_len >= 0; sdi++) {
385 		/*
386 		 * check vendor & product ID
387 		 */
388 		if (strncmp(id_name, sdi->id_name, sdi->id_len) != 0)
389 			continue;
390 		id_pass = sdi - sddevinfo;
391 
392 		/*
393 		 * check revision
394 		 */
395 		if (strncmp(sdi->revs, sci->sci_revision, 4) == 0)
396 			index = id_pass;
397 		else {
398 			for (i = 0; i < 4; i++) {
399 				if (*(sdi->revs + i) == '?')
400 					continue;
401 				if (*(sdi->revs + i) != sci->sci_revision[i])
402 					break;
403 			}
404 			if (i < 4)
405 				continue;
406 		}
407 
408 		/*
409 		 * check capacity
410 		 */
411 		if (capacity == -1)
412 			break;
413 		if (sdi->capacity == -1) {
414 			printf("sd%d: capacity=0x%x(%d)\n",
415 				unit, capacity, capacity);
416 			break;
417 		}
418 		if (capacity == sdi->capacity)
419 			break;
420 	}
421 	if (index == 0)
422 		index = id_pass;
423 
424 	return (index);
425 }
426 
427 search_index(type)
428 	register int type;
429 {
430 	register struct sddevinfo *sdi;
431 	register int i;
432 	int index;
433 
434 	index = UNKNOWN_DISK;
435 	i = 0;
436 	for (sdi = sddevinfo; sdi->id_len > 0; sdi++) {
437 		if (sdi->type == type) {
438 			index = i;
439 			break;
440 		}
441 		i++;
442 	}
443 	return (index);
444 }
445 
446 static
447 sd_check(ii, sc)
448 	register struct iop/**/_device *ii;
449 	register struct scsi *sc;
450 {
451 	register struct sc_inq *sci;
452 	register struct sc_rcap *scr;
453 	register int intr;
454 	register int slave;
455 	register int unit;
456 	struct sdc_softc *sdc;
457 	struct sdd_softc *sdd;
458 	struct sc_extnd *sce;
459 	int retrycnt;
460 	int index;
461 	int media_in;
462 
463 	intr = ii->ii_intr;
464 	slave = ii->ii_slave;
465 	unit = ii->ii_unit;
466 	sdc = &sdc_softc[ii->ii_ctlr];
467 	sdd = &sdd_softc[unit];
468 	scr = (struct sc_rcap *)sc->sc_param;
469 	sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0];
470 
471 	/*
472 	 * check if the logical unit is ready.
473 	 *	(by TEST UNIT READY command)
474 	 */
475 	media_in = sd_tstdrv(ii, sc);
476 	if (media_in < 0)
477 		return (-3);
478 
479 	/*
480 	 * Get controller and drive information.
481 	 *	(by INQUIRY command)
482 	 */
483 	retrycnt = 0;
484 	sci = get_sc_inq(intr);
485 loop_inq:
486 	if (retrycnt++ > MAXPROBERETRY)
487 		return (-1);
488 
489 	scop_inquiry(intr, sc, slave, SCSI_INTDIS, sizeof(struct sc_inq), sci);
490 	sc->sc_tstatus &= TGSTMASK;
491 
492 	if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD) {
493 
494 		bzero((caddr_t)sce, RSEN_CNT);
495 		scop_rsense(intr, sc, slave, SCSI_INTDIS, RSEN_CNT,
496 				(caddr_t)sce);
497 		sc->sc_tstatus &= TGSTMASK;
498 		if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD)
499 			return (-1);
500 		if (sce->sce_extend != 0x70)
501 			goto loop_inq;
502 
503 		switch (sce->sce_sdecode) {
504 
505 		case 0x04:	/* Drive Not Ready */
506 		case 0x28:	/* Medium Changed */
507 		case 0x29:	/* Power On or Reset or Bus Device Reset */
508 		case 0x2a:	/* Mode Select Parameter Changed */
509 			break;
510 
511 		default:
512 			return (-1);
513 		}
514 		DELAY(D100MSEC);		/* wait 100 ms. */
515 		goto loop_inq;
516 	}
517 
518 	index = identity_check(sci, -1, unit);
519 
520 	switch (sddevinfo[index].type) {
521 
522 	case SMO_S501:
523 	case SMO_S501_ISO:
524 	case SMO_S501_ISO2:
525 		sdc->sdc_firmware =
526 			SDCFW_MO | (sdc->sdc_firmware & ~SDCFW_DEVMASK);
527 		break;
528 
529 	defaults:
530 		break;
531 	}
532 
533 	if (sci->sci_qual & 0x80) {
534 		/*
535 		 * removable medium device
536 		 */
537 		sdc->sdc_firmware |= SDCFW_RMB;
538 		if ((media_in == 0) || ((sdc->sdc_firmware & SDCFW_MO) == 0))
539 			return (index);
540 	}
541 
542 	/****************/
543 	/* HD & MO only */
544 	/****************/
545 	/*
546 	 * Get drive capacity
547 	 *	(by READ CAPACITY command)
548 	 */
549 	retrycnt = 0;
550 loop_rcap:
551 	if (retrycnt++ > MAXPROBERETRY)
552 		return (-4);
553 
554 	scop_rcap(intr, sc, slave, SCSI_INTDIS, 8, (caddr_t)0);
555 	sc->sc_tstatus &= TGSTMASK;
556 	if (sc->sc_istatus != INST_EP)
557 		return (-5);
558 	if (sc->sc_tstatus == TGST_CC) {
559 		bzero((caddr_t)sce, RSEN_CNT);
560 		scop_rsense(intr, sc, slave, SCSI_INTDIS, RSEN_CNT,
561 				(caddr_t)sce);
562 		sc->sc_tstatus &= TGSTMASK;
563 		if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD)
564 			return (-6);
565 		if (sderrordisp((caddr_t)sce, ii) == FORMAT_MODE_CORRUPTED) {
566 			scr->scr_nblock = 0;
567 			scr->scr_blocklen = DEV_BSIZE;
568 			sdd->sdd_flags |= SDDF_NONFMT;
569 		} else {
570 			DELAY(D100MSEC);		/* wait 100 ms. */
571 			goto loop_rcap;
572 		}
573 	}
574 	else if (sc->sc_tstatus != TGST_GOOD) {
575 		DELAY(D100MSEC);		/* wait 100 ms. */
576 		goto loop_rcap;
577 	}
578 
579 	sdd->sdd_nsect = scr->scr_nblock + 1;
580 	sdd->sdd_sectsize = scr->scr_blocklen;
581 
582 	index = identity_check(sci, scr->scr_nblock +1, unit);
583 
584 	return (index);
585 }
586 
587 static
588 sd_tstdrv(ii, sc)
589 	register struct iop/**/_device *ii;
590 	register struct scsi *sc;
591 {
592 	register struct sc_extnd *sce;
593 	register int intr;
594 	register int slave;
595 	register int retrycnt;
596 	struct sdc_softc *sdc;
597 	struct sdd_softc *sdd;
598 
599 	sdc = &sdc_softc[ii->ii_ctlr];
600 	sdd = &sdd_softc[ii->ii_unit];
601 
602 	intr = ii->ii_intr;
603 	slave = ii->ii_slave;
604 	sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0];
605 	retrycnt = 0;
606 loop_tst:
607 	if (retrycnt++ > MAXPROBERETRY)
608 		return (-1);
609 
610 	scop_tst(intr, sc, slave, SCSI_INTDIS);
611 	sc->sc_tstatus &= TGSTMASK;
612 	if (sc->sc_istatus != INST_EP) {
613 		DELAY(D100MSEC);		/* wait 100 ms. */
614 		goto loop_tst;
615 	}
616 
617 	switch (sc->sc_tstatus) {
618 
619 	case TGST_CC:
620 		/* Get error code */
621 		bzero((caddr_t)sce, RSEN_CNT);
622 		scop_rsense(intr, sc, slave, SCSI_INTDIS, RSEN_CNT,
623 				(caddr_t)sce);
624 		sc->sc_tstatus &= TGSTMASK;
625 		if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD) {
626 			DELAY(D100MSEC);	/* wait 100 ms. */
627 			goto loop_tst;
628 		}
629 
630 		if (sce->sce_extend != 0x70)
631 			goto loop_tst;
632 
633 		switch (sce->sce_skey) {
634 
635 		case 0x0:		/* No Sense */
636 		case 0x4:		/* Hardware error */
637 		case 0x6:		/* Unit attention */
638 			goto loop_tst;
639 
640 		case 0x2:		/* Not ready */
641 			switch (sce->sce_sdecode) {
642 
643 			case 0x04:	/* Not ready */
644 				/*
645 				 * Drive not ready... so start..
646 				 */
647 				scop_stst(intr, sc, slave, SCSI_INTDIS, SDSS_START);
648 				DELAY(D100MSEC * 10);	/* wait 1 sec. */
649 				goto loop_tst;
650 
651 			case 0x0a:	/* No Disk *//*MO*/
652 			default:
653 				DELAY(D100MSEC);
654 				goto loop_tst;
655 			}
656 			break;
657 
658 		case 0x03:
659 			if (sce->sce_sdecode == FORMAT_MODE_CORRUPTED)
660 				return (1);	/* ignore error */
661 			/* fall through */
662 
663 		default:
664 			return (-2);
665 		}
666 		break;
667 
668 	case TGST_BUSY:
669 		goto loop_tst;
670 
671 	case TGST_GOOD:
672 		break;
673 
674 	default:
675 		return (-3);
676 	}
677 
678 	return (1);
679 }
680 
681 static
682 sd_other_pages(ii, sc)
683 	register struct iop/**/_device *ii;
684 	register struct scsi *sc;
685 {
686 	register struct sddevinfo *sdi;
687 	char **p;
688 	char *page;
689 	int length;
690 	int retrycnt;
691 	int len;
692 
693 	sdi = &sddevinfo[ii->ii_type];
694 	if ((p = sdi->other_pages) == NULL)
695 		return (0);
696 
697 	/*
698 	 * set other parameters
699 	 */
700 	while (page = *p++) {
701 		retrycnt = 0;
702 loop_other_pages:
703 		bzero((caddr_t)sdtmp, 4);
704 		length = *(page + 1) + 2;
705 		bcopy(page, &sdtmp[4], length);
706 		if (retrycnt++ > MAXPROBERETRY)
707 			return (-1);
708 
709 		scop_mselect(ii->ii_intr, sc, ii->ii_slave, SCSI_INTDIS,
710 				(SDM_PF<<24) + length +4, (caddr_t)sdtmp);
711 		sc->sc_tstatus &= TGSTMASK;
712 		if ((sc->sc_istatus != INST_EP)
713 				|| (sc->sc_tstatus != TGST_GOOD)) {
714 			struct sc_extnd *sce;
715 
716 			sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0];
717 			scop_rsense(ii->ii_intr, sc, ii->ii_slave, SCSI_INTDIS,
718 						RSEN_CNT, (caddr_t)sce);
719 			switch (sce->sce_skey) {
720 
721 			case 0x00:
722 			case 0x02:
723 			case 0x04:
724 			case 0x06:
725 				DELAY(D100MSEC);   /* 100 ms. */
726 				goto loop_other_pages;
727 
728 			default:
729 				return (-1);
730 			}
731 		}
732 	}
733 
734 	if (sdi->firm_flags & FIRM_CACHE_ON)
735 		sdc_softc[ii->ii_ctlr].sdc_firmware |= SDCFW_CACHE;
736 	else
737 		sdc_softc[ii->ii_ctlr].sdc_firmware &= ~SDCFW_CACHE;
738 
739 	return (1);
740 }
741 
742 static
743 sd_err_rcv(ii, sc)
744 	register struct iop/**/_device *ii;
745 	register struct scsi *sc;
746 {
747 	register struct sdc_softc *sdc;
748 	register int intr;
749 	register int slave;
750 	register int len;
751 	struct sc_extnd *sce;
752 	struct sdd_softc *sdd;
753 	struct sddevinfo *sdi;
754 	int retrycnt;
755 	char *erp_page;
756 
757 	intr = ii->ii_intr;
758 	slave = ii->ii_slave;
759 	sdc = &sdc_softc[ii->ii_ctlr];
760 	sdd = &sdd_softc[ii->ii_unit];
761 	sdi = &sddevinfo[ii->ii_type];
762 	sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0];
763 
764 	/*
765 	 * set Default DISK sector size
766 	 */
767 	if (sdd->sdd_sectsize == 0)
768 		sdd->sdd_sectsize = DEV_BSIZE;
769 
770 
771 	if (sdi->ERP_page == NULL) {
772 		/*
773 		 * use default error recovery parameters
774 		 */
775 		sdc->sdc_firmware |= SDCFW_DEFMODE;
776 		return (0);
777 	}
778 
779 	if (sdi->firm_flags & FIRM_AWRE)
780 		sdc->sdc_firmware |= SDCFW_AWRE;
781 	if (sdi->firm_flags & FIRM_ARRE)
782 		sdc->sdc_firmware |= SDCFW_ARRE;
783 	/*
784 	 * set ERROR RECOVERY PARAMETERS
785 	 */
786 loop_err_rcv:
787 	bzero((caddr_t)sdtmp, 4);
788 	erp_page = sdi->ERP_page;
789 	len = *(erp_page + 1) + 2;
790 	bcopy(erp_page, &sdtmp[4], len);
791 
792 	scop_mselect(intr, sc, slave, SCSI_INTDIS,
793 			(SDM_PF<<24) + len +4, (caddr_t)sdtmp);
794 	sc->sc_tstatus &= TGSTMASK;
795 	if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD) {
796 		if (sc->sc_tstatus == TGST_CC) {
797 			bzero((caddr_t)sce, RSEN_CNT);
798 			scop_rsense(intr, sc, slave, SCSI_INTDIS, RSEN_CNT,
799 					(caddr_t)sce);
800 			if (sce->sce_sdecode == 0x2a) {
801 				/* mode select parameter changed */
802 				goto ercv_done;
803 			} else if (sce->sce_skey == 0x6) {
804 				/* unit attention */
805 				goto loop_err_rcv;
806 			}
807 		}
808 		/*
809 		 * use default ERROR RECOVERY mode
810 		 */
811 		sdc->sdc_firmware |= SDCFW_DEFMODE;
812 		sdc->sdc_firmware &= ~(SDCFW_AWRE|SDCFW_ARRE);
813 	}
814 
815 ercv_done:
816 
817 	return (1);
818 }
819 
820 static
821 sd_synctr_on(ii, sc)
822 	register struct iop/**/_device *ii;
823 	register struct scsi *sc;
824 {
825 	register struct sddevinfo *sdi;
826 	register struct sync_param *syncp;
827 
828 	sdi = &sddevinfo[ii->ii_type];
829 
830 	if (sdi->firm_flags & FIRM_SYNCTR) {
831 		scinit(sc, ii->ii_slave, DEV_BSIZE);
832 		sc->sc_opcode = SCOP_TST;
833 		sc->sc_message = MSG_EXTND;	/* extended message */
834 		sc->sc_param[0] = MSG_EXTND;
835 		sc->sc_param[1] = 0x03;
836 		sc->sc_param[2] = 0x01;		/* synchronous transfer */
837 		sc->sc_param[3] = sdi->tr_period;	/* transfer period */
838 		sc->sc_param[4] = sdi->tr_offset;	/* REQ offset */
839 
840 		if (sdc_softc[ii->ii_ctlr].sdc_firmware & SDCFW_CACHE)
841 			sc->sc_tstatus |= TS_CONTR_ON;	/* contiguous TR ON */
842 		else
843 			sc->sc_tstatus |= TS_CONTR_OFF;	/* contiguous TR OFF */
844 
845 #ifdef news1800
846 		if (scsi_berr_bug() != 0) {
847 			sc->sc_tstatus &= ~TS_CONTR_ON;
848 			sc->sc_tstatus |= TS_CONTR_OFF;
849 		}
850 #endif
851 
852 		if (sc->sc_tstatus & TS_CONTR_OFF)
853 			sdc_softc[ii->ii_ctlr].sdc_firmware &= ~SDCFW_CONTR;
854 		else
855 			sdc_softc[ii->ii_ctlr].sdc_firmware |= SDCFW_CONTR;
856 
857 		sc_go(ii->ii_intr, sc, SCSI_INTDIS);
858 
859 		syncp = &sd_sync_param[ii->ii_unit];
860 		syncp->tr_period = sc->sc_param[3];
861 		syncp->tr_offset = sc->sc_param[4];
862 		if (sc->sc_param[4])
863 			sdd_softc[ii->ii_unit].sdd_flags |= SDDF_SYNCTR;
864 	}
865 }
866 
867 
868 sdattach(ii)
869 	register struct iop/**/_device *ii;
870 {
871 	register int unit;
872 	register int i;
873 	struct sdc_softc *sdc;
874 	struct sdd_softc *sdd;
875 	int dummy;
876 
877 	sdc = &sdc_softc[ii->ii_ctlr];
878 	sdc->sdc_timeo = 60;			/* timeout 60 sec */
879 
880 	unit = ii->ii_unit;
881 	sdd = &sdd_softc[unit];
882 	sdd->sdd_stoptime = OD_STOPTIME;	/* REMOVABLE MEDIA */
883 	sdd->sdd_start = -2;
884 
885 	sdmaptype(ii);
886 
887 	if (sdwstart == 0) {
888 		sdwstart++;
889 		timeout(sdwatch, (caddr_t)0, hz);
890 		timeout(sdstop, (caddr_t)0, hz);
891 	}
892 
893 	/*
894 	 * initialize open flag
895 	 */
896 	for (i = 0; i < PNUM; i++) {
897 		sd_b_openf[unit][i] = 0;
898 		sd_c_openf[unit][i] = 0;
899 	}
900 
901 	if (re_init_done > 0)
902 		return;
903 
904 	if (sdc->sdc_firmware & SDCFW_HD) {
905 		/*
906 		 * If device is Hard Disk,
907 		 *	then get partition information.
908 		 */
909 		sdrpartinfo(ii);
910 		dummy = DEV_BSIZE * sdstdrv[unit].rps * sdstdrv[unit].nsect;
911 	} else
912 		dummy = DEV_BSIZE * 40 * 31;
913 
914 	if (ii->ii_dk >= 0 && dummy)
915 		dk_wpms[ii->ii_dk] = dummy / (2 * 1000000);
916 }
917 
918 sdmaptype(ii)
919 	register struct iop/**/_device *ii;
920 {
921 	printf("sd%d: %s\n", ii->ii_unit, sddevinfo[ii->ii_type].call_name);
922 }
923 
924 int sd_b_major = -1;
925 
926 sd_b_open(dev, flag)
927 	dev_t dev;
928 	int flag;
929 {
930 	sd_b_major = major(dev);
931 	return (_sdopen(dev, flag, S_IFBLK));
932 }
933 
934 int sd_c_major = -1;
935 
936 sd_c_open(dev, flag)
937 	dev_t dev;
938 	int flag;
939 {
940 	sd_c_major = major(dev);
941 	return (_sdopen(dev, flag, S_IFCHR));
942 }
943 
944 _sdopen(dev, flag, fmt)
945 	register dev_t dev;
946 	int flag;
947 	int fmt;
948 {
949 	register struct iop/**/_device *ii;
950 	register struct sdd_softc *sdd;
951 	register struct sdc_softc *sdc;
952 	register struct sddevinfo *sdi;
953 	register int unit;
954 	register int i;
955 	u_char *sdopfp;
956 	u_char	old_sdopf;
957 	int media_changed;
958 	int s;
959 	int stat;
960 	struct scsi uscsi;
961 
962 	unit = dev2unit(dev);
963 	if (unit >= nsd || (ii = sddinfo[unit]) == 0 || ii->ii_alive == 0)
964 		return (ENXIO);
965 
966 	sdd = &sdd_softc[unit];
967 	sdc = &sdc_softc[ii->ii_ctlr];
968 	sdi = &sddevinfo[ii->ii_type];
969 
970 	if (sdd->sdd_flags & SDDF_XUSE)
971 		return (EBUSY);
972 
973 	/*
974 	 * LOCK while sdstop() running.
975 	 */
976 	s = splclock();
977 	while (sdc->sdc_state & SDCS_SCUNLOCK) {
978 		sdc->sdc_state |= SDCS_OPEN_WAIT;
979 		sleep((caddr_t)sdc, PRIBIO);
980 	}
981 	splx(s);
982 
983 	/*
984 	 * LOCK sdtmp buffer
985 	 */
986 	s = splclock();
987 	while (sdtmp_stat & B_BUSY) {
988 		sdtmp_stat |= B_WANTED;
989 		sleep((caddr_t)sdtmp, PRIBIO);
990 	}
991 	sdtmp_stat |= B_BUSY;
992 	splx(s);
993 	sdd->sdd_flags |= SDDF_GETTMP;
994 
995 	if ((fmt & S_IFMT) == S_IFBLK)
996 		sdopfp = &sd_b_openf[unit][dev2part(dev)];
997 	else
998 		sdopfp = &sd_c_openf[unit][dev2part(dev)];
999 	old_sdopf = *sdopfp;
1000 	if (old_sdopf <= 1)
1001 		*sdopfp += 1;		/* 1: 1st open (ONLY_ONE) */
1002 					/* 2: already opened */
1003 	stat = 0;
1004 	media_changed = 0;
1005 
1006 	/*
1007 	 * From here on until pre_open_done is only for removable devices
1008 	 */
1009 	if ((sdc->sdc_firmware & SDCFW_RMB) == 0)
1010 		goto pre_open_done;
1011 
1012 	if ((minor(dev) & 0x80) || (dev == rootdev))
1013 		sdd->sdd_stoptime = 0x7fffffff;		/*XXX*/
1014 
1015 	/*
1016 	 * Start Unit
1017 	 */
1018 	s = splclock();	/* inhibit clock interrupt */
1019 	i = sdd->sdd_start;
1020 	sdd->sdd_start = sdd->sdd_stoptime;
1021 	splx(s);
1022 	if (i <= 0) {
1023 		scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize);
1024 		uscsi.sc_opcode = SCOP_STST;
1025 		uscsi.sc_count = SDSS_START;
1026 
1027 		if (sdcmd(dev, &uscsi)) {
1028 			sdd->sdd_start = i;
1029 			if ((flag & FWRITE) == 0)
1030 				goto sdopen_setup;
1031 			stat = EIO;
1032 			goto pre_open_done;
1033 		}
1034 	}
1035 
1036 	/*
1037 	 * prevent medium removal
1038 	 */
1039 	scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize);
1040 	uscsi.sc_opcode = SCOP_MEDRMV;
1041 	uscsi.sc_count = SDRMV_PREV;
1042 	if (sdcmd(dev, &uscsi)) {
1043 		stat = EIO;
1044 		goto pre_open_done;
1045 	}
1046 	sdd->sdd_flags |= SDDF_INHRMV;
1047 
1048 sdopen_setup:
1049 	if ((sdd->sdd_flags & SDDF_SAMEDSK) == SDDF_DSKCHGD) {
1050 		sdd->sdd_flags |= SDDF_SAMEDSK;
1051 		media_changed = 1;
1052 
1053 		/*
1054 		 * From here on until mo_check_done is only for MO device
1055 		 */
1056 		if ((sdc->sdc_firmware & SDCFW_MO) == 0)
1057 			goto mo_check_done;
1058 
1059 		/*
1060 		 * Mode Sense
1061 		 */
1062 		bzero(sdtmp, 36);
1063 		scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize);
1064 		uscsi.sc_cpoint = sdtmp;
1065 		uscsi.sc_ctrnscnt = 36;
1066 		uscsi.sc_opcode = SCOP_MSENSE;
1067 		uscsi.sc_lad = (SDM_PF << 16)|((SDM_PC_CUR|SDM_PCODE_ALL) << 8);
1068 		uscsi.sc_count = 36;
1069 
1070 		if (sdcmd(dev, &uscsi) == 0) {
1071 			/*
1072 			 * check Write Protect mode
1073 			 */
1074 			if (sdtmp[2] & 0x80)
1075 				sdd->sdd_flags |= SDDF_WPROTECT;
1076 			else
1077 				sdd->sdd_flags &= ~SDDF_WPROTECT;
1078 			/*
1079 			 * check Format Mode
1080 			 */
1081 			if (sdtmp[26] == 2) {
1082 				ii->ii_type = search_index(SMO_S501);
1083 				if (mo_disp_format)
1084 					printf("sd%d: format mode 2 (original format)\n", unit);
1085 			} else if (sdtmp[26] == 3) {
1086 				int spare;
1087 
1088 				spare = *(short *)&sdtmp[32];
1089 				if (spare == 2048)
1090 					ii->ii_type =
1091 						search_index(SMO_S501_ISO2);
1092 				else
1093 					ii->ii_type =
1094 						search_index(SMO_S501_ISO);
1095 				if (mo_disp_format)
1096 					printf("sd%d: format mode 3 (ISO format) spare=%d\n", unit, spare);
1097 			} else {
1098 				sdd->sdd_flags |= SDDF_NONFMT;
1099 				if (mo_disp_format)
1100 					printf("sd%d: Non format\n", unit);
1101 			}
1102 			sdi = &sddevinfo[ii->ii_type];
1103 		}
1104 
1105 		/*
1106 		 * Mode Select
1107 		 *	Error Recovery Parameters set
1108 		 */
1109 		i = *(sdi->ERP_page +1) + 2;	/* page length */
1110 		bzero(sdtmp, i + 4);
1111 		bcopy(sdi->ERP_page, (caddr_t)&sdtmp[4], i);
1112 		scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize);
1113 		uscsi.sc_cpoint = sdtmp;
1114 		uscsi.sc_ctrnscnt = i + 4;
1115 		uscsi.sc_opcode = SCOP_MSELECT;
1116 		uscsi.sc_lad = (SDM_PF << 16);
1117 		uscsi.sc_count = i + 4;
1118 
1119 		(void) sdcmd(dev, &uscsi);
1120 
1121 		/*
1122 		 * Read Grown Defect list
1123 		 */
1124 		scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize);
1125 		uscsi.sc_cpoint = sdtmp;
1126 		uscsi.sc_ctrnscnt = 4;
1127 		uscsi.sc_opcode = SCOP_RDL;
1128 		uscsi.sc_cdb.un_type1.t1_ladhi = (SDDL_GLIST|SDDL_PHYSFMT) << 8;
1129 		uscsi.sc_cdb.un_type1.t1_p3 = 4;
1130 
1131 		(void) sdcmd(dev, &uscsi);
1132 		i = *(short *)&sdtmp[2] / 8;
1133 		if (i > (1024*9/10))
1134 			printf("sd%d: WARNING: DEFECT SPARE LOCATION < 10%\n",
1135 				unit);
1136 mo_check_done:
1137 		/*
1138 		 * Read Capacity
1139 		 */
1140 		bzero((caddr_t)sdtmp, 8);
1141 		scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize);
1142 		uscsi.sc_cpoint = sdtmp;
1143 		uscsi.sc_ctrnscnt = 8;
1144 		uscsi.sc_opcode = SCOP_RCAP;
1145 
1146 		(void) sdcmd(dev, &uscsi);
1147 		sdd->sdd_nsect = *(int *)&sdtmp[0] + 1;
1148 		sdd->sdd_sectsize = *(int *)&sdtmp[4];
1149 
1150 		if ((sdd->sdd_sectsize != DEV_BSIZE)
1151 				&& (sdd->sdd_sectsize != SDBSIZE1K))
1152 			sdd->sdd_sectsize = DEV_BSIZE;
1153 	}
1154 
1155 	if ((sdd->sdd_flags & SDDF_WPROTECT) && (flag & FWRITE))
1156 		stat = EROFS;
1157 
1158 pre_open_done:
1159 
1160 	if (stat == 0) {
1161 		if ((isalone(unit) == ONLY_ONE) || media_changed) {
1162 			/*
1163 			 * read partition information from sector zero.
1164 			 */
1165 			sdrpartinfo(ii);
1166 			if (ii->ii_dk >= 0) {
1167 				dk_wpms[ii->ii_dk] =
1168 					sdd->sdd_sectsize * sdstdrv[unit].rps
1169 					* sdstdrv[unit].nsect / (2 * 1000000);
1170 			}
1171 		}
1172 	} else {
1173 		/*
1174 		 * open error
1175 		 */
1176 		*sdopfp = old_sdopf;
1177 		if ((sdd->sdd_flags & SDDF_INHRMV) && (isalone(unit) == 0)) {
1178 			sdd->sdd_flags &= ~SDDF_INHRMV;
1179 			scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize);
1180 			uscsi.sc_opcode = SCOP_MEDRMV;
1181 			uscsi.sc_count = SDRMV_ALLOW;
1182 			(void) sdcmd(dev, &uscsi);
1183 		}
1184 	}
1185 
1186 	/*
1187 	 * UNLOCK open
1188 	 */
1189 	s = splclock();
1190 	sdd->sdd_flags &= ~SDDF_GETTMP;
1191 	if (sdtmp_stat & B_WANTED)
1192 		wakeup((caddr_t)sdtmp);
1193 	sdtmp_stat &= ~(B_BUSY|B_WANTED);
1194 	splx(s);
1195 	return (stat);
1196 }
1197 
1198 int sd_access_check_on;		/* Common flags for sd_access_check() */
1199 
1200 sd_access_check(bp)
1201 	register struct buf *bp;
1202 {
1203 	register struct iop/**/_device *ii;
1204 	register struct sdd_softc *sdd;
1205 	int unit;
1206 	int check_part;
1207 	int limit;
1208 	int over;
1209 	register struct size *sizes;
1210 	register int lba;	/* logical block address */
1211 	register int sz;
1212 	register int i;
1213 
1214 	check_part = 0;
1215 	unit = dev2unit(bp->b_dev);
1216 	ii = sddinfo[unit];
1217 	sdd = &sdd_softc[unit];
1218 	sizes = sdstdrv[unit].sizes;
1219 
1220 	lba = sizes[dev2part(bp->b_dev)].sd_blkoff + dkblock(bp);
1221 	sz = howmany(bp->b_bcount, sdd->sdd_sectsize);
1222 
1223 	/*
1224 	 * When block device is used,
1225 	 *	inhibit raw device write operation.
1226 	 */
1227 	if ((major(bp->b_dev) == sd_c_major)			/* RAW I/O */
1228 	    && ((bp->b_flags & B_READ) == 0)			/* WRITE */
1229 	    && ((ii->ii_flags & SD_F_ENW) == 0)			/* INHIBIT */
1230 	    && ((sd_access_check_on & SD_F_ENW) == 0)) {
1231 
1232 		for (i = 0; i < PNUM; i++) {
1233 			if (sd_b_openf[unit][i] == 0)
1234 				continue;
1235 			/*
1236 			 *   |----|========|---|======|-------|
1237 			 * 1 |---+++--------------------------| CUT OFF
1238 			 * 2 |---++++++++++++-----------------| CUT OFF
1239 			 * 3 |---++++++++++++++++-------------| CUT OFF
1240 			 * 4 |---++++++++++++++++++++++++-----| CUT OFF
1241 			 * 5 |-------+++----------------------| ERROR
1242 			 * 6 |------------+++-----------------| ERROR
1243 			 * 7 |------------+++++++-------------| ERROR
1244 			 * 8 |------------+++++++++++++++-----| ERROR
1245 			 */
1246 			if ((lba < (sizes[i].sd_blkoff + sizes[i].sd_nblocks))
1247 			    && ((lba + sz) > sizes[i].sd_blkoff))
1248 				check_part |= (1 << i);
1249 		}
1250 	}
1251 
1252 	if (check_part) {
1253 		limit = 0x7fffffff;	/* XXX */
1254 		for (i = 0; i < PNUM; i++) {
1255 			if ((check_part & (1 << i)) == 0)
1256 				continue;
1257 
1258 			if (lba >= sizes[i].sd_blkoff) {
1259 				bp->b_flags |= B_ERROR;
1260 				bp->b_error = EIO;
1261 				bp->b_resid = bp->b_bcount;
1262 
1263 				printf("sd%d%c: RAW DEVICE WRITE PROTECTED: ",
1264 					unit, pname[dev2part(bp->b_dev)]);
1265 				printf("sn = 0x%x(%d), off = 0x%x(%d)\n",
1266 					dkblock(bp)*DEV_BSIZE/sdd->sdd_sectsize,
1267 					dkblock(bp)*DEV_BSIZE/sdd->sdd_sectsize,
1268 					sizes[dev2part(bp->b_dev)].sd_blkoff,
1269 					sizes[dev2part(bp->b_dev)].sd_blkoff);
1270 
1271 				return (-1);
1272 			}
1273 
1274 			if (sizes[i].sd_blkoff < limit)
1275 				limit = sizes[i].sd_blkoff;
1276 		}
1277 	} else {
1278 		limit = sizes[dev2part(bp->b_dev)].sd_blkoff
1279 			+ sizes[dev2part(bp->b_dev)].sd_nblocks;
1280 	}
1281 
1282 	if ((over = (lba + sz) - limit) > 0) {
1283 		/*
1284 		 * Logical Block Address is outside the valid area.
1285 		 */
1286 		if (((ii->ii_flags & SD_F_EOLBA) != 0)
1287 			|| ((sd_access_check_on & SD_F_EOLBA) != 0)) {
1288 			/*
1289 			 * error if outside LBA
1290 			 */
1291 			return(-1);
1292 		}
1293 		bp->b_resid = bp->b_bcount - (sz - over) * sdd->sdd_sectsize;
1294 		if (bp->b_resid >= bp->b_bcount) {
1295 			bp->b_resid = bp->b_bcount;
1296 			return(-1);
1297 		}
1298 	}
1299 
1300 	return (0);
1301 }
1302 
1303 sd_b_close(dev, flag)
1304 	dev_t dev;
1305 	int flag;
1306 {
1307 	return (_sdclose(dev, flag, S_IFBLK));
1308 }
1309 
1310 sd_c_close(dev, flag)
1311 	dev_t dev;
1312 	int flag;
1313 {
1314 	return (_sdclose(dev, flag, S_IFCHR));
1315 }
1316 
1317 _sdclose(dev, flag, fmt)
1318 	register dev_t dev;
1319 	int flag;
1320 	int fmt;
1321 {
1322 	register struct iop/**/_device *ii;
1323 	register struct sdd_softc *sdd;
1324 	register int unit;
1325 	struct sdc_softc *sdc;
1326 	struct scsi uscsi;
1327 	struct sc_extnd *sce;
1328 
1329 	unit = dev2unit(dev);
1330 	if (unit >= nsd || (ii = sddinfo[unit]) == 0 || ii->ii_alive == 0)
1331 		return (ENXIO);
1332 
1333 	sdd = &sdd_softc[unit];
1334 	sdc = &sdc_softc[ii->ii_ctlr];
1335 	sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0];
1336 
1337 	/*
1338 	 * still remain jobs
1339 	 *	sleep about 10ms -> 1sec
1340 	 */
1341 	while (ii->ii_mi->im_tab.b_actf != NULL)
1342 		sleep((caddr_t)&lbolt, PRIBIO);
1343 
1344 	if ((fmt & S_IFMT) == S_IFBLK)
1345 		sd_b_openf[unit][dev2part(dev)] = 0;
1346 	else
1347 		sd_c_openf[unit][dev2part(dev)] = 0;
1348 	sdd->sdd_flags &= ~SDDF_XUSE;
1349 
1350 	if ((sdc->sdc_firmware & SDCFW_RMB) && (isalone(unit) == 0)) {
1351 		sdd->sdd_flags &= ~SDDF_INHRMV;
1352 		scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize);
1353 		uscsi.sc_opcode = SCOP_MEDRMV;
1354 		uscsi.sc_count = SDRMV_ALLOW;
1355 		(void) sdcmd(dev, &uscsi);
1356 	}
1357 	return (0);
1358 }
1359 
1360 sdcmd(dev, usc)
1361 	dev_t dev;
1362 	struct scsi *usc;
1363 {
1364 	register struct buf *bp;
1365 	register struct scsi *ksc;
1366 	register u_char *point;
1367 	register int unit;
1368 	int error;
1369 	int s;
1370 	int cnt;
1371 
1372 	if (usc == 0)
1373 		return (ENXIO);
1374 
1375 	error = 0;
1376 	unit = dev2unit(dev);
1377 	bp = &csdbuf[unit];
1378 
1379 	/*
1380 	 * LOCK csdbuf
1381 	 */
1382 	s = splclock();
1383 	while (bp->b_flags & B_BUSY) {
1384 		bp->b_flags |= B_WANTED;
1385 		sleep((caddr_t)bp, PRIBIO);
1386 	}
1387 	bzero((caddr_t)bp, sizeof(struct buf));
1388 	bp->b_flags = B_BUSY|B_READ;
1389 	splx(s);
1390 
1391 	ksc = &kernscsi[unit];
1392 	bcopy((caddr_t)usc, (caddr_t)ksc, sizeof(struct scsi));
1393 	/*
1394 	 * setup command buffer
1395 	 */
1396 	bp->b_dev = dev;
1397 	bp->b_proc = curproc;
1398 	cnt = ksc->sc_ctrnscnt;
1399 	bp->b_bcount = cnt;
1400 
1401 	point = ksc->sc_cpoint;
1402 	bp->b_un.b_addr = (caddr_t)point;
1403 	if (cnt > 0) {
1404 		if (point == NULL) {
1405 			ksc->sc_cpoint = point = get_scsi(unit)->sc_param;
1406 			if (cnt > 20) {
1407 				error = EFAULT;
1408 				goto done;
1409 			}
1410 		}
1411 		if (point < (u_char *)KERNBASE) {
1412 			if (useracc(point, cnt, B_WRITE) == NULL) {
1413 				error = EFAULT;
1414 				goto done;
1415 			}
1416 			curproc->p_flag |= P_PHYSIO;
1417 			vslock(point, cnt);
1418 			bp->b_flags |= B_PHYS;
1419 		}
1420 #ifndef mips
1421 		else {
1422 			if (kernacc(point, cnt, B_WRITE) == NULL) {
1423 				error = EFAULT;
1424 				goto done;
1425 			}
1426 		}
1427 #endif
1428 		ksc->sc_tstatus = TS_MAPPED_PIO;	/* XXX */
1429 	}
1430 
1431 	/*
1432 	 * call strategy entry, and wait command done.
1433 	 */
1434 	sdstrategy(bp);
1435 	iowait(bp);
1436 
1437 	if ((cnt > 0) && (point < (u_char *)KERNBASE)) {
1438 		vsunlock(point, cnt, B_READ);
1439 		curproc->p_flag &= ~P_PHYSIO;
1440 	}
1441 	if ((bp->b_flags & B_ERROR) == 0)
1442 		error = 0;
1443 	else {
1444 		if (bp->b_error)
1445 			error = bp->b_error;
1446 		else
1447 			error = EIO;
1448 	}
1449 	bcopy((caddr_t)ksc, (caddr_t)usc, sizeof(struct scsi));
1450 
1451 done:
1452 	/*
1453 	 * UNLOCK csdbuf
1454 	 */
1455 	s = splclock();
1456 	if (bp->b_flags & B_WANTED)
1457 		wakeup((caddr_t)bp);
1458 	bp->b_flags = 0;
1459 	splx(s);
1460 	return (error);
1461 }
1462 
1463 /*
1464  * read partition information from sector zero.
1465  */
1466 sdrpartinfo(ii)
1467 	register struct iop/**/_device *ii;
1468 {
1469 	register struct disklabel *dlp;
1470 	register struct sdst *hsp;
1471 	register struct sdst *st;
1472 	register int unit;
1473 	register int i;
1474 	struct firstsector *fsp;
1475 	struct sdc_softc *sdc;
1476 	struct sdd_softc *sdd;
1477 	struct sddevinfo *sdi;
1478 	struct scsi uscsi;
1479 	int s;
1480 
1481 	sdi = &sddevinfo[ii->ii_type];
1482 	unit = ii->ii_unit;
1483 
1484 	sdd = &sdd_softc[unit];
1485 	sdc = &sdc_softc[ii->ii_ctlr];
1486 
1487 	if ((sdd->sdd_flags & (SDDF_NONFMT|SDDF_FMTDONE)) == 0) {
1488 		register struct sc_rcap *scr = (struct sc_rcap *)sdtmp;
1489 
1490 		sdd->sdd_flags |= SDDF_FMTDONE;
1491 
1492 		bzero((caddr_t)sdtmp, 8);
1493 		scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize);
1494 		uscsi.sc_cpoint = (u_char *)scr;
1495 		uscsi.sc_ctrnscnt = 8;
1496 		uscsi.sc_opcode = SCOP_RCAP;
1497 		(void) sdcmd(unit << 3, &uscsi);
1498 
1499 		sdd->sdd_nsect = scr->scr_nblock + 1;
1500 		sdd->sdd_sectsize = scr->scr_blocklen;
1501 		if (sdd->sdd_sectsize == 0)
1502 			sdd->sdd_sectsize = SDBSIZE1K;
1503 	}
1504 
1505 	bzero(sdtmp, DEV_BSIZE);
1506 
1507 	if ((sdd->sdd_flags & SDDF_NONFMT) == 0) {
1508 		scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize);
1509 		uscsi.sc_cpoint = sdtmp;
1510 		uscsi.sc_ctrnscnt = DEV_BSIZE;
1511 		uscsi.sc_opcode = SCOP_READ;
1512 		uscsi.sc_lad = 0;
1513 		uscsi.sc_count = 1;
1514 
1515 		(void) sdcmd(unit << 3, &uscsi);
1516 		sdd->sdd_flags &= ~SDDF_SKIPCHECK;
1517 	}
1518 
1519 	fsp = (struct firstsector *)sdtmp;
1520 	dlp = (struct disklabel *)(sdtmp + LABELOFFSET);
1521 
1522 	s = splclock();
1523 	hsp = &sdstdrv[unit];
1524 	bzero((caddr_t)hsp, sizeof (struct sdst));
1525 	bzero(&sdlabel[unit], sizeof (struct disklabel));
1526 
1527 	if ((dlp->d_magic == DISKMAGIC)
1528 	    && ((ii->ii_flags & SD_F_IGNLABEL) == 0)) {
1529 		sdlabel[unit] = *dlp;
1530 		disklabel2sdst(unit, dlp, hsp);
1531 	} else {
1532 		if ((ii->ii_type == UNKNOWN_DISK)
1533 				|| (sdi->sdstp->sizes == calc_disk_sizes)) {
1534 			/*
1535 			 * If device is UNKNOWN PARTITION SIZE,
1536 			 *	calculate default partition from capacity.
1537 			 */
1538 			st = sdi->sdstp;
1539 			hsp->nsect = st->nsect;		/* # sectors/track */
1540 			hsp->ntrak = st->ntrak;		/* # tracks/cylinder */
1541 			hsp->nspc = st->nspc;		/* # sectors/cylinder */
1542 			hsp->ncyl = st->ncyl;		/* # cylinders */
1543 			hsp->rps = st->rps;		/* # revolutions/sec */
1544 			hsp->sizes = sdsizedrv[unit];	/* partition table */
1545 
1546 			sd_calcpart(ii, hsp->sizes,
1547 					sdd->sdd_nsect, sdd->sdd_sectsize);
1548 			sdst2disklabel(unit, hsp, &sdlabel[unit]);
1549 		} else {
1550 			/*
1551 			 * If device is support disk,
1552 			 *	copy default partition from size table.
1553 			 */
1554 			st = sdi->sdstp;
1555 
1556 			hsp->nsect = st->nsect;	/* # sectors/track */
1557 			hsp->ntrak = st->ntrak;	/* # tracks/cylinder */
1558 			hsp->nspc = st->nspc;	/* # sectors/cylinder */
1559 			hsp->ncyl = st->ncyl;	/* # cylinders */
1560 			hsp->rps = st->rps;	/* # revolutions / second */
1561 			hsp->sizes = sdsizedrv[unit];	/* partition table */
1562 
1563 			for (i = 0; i < PNUM; i++) {
1564 			    hsp->sizes[i].sd_nblocks = st->sizes[i].sd_nblocks;
1565 			    hsp->sizes[i].sd_blkoff = st->sizes[i].sd_blkoff;
1566 			}
1567 			sdst2disklabel(unit, hsp, &sdlabel[unit]);
1568 		}
1569 	}
1570 
1571 	/* BEGIN XXX*/
1572 	if (hsp->rps == 0) {
1573 		/*
1574 		 * If device is support disk,
1575 		 *	copy default partition from size table.
1576 		 */
1577 		st = sdi->sdstp;
1578 
1579 		hsp->nsect = st->nsect;		/* # sectors/track */
1580 		hsp->ntrak = st->ntrak;		/* # tracks/cylinder */
1581 		hsp->nspc = st->nspc;		/* # sectors/cylinder */
1582 		hsp->ncyl = st->ncyl;		/* # cylinders */
1583 		hsp->rps = st->rps;		/* # revolutions / second */
1584 		sdst2disklabel(unit, hsp, &sdlabel[unit]);
1585 	}
1586 	/* END XXX*/
1587 	(void)splx(s);
1588 }
1589 
1590 static char Warn_Part[] = "sd%d: PARTITION TABLE CHANGED\n";
1591 static char Pr_Part_Fmt[] = "sd%d%c: nblk=%d, off=%d\n";
1592 
1593 #define stsz(N) st->sizes[(N)].sd_nblocks
1594 #define stof(N) st->sizes[(N)].sd_blkoff
1595 #define dlsz(N) dlp->d_partitions[(N)].p_size
1596 #define dlof(N) dlp->d_partitions[(N)].p_offset
1597 #define disz(N) dip->di_part[(N)].dp_nblocks
1598 #define diof(N) dip->di_part[(N)].dp_blkoff
1599 
1600 #ifndef BBSIZE
1601 #define BBSIZE 8192
1602 #endif
1603 
1604 static
1605 check_sdst(unit, st)
1606 	int unit;
1607 	struct sdst *st;
1608 {
1609 	if (st->nsect == 0) {
1610 		st->nsect = 1;
1611 		printf("sd%d: nsect SHOULD BE != 0, 1 assumed\n", unit);
1612 	}
1613 
1614 	if (st->rps == 0) {
1615 		st->rps = 60;
1616 		printf("sd%d: rps SHOULD BE != 0, 60 assumed\n", unit);
1617 	}
1618 }
1619 
1620 static
1621 disklabel2sdst(unit, dlp, st)
1622 	int unit;
1623 	register struct disklabel *dlp;
1624 	register struct sdst *st;
1625 {
1626 	register int i;
1627 	int msg_header_printed;
1628 
1629 	msg_header_printed = 0;
1630 
1631 	st->nsect = dlp->d_nsectors;	/* # sectors/track */
1632 	st->ntrak = dlp->d_ntracks;	/* # tracks/cylinder */
1633 	st->nspc = dlp->d_secpercyl;	/* # sectors/cylinder */
1634 	st->ncyl = dlp->d_ncylinders;	/* # cylinders */
1635 	st->rps = dlp->d_rpm / 60;	/* # revolutions / second */
1636 	st->sizes = sdsizedrv[unit];	/* partition table */
1637 
1638 	check_sdst(unit, st);
1639 
1640 	for (i = 0; i < PNUM; i++) {
1641 		if (msg_header_printed == 0) {
1642 			if (((stsz(i) != 0) || (stof(i) != 0))
1643 			    && ((stsz(i) != dlsz(i)) || (stof(i) != dlof(i)))) {
1644 				msg_header_printed = 1;
1645 			}
1646 		}
1647 	}
1648 
1649 	for (i = 0; i < PNUM; i++) {
1650 		stsz(i) = dlsz(i);
1651 		stof(i) = dlof(i);
1652 	}
1653 
1654 	if (msg_header_printed) {
1655 		printf(Warn_Part, unit);
1656 		for (i = 0; i < PNUM; i++)
1657 			printf(Pr_Part_Fmt, unit, pname[i], stsz(i), stof(i));
1658 	}
1659 }
1660 
1661 static
1662 sdst2disklabel(unit, st, dlp)
1663 	int unit;	/*XXX*/
1664 	register struct sdst *st;
1665 	register struct disklabel *dlp;
1666 {
1667 	register int i;
1668 
1669 	dlp->d_type = DTYPE_SCSI;			/* drive type */
1670 	dlp->d_secsize = sdd_softc[unit].sdd_sectsize;	/* # of bytes per sector */
1671 	dlp->d_nsectors = st->nsect;	/* # sectors/track */
1672 	dlp->d_ntracks = st->ntrak;	/* # tracks/cylinder */
1673 	dlp->d_ncylinders = st->ncyl;	/* # cylinders */
1674 	dlp->d_secpercyl = st->nspc;	/* # sectors/cylinder */
1675 	dlp->d_rpm = st->rps * 60;	/* # revolutions / minute */
1676 	dlp->d_bbsize = BBSIZE;	/*XXX*/	/* size of boot area at sn0, bytes */
1677 	dlp->d_sbsize = SBSIZE;	/*XXX*/	/* max size of fs superblock, bytes */
1678 
1679 	for (i = 0; i < PNUM; i++) {
1680 		dlsz(i) = stsz(i);
1681 		dlof(i) = stof(i);
1682 	}
1683 }
1684 
1685 #undef stsz
1686 #undef stof
1687 #undef dlsz
1688 #undef dlof
1689 #undef disz
1690 #undef diof
1691 
1692 sd_calcpart(ii, disk_sizes, nsect, sectsize)
1693 	register struct iop/**/_device *ii;
1694 	register struct size disk_sizes[];
1695 	int nsect;
1696 	int sectsize;
1697 {
1698 	register struct defpart *dp;
1699 	register int size_mb;
1700 	register int i;
1701 	int psize;
1702 
1703 	size_mb = nsect * sectsize / (1024 * 1024);
1704 
1705 	for (dp = defpart_std; dp->range_max; dp++)
1706 		if ((dp->range_min <= size_mb) && (size_mb < dp->range_max))
1707 			break;
1708 
1709 	/* PASS1 */
1710 	for (i = 0; i < PNUM; i++) {
1711 		psize = dp->partsize[i];
1712 
1713 		switch (psize) {
1714 
1715 		case PART_UNUSED:
1716 			disk_sizes[i].sd_nblocks = 0;
1717 			break;
1718 
1719 		case PART_SPEC:
1720 			disk_sizes[i].sd_nblocks = nsect * sectsize / DEV_BSIZE;
1721 			break;
1722 
1723 		case PART_CALCF:
1724 		case PART_CALCG:
1725 			break;
1726 
1727 		default:
1728 			disk_sizes[i].sd_nblocks = psize;
1729 			break;
1730 		}
1731 	}
1732 
1733 	/* PASS2 */
1734 	for (i = 0; i < PNUM; i++) {
1735 		psize = dp->partsize[i];
1736 
1737 		switch (psize) {
1738 
1739 		case PART_UNUSED:
1740 		case PART_SPEC:
1741 			break;
1742 
1743 		case PART_CALCF:
1744 			disk_sizes[i].sd_nblocks =
1745 				disk_sizes[PART_C].sd_nblocks -
1746 				(disk_sizes[PART_A].sd_nblocks +
1747 				 disk_sizes[PART_B].sd_nblocks +
1748 				 disk_sizes[PART_D].sd_nblocks +
1749 				 disk_sizes[PART_E].sd_nblocks +
1750 				 disk_sizes[PART_H].sd_nblocks);
1751 			break;
1752 
1753 		case PART_CALCG:
1754 			disk_sizes[i].sd_nblocks =
1755 				disk_sizes[PART_C].sd_nblocks -
1756 				(disk_sizes[PART_A].sd_nblocks +
1757 				 disk_sizes[PART_B].sd_nblocks +
1758 				 disk_sizes[PART_H].sd_nblocks);
1759 			break;
1760 
1761 		default:
1762 			break;
1763 		}
1764 	}
1765 
1766 	/* OFFSET */
1767 	disk_sizes[PART_A].sd_blkoff = 0;
1768 	disk_sizes[PART_B].sd_blkoff = disk_sizes[PART_A].sd_nblocks;
1769 	disk_sizes[PART_C].sd_blkoff = 0;
1770 	disk_sizes[PART_D].sd_blkoff = disk_sizes[PART_A].sd_nblocks
1771 					+ disk_sizes[PART_B].sd_nblocks
1772 					+ disk_sizes[PART_H].sd_nblocks;
1773 	disk_sizes[PART_E].sd_blkoff = disk_sizes[PART_D].sd_blkoff
1774 					+ disk_sizes[PART_D].sd_nblocks;
1775 	disk_sizes[PART_F].sd_blkoff = disk_sizes[PART_E].sd_blkoff
1776 					+ disk_sizes[PART_E].sd_nblocks;
1777 	disk_sizes[PART_G].sd_blkoff = disk_sizes[PART_D].sd_blkoff;
1778 
1779 	if (disk_sizes[PART_H].sd_nblocks == 0)
1780 		disk_sizes[PART_H].sd_blkoff = 0;
1781 	else {
1782 		disk_sizes[PART_H].sd_blkoff =
1783 			disk_sizes[PART_A].sd_nblocks +
1784 			disk_sizes[PART_B].sd_nblocks;
1785 	}
1786 
1787 	for (i = 0; i < PNUM; i++)
1788 		if (disk_sizes[i].sd_nblocks == 0)
1789 			disk_sizes[i].sd_blkoff = 0;
1790 }
1791 
1792 int sd_str_pr = 0;
1793 
1794 sdstrategy(bp)
1795 	register struct buf *bp;
1796 {
1797 	register struct iop/**/_device *ii;
1798 	register struct sdst *st;
1799 	register struct buf *dp;
1800 	register int unit;
1801 	register int ssize;
1802 	struct sdd_softc *sdd;
1803 	struct sdc_softc *sdc;
1804 	long bn;
1805 	int xunit;
1806 	int s;
1807 
1808 	xunit = dev2part(bp->b_dev);
1809 	unit = dev2unit(bp->b_dev);
1810 	if (unit >= nsd || (ii = sddinfo[unit]) == 0 || ii->ii_alive == 0)
1811 		goto bad;
1812 
1813 	if (bp != &csdbuf[unit]) {
1814 		/*
1815 		 * READ / WRITE command
1816 		 */
1817 		sdd = &sdd_softc[unit];
1818 		if (sdd->sdd_flags & SDDF_NONFMT)
1819 			goto bad;
1820 		sdc = &sdc_softc[ii->ii_ctlr];
1821 		ssize = sdd->sdd_sectsize;
1822 		if ((ssize != DEV_BSIZE)
1823 			&& ((((dkblock(bp) * DEV_BSIZE) % ssize) != 0)
1824 				|| (((bp->b_flags & B_READ) == 0) &&
1825 				    ((bp->b_bcount % ssize) != 0)))) {
1826 			goto bad;
1827 		}
1828 
1829 		st = &sdstdrv[unit];
1830 		bn = dkblock(bp);
1831 		bp->b_resid = 0;
1832 		if ((bn < 0) || (bn >= st->sizes[xunit].sd_nblocks))
1833 			goto bad2;
1834 		if (sd_access_check(bp) < 0)
1835 			goto bad2;
1836 
1837 #ifdef notdef /* KU: XXX */
1838 		bp->b_cylin = (bn + st->sizes[xunit].sd_blkoff) / st->nspc;
1839 	} else {
1840 		bp->b_cylin = 0;
1841 #endif
1842 	}
1843 
1844 	s = splsc();
1845 	dp = &sdutab[ii->ii_unit];
1846 	disksort(dp, bp);
1847 	if (dp->b_active == 0) {
1848 		sdustart(ii);
1849 		bp = &ii->ii_mi->im_tab;
1850 		if (bp->b_actf && bp->b_active == 0)
1851 			sdstart(ii->ii_mi);
1852 	}
1853 	splx(s);
1854 	return;
1855 
1856 bad:
1857 	bp->b_flags |= B_ERROR;
1858 	goto done;
1859 bad2:
1860 	bp->b_resid = bp->b_bcount;
1861 done:
1862 	iodone(bp);
1863 }
1864 
1865 /*
1866  * Unit start routine.
1867  */
1868 sdustart(ii)
1869 	register struct iop/**/_device *ii;
1870 {
1871 	register struct iop/**/_ctlr *im;
1872 	register struct buf *dp;
1873 
1874 	if (ii == NULL)
1875 		return;
1876 	im = ii->ii_mi;
1877 	dk_busy &= ~(1 << ii->ii_dk);
1878 	dp = &sdutab[ii->ii_unit];
1879 	if (dp->b_actf == NULL)
1880 		return;
1881 	/*
1882 	 * If the controller is active, just remember
1883 	 * that this device would like to be positioned ...
1884 	 * if we tried to position now we would confuse the SD.
1885 	 */
1886 	if (im->im_tab.b_active) {
1887 		sdc_softc[im->im_ctlr].sdc_softas |= (1 << ii->ii_slave);
1888 		return;
1889 	}
1890 	/*
1891 	 * If we have already positioned this drive,
1892 	 * then just put it on the ready queue.
1893 	 */
1894 	if (dp->b_active == 0)
1895 		dp->b_active = 1;
1896 	/*
1897 	 * Device is ready to go
1898 	 * put it on the ready queue for the controller
1899 	 * (unless its already there.)
1900 	 */
1901 	if (dp->b_active != 2) {
1902 		im->im_tab.b_actf = dp;
1903 		dp->b_active = 2;
1904 	}
1905 }
1906 
1907 /*
1908  * Start up a transfer on a drive.
1909  */
1910 sdstart(im)
1911 	register struct iop/**/_ctlr *im;
1912 {
1913 	register struct buf *bp;
1914 	register struct buf *dp;
1915 	register struct sdc_softc *sdc;
1916 
1917 loop:
1918 	/*
1919 	 * Pull a request off the controller queue.
1920 	 */
1921 	if ((dp = im->im_tab.b_actf) == NULL)
1922 		return;
1923 	if ((bp = dp->b_actf) == NULL)
1924 		return;
1925 	/*
1926 	 * Mark controller busy, and
1927 	 * determine destination of this request.
1928 	 */
1929 	im->im_tab.b_active++;
1930 
1931 	sdexec(bp);
1932 }
1933 
1934 void
1935 sdexec(bp)
1936 	register struct buf *bp;
1937 {
1938 	register struct iop/**/_device *ii;
1939 	register struct buf_stat *bs;
1940 	register struct scsi *sc;
1941 	register int ssize;
1942 	register int unit;
1943 	register int intr;
1944 	register int bn;
1945 	struct sdc_softc *sdc;
1946 	struct sdd_softc *sdd;
1947 	struct sdst *st;
1948 	int sz;
1949 	int over;
1950 	struct sc_map *map;
1951 
1952 	unit = dev2unit(bp->b_dev);
1953 	ii = sddinfo[unit];
1954 	intr = ii->ii_intr;
1955 	sdd = &sdd_softc[unit];
1956 	sdc = &sdc_softc[ii->ii_ctlr];
1957 
1958 	sc = get_scsi(intr);
1959 
1960 	if (bp == &csdbuf[unit]) {	/* do sdcmd() */
1961 		bcopy((caddr_t)&kernscsi[unit],
1962 			(caddr_t)sc, sizeof(struct scsi));
1963 		if (bp->b_un.b_addr == NULL) {
1964 			map = 0;
1965 		} else {
1966 			map = get_sc_map(intr);
1967 			sc->sc_map = (struct sc_map *)ipc_phys(map);
1968 		}
1969 	} else {			/* R/W */
1970 		ssize = sdd->sdd_sectsize;
1971 
1972 		st = &sdstdrv[unit];
1973 		bn = dkblock(bp);
1974 		if (sdd->sdd_lastblk / st->nspc != bn / st->nspc)
1975 			dk_seek[ii->ii_dk]++;
1976 
1977 		st = &sdstdrv[unit];
1978 		bn = dkblock(bp);
1979 
1980 		/*
1981 		 * Setup for the transfer, and get in the IOP queue.
1982 		 */
1983 		scinit(sc, ii->ii_slave, ssize);
1984 		sc->sc_ctrnscnt = bp->b_bcount - bp->b_resid;
1985 		map = get_sc_map(intr);
1986 		sc->sc_map = (struct sc_map *)ipc_phys(map);
1987 
1988 		/* cdb */
1989 		sc->sc_cdb.un_type1.t1_opcode =
1990 				(bp->b_flags & B_READ) ?	SCOP_EREAD :
1991 				(ii->ii_flags & SD_F_WRTVRFY) ?	SCOP_WRTVRFY :
1992 								SCOP_EWRITE;
1993 #ifdef mips
1994 		{
1995 		int v;
1996 
1997 		v = (bn + st->sizes[dev2part(bp->b_dev)].sd_blkoff)
1998 					* DEV_BSIZE / sdd->sdd_sectsize;
1999 		sc->sc_ladhi = v >> 16;
2000 		sc->sc_ladlo = v;
2001 
2002 		v = (sc->sc_ctrnscnt + ssize - 1) / ssize;
2003 		sc->sc_cdb.un_type1.t1_p2 = v >> 8;
2004 		sc->sc_cdb.un_type1.t1_p3 = v;
2005 		}
2006 #else
2007 		*(u_int *)(&sc->sc_cdb.un_type1.t1_ladhi) =
2008 				(bn + st->sizes[dev2part(bp->b_dev)].sd_blkoff)
2009 					* DEV_BSIZE / sdd->sdd_sectsize;
2010 		*(u_short *)(&sc->sc_cdb.un_type1.t1_p2) =
2011 				    (sc->sc_ctrnscnt + ssize -1) / ssize;
2012 #endif
2013 		if ((sdd->sdd_flags & SDDF_ERASEOFF)
2014 				&& ((bp->b_flags & B_READ) == 0)) {
2015 			sc->sc_ctrl = 0x40;
2016 		}
2017 	}
2018 
2019 	sdc->sdc_firmware |= SDCFW_BUSY;
2020 	iop/**/go(ii, map);
2021 }
2022 
2023 /*
2024  * Now all ready to go.
2025  */
2026 sddgo(im)
2027 	register struct iop/**/_ctlr *im;
2028 {
2029 	register int intr;
2030 
2031 	im->im_tab.b_active = 2;
2032 	intr = im->im_intr;
2033 
2034 	sc_go(intr, get_scsi(intr), SCSI_INTEN);
2035 }
2036 
2037 /*
2038  * copyin(), copyout() can't use in the interrupt routine.
2039  *	because user process is changed.
2040  */
2041 /*
2042  * Handle a disk interrupt.
2043  *	d: controller number
2044  */
2045 sdintr(d)
2046 	int d;
2047 {
2048 	register struct iop/**/_ctlr *im;
2049 	register struct sdc_softc *sdc;
2050 	register struct sdd_softc *sdd;
2051 	register struct scsi *sc;
2052 	register int intr;
2053 	register int unit;
2054 	register int slave;
2055 	register int as;
2056 	struct iop/**/_device *ii;
2057 	struct sddevinfo *sdi;
2058 	struct sc_extnd *sce;
2059 	struct sdst *st;
2060 	struct buf *bp;
2061 	struct buf *dp;
2062 	char *erp_page;
2063 	int code;
2064 	int len;
2065 	int tstatus;
2066 	int delay_start();
2067 	int delay_medrmv();
2068 	int wait_re_init_done();
2069 
2070 	im = sdminfo[d];
2071 	sdc = &sdc_softc[im->im_ctlr];
2072 	intr = im->im_intr;
2073 	as = sdc->sdc_softas;
2074 
2075 	sdc->sdc_wticks = 0;
2076 	sc = get_scsi(intr);
2077 	/*
2078 	 * If SDCS_IOCTL bit is set, then don't check error.
2079 	 */
2080 	if (sdc->sdc_state & SDCS_IOCTL) {
2081 		sdc->sdc_state &= ~SDCS_IOCTL;
2082 		sdd = &sdd_softc[(sdip[d][sc->sc_identify & IDT_DRMASK])->ii_unit];
2083 
2084 		if (sdc->sdc_state & SDCS_SCUNLOCK) {
2085 			int s;
2086 
2087 			sdc->sdc_state &= ~SDCS_SCUNLOCK;
2088 			s = splclock();
2089 			if (sdc->sdc_state & SDCS_OPEN_WAIT) {
2090 				sdc->sdc_state &= ~SDCS_OPEN_WAIT;
2091 				wakeup((caddr_t)sdc);
2092 			}
2093 			splx(s);
2094 			/*
2095 			 * UNLOCK SCSI access
2096 			 */
2097 			sdc->sdc_firmware &= ~SDCFW_BUSY;
2098 		}
2099 		return;
2100 	}
2101 
2102 	im->im_tab.b_active = 1;
2103 	/*
2104 	 * Get device and block structures, and a pointer
2105 	 * to the iop_device for the drive.
2106 	 */
2107 	dp = im->im_tab.b_actf;
2108 	bp = dp->b_actf;
2109 	unit = dev2unit(bp->b_dev);
2110 
2111 	ii = sddinfo[unit];
2112 	slave = ii->ii_slave;
2113 	st = &sdstdrv[unit];
2114 	dk_busy &= ~(1 << ii->ii_dk);
2115 	sdd = &sdd_softc[unit];
2116 	sdi = &sddevinfo[ii->ii_type];
2117 	sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0];
2118 
2119 	/*
2120 	 * Check error on the drive.
2121 	 */
2122 	tstatus = sc->sc_tstatus & TGSTMASK;
2123 	if (sc->sc_istatus != INST_EP) {
2124 		/*
2125 		 * initiator status is bad.
2126 		 *	check & retry !!
2127 		 */
2128 		if ((sc->sc_istatus&(INST_EP|INST_PRE)) == (INST_EP|INST_PRE)) {
2129 			/* detect parity error or abnormal terminate */
2130 			if ((sc->sc_istatus & INST_LB) == 0)
2131 				printf("sd%d: SCSI bus parity error\n", unit);
2132 			sdc->sdc_countcc--;
2133 			goto sdintr_exec;
2134 		}
2135 		if ((sc->sc_istatus & INST_EP) == 0) {
2136 			if (sc->sc_istatus & (INST_WAIT | INST_IP | INST_WR)) {
2137 				if (++sdc->sdc_retrycnt < NRETRY) {
2138 					im->im_tab.b_active = 2;
2139 					/*
2140 					 * Konomama return sitemo,
2141 					 * lost interrupt ni narudake deha
2142 					 * naidarou ka ?
2143 					 * Isso error ni sitahou ga
2144 					 * ii nodeha naidarou ka ?
2145 					 */
2146 					return;
2147 				}
2148 			}
2149 			printf("SCSI%d: abnormal termination\n", intr);
2150 			printf("ISTAT = 0x%x, TSTAT = 0x%x\n",
2151 					sc->sc_istatus, sc->sc_tstatus);
2152 			if (++sdc->sdc_nhrderr >= MAXHRDERR) {
2153 				printf("SCSI%d: too many hard errors\n", intr);
2154 				sdc->sdc_nhrderr = 0;
2155 				goto sdintr_error;
2156 			}
2157 			screset(intr);
2158 			goto sdintr_exec;
2159 		}
2160 		if ((sc->sc_istatus & (INST_TO|INST_HE)) != 0) {
2161 			if (sc->sc_istatus & INST_HE) {
2162 				/*
2163 				 * SCSI bus reset is occured.
2164 				 *	to be continue --> hdreset()
2165 				 */
2166 				re_init_done = 0;
2167 				timeout(wait_re_init_done, bp, 10*hz);
2168 				return;
2169 			}
2170 			if (++sdc->sdc_nhrderr >= MAXHRDERR) {
2171 				printf("SCSI%d: too many hard errors (ISTAT=0x%x)\n",
2172 					intr, sc->sc_istatus);
2173 				sdc->sdc_nhrderr = 0;
2174 				goto sdintr_error;
2175 			}
2176 			if (++sdc->sdc_retrycnt >= NRETRY) {
2177 				printf("SCSI%d: too many initiator errors (ISTAT=0x%x)\n",
2178 					intr, sc->sc_istatus);
2179 				goto sdintr_error;
2180 			}
2181 			DELAY(D100MSEC * 10);
2182 			goto sdintr_exec;
2183 		}
2184 	}
2185 
2186 	if (sdd->sdd_flags & SDDF_SKIPCHECK)
2187 		goto sdintr_done;
2188 
2189 check_target_status:
2190 	/*
2191 	 * check target status
2192 	 */
2193 	switch (sdc->sdc_state) {
2194 
2195 	/********************************/
2196 	/*				*/
2197 	/*	NORMAL OPERATION	*/
2198 	/*				*/
2199 	/********************************/
2200 	case SDCS_NORMAL:
2201 		switch (tstatus) {
2202 
2203 		case TGST_GOOD:
2204 			break;
2205 
2206 		case TGST_CC:
2207 			sdc->sdc_state |= SDCS_RSENSE;
2208 sdintr_rsense:
2209 			im->im_tab.b_active = 2;
2210 			bzero((caddr_t)sce, RSEN_CNT);
2211 			scop_rsense(intr, sc, slave,
2212 					SCSI_INTEN, RSEN_CNT, (caddr_t)sce);
2213 			return;
2214 
2215 		case TGST_BUSY:
2216 			if (++sdc->sdc_retrycnt > MAXRETRYCNT) {
2217 				goto sdintr_error;
2218 			}
2219 			timeout(sdexec, (caddr_t)bp, hz);
2220 			return;
2221 
2222 		default:
2223 			printf("sd%d: bad target status 0x%x\n",
2224 						unit, sc->sc_tstatus);
2225 			goto sdintr_error;
2226 		}
2227 		break;
2228 
2229 	/****************************************/
2230 	/*					*/
2231 	/*	REQUEST SENSE analysis		*/
2232 	/*					*/
2233 	/****************************************/
2234 	case SDCS_RSENSE:
2235 	case SDCS_PREVRMB|SDCS_RSENSE:
2236 	case SDCS_ECC|SDCS_RASREAD|SDCS_RSENSE:
2237 	case SDCS_ECC|SDCS_RASWRITE|SDCS_RSENSE:
2238 	case SDCS_ECCOFF|SDCS_RSENSE:
2239 	case SDCS_ECCOFF|SDCS_RASBLK|SDCS_RSENSE:
2240 	case SDCS_ECCOFF|SDCS_RASBLK|SDCS_LOSTDATA|SDCS_RSENSE:
2241 	case SDCS_ECC|SDCS_RASBLK|SDCS_RSENSE:
2242 	case SDCS_ECC|SDCS_RASBLK|SDCS_LOSTDATA|SDCS_RSENSE:
2243 		if (tstatus != TGST_GOOD) {
2244 			printf("sd%d: bad target status 0x%x\n",
2245 						unit, sc->sc_tstatus);
2246 			goto sdintr_error;
2247 		}
2248 		/*
2249 		 * error message print out
2250 		 */
2251 		code = sderrordisp(sce, ii);
2252 
2253 
2254 		if ((sdc->sdc_state == (SDCS_ECC|SDCS_RASBLK|SDCS_RSENSE)) ||
2255 		    (sdc->sdc_state == (SDCS_ECC|SDCS_RASBLK|SDCS_LOSTDATA|SDCS_RSENSE))) {
2256 			printf("sd%d: cannot reassign block %d\n",
2257 						unit, sdd->sdd_badsect);
2258 			goto sdintr_error;
2259 		}
2260 		if (sdc->sdc_state == (SDCS_PREVRMB|SDCS_RSENSE)) {
2261 			if (sce->sce_skey == 0x2) {
2262 				/*
2263 				 * Not ready
2264 				 */
2265 				sdc->sdc_state = SDCS_PREVRMB;
2266 				timeout(delay_medrmv, (caddr_t)ii, hz);
2267 				return;
2268 			}
2269 		}
2270 
2271 		/*			*/
2272 		/* RSENSE error handler	*/
2273 		/*			*/
2274 		switch (code) {
2275 
2276 		/********************************/
2277 		/*	continue		*/
2278 		/********************************/
2279 		/* NO SENSE */
2280 		case 0x00:	/* No Additional Sense Information */
2281 		/* RECOVERED ERROR */
2282 		case 0x38:	/* Recovered with Auto-Reallocation */
2283 			sdc->sdc_state &= ~SDCS_RSENSE;
2284 			goto check_target_status;
2285 
2286 		/********************************/
2287 		/*	continue or error	*/
2288 		/********************************/
2289 		/* ILLEGAL REQUEST */
2290 
2291 		case 0x21:	/* illegal Logical Block Address */
2292 			if (&st->sizes[dev2part(bp->b_dev)] == NULL)
2293 				goto sdintr_error;
2294 			if (bp->b_bcount > 0) {
2295 				bp->b_resid = bp->b_bcount
2296 				    - (sdd->sdd_badsect * sdd->sdd_sectsize
2297 				    - (st->sizes[dev2part(bp->b_dev)].sd_blkoff
2298 				    + dkblock(bp)) * DEV_BSIZE);
2299 			}
2300 			if (bp->b_resid >= bp->b_bcount || bp->b_resid <= 0) {
2301 				/*
2302 				 * all I/O failure
2303 				 */
2304 				bp->b_resid = bp->b_bcount;
2305 				goto sdintr_error;
2306 			}
2307 			/* Ignore error */
2308 			break;
2309 
2310 		/* MEDIUM ERROR */
2311 		case 0x31:	/* Medium Format Corrupted */
2312 			sdd->sdd_flags |= SDDF_NONFMT;
2313 			/* Ignore error */
2314 			break;
2315 
2316 		/********************************/
2317 		/*	more retry		*/
2318 		/********************************/
2319 		/* MEDIUM or RECOVERED ERROR */
2320 		case 0x10:	/* ID CRC Error */
2321 		case 0x12:	/* No Address Mark found in ID field */
2322 		case 0x13:	/* No Address Mark found in Data field */
2323 		case 0x14:	/* No recode found */
2324 		/* H/W or MEDIUM or RECOVERED ERROR */
2325 		case 0x15:	/* Seek Positioning Error */
2326 			if (sd_ignore_error) {
2327 				sdc->sdc_state = SDCS_NORMAL;
2328 				goto check_target_status;
2329 			}
2330 			/* fall through */
2331 
2332 		/* H/W ERROR */
2333 		case 0x01:	/* No Index/Address Mark Found signal */
2334 		case 0x02:	/* No Seek Complete */
2335 		case 0x06:	/* No Track Zero found */
2336 		/* H/W ERROR or RECOVERED ERROR */
2337 		case 0x03:	/* Write Fault */
2338 		case 0x08:	/* Logical Unit Communication Failure */
2339 		case 0x09:	/* Track Following Error */
2340 		case 0x0b:	/* Load/Unload Failure */
2341 		case 0x0c:	/* Spindle Failure */
2342 		case 0x0d:	/* Focus Failure */
2343 		case 0x0e:	/* Tracking Failure */
2344 		case 0x0f:	/* Drive Initialization Failure */
2345 			sdc->sdc_state = SDCS_ECC|SDCS_ECC_HOLD|SDCS_REZERO;
2346 
2347 			scinit(sc, slave, sdd->sdd_sectsize);
2348 			/* sc_cdb */
2349 			sc->sc_opcode = SCOP_REZERO;
2350 
2351 			sddgo(im);
2352 			return;
2353 
2354 		/********************************/
2355 		/*	re-allocate & retry	*/
2356 		/********************************/
2357 		/* MEDIUM or RECOVERED ERROR */
2358 		case 0x11:	/* Unrecovered Read Error */
2359 			if (sdc->sdc_state & SDCS_RASREAD) {
2360 sdintr_lostdata:
2361 				sdc->sdc_state =
2362 					SDCS_ECC|SDCS_RASBLK|SDCS_LOSTDATA;
2363 				im->im_tab.b_active = 2;
2364 				scop_rasblk(intr, sc, slave,
2365 					SCSI_INTEN, sdd->sdd_badsect);
2366 				sdd->sdd_flags &= ~SDDF_VBADSECT;
2367 				return;
2368 			}
2369 			/* fall through */
2370 
2371 		/* RECOVERED ERROR */
2372 		case 0x17:	/* Recovered read data with retries */
2373 		case 0x18:	/* Recovered read data with ECC */
2374 			/*
2375 			 * set ECC ON & more retry
2376 			 */
2377 			if (sdc->sdc_firmware & SDCFW_DEFMODE)
2378 				goto sdintr_ecc;
2379 
2380 			if (sdc->sdc_state & SDCS_RASREAD)
2381 				goto sdintr_rasblk;
2382 
2383 			sdc->sdc_state = SDCS_ECC;
2384 			goto sdintr_msel_set;
2385 
2386 		/********************************/
2387 		/*	unit start & retry	*/
2388 		/********************************/
2389 		/* NOT READY */
2390 		case 0x04:	/* Drive Not Ready */
2391 			if (sdc->sdc_state & SDCS_ECC)
2392 				sdc->sdc_state = SDCS_ECCOFF|SDCS_RETRY;
2393 			else
2394 				sdc->sdc_state = SDCS_RETRY;
2395 			goto sdintr_stst;
2396 
2397 		/********************************/
2398 		/*	retry			*/
2399 		/********************************/
2400 		/* UNIT ATTENTION */
2401 		case 0x28:	/* Medium Changed */
2402 			sdd->sdd_flags &= ~(SDDF_NONFMT
2403 					    |SDDF_SAMEDSK
2404 					    |SDDF_REQ_EJECT
2405 					    |SDDF_XUSE
2406 					    |SDDF_INHRMV
2407 					    |SDDF_ERASEOFF);
2408 			/* fall through */
2409 
2410 		case 0x29: /* Power On or Reset or Bus Device Reset */
2411 			if (sdc->sdc_firmware & SDCFW_RMB) {
2412 				/***************************/
2413 				/* medium removable device */
2414 				/***************************/
2415 				sdc->sdc_state = SDCS_PREVRMB;
2416 				im->im_tab.b_active = 2;
2417 				scop_medrmv(intr, sc, slave,
2418 					    SCSI_INTEN, SDRMV_PREV);
2419 				return;
2420 			}
2421 
2422 		case 0x2a:	/* Mode Select Parameter Changed */
2423 		case 0x47:	/* SCSI interface bus parity error */
2424 			if (sdc->sdc_state & SDCS_ECC) {
2425 				sdc->sdc_state = SDCS_RETRY;
2426 				goto sdintr_msel_reset;
2427 			}
2428 			sdc->sdc_state = SDCS_NORMAL;
2429 			goto sdintr_exec;
2430 
2431 		/********************************/
2432 		/*	set error flag		*/
2433 		/********************************/
2434 		case 0x40:	/* RAM failure */
2435 		case 0x41:	/* Data Path diagnostic failure */
2436 		case 0x42:	/* Power On diagnostic failure */
2437 
2438 		case 0xb2:	/* Caddy load/eject failed */
2439 		case 0xb4:	/* Focus servo failure */
2440 		case 0xb5:	/* Spindle servo failure */
2441 		case 0xb6:	/* Caddy load mechanism failed */
2442 			goto sdintr_error;
2443 
2444 /*MO*/		case 0x80:	/* Limit Laser Life */
2445 /*MO*/		case 0x81:	/* Focus Coil Over-current Failure */
2446 /*MO*/		case 0x82:	/* Tracking Coil Over-current Failure */
2447 /*MO*/		case 0x83:	/* Temperature Alarm */
2448 /*CD*/	/*	case 0x80: */	/* Prevent bit is set */
2449 /*CD*/	/*	case 0x81: */	/* Logical unit is reserved */
2450 /*CD*/	/*	case 0x82: */	/* End of usr area encountered */
2451 /*CD*/	/*	case 0x83: */	/* Overlapped commands attempted */
2452 			goto sdintr_error;
2453 
2454 		default:
2455 			/*
2456 			 *	error detect, but what shall we do ?
2457 			 */
2458 	/*	case 0x05: */	/* Drive Not Selected */
2459 	/*	case 0x07: */	/* Multiple Drives Selected */
2460 	/*	case 0x0a: */	/* No disk */
2461 	/*	case 0x1a: */	/* Parameter overrun */
2462 	/*	case 0x1b: */	/* Synchronous transfer error */
2463 	/*	case 0x1d: */	/* Compare error */
2464 	/*	case 0x22: */	/* Illegal function for device type */
2465 	/*	case 0x23: */	/* Illegal function for Medium type */
2466 	/*	case 0x25: */	/* Illegal LUN */
2467 	/*	case 0x27: */	/* Write Protected */
2468 	/*	case 0x2b: */	/* Firmware has been downloaded */
2469 	/*	case 0x39: */	/* Automatic Reallocation Failure */
2470 	/*	case 0x43: */	/* Message Reject Error */
2471 	/*	case 0x45: */	/* Selection/Reselection failure */
2472 	/*	case 0x48: */	/* Initiator detected error */
2473 	/*	case 0x49: */	/* Inappropriate/illegal message */
2474 	/*	case 0x60: */	/* COPY: STATUS error */
2475 	/*	case 0x85: */	/* Audio address not valid */
2476 	/*	case 0xb0: */	/* Caddy not inserted in drive */
2477 	/*	case 0xb1: */	/* Unable to recover TOC */
2478 	/*	case 0xb3: */	/* CIRC unrecovered data error(L-EC off) */
2479 	/*	case 0xc3: */	/* COPY: Illegale CDB length */
2480 	/*	case 0xc5: */	/* COPY: Catastrophic error */
2481 	/*	case 0xc6: */	/* COPY: Illegal phase change */
2482 	/*	case 0xfc: */	/* COPY: MODE SENSE failed */
2483 
2484 			/*
2485 			 *	medium error
2486 			 */
2487 	/*	case 0x19: */	/* Defect list error */
2488 	/*	case 0x1c: */	/* Primary Defect List not found */
2489 	/*	case 0x30: */	/* Incompatible Cartridge */
2490 	/*	case 0x32: */	/* No Spare Defect Location Available */
2491 	/*	case 0x3a: */	/* Defect List Update Failure */
2492 	/*	case 0x3d: */	/* Defect List Not Available */
2493 			goto sdintr_error;
2494 		}
2495 		/*
2496 		 * No error detected or ignored.
2497 		 */
2498 		break;
2499 
2500 	/************************************************/
2501 	/*						*/
2502 	/*	PREVENT MEDIUM REMOVABLE COMMAND	*/
2503 	/*						*/
2504 	/************************************************/
2505 	case SDCS_PREVRMB:
2506 		if (tstatus == TGST_CC) {
2507 			sdc->sdc_state = SDCS_PREVRMB|SDCS_RSENSE;
2508 			goto sdintr_rsense;
2509 		}
2510 		sdd->sdd_flags |= SDDF_INHRMV;
2511 		if (sdc->sdc_state & SDCS_ECC) {
2512 			sdc->sdc_state = SDCS_RETRY;
2513 			goto sdintr_msel_reset;
2514 		}
2515 		sdc->sdc_state = SDCS_NORMAL;
2516 		goto sdintr_exec;
2517 		break;
2518 
2519 	/****************************************/
2520 	/*					*/
2521 	/*	REZERO done & RETRY COMMAND	*/
2522 	/*					*/
2523 	/****************************************/
2524 	case SDCS_ECC|SDCS_ECC_HOLD|SDCS_REZERO:
2525 		if (sdc->sdc_firmware & SDCFW_DEFMODE) {
2526 			sdc->sdc_state = SDCS_ECC|SDCS_ECC_HOLD|SDCS_RETRY;
2527 			goto sdintr_stst;
2528 		}
2529 
2530 		sdc->sdc_state = SDCS_ECC|SDCS_ECC_HOLD;
2531 		goto sdintr_msel_set;
2532 
2533 	/********************************/
2534 	/*				*/
2535 	/*	RETRY COMMAND		*/
2536 	/*				*/
2537 	/********************************/
2538 	case SDCS_RETRY:
2539 		sdc->sdc_state = SDCS_NORMAL;
2540 		goto sdintr_exec;
2541 
2542 	/************************************************/
2543 	/*						*/
2544 	/*	ERROR CORRECTION ON MODE SELECT result	*/
2545 	/*						*/
2546 	/************************************************/
2547 	case SDCS_ECC:
2548 		if (tstatus != TGST_GOOD) {
2549 			printf("sd%d: bad target status 0x%x\n",
2550 						unit, sc->sc_tstatus);
2551 			goto sdintr_error;
2552 		}
2553 sdintr_ecc:
2554 		if (bp->b_flags & B_READ) {
2555 			sdc->sdc_state = SDCS_ECC|SDCS_RASREAD;
2556 			im->im_tab.b_active = 2;
2557 			scop_rdwr(intr, sc, slave, SCSI_INTEN,
2558 					B_READ, sdwork,
2559 					sdd->sdd_badsect, sdd->sdd_sectsize);
2560 			return;
2561 		}
2562 		goto sdintr_rasblk;
2563 
2564 	/************************************************/
2565 	/*						*/
2566 	/*	READ DATA from BAD BLOCK result		*/
2567 	/*						*/
2568 	/************************************************/
2569 	case SDCS_ECC|SDCS_RASREAD:
2570 		if (tstatus == TGST_CC) {
2571 			sdc->sdc_state = SDCS_ECC|SDCS_RASREAD|SDCS_RSENSE;
2572 			goto sdintr_rsense;
2573 		} else if (tstatus != TGST_GOOD) {
2574 			printf("sd%d: bad target status 0x%x\n",
2575 						unit, sc->sc_tstatus);
2576 			printf("sd%d: cannot read block\n", unit);
2577 			goto sdintr_error;
2578 		}
2579 sdintr_rasblk:
2580 		if (sdd->sdd_flags & SDDF_WPROTECT)
2581 			goto sdintr_error;
2582 		sdc->sdc_state = SDCS_ECC|SDCS_RASBLK;
2583 		im->im_tab.b_active = 2;
2584 		scop_rasblk(intr, sc, slave, SCSI_INTEN, sdd->sdd_badsect);
2585 		sdd->sdd_flags &= ~SDDF_VBADSECT;
2586 		return;
2587 
2588 	/****************************************/
2589 	/*					*/
2590 	/*	REASSIGN BLOCK result		*/
2591 	/*					*/
2592 	/****************************************/
2593 	case SDCS_ECC|SDCS_RASBLK:
2594 		if (tstatus == TGST_CC) {
2595 			sdc->sdc_state = SDCS_ECC|SDCS_RASBLK|SDCS_RSENSE;
2596 			goto sdintr_rsense;
2597 		} else if (tstatus != TGST_GOOD) {
2598 			printf("sd%d: bad target status 0x%x\n",
2599 						unit, sc->sc_tstatus);
2600 			goto sdintr_error;
2601 		}
2602 		printf("sd%d: block %d is reassigned\n",
2603 			unit, sdd->sdd_badsect);
2604 		if (bp->b_flags & B_READ) {
2605 sdintr_raswrite:
2606 			sdc->sdc_state = SDCS_ECC|SDCS_RASWRITE;
2607 			im->im_tab.b_active = 2;
2608 			scop_rdwr(intr, sc, slave, SCSI_INTEN,
2609 					B_WRITE, sdwork,
2610 					sdd->sdd_badsect, sdd->sdd_sectsize);
2611 			return;
2612 		}
2613 		sdc->sdc_state = SDCS_RETRY;
2614 		goto sdintr_msel_reset;
2615 
2616 	/************************************************/
2617 	/*						*/
2618 	/*	WRITE DATA to REASSIGNED BLOCK result	*/
2619 	/*						*/
2620 	/************************************************/
2621 	case SDCS_ECC|SDCS_RASWRITE:
2622 		if (tstatus == TGST_CC) {
2623 			sdc->sdc_state = SDCS_ECC|SDCS_RASWRITE|SDCS_RSENSE;
2624 			goto sdintr_rsense;
2625 		} else if (tstatus != TGST_GOOD) {
2626 			printf("sd%d: bad target status 0x%x\n",
2627 						unit, sc->sc_tstatus);
2628 			goto sdintr_error;
2629 		}
2630 		sdc->sdc_state = SDCS_RETRY;
2631 		goto sdintr_msel_reset;
2632 
2633 	/****************************************/
2634 	/*					*/
2635 	/*	reset ECC & RETRY TIMES		*/
2636 	/*					*/
2637 	/****************************************/
2638 	case SDCS_ECCOFF|SDCS_RETRY:
2639 		sdc->sdc_state = SDCS_RETRY;
2640 		goto sdintr_msel_reset;
2641 
2642 	/********************************************************/
2643 	/*							*/
2644 	/*	READ DATA from BAD BLOCK result in faliure	*/
2645 	/*							*/
2646 	/********************************************************/
2647 	case SDCS_ECC|SDCS_RASBLK|SDCS_LOSTDATA:
2648 		if (tstatus == TGST_CC) {
2649 			sdc->sdc_state =
2650 				SDCS_ECC|SDCS_RASBLK|SDCS_LOSTDATA|SDCS_RSENSE;
2651 			goto sdintr_rsense;
2652 		} else if (tstatus != TGST_GOOD) {
2653 			printf("sd%d: rasblk: bad target status 0x%x\n",
2654 				unit, sc->sc_tstatus);
2655 			goto sdintr_error;
2656 		}
2657 		bzero(sdwork, sdd->sdd_sectsize);
2658 		scop_rdwr(intr, sc, slave, SCSI_INTDIS,
2659 			B_WRITE, sdwork, sdd->sdd_badsect, sdd->sdd_sectsize);
2660 		printf("sd%d: block %d is reassigned (lost data)\n",
2661 			unit, sdd->sdd_badsect);
2662 		goto sdintr_error;
2663 
2664 	/****************************************/
2665 	/*					*/
2666 	/*	issue START UNIT command	*/
2667 	/*					*/
2668 	/****************************************/
2669 	case SDCS_ECC|SDCS_ECC_HOLD:
2670 		/*
2671 		 * Drive not ready... so start..
2672 		 */
2673 		sdc->sdc_state = SDCS_ECC|SDCS_ECC_HOLD|SDCS_RETRY;
2674 sdintr_stst:
2675 		timeout(delay_start, (caddr_t)ii, hz);
2676 		return;
2677 
2678 	/****************************************/
2679 	/*					*/
2680 	/*	RETRY with ECC & more RETRYS	*/
2681 	/*					*/
2682 	/****************************************/
2683 	case SDCS_ECC|SDCS_ECC_HOLD|SDCS_RETRY:
2684 		sdc->sdc_state = SDCS_ECCOFF;
2685 sdintr_exec:
2686 		if (sdc->sdc_countcc++ > MAXRETRYCNT)
2687 			goto sdintr_error;
2688 		sdexec(bp);
2689 		return;
2690 
2691 	/****************************************/
2692 	/*					*/
2693 	/*	reset ECC & RETRY TIMES		*/
2694 	/*					*/
2695 	/****************************************/
2696 	case SDCS_ECCOFF:
2697 		if (tstatus == TGST_CC) {
2698 			sdc->sdc_state = SDCS_ECCOFF|SDCS_RSENSE;
2699 			goto sdintr_rsense;
2700 		} else if (tstatus != TGST_GOOD) {
2701 			printf("sd%d: bad target status 0x%x\n",
2702 				unit, sc->sc_tstatus);
2703 			goto sdintr_error;
2704 		}
2705 		sdc->sdc_state = SDCS_NORMAL;
2706 		goto sdintr_msel_reset;
2707 
2708 sdintr_msel_set:
2709 		/*
2710 		 * set more ERROR RECOVERY PARAMETERS
2711 		 */
2712 		if ((erp_page = sdi->max_ERP_page) == NULL)
2713 			goto check_target_status;
2714 		bzero((caddr_t)sc->sc_param, 4);
2715 		len = *(erp_page + 1) + 2;
2716 		bcopy(erp_page, &sc->sc_param[4], len);
2717 
2718 		im->im_tab.b_active = 2;
2719 		scop_mselect(intr, sc, slave, SCSI_INTEN,
2720 				(SDM_PF<<24) + len +4, (caddr_t)0);
2721 		return;
2722 
2723 sdintr_msel_reset:
2724 		if (sdc->sdc_firmware & SDCFW_DEFMODE)
2725 			goto sdintr_exec;
2726 
2727 		/*
2728 		 * set normal ERROR RECOVERY PARAMETERS
2729 		 */
2730 		erp_page = sdi->ERP_page;
2731 		bzero((caddr_t)sc->sc_param, 4);
2732 		len = *(erp_page + 1) + 2;
2733 		bcopy(erp_page, &sc->sc_param[4], len);
2734 
2735 		im->im_tab.b_active = 2;
2736 		scop_mselect(intr, sc, slave, SCSI_INTEN,
2737 				(SDM_PF<<24) + len +4, (caddr_t)0);
2738 		return;
2739 
2740 sdintr_error:
2741 		bp->b_flags |= B_ERROR;
2742 		if (sdc->sdc_state & SDCS_ECC) {
2743 			sdc->sdc_state = SDCS_NORMAL;
2744 			goto sdintr_msel_reset;
2745 		}
2746 		break;
2747 
2748 	/*
2749 	 * UNKNOWN STATUS
2750 	 */
2751 	default:
2752 		printf("sd%d: unknown status (0x%x)\n", unit, sdc->sdc_state);
2753 		goto sdintr_error;
2754 	}
2755 
2756 sdintr_done:
2757 
2758 	if (bp->b_flags & B_ERROR) {
2759         printf("%s%d%c: hard error sn%d ", "sd",
2760             minor(bp->b_dev) >> 3, 'a'+(minor(bp->b_dev)&07), bp->b_blkno);
2761 		printf("\n");
2762 	}
2763 	sdd->sdd_lastblk = dkblock(bp) + btodb(bp->b_bcount - bp->b_resid);
2764 	sdc->sdc_countcc = 0;
2765 	sdc->sdc_retrycnt = 0;
2766 	sdd->sdd_flags &= ~SDDF_VBADSECT;
2767 
2768 	if (im->im_tab.b_active) {
2769 		im->im_tab.b_active = 0;
2770 		im->im_tab.b_errcnt = 0;
2771 		im->im_tab.b_actf = 0;
2772 		dp->b_active = 0;
2773 		dp->b_errcnt = 0;
2774 		dp->b_actf = bp->b_actf;
2775 		if (bp == &csdbuf[unit]) {
2776 			register struct scsi *ksc = &kernscsi[unit];
2777 			/* copy result */
2778 			bcopy((caddr_t)sc, (caddr_t)ksc, sizeof(struct scsi));
2779 		}
2780 
2781 		iodone(bp);
2782 
2783 		/*
2784 		 * If this unit has more work to do,
2785 		 * then start it up right away.
2786 		 */
2787 		if (dp->b_actf)
2788 			sdustart(ii);
2789 	}
2790 	as &= ~(1 << slave);
2791 
2792 	sdc->sdc_state = SDCS_NORMAL;
2793 
2794 	/*
2795 	 * UNLOCK SCSI access
2796 	 */
2797 	sdc->sdc_firmware &= ~SDCFW_BUSY;
2798 
2799 start:
2800 	/*
2801 	 * Process other units which need attention.
2802 	 * For each unit which needs attention, call
2803 	 * the unit start routine to place the slave
2804 	 * on the controller device queue.
2805 	 */
2806 	sdc->sdc_softas = 0;
2807 	while (unit = ffs(as)) {
2808 		unit--;
2809 		as &= ~(1 << unit);
2810 		sdustart(sdip[im->im_ctlr][unit]);
2811 	}
2812 	/*
2813 	 * If the controller is not transferring,
2814 	 * but there are devices ready to transfer,
2815 	 * start the controller.
2816 	 */
2817 	if (im->im_tab.b_actf && im->im_tab.b_active == 0)
2818 		(void) sdstart(im);
2819 }
2820 
2821 wait_re_init_done(bp)
2822 	register struct buf *bp;
2823 {
2824 	if (re_init_done >= 2)
2825 		sdexec(bp);
2826 	else
2827 		timeout(wait_re_init_done, bp, 10*hz);
2828 }
2829 
2830 delay_start(ii)
2831 	struct iop/**/_device *ii;
2832 {
2833 	ii->ii_mi->im_tab.b_active = 2;
2834 	scop_stst(ii->ii_intr, get_scsi(ii->ii_intr), ii->ii_slave,
2835 			SCSI_INTEN, SDSS_START);
2836 }
2837 
2838 delay_medrmv(ii)
2839 	struct iop/**/_device *ii;
2840 {
2841 	ii->ii_mi->im_tab.b_active = 2;
2842 	scop_medrmv(ii->ii_intr, get_scsi(ii->ii_intr), ii->ii_slave,
2843 			SCSI_INTEN, SDRMV_PREV);
2844 }
2845 
2846 sderrordisp(rsen_data, ii)
2847 	u_char *rsen_data;
2848 	struct iop/**/_device *ii;
2849 {
2850 	register struct sc_extnd *sce;
2851 	register struct sdc_softc *sdc;
2852 	register struct sdd_softc *sdd;
2853 	register int unit;
2854 	register int code;
2855 	struct sc_nextnd *scn;
2856 	struct msg_list *ml;
2857 
2858 	unit = ii->ii_unit;
2859 	sdc = &sdc_softc[ii->ii_ctlr];
2860 	sdd = &sdd_softc[unit];
2861 
2862 	sce = (struct sc_extnd *)rsen_data;
2863 
2864 	if (sce->sce_extend == 0x70) {
2865 		/*
2866 		 * Extended Sense data
2867 		 */
2868 		code = sce->sce_sdecode;
2869 
2870 		if (code & 0x80)
2871 			ml = ecodelist_mo;
2872 		else
2873 			ml = ecodelist;
2874 
2875 		if (sce->sce_advalid) {
2876 			if ((sdd->sdd_flags & SDDF_VBADSECT) == 0) {
2877 #ifdef mips
2878 				sdd->sdd_badsect = (sce->sce_infob1 << 24) +
2879 						   (sce->sce_infob2 << 16) +
2880 						   (sce->sce_infob3 <<  8) +
2881 						   (sce->sce_infob4);
2882 #else
2883 				sdd->sdd_badsect = *((int *)&sce->sce_infob1);
2884 #endif
2885 				sdd->sdd_flags |= SDDF_VBADSECT;
2886 			}
2887 		}
2888 
2889 		if (!rsense_msg_disp && !isdispmsg(code, ml, sdc->sdc_countcc))
2890 			return (code);
2891 
2892 		if (sce->sce_advalid) {
2893 			int sn;
2894 #ifdef mips
2895 			sn = (sce->sce_infob1 << 24) +
2896 			     (sce->sce_infob2 << 16) +
2897 			     (sce->sce_infob3 <<  8) +
2898 			     (sce->sce_infob4);
2899 #else
2900 			sn = *((int *)&sce->sce_infob1);
2901 #endif
2902 			if (sce->sce_addlen >= 5) {
2903 				printf("sd%d(sn %d): skey=0x%x, code=0x%x\n",
2904 					unit, sn, sce->sce_skey, code);
2905 			} else {
2906 				printf("sd%d(sn %d): skey=0x%x\n",
2907 					unit, sn, sce->sce_skey);
2908 			}
2909 		} else {
2910 			if (sce->sce_addlen >= 5)
2911 				printf("sd%d: skey=0x%x, code=0x%x\n",
2912 					unit, sce->sce_skey, code);
2913 			else
2914 				printf("sd%d: skey=0x%x\n",
2915 					unit, sce->sce_skey);
2916 		}
2917 		if (sce->sce_addlen >= 6)
2918 			printf("sd%d: ASCQ=0x%x\n", unit, sce->sce_ascq);
2919 		{
2920 			u_char *p;
2921 			int len;
2922 
2923 			len = 8 + sce->sce_addlen;
2924 			if (len > RSEN_CNT)
2925 				len = RSEN_CNT;
2926 			p = (u_char *)sce;
2927 			printf("sd%d: ", unit);
2928 			while (len--)
2929 				printf("%x ", *p++);
2930 			printf("\n");
2931 		}
2932 	} else {
2933 		/*
2934 		 * Non-extended Sense data
2935 		 */
2936 		scn = (struct sc_nextnd *)rsen_data;
2937 
2938 		code = scn->scn_ecode;
2939 		ml = ecodelist;
2940 		if (sce->sce_advalid) {
2941 			if ((sdd->sdd_flags & SDDF_VBADSECT) == 0) {
2942 				sdd->sdd_badsect = scn->scn_secno;
2943 				sdd->sdd_flags |= SDDF_VBADSECT;
2944 			}
2945 		}
2946 		if (rsense_msg_disp || isdispmsg(code, ml, sdc->sdc_countcc)) {
2947 			if (sce->sce_advalid)
2948 				printf("sd%d(sn %d): code=0x%x\n",
2949 					unit, scn->scn_secno, code);
2950 			else
2951 				printf("sd%d: code=0x%x\n", unit, code);
2952 		}
2953 	}
2954 	return (code);
2955 }
2956 
2957 void
2958 sdminphys(bp)
2959 	struct buf *bp;
2960 {
2961 	if (bp->b_bcount > MAXSDPHYS)
2962 		bp->b_bcount = MAXSDPHYS;
2963 }
2964 
2965 
2966 #define	sdphysio	physio
2967 
2968 sdread(dev, uio, flag)
2969 	register dev_t dev;
2970 	struct uio *uio;
2971 	int flag;
2972 {
2973 	register struct iop/**/_device *ii;
2974 	register int unit;
2975 
2976 	unit = dev2unit(dev);
2977 	if (unit >= nsd || (ii = sddinfo[unit]) == 0)
2978 		return (ENXIO);
2979 
2980 	return (sdphysio(sdstrategy, &rsdbuf[unit], dev, B_READ, sdminphys, uio));
2981 }
2982 
2983 sdwrite(dev, uio, flag)
2984 	register dev_t dev;
2985 	struct uio *uio;
2986 	int flag;
2987 {
2988 	register struct iop/**/_device *ii;
2989 	register int unit;
2990 
2991 	unit = dev2unit(dev);
2992 	if (unit >= nsd || (ii = sddinfo[unit]) == 0)
2993 		return (ENXIO);
2994 
2995 	return (sdphysio(sdstrategy, &rsdbuf[unit], dev, B_WRITE, sdminphys, uio));
2996 }
2997 
2998 #define MAXBL 256
2999 
3000 struct Partinfo {
3001 /*00*/	daddr_t dp_nblocks;		/* partition size (sector #) */
3002 /*04*/	daddr_t dp_blkoff;		/* partition start block */
3003 /*08*/
3004 };
3005 
3006 struct dkst {
3007 /*00*/	int dks_ncyl;			/* # cylinders / drive */
3008 /*04*/	int dks_ntrak;			/* # tracks / cylinder */
3009 /*08*/	int dks_nsect;			/* # sectors / track */
3010 /*0c*/	int dks_rps;			/* # revolutions / second */
3011 /*10*/
3012 };
3013 
3014 /*ARGSUSED*/
3015 sdioctl(dev, cmd, data, flag)
3016 	dev_t dev;
3017 	int cmd;
3018 	caddr_t data;
3019 	int flag;
3020 {
3021 	register struct iop/**/_device *ii;
3022 	register struct sc_ureq *scu;
3023 	register struct sdst *st;
3024 	register struct scsi *sc;
3025 	register int unit;
3026 	register int ctlr;
3027 	register int slave;
3028 	struct sdc_softc *sdc;
3029 	struct sdd_softc *sdd;
3030 	struct Partinfo *pi;
3031 	struct dkst *di;
3032 	struct buf *bp;
3033 	struct sddevinfo *sdi;
3034 	struct sdst *stp;
3035 	struct scsi uscsi;
3036 	int error;
3037 	int i;
3038 	int s;
3039 	int tstatus;
3040 	char *p;
3041 	int blkno, count;
3042 
3043 	unit = dev2unit(dev);
3044 	if (unit >= nsd || (ii = sddinfo[unit]) == 0 || ii->ii_alive == 0)
3045 		return (ENXIO);
3046 
3047 	slave = ii->ii_slave;
3048 	ctlr = ii->ii_ctlr;
3049 	sdc = &sdc_softc[ctlr];
3050 	sdd = &sdd_softc[unit];
3051 	sc = &uscsi;
3052 
3053 	error = 0;
3054 	switch (cmd) {
3055 
3056 	case DIOCWLABEL:
3057 		if (*(int *)data & SD_F_ENW)
3058 			ii->ii_flags |= SD_F_ENW;
3059 		else
3060 			ii->ii_flags &= ~SD_F_ENW;
3061 		break;
3062 
3063 	case DIOCGDINFO:
3064 		*(struct disklabel *)data = sdlabel[unit];
3065 		break;
3066 
3067 	case DIOCSDINFO:
3068 		sdlabel[unit] = *(struct disklabel *)data;
3069 		disklabel2sdst(unit, &sdlabel[unit], &sdstdrv[unit]);
3070 		break;
3071 
3072 	case DIOCWDINFO:
3073 	case DKIOCRGEOM:
3074 		switch (cmd) {
3075 		case DKIOCRGEOM:
3076 			st = &sdstdrv[unit];
3077 			sdi = &sddevinfo[ii->ii_type];
3078 			stp = sdi->sdstp;
3079 
3080 			st->ncyl = stp->ncyl;	/* # cylinders / drive */
3081 			st->ntrak = stp->ntrak;	/* # tracks / cylinder */
3082 			st->nsect = stp->nsect;	/* # sectors / track */
3083 			st->rps = stp->rps;	/* # revolutions / second */
3084 
3085 			sdst2disklabel(unit, st, &sdlabel[unit]);
3086 
3087 			if (*(int *)data == RGEOM_SDINFO)
3088 				goto done;
3089 
3090 			break;
3091 
3092 		case DIOCWDINFO:
3093 			sdlabel[unit] = *(struct disklabel *)data;
3094 
3095 			break;
3096 		}
3097 
3098 		/*
3099 		 * Common code for DIOCWDINFO and DKIOCRGEOM
3100 		 */
3101 
3102 		/**** READ sector 0 ****/
3103 		/*
3104 		 * LOCK sdtmp buffer
3105 		 */
3106 		s = splclock();
3107 		while (sdtmp_stat & B_BUSY) {
3108 			sdtmp_stat |= B_WANTED;
3109 			sleep((caddr_t)sdtmp, PRIBIO);
3110 		}
3111 		sdtmp_stat |= B_BUSY;
3112 		splx(s);
3113 
3114 		bzero(sdtmp, DEV_BSIZE);
3115 
3116 		if ((sdd->sdd_flags & SDDF_NONFMT) == 0) {
3117 			scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize);
3118 			uscsi.sc_cpoint = sdtmp;
3119 			uscsi.sc_ctrnscnt = DEV_BSIZE;
3120 			uscsi.sc_opcode = SCOP_READ;
3121 			uscsi.sc_lad = 0;
3122 			uscsi.sc_count = 1;
3123 			error = sdcmd(dev, &uscsi);
3124 		} else {
3125 			error = EIO;
3126 		}
3127 
3128 		if (error) {
3129 			/*
3130 			 * UNLOCK sdtmp buffer
3131 			 */
3132 			s = splclock();
3133 			if (sdtmp_stat & B_WANTED)
3134 				wakeup((caddr_t)sdtmp);
3135 			sdtmp_stat &= ~(B_BUSY|B_WANTED);
3136 			splx(s);
3137 
3138 			break;
3139 		}
3140 
3141 		*(struct disklabel *)(sdtmp + LABELOFFSET) = sdlabel[unit];
3142 
3143 		/**** WRITE sector 0 ****/
3144 
3145 		if (error == 0) {
3146 			if ((sdd->sdd_flags & SDDF_NONFMT) == 0) {
3147 				scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize);
3148 				uscsi.sc_cpoint = sdtmp;
3149 				uscsi.sc_ctrnscnt = DEV_BSIZE;
3150 				uscsi.sc_opcode = SCOP_WRITE;
3151 
3152 				uscsi.sc_lad = 0;
3153 				uscsi.sc_count = 1;
3154 
3155 				error = sdcmd(dev, &uscsi);
3156 			} else
3157 				error = EIO;
3158 		}
3159 
3160 		/*
3161 		 * UNLOCK sdtmp buffer
3162 		 */
3163 		s = splclock();
3164 		if (sdtmp_stat & B_WANTED)
3165 			wakeup((caddr_t)sdtmp);
3166 		sdtmp_stat &= ~(B_BUSY|B_WANTED);
3167 		splx(s);
3168 
3169 		disklabel2sdst(unit, &sdlabel[unit], &sdstdrv[unit]);
3170 
3171 		break;
3172 
3173 	case DKIOCGGEOM:
3174 		st = &sdstdrv[unit];
3175 		di = (struct dkst *)data;
3176 
3177 		di->dks_ncyl = st->ncyl;	/* # cylinders / drive */
3178 		di->dks_ntrak = st->ntrak;	/* # tracks / cylinder */
3179 		di->dks_nsect = st->nsect;	/* # sectors / track */
3180 		di->dks_rps = st->rps;		/* # revolutions / second */
3181 
3182 		break;
3183 
3184 	case DKIOCSGEOM:
3185 		st = &sdstdrv[unit];
3186 		di = (struct dkst *)data;
3187 
3188 		st->ncyl = di->dks_ncyl;	/* # cylinders / drive */
3189 		st->ntrak = di->dks_ntrak;	/* # tracks / cylinder */
3190 		st->nsect = di->dks_nsect;	/* # sectors / track */
3191 		st->rps = di->dks_rps;		/* # revolutions / second */
3192 
3193 		sdst2disklabel(unit, st, &sdlabel[unit]);
3194 		break;
3195 
3196 	case DKIOCGPART:
3197 	case DKIOCSPART:
3198 		/*
3199 		 * partition information
3200 		 */
3201 		st = &sdstdrv[unit];
3202 		pi = (struct Partinfo *)data;
3203 
3204 		if (cmd == DKIOCGPART) {
3205 			pi->dp_nblocks = st->sizes[dev2part(dev)].sd_nblocks;
3206 			pi->dp_blkoff = st->sizes[dev2part(dev)].sd_blkoff;
3207 		} else {
3208 			st->sizes[dev2part(dev)].sd_nblocks = pi->dp_nblocks;
3209 			st->sizes[dev2part(dev)].sd_blkoff = pi->dp_blkoff;
3210 
3211 			sdst2disklabel(unit, st, &sdlabel[unit]);
3212 		}
3213 		break;
3214 
3215 	case DKIOCGUNIT:
3216 		*(int *)data = slave;
3217 		break;
3218 
3219 	case DKIOCGCHAN:
3220 		*(int *)data = ii->ii_intr;
3221 		break;
3222 
3223 	case DKIOCSEEK:
3224 		scinit(sc, slave, sdd->sdd_sectsize);
3225 		sc->sc_opcode = SCOP_SEEK;
3226 		sc->sc_lad = *(int *)data;
3227 
3228 		(void) sdcmd(dev, sc);
3229 		tstatus = sc->sc_tstatus & TGSTMASK;
3230 		if ((sc->sc_istatus != INST_EP) || (tstatus != TGST_GOOD))
3231 			error = ESPIPE;
3232 		break;
3233 
3234 	case DKIOCRSEC0:
3235 	case DKIOCRBOOT1:
3236 	case DKIOCRBOOT:
3237 		if (sdd->sdd_flags & SDDF_NONFMT) {
3238 			error = EIO;
3239 			break;
3240 		}
3241 		switch (cmd) {
3242 
3243 		case DKIOCRSEC0:
3244 			blkno = 0;
3245 			count = 1;
3246 			break;
3247 
3248 		case DKIOCRBOOT1:
3249 			blkno = 1;
3250 			count = 15;
3251 			break;
3252 
3253 		default:
3254 			blkno = 0;
3255 			count = 16;
3256 		}
3257 		p = (char *)*(int *)data;
3258 		for (i = 0; !error && i < count; i++) {
3259 			s = splclock();
3260 			while (sdtmp_stat & B_BUSY) {
3261 				sdtmp_stat |= B_WANTED;
3262 				sleep((caddr_t)sdtmp, PRIBIO);
3263 			}
3264 			sdtmp_stat |= B_BUSY;
3265 			splx(s);
3266 			scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize);
3267 			uscsi.sc_cpoint = sdtmp;
3268 			uscsi.sc_ctrnscnt = DEV_BSIZE;
3269 			uscsi.sc_opcode = SCOP_READ;
3270 			uscsi.sc_lad = blkno;
3271 			uscsi.sc_count = 1;
3272 			if (error = sdcmd(dev, &uscsi))
3273 				goto dkior_done;
3274 			if (error = copyout(sdtmp, p, DEV_BSIZE))
3275 				goto dkior_done;
3276 			blkno++;
3277 			p += DEV_BSIZE;
3278 
3279 dkior_done:
3280 			s = splclock();
3281 			if (sdtmp_stat & B_WANTED)
3282 				wakeup((caddr_t)sdtmp);
3283 			sdtmp_stat &= ~(B_BUSY|B_WANTED);
3284 			splx(s);
3285 		}
3286 		break;
3287 
3288 	case DKIOCWSEC0:
3289 	case DKIOCWBOOT1:
3290 	case DKIOCWBOOT:
3291 		if (sdd->sdd_flags & SDDF_NONFMT) {
3292 			error = EIO;
3293 			break;
3294 		}
3295 		switch (cmd) {
3296 
3297 		case DKIOCWSEC0:
3298 			blkno = 0;
3299 			count = 1;
3300 			break;
3301 
3302 		case DKIOCWBOOT1:
3303 			blkno = 1;
3304 			count = 15;
3305 			break;
3306 
3307 		default:
3308 			blkno = 0;
3309 			count = 16;
3310 		}
3311 		p = (char *)*(int *)data;
3312 		for (i = 0; !error && i < count; i++) {
3313 			s = splclock();
3314 			while (sdtmp_stat & B_BUSY) {
3315 				sdtmp_stat |= B_WANTED;
3316 				sleep(sdtmp, PRIBIO);
3317 			}
3318 			sdtmp_stat |= B_BUSY;
3319 			splx(s);
3320 			if (error = copyin(p, sdtmp, DEV_BSIZE))
3321 				goto dkiow_done;
3322 			scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize);
3323 			uscsi.sc_cpoint = sdtmp;
3324 			uscsi.sc_ctrnscnt = DEV_BSIZE;
3325 			uscsi.sc_opcode = SCOP_WRITE;
3326 			uscsi.sc_lad = blkno;
3327 			uscsi.sc_count = 1;
3328 			if (error = sdcmd(dev, &uscsi))
3329 				goto dkiow_done;
3330 			blkno++;
3331 			p += DEV_BSIZE;
3332 
3333 dkiow_done:
3334 			s = splclock();
3335 			if (sdtmp_stat & B_WANTED)
3336 				wakeup(sdtmp);
3337 			sdtmp_stat &= ~(B_BUSY|B_WANTED);
3338 			splx(s);
3339 		}
3340 		break;
3341 
3342 	case SDIOC_PRVRMV:
3343 	case SDIOC_ALWRMV:
3344 		/*
3345 		 * prevent/allow medium removal
3346 		 */
3347 		scinit(sc, ii->ii_slave, sdd->sdd_sectsize);
3348 		sc->sc_opcode = SCOP_MEDRMV;
3349 		sc->sc_count = (cmd==SDIOC_PRVRMV)? SDRMV_PREV : SDRMV_ALLOW;
3350 		if (cmd == SDIOC_PRVRMV)
3351 			sdd->sdd_flags |= SDDF_INHRMV;
3352 		else
3353 			sdd->sdd_flags &= ~SDDF_INHRMV;
3354 
3355 		error = sdcmd(dev, sc);
3356 		break;
3357 
3358 	case SDIOC_SXUSE:
3359 		if (isalone(unit) != ONLY_ONE)
3360 			return (EBUSY);
3361 		sdd->sdd_flags |= SDDF_XUSE;
3362 		break;
3363 
3364 	case SDIOC_RXUSE:
3365 		sdd->sdd_flags &= ~SDDF_XUSE;
3366 		break;
3367 
3368 	case SDIOC_ERSON:
3369 		sdd->sdd_flags &= ~SDDF_ERASEOFF;
3370 		break;
3371 
3372 	case SDIOC_ERSOFF:
3373 		if ((sdd->sdd_flags & SDDF_XUSE) != 0)
3374 			return (EBUSY);
3375 		sdd->sdd_flags |= SDDF_ERASEOFF;
3376 		sdd->sdd_flags &= ~SDDF_NONFMT;
3377 		break;
3378 
3379 	case SDIOC_FORMAT:
3380 		/*
3381 		 * format unit
3382 		 */
3383 		if ((flag & FWRITE) == 0)
3384 			return (EINVAL);
3385 		if (isalone(unit) != ONLY_ONE)
3386 			return (EBUSY);
3387 		sdd->sdd_flags |= SDDF_XUSE;
3388 		sdd->sdd_flags &= ~(SDDF_NONFMT|SDDF_FMTDONE|SDDF_SAMEDSK);
3389 		scinit(sc, ii->ii_slave, sdd->sdd_sectsize);
3390 		sc->sc_ctrnscnt = 4;
3391 		sc->sc_opcode = SCOP_FMT;
3392 
3393 		sc->sc_lad = ((sddevinfo[ii->ii_type].fmt_opts & FMT_DLFMT)
3394 				| SDF_FMTDAT) << 16;
3395 
3396 		switch (sddevinfo[ii->ii_type].type) {
3397 
3398 		case SMO_S501:
3399 		case SMO_S501_ISO:
3400 		case SMO_S501_ISO2:
3401 			sc->sc_lad |= ((SDF_MKCDA|SDF_MKPLST) << 8);
3402 			break;
3403 
3404 		default:
3405 			break;
3406 		}
3407 
3408 		{
3409 			struct fmt_data *fdata = (struct fmt_data *)data;
3410 
3411 			error = copyin((caddr_t)fdata->dlh, sc->sc_param, 4);
3412 			if (error != 0) {
3413 				sdd->sdd_flags &= ~SDDF_XUSE;
3414 				break;
3415 			}
3416 			if (fdata->noglist)
3417 				sc->sc_lad |= (SDF_CMPLST<<16);
3418 		}
3419 
3420 		if (sdd->sdd_flags & SDDF_ERASEOFF)
3421 			sc->sc_ctrl = 0x40;
3422 
3423 		error = sdcmd(dev, sc);
3424 		sdd->sdd_flags &= ~SDDF_XUSE;
3425 		break;
3426 
3427 	case SDIOC_FORMAT2:
3428 		/*
3429 		 * format unit
3430 		 */
3431 		if ((flag & FWRITE) == 0)
3432 			return (EINVAL);
3433 		if (isalone(unit) != ONLY_ONE)
3434 			return (EBUSY);
3435 		sdd->sdd_flags |= SDDF_XUSE;
3436 		sdd->sdd_flags &= ~(SDDF_NONFMT|SDDF_FMTDONE|SDDF_SAMEDSK);
3437 
3438 		scu = (struct sc_ureq *)data;
3439 		error = sd_scu_exec(dev, scu, sc);
3440 		sdd->sdd_flags &= ~SDDF_XUSE;
3441 		break;
3442 
3443 	case SDIOC_GSTOPT:
3444 	case SDIOC_SSTOPT:
3445 		/*
3446 		 * get/set stop-unit timer
3447 		 */
3448 		if (cmd == SDIOC_GSTOPT)
3449 			*(int *)data = sdd->sdd_stoptime;
3450 		else {
3451 			if (*(int *)data == 0)
3452 				return (EINVAL);
3453 			sdd->sdd_stoptime = *(int *)data;
3454 		}
3455 		break;
3456 
3457 	case SDIOC_SEJECT:
3458 		/*
3459 		 * set auto eject flag
3460 		 */
3461 		sdd->sdd_flags |= SDDF_REQ_EJECT;
3462 		break;
3463 
3464 	case SDIOC_GFLAGS:
3465 		/*
3466 		 * get ii->ii_flags
3467 		 */
3468 		*(int *)data = ii->ii_flags;
3469 		break;
3470 
3471 	case SDIOC_SFLAGS:
3472 		/*
3473 		 * set ii->ii_flags
3474 		 */
3475 		ii->ii_flags = *(int *)data;
3476 		break;
3477 
3478 	case SDIOC_RASBLK:
3479 		/*
3480 		 * reassign block
3481 		 */
3482 		{
3483 			struct sc_rab *sca = (struct sc_rab *)sc->sc_param;
3484 
3485 			scinit(sc, ii->ii_slave, sdd->sdd_sectsize);
3486 			sc->sc_opcode = SCOP_RASBLK;
3487 			sc->sc_ctrnscnt = 8;
3488 
3489 			sca->sca_dllen = 4;
3490 			sca->sca_dlad[0] = *(int *)data;
3491 
3492 			error = sdcmd(dev, sc);
3493 		}
3494 		break;
3495 
3496 	case SDIOC_GNICKNAME:
3497 		{
3498 			int len;
3499 
3500 			len = strlen(sddevinfo[ii->ii_type].call_name);
3501 
3502 			if (len > IOCPARM_MASK)
3503 				len = IOCPARM_MASK;
3504 
3505 			error = copyout(
3506 				(caddr_t) sddevinfo[ii->ii_type].call_name,
3507 				(caddr_t) *(int *)data,
3508 				len);
3509 		}
3510 		break;
3511 
3512 	case SDIOC_GTYPINDEX:
3513 		*(int *)data = (int)ii->ii_type;
3514 		break;
3515 
3516 #ifdef SDIOC_SSYNCPARAM
3517 	case SDIOC_SSYNCPARAM:
3518 		{
3519 		struct sync_param *syncp;
3520 
3521 		syncp = (struct sync_param *)data;
3522 		scinit(sc, ii->ii_slave, sdd->sdd_sectsize);
3523 		sc->sc_opcode = SCOP_TST;
3524 		sc->sc_message = MSG_EXTND;	/* extended message */
3525 		sc->sc_param[0] = MSG_EXTND;
3526 		sc->sc_param[1] = 0x03;
3527 		sc->sc_param[2] = 0x01;		/* synchronous transfer */
3528 		sc->sc_param[3] = syncp->tr_period;	/* transfer period */
3529 		sc->sc_param[4] = syncp->tr_offset;	/* REQ offset */
3530 
3531 		(void) sdcmd(dev, sc);
3532 
3533 		syncp = &sd_sync_param[unit];
3534 		syncp->tr_period = sc->sc_param[3];
3535 		syncp->tr_offset = sc->sc_param[4];
3536 
3537 		if (syncp->tr_offset)
3538 			sdd->sdd_flags |= SDDF_SYNCTR;
3539 		else
3540 			sdd->sdd_flags &= ~SDDF_SYNCTR;
3541 		}
3542 		break;
3543 
3544 	case SDIOC_GSYNCPARAM:
3545 		{
3546 		struct sync_param *syncp = (struct sync_param *)data;
3547 
3548 		syncp->tr_period = sd_sync_param[unit].tr_period;
3549 		syncp->tr_offset = sd_sync_param[unit].tr_offset;
3550 		}
3551 		break;
3552 #endif /* SDIOC_SSYNCPARAM */
3553 
3554 	case MTIOCTOP:
3555 		{
3556 			register struct mtop *mtop = (struct mtop *)data;
3557 			register int lba;
3558 			int rest;
3559 			int blength;
3560 
3561 			switch (mtop->mt_op) {
3562 
3563 			case MTOFFL:
3564 				/*
3565 				 * set auto eject flag
3566 				 */
3567 				sdd->sdd_flags |= SDDF_REQ_EJECT;
3568 				break;
3569 
3570 #ifdef MTERASE
3571 			case MTERASE:
3572 				if (isalone(unit) != ONLY_ONE)
3573 					return (EBUSY);
3574 				sdd->sdd_flags |= SDDF_XUSE;
3575 				st = &sdstdrv[unit];
3576 				/*
3577 				 * MO disk erase
3578 				 *	block 0 to end (C partition)
3579 				 */
3580 				lba = 0;
3581 				rest = sdd->sdd_nsect;	/* C part size */
3582 				while (rest > 0) {
3583 					blength = (rest > MAXBL)? MAXBL : rest;
3584 					scinit(sc, ii->ii_slave,
3585 							sdd->sdd_sectsize);
3586 					sc->sc_opcode = SCOP_MOERASE;
3587 					sc->sc_lad = lba;
3588 					sc->sc_count = (blength % MAXBL);
3589 
3590 					(void) sdcmd(dev, sc);
3591 					lba += blength;
3592 					rest -= blength;
3593 				}
3594 				sdd->sdd_flags &= ~SDDF_XUSE;
3595 				break;
3596 #endif /* MTERASE */
3597 
3598 			default:
3599 				return (EINVAL);
3600 			}
3601 		}
3602 		break;
3603 
3604 	case SCSIIOCCMD:
3605 		scu = (struct sc_ureq *)data;
3606 		if ((scu->scu_count > 0) && scu->scu_addr) {
3607 			if (useracc(scu->scu_addr, scu->scu_count, B_WRITE)
3608 			    == NULL) {
3609 				error = EFAULT;
3610 				break;
3611 			}
3612 		}
3613 		error = sd_scu_exec(dev, scu, sc);
3614 		break;
3615 
3616 
3617 	case SDIOC_INQUIRY:
3618 		/*
3619 		 * LOCK sdtmp buffer
3620 		 */
3621 		s = splclock();
3622 		while (sdtmp_stat & B_BUSY) {
3623 			sdtmp_stat |= B_WANTED;
3624 			sleep((caddr_t)sdtmp, PRIBIO);
3625 		}
3626 		sdtmp_stat |= B_BUSY;
3627 		splx(s);
3628 
3629 		bzero((caddr_t)sdtmp, sizeof(struct sc_inq));
3630 		scinit(&uscsi, ii->ii_slave, sdd->sdd_sectsize);
3631 		uscsi.sc_cpoint = sdtmp;
3632 		uscsi.sc_ctrnscnt = sizeof(struct sc_inq);
3633 		uscsi.sc_opcode = SCOP_INQUIRY;
3634 		uscsi.sc_count = sizeof(struct sc_inq);
3635 
3636 		if ((error = sdcmd(dev, &uscsi)) == 0)
3637 			bcopy((caddr_t)sdtmp, data, sizeof(struct sc_inq));
3638 		/*
3639 		 * UNLOCK open
3640 		 */
3641 		s = splclock();
3642 		if (sdtmp_stat & B_WANTED)
3643 			wakeup((caddr_t)sdtmp);
3644 		sdtmp_stat &= ~(B_BUSY|B_WANTED);
3645 		splx(s);
3646 		break;
3647 
3648 
3649 	case SCSIIOCGTIMEO:
3650 		*(int *)data = sdc->sdc_timeo;
3651 		break;
3652 
3653 	case SCSIIOCSTIMEO:
3654 		if (*(int *)data == 0)
3655 			return (EINVAL);
3656 		sdc->sdc_timeo = *(int *)data;
3657 		sdc->sdc_wticks = 0;
3658 		break;
3659 
3660 	default:
3661 		error = EINVAL;
3662 		break;
3663 	}
3664 
3665 done:
3666 	return (error);
3667 }
3668 
3669 static
3670 sd_scu_exec(dev, scu, sc)
3671 	dev_t dev;
3672 	register struct sc_ureq *scu;
3673 	register struct scsi *sc;
3674 {
3675 	struct sdd_softc *sdd;
3676 	int error;
3677 
3678 	sdd = &sdd_softc[dev2unit(dev)];
3679 
3680 	if (((scu->scu_identify & MSG_IDENT) == 0)
3681 		|| (scu->scu_identify & ~(MSG_IDENT|IDT_DISCON|IDT_DRMASK))
3682 		|| (scu->scu_addr && (scu->scu_bytesec == 0))) {
3683 		return (EINVAL);
3684 	}
3685 
3686 	bzero((caddr_t)sc, sizeof(struct scsi));
3687 	sc->sc_tstatus = scu->scu_tstatus;
3688 	sc->sc_identify = scu->scu_identify;
3689 	sc->sc_message = scu->scu_message;
3690 	sc->sc_bytesec = scu->scu_bytesec;
3691 	sc->sc_cpoint = scu->scu_addr;
3692 	sc->sc_ctrnscnt = scu->scu_count;
3693 	bcopy((caddr_t)scu->scu_cdb, &sc->sc_cdb, sizeof(sc->sc_cdb));
3694 
3695 	bcopy((caddr_t)scu->scu_param, (caddr_t)sc->sc_param,
3696 						sizeof(sc->sc_param));
3697 
3698 	sdd->sdd_flags |= SDDF_SKIPCHECK;
3699 	error = sdcmd(dev, sc);
3700 	sdd->sdd_flags &= ~SDDF_SKIPCHECK;
3701 
3702 	scu->scu_istatus = sc->sc_istatus;
3703 	scu->scu_tstatus = sc->sc_tstatus;
3704 	scu->scu_message = sc->sc_message;
3705 	bcopy((caddr_t)sc->sc_param, (caddr_t)scu->scu_param,
3706 		sizeof(sc->sc_param));
3707 	return (error);
3708 }
3709 
3710 /*ARGSUSED*/
3711 sddump(dev)
3712 	dev_t dev;
3713 {
3714 	return (ENXIO);
3715 }
3716 
3717 sdsize(dev)
3718 	register dev_t dev;
3719 {
3720 	register struct iop/**/_device *ii;
3721 	register struct sdd_softc *sdd;
3722 	register struct sdst *st;
3723 	register int unit;
3724 	int i;
3725 
3726 	unit = dev2unit(dev);
3727 	if (unit >= nsd || (ii = sddinfo[unit]) == 0 || ii->ii_alive == 0)
3728 		return (-1);
3729 
3730 	sdd = &sdd_softc[unit];
3731 	switch (sdc_softc[ii->ii_ctlr].sdc_firmware & SDCFW_DEVMASK) {
3732 
3733 	case SDCFW_HD:		/* Hard Disk */
3734 		st = &sdstdrv[unit];
3735 		break;
3736 
3737 	case SDCFW_MO:		/* MO only */
3738 		if ((sdd->sdd_flags & SDDF_SAMEDSK) == SDDF_DSKCHGD) {
3739 			/*
3740 			 * read partition information,
3741 			 *	and set up sdstdrv[unit]
3742 			 */
3743 			if (sd_b_open(dev, FREAD|FWRITE) != 0) {
3744 				/*
3745 				 * block device open error
3746 				 */
3747 				return (-1);
3748 			} else {
3749 				/*
3750 				 * use disk partition information
3751 				 */
3752 				st = &sdstdrv[unit];
3753 				if (isalone(unit) == ONLY_ONE)
3754 					sd_b_close(dev, 0);
3755 			}
3756 		} else if (sdd->sdd_flags & SDDF_NONFMT) {
3757 			/*
3758 			 * medium is not initialized.
3759 			 */
3760 			return (-1);
3761 		} else {
3762 			st = &sdstdrv[unit];
3763 		}
3764 		break;
3765 
3766 	default:
3767     /*  case SDCFW_CD: */
3768 		return (-1);
3769 
3770 	}
3771 
3772 	if (st->sizes == NULL)
3773 		return (-1);					/* XXX */
3774 	else
3775 		return (st->sizes[dev2part(dev)].sd_nblocks);	/* XXX */
3776 }
3777 
3778 /*
3779  * Reset driver.
3780  * Cancel software state of all pending transfers,
3781  * and restart all units and the controller.
3782  */
3783 sdreset()
3784 {
3785 	register struct iop/**/_ctlr *im;
3786 	register struct iop/**/_device *ii;
3787 	register struct sdc_softc *sdc;
3788 	register struct sdd_softc *sdd;
3789 	register int i;
3790 	register int unit;
3791 
3792 	re_init_done = 1;
3793 	for (i = 0; i < nsdc; i++) {
3794 		im = sdminfo[i];
3795 		if (im == 0)
3796 			continue;
3797 		if (im->im_alive == 0)
3798 			continue;
3799 		printf(" sdc%d: ", i);
3800 		sdc = &sdc_softc[i];
3801 		sdc->sdc_wticks = 0;
3802 
3803 		/* scop_init() is already called by screset() */
3804 
3805 		sdtmp_stat &= ~B_BUSY;
3806 
3807 		for (unit = 0; unit < nsd; unit++) {
3808 			ii = sddinfo[unit];
3809 			if (ii == 0)
3810 				continue;
3811 			if (ii->ii_alive == 0)
3812 				continue;
3813 			if (ii->ii_mi != im)
3814 				continue;
3815 
3816 			csdbuf[unit].b_flags &= ~B_BUSY;
3817 
3818 			sdd = &sdd_softc[unit];
3819 			sdd->sdd_flags = 0;
3820 
3821 			/*
3822 			 * UNLOCK SCSI access
3823 			 */
3824 			sdc->sdc_firmware &= ~SDCFW_BUSY;
3825 
3826 			if (sdslave(ii, ii->ii_addr, im->im_intr) == 0) {
3827 				printf("sd%d: not ready\n", ii->ii_slave);
3828 				continue;
3829 			}
3830 			sdattach(ii);
3831 		}
3832 	}
3833 	re_init_done = 2;
3834 }
3835 
3836 int sd_long_timeout = 24 * 60 * 60;	/* 24 hours */
3837 
3838 #define max(a, b) (((a)>(b))?(a):(b))
3839 
3840 /*
3841  * Wake up every second and if interrupt is pending
3842  * but nothing has happened increment a counter.
3843  * If nothing happens for sdc_timeo seconds, reset the IOP
3844  * and begin anew.
3845  */
3846 sdwatch()
3847 {
3848 	register struct iop/**/_ctlr *im;
3849 	register struct sdc_softc *sdc;
3850 	register int i;
3851 	register int unit;
3852 	int timeo;
3853 
3854 	extern int Scsi_Disconnect;
3855 
3856 	timeout(sdwatch, (caddr_t)0, hz);
3857 	for (i = 0; i < nsdc; i++) {
3858 		im = sdminfo[i];
3859 		if (im == 0)
3860 			continue;
3861 		if (im->im_alive == 0)
3862 			continue;
3863 		sdc = &sdc_softc[i];
3864 
3865 		if (im->im_tab.b_active)
3866 			goto active;
3867 
3868 		for (unit = 0; unit < nsd; unit++)
3869 			if (sdutab[unit].b_active && sddinfo[unit]->ii_mi == im)
3870 				goto active;
3871 
3872 		sdc->sdc_wticks = 0;
3873 		continue;
3874 active:
3875 		if (Scsi_Disconnect)
3876 			timeo = sdc->sdc_timeo;
3877 		else
3878 			timeo = max(sdc->sdc_timeo, sd_long_timeout);
3879 
3880 		if (sdc->sdc_wticks++ >= timeo) {
3881 			register struct scsi *sc;
3882 
3883 			sc = get_scsi(im->im_intr);
3884 			sdc->sdc_wticks = 0;
3885 			printf("sdc%d: lost interrupt\n", i);
3886 
3887 			screset(im->im_intr);
3888 		}
3889 	}
3890 }
3891 
3892 /*
3893  * sdstop() is timer interrupt routine.
3894  *	So, can't use sleep().
3895  */
3896 sdstop()
3897 {
3898 	register struct iop/**/_ctlr *im;
3899 	register struct iop/**/_device *ii;
3900 	register struct sdc_softc *sdc;
3901 	register struct sdd_softc *sdd;
3902 	register int unit;
3903 	register int intr;
3904 	register int i;
3905 	struct scsi *sc;
3906 	int eject_sw;
3907 
3908 	timeout(sdstop, (caddr_t)0, hz);
3909 
3910 	for (i = 0; i < nsdc; i++) {
3911 		im = sdminfo[i];
3912 		if (im == 0)
3913 			continue;
3914 		if (im->im_alive == 0)
3915 			continue;
3916 		for (unit = 0; unit < nsd; unit++) {
3917 			if ((ii = sddinfo[unit]) == 0)
3918 				continue;
3919 			if (ii->ii_mi != im)
3920 				continue;
3921 			sdc = &sdc_softc[ii->ii_ctlr];
3922 			if ((sdc->sdc_firmware & SDCFW_RMB) == 0)
3923 				continue;
3924 			intr = ii->ii_intr;
3925 			if (isalone(unit))
3926 				continue;
3927 			/**********************/
3928 			/*    MO & CD-ROM     */
3929 			/**********************/
3930 			/*
3931 			 * there is no process which open the unit.
3932 			 */
3933 			sdd = &sdd_softc[unit];
3934 			sc = get_scsi(intr);
3935 			if (sdd->sdd_start > 0)
3936 				sdd->sdd_start--;
3937 			else if (sdd->sdd_start == 0) {
3938 				/*
3939 				 * Now stop the unit.
3940 				 * check SCSI access
3941 				 */
3942 				if (sdc->sdc_firmware & SDCFW_BUSY)
3943 					continue;
3944 				sdc->sdc_firmware |= SDCFW_BUSY;
3945 				sdc->sdc_state |= SDCS_IOCTL|SDCS_SCUNLOCK;
3946 
3947 				eject_sw = (sdd->sdd_flags & SDDF_REQ_EJECT) ?
3948 						SDSS_EJECT : SDSS_STOP;
3949 				scop_stst(intr, sc, ii->ii_slave,
3950 						SCSI_INTEN, eject_sw);
3951 				sdd->sdd_start = -2;
3952 			}
3953 		}
3954 	}
3955 }
3956 
3957 isalone(unit)
3958 	register int unit;
3959 {
3960 	register int i, n;
3961 
3962 	n = 0;
3963 	for (i = 0; i < PNUM; i++)
3964 		n += (sd_b_openf[unit][i] + sd_c_openf[unit][i]);
3965 	return (n);
3966 }
3967 
3968 /************************************************
3969  * Convert Hex and RS code table definition	*
3970  ************************************************/
3971 
3972 #define	X8_L	0x001d
3973 #define	X8_H	0x1d00
3974 
3975 
3976 #define	hextors(data)	hxtable[(int)((data) & 0xff)]
3977 #define	XORMASK(code)	xortable[(unsigned int)(code)]
3978 
3979 int	hxtable[256] = {
3980 	0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6,
3981 	0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
3982 	0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81,
3983 	0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
3984 	0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21,
3985 	0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
3986 	0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9,
3987 	0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
3988 	0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd,
3989 	0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
3990 	0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd,
3991 	0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
3992 	0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e,
3993 	0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
3994 	0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b,
3995 	0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
3996 	0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d,
3997 	0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
3998 	0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c,
3999 	0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
4000 	0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd,
4001 	0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
4002 	0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e,
4003 	0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
4004 	0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76,
4005 	0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
4006 	0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa,
4007 	0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
4008 	0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51,
4009 	0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
4010 	0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8,
4011 	0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf,
4012 };
4013 
4014 int xortable[256] = {
4015 	0x00000000, 0x90910101, 0x91210201, 0x01b00300,
4016 	0x92410401, 0x02d00500, 0x03600600, 0x93f10701,
4017 	0x94810801, 0x04100900, 0x05a00a00, 0x95310b01,
4018 	0x06c00c00, 0x96510d01, 0x97e10e01, 0x07700f00,
4019 	0x99011001, 0x09901100, 0x08201200, 0x98b11301,
4020 	0x0b401400, 0x9bd11501, 0x9a611601, 0x0af01700,
4021 	0x0d801800, 0x9d111901, 0x9ca11a01, 0x0c301b00,
4022 	0x9fc11c01, 0x0f501d00, 0x0ee01e00, 0x9e711f01,
4023 	0x82012001, 0x12902100, 0x13202200, 0x83b12301,
4024 	0x10402400, 0x80d12501, 0x81612601, 0x11f02700,
4025 	0x16802800, 0x86112901, 0x87a12a01, 0x17302b00,
4026 	0x84c12c01, 0x14502d00, 0x15e02e00, 0x85712f01,
4027 	0x1b003000, 0x8b913101, 0x8a213201, 0x1ab03300,
4028 	0x89413401, 0x19d03500, 0x18603600, 0x88f13701,
4029 	0x8f813801, 0x1f103900, 0x1ea03a00, 0x8e313b01,
4030 	0x1dc03c00, 0x8d513d01, 0x8ce13e01, 0x1c703f00,
4031 	0xb4014001, 0x24904100, 0x25204200, 0xb5b14301,
4032 	0x26404400, 0xb6d14501, 0xb7614601, 0x27f04700,
4033 	0x20804800, 0xb0114901, 0xb1a14a01, 0x21304b00,
4034 	0xb2c14c01, 0x22504d00, 0x23e04e00, 0xb3714f01,
4035 	0x2d005000, 0xbd915101, 0xbc215201, 0x2cb05300,
4036 	0xbf415401, 0x2fd05500, 0x2e605600, 0xbef15701,
4037 	0xb9815801, 0x29105900, 0x28a05a00, 0xb8315b01,
4038 	0x2bc05c00, 0xbb515d01, 0xbae15e01, 0x2a705f00,
4039 	0x36006000, 0xa6916101, 0xa7216201, 0x37b06300,
4040 	0xa4416401, 0x34d06500, 0x35606600, 0xa5f16701,
4041 	0xa2816801, 0x32106900, 0x33a06a00, 0xa3316b01,
4042 	0x30c06c00, 0xa0516d01, 0xa1e16e01, 0x31706f00,
4043 	0xaf017001, 0x3f907100, 0x3e207200, 0xaeb17301,
4044 	0x3d407400, 0xadd17501, 0xac617601, 0x3cf07700,
4045 	0x3b807800, 0xab117901, 0xaaa17a01, 0x3a307b00,
4046 	0xa9c17c01, 0x39507d00, 0x38e07e00, 0xa8717f01,
4047 	0xd8018001, 0x48908100, 0x49208200, 0xd9b18301,
4048 	0x4a408400, 0xdad18501, 0xdb618601, 0x4bf08700,
4049 	0x4c808800, 0xdc118901, 0xdda18a01, 0x4d308b00,
4050 	0xdec18c01, 0x4e508d00, 0x4fe08e00, 0xdf718f01,
4051 	0x41009000, 0xd1919101, 0xd0219201, 0x40b09300,
4052 	0xd3419401, 0x43d09500, 0x42609600, 0xd2f19701,
4053 	0xd5819801, 0x45109900, 0x44a09a00, 0xd4319b01,
4054 	0x47c09c00, 0xd7519d01, 0xd6e19e01, 0x46709f00,
4055 	0x5a00a000, 0xca91a101, 0xcb21a201, 0x5bb0a300,
4056 	0xc841a401, 0x58d0a500, 0x5960a600, 0xc9f1a701,
4057 	0xce81a801, 0x5e10a900, 0x5fa0aa00, 0xcf31ab01,
4058 	0x5cc0ac00, 0xcc51ad01, 0xcde1ae01, 0x5d70af00,
4059 	0xc301b001, 0x5390b100, 0x5220b200, 0xc2b1b301,
4060 	0x5140b400, 0xc1d1b501, 0xc061b601, 0x50f0b700,
4061 	0x5780b800, 0xc711b901, 0xc6a1ba01, 0x5630bb00,
4062 	0xc5c1bc01, 0x5550bd00, 0x54e0be00, 0xc471bf01,
4063 	0x6c00c000, 0xfc91c101, 0xfd21c201, 0x6db0c300,
4064 	0xfe41c401, 0x6ed0c500, 0x6f60c600, 0xfff1c701,
4065 	0xf881c801, 0x6810c900, 0x69a0ca00, 0xf931cb01,
4066 	0x6ac0cc00, 0xfa51cd01, 0xfbe1ce01, 0x6b70cf00,
4067 	0xf501d001, 0x6590d100, 0x6420d200, 0xf4b1d301,
4068 	0x6740d400, 0xf7d1d501, 0xf661d601, 0x66f0d700,
4069 	0x6180d800, 0xf111d901, 0xf0a1da01, 0x6030db00,
4070 	0xf3c1dc01, 0x6350dd00, 0x62e0de00, 0xf271df01,
4071 	0xee01e001, 0x7e90e100, 0x7f20e200, 0xefb1e301,
4072 	0x7c40e400, 0xecd1e501, 0xed61e601, 0x7df0e700,
4073 	0x7a80e800, 0xea11e901, 0xeba1ea01, 0x7b30eb00,
4074 	0xe8c1ec01, 0x7850ed00, 0x79e0ee00, 0xe971ef01,
4075 	0x7700f000, 0xe791f101, 0xe621f201, 0x76b0f300,
4076 	0xe541f401, 0x75d0f500, 0x7460f600, 0xe4f1f701,
4077 	0xe381f801, 0x7310f900, 0x72a0fa00, 0xe231fb01,
4078 	0x71c0fc00, 0xe151fd01, 0xe0e1fe01, 0x7070ff00
4079 };
4080 
4081 /********************************************************
4082  * EDC (Error Detection Code) check			*
4083  *			(using CRC code)		*
4084  *	MODE 1 : Sync + Header + User data + edc	*
4085  *	MODE 2 : Sub header + User data + edc		*
4086  ********************************************************/
4087 
4088 #define	SYNC_EDC	0x908eff4e	/* sector sync EDC value	*/
4089 #define	HEADER		4		/* header length 4 bytes	*/
4090 #define	SUB_H		8		/* Subheader length 8 bytes	*/
4091 #define	USER_DATA	2048		/* User data length 2048 bytes	*/
4092 #define	EDC_LEN		4		/* EDC code length 4 bytes	*/
4093 
4094 cal_edc1(db, mode)
4095 	register unsigned char	*db;
4096 	int mode;
4097 {
4098 	register int j;
4099 	register unsigned int work;
4100 
4101 	j = USER_DATA + EDC_LEN;
4102 	if (mode == 2) {
4103 		j += SUB_H;
4104 		work = 0;
4105 	} else {
4106 		j += HEADER;
4107 		work = SYNC_EDC;
4108 	}
4109 	while (--j >= 0)
4110 		work = ((work >> 8) | (*db++ << 24)) ^ XORMASK(work & 0xff);
4111 
4112 	return (work);
4113 }
4114 
4115 
4116 /************************************************/
4117 /*	error detection & correction		*/
4118 /*	if form 1				*/
4119 /*	    header area should be zero		*/
4120 /************************************************/
4121 
4122 /*
4123  *	error detection & correction  P-direction
4124  */
4125 p_dir(dbuf)
4126 	register unsigned short	*dbuf;
4127 {
4128 	unsigned short	s0, s1, d;
4129 	register int	col, row;
4130 	register int	x;
4131 	unsigned char	s0l, s0h, s1l, s1h;
4132 
4133 	/*
4134 	 * calculate syndrome S0 S1
4135 	 */
4136 	for (col = 0; col < 43; col++) {
4137 		s0 = s1 = 0;
4138 
4139 		for (row = 0; row < 26; row++) {
4140 			d = dbuf[43 * row + col];
4141 			s0 ^= d;
4142 			s1 = rsshift(s1) ^ d;
4143 		}
4144 
4145 		s0h = s0 & 0x00ff;
4146 		s1h = s1 & 0x00ff;
4147 		s0l = (s0 >> 8) & 0x00ff;
4148 		s1l = (s1 >> 8) & 0x00ff;
4149 		/*
4150 		 * calculate error position & correction
4151 		 */
4152 		if (s0l != 0) {
4153 			if((x = hextors(s1l) - hextors(s0l)) < 0)
4154 				x += 255;
4155 			if ((x >= 0) && (x < 26)) {
4156 				x = 25 - x;
4157 				/*
4158 				 * correction
4159 				 */
4160 				dbuf[43 * x + col] ^= (s0 & 0xff00);
4161 			}
4162 		}
4163 
4164 		/*
4165 		 * calculate error position & correction
4166 		 */
4167 		if (s0h != 0) {
4168 			if((x = hextors(s1h) - hextors(s0h)) < 0)
4169 				x += 255;
4170 			if ((x >= 0) && (x < 26)) {
4171 				x = 25 - x;
4172 				/*
4173 				 * correction
4174 				 */
4175 				dbuf[43 * x + col] ^= (s0 & 0x00ff);
4176 			}
4177 		}
4178 	}
4179 }
4180 
4181 /*
4182  * error detection & correction  Q-direction
4183  */
4184 q_dir(dbuf)
4185 	register unsigned short	*dbuf;
4186 {
4187 	unsigned short s0, s1, d;
4188 	register int col, row;
4189 	register int x;
4190 	unsigned char s0l, s0h, s1l, s1h;
4191 
4192 	/*
4193 	 * calculate syndrome S0 S1
4194 	 */
4195 	for (row = 0; row < 26; row++) {
4196 		s0 = s1 = 0;
4197 
4198 		for (col = 0; col < 45; col++) {
4199 			if (col < 43)
4200 				d = dbuf[(44 * col + 43 * row) % 1118];
4201 			else if (col == 43)
4202 				d = dbuf[43 * 26 + row];
4203 			else
4204 				d = dbuf[44 * 26 + row];
4205 			s0 ^= d;
4206 			s1 = rsshift(s1) ^ d;
4207 		}
4208 
4209 		s0h = s0 & 0x00ff;
4210 		s1h = s1 & 0x00ff;
4211 		s0l = (s0 >> 8) & 0x00ff;
4212 		s1l = (s1 >> 8) & 0x00ff;
4213 		/*
4214 		 * calculate error position & correction
4215 		 */
4216 		if (s0l != 0) {
4217 			if((x = hextors(s1l) - hextors(s0l)) < 0)
4218 				x += 255;
4219 			if (x >= 0 && x < 45) {
4220 				x = 44 - x;
4221 				/*
4222 				 * correction
4223 				 */
4224 				if (x < 43)
4225 					dbuf[(44 * x + 43 * row) % 1118]
4226 						^= s0 & 0xff00;
4227 				else if (x == 43)
4228 					dbuf[43 * 26 + row] ^= s0 & 0xff00;
4229 				else
4230 					dbuf[44 * 26 + row] ^= s0 & 0xff00;
4231 			}
4232 		}
4233 
4234 		/*
4235 		 * calculate error position & correction
4236 		 */
4237 		if (s0h != 0) {
4238 			if((x = hextors(s1h) - hextors(s0h)) < 0)
4239 				x += 255;
4240 			if ((x >= 0) && (x < 45)) {
4241 				x = 44 - x;
4242 				/*
4243 				 * correction
4244 				 */
4245 				if (x < 43)
4246 					dbuf[(44 * x + 43 * row) % 1118]
4247 						^= s0 & 0x00ff;
4248 				else if ( x == 43)
4249 					dbuf[43 * 26 + row] ^= s0 & 0x00ff;
4250 				else
4251 					dbuf[44 * 26 + row] ^= s0 & 0x00ff;
4252 			}
4253 		}
4254 	}
4255 }
4256 
4257 /*
4258  *	shift high & low byte at the same time
4259  */
4260 rsshift(d)
4261 	unsigned short d;
4262 {
4263 	register int x;
4264 	register int dmy;	/* This way is faster */
4265 
4266 	dmy = (int)d;
4267 	x = (dmy << 1) & 0xfefe;	/* clear LSB of high & low byte */
4268 	if ((dmy & 0x0080) != 0)
4269 		x ^= X8_L;
4270 	if ((dmy & 0x8000) != 0)
4271 		x ^= X8_H;
4272 	return(x);
4273 }
4274 #endif /* NSD > 0 */
4275