FreeBSD/Linux Kernel Cross Reference
sys/sqtzdc/zd.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1992-1 Carnegie Mellon University
4 * Copyright (c) 1991 Sequent Computer Systems
5 * All Rights Reserved.
6 *
7 * Permission to use, copy, modify and distribute this software and its
8 * documentation is hereby granted, provided that both the copyright
9 * notice and this permission notice appear in all copies of the
10 * software, derivative works or modified versions, and any portions
11 * thereof, and that both notices appear in supporting documentation.
12 *
13 * CARNEGIE MELLON AND SEQUENT COMPUTER SYSTEMS ALLOW FREE USE OF
14 * THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON AND
15 * SEQUENT COMPUTER SYSTEMS DISCLAIM ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 *
18 * Carnegie Mellon requests users of this software to return to
19 *
20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
24 *
25 * any improvements or extensions that they make and grant Carnegie Mellon
26 * the rights to redistribute these changes.
27 */
28
29 /*
30 * HISTORY
31 * $Log: zd.c,v $
32 * Revision 2.7 93/03/11 14:05:45 danner
33 * u_long -> u_int
34 * [93/03/10 danner]
35 *
36 * Revision 2.6 92/08/03 18:16:35 jfriedl
37 * Add "zd_devinfo" routine.
38 * [92/08/03 14:36:10 jms]
39 *
40 * Revision 2.5 92/02/24 09:58:46 elf
41 * Removed gratuitous reference to undefined variable in zdgetstat.
42 * [92/02/24 elf]
43 *
44 * Revision 2.4 92/02/23 22:45:21 elf
45 * Added zdgetstat().
46 * [92/02/22 19:52:59 af]
47 *
48 * Revision 2.3 91/07/31 18:08:03 dbg
49 * Changed copyright.
50 * [91/07/31 dbg]
51 *
52 * Revision 2.2 91/05/08 13:07:55 dbg
53 * Changes for new kmem_alloc interface.
54 *
55 * Adapted for pure Mach kernel.
56 * [91/03/22 dbg]
57 *
58 */
59
60 /*
61 * zd.c
62 *
63 * ZDC SMD Disk Driver
64 */
65
66 #ifdef MACH_KERNEL
67 #include <vm/vm_kern.h>
68
69 #include <sys/types.h>
70 #include <sys/time.h>
71
72 #include <device/buf.h>
73 #include <device/errno.h>
74 #include <device/param.h>
75
76 #include <sqt/macros.h>
77 #include <sqt/vm_defs.h>
78 #include <sqt/slicreg.h>
79 #include <sqt/clkarb.h>
80
81 #include <sqt/mutex.h>
82 #include <sqt/intctl.h>
83
84 #include <sqtzdc/zdc.h>
85 #include <sqtzdc/zdbad.h>
86 #include <sqtzdc/ioconf.h>
87
88 #define PZERO (0) /* unused */
89 #define FWRITE D_WRITE
90 #define EACCES D_ALREADY_OPEN
91
92 #else MACH_KERNEL
93 #include "sys/param.h"
94 #include "sys/file.h"
95 #include "sys/user.h"
96 #include "sys/buf.h"
97 #include "sys/systm.h"
98 #include "sys/uio.h"
99 #include "sys/ioctl.h"
100 #include "sys/proc.h"
101 #include "sys/kernel.h"
102 #include "sys/dk.h"
103 #include "sys/vm.h"
104
105 #include "sqt/slicreg.h"
106 #include "sqt/clkarb.h"
107
108 #include "sqt/mutex.h"
109 #include "sqt/intctl.h"
110 #include "sqt/pte.h"
111 #include "sqt/mftpr.h"
112 #include "sqt/plocal.h"
113
114 #include "sqtzdc/zdc.h"
115 #include "sqtzdc/zdbad.h"
116 #include "sqtzdc/ioconf.h"
117 #endif MACH_KERNEL
118
119 #define ZDUNIT(dev) (minor(dev) >> 0x3)
120 #define ZDPART(dev) (minor(dev) & 0x7)
121 #define PARTCHR(dev) ('a' + ZDPART(dev))
122 #define NUDGE_ZDC(ctlp, cbp, s) { \
123 (s) = splhi(); \
124 mIntr((ctlp)->zdc_slicaddr, CBBIN, (u_char)((cbp) - (ctlp)->zdc_cbp)); \
125 splx((s)); \
126 }
127 #define PZOPEN (PZERO - 1) /* not signallable */
128 #define b_diskaddr b_resid
129 #define b_psect b_error
130 #define B_IOCTL B_MD1
131 /*
132 * PTECLOFF returns offset in cluster of memory pointed at by pte.
133 */
134 #define PTECLOFF(pte) ((unsigned)((*(int*)(&(pte))) & ((~(NBPG-1))&CLOFSET)))
135
136 extern struct zdc_ctlr *zdctrlr; /* zdctrlr array */
137 extern struct zd_unit *zdunit; /* zdunit array */
138 extern struct zdsize *zdparts[]; /* Partition tables */
139 extern int zdntypes; /* known drive types */
140 extern int zdc_iovpercb; /* no of iovecs per cb */
141 extern int zdc_AB_throttle; /* Channel A&B DMA throttle */
142 extern short zdcretry; /* retry count on errors */
143 extern u_char zdctrl; /* additional icb_ctrl bits */
144 extern u_char base_cb_intr; /* base interrupt for zdc driver */
145 extern u_char base_err_intr; /* base controller interrupt */
146 extern simple_lock_data_t
147 zdcprlock; /* coordinate error printfs */
148
149 #define DEBUG 1
150
151 #ifdef DEBUG
152 int zddebug = 0;
153 #endif DEBUG
154
155 caddr_t zd_compcodes[] = {
156 "Command in progress",
157 "Successful completion",
158 "Write protect fault",
159 "Drive Fault",
160 "Seek error",
161 "Seek timeout",
162 "Channel timeout",
163 "DMA timeout",
164 "Header ECC error",
165 "Soft ECC error",
166 "Correctable ECC error",
167 "Uncorrectable ECC error",
168 "Sector not found",
169 "Bad data sector",
170 "Sector overrun",
171 "No data synch",
172 "Fifo data lost",
173 "Illegal cb_cmd",
174 "Illegal cb_mod",
175 "Illegal disk address",
176 "cb_addr not 16-byte aligned",
177 "Illegal cb_count",
178 "cb_iovec not 32-byte aligned",
179 "Non-zero cb_iovec and page size invalid",
180 "Illegal icb_pagesize",
181 "icb_dumpaddr not 16-byte aligned",
182 "Bad drive",
183 "In-use CB reused",
184 "Access error during DMA",
185 "Channel not configured",
186 "Channel was reset",
187 "Unexpected status from DDC",
188 "Unknown Completion code"
189 };
190 int zdncompcodes = sizeof(zd_compcodes) / sizeof(zd_compcodes[0]);
191
192 #ifdef MACH
193 static struct buf zdbuf; /* needed for physio */
194 #endif
195
196 /*
197 * zdopen
198 *
199 * Return:
200 * 0 - success.
201 * EACCES - open for write but drive write-protected.
202 * ENXIO - all other failures.
203 */
204 zdopen(dev, mode)
205 dev_t dev;
206 int mode;
207 {
208 register struct zd_unit *up;
209 register struct zdcdd *dd; /* channel configuration */
210 register struct zdc_dev *zdv; /* config data */
211 int retval; /* return value */
212 u_char oldcfg; /* previous cfg state */
213 struct zdcdd *zdget_chancfg();
214
215 up = &zdunit[ZDUNIT(dev)];
216
217 #ifdef DEBUG
218 if (zddebug)
219 printf("O");
220 #endif DEBUG
221
222 /*
223 * Fail open if the unit is bad or if the unit was not bound
224 * to a drive during configuration.
225 */
226 if (ZDUNIT(dev) >= zdc_conf->zc_nent ||
227 up->zu_state == ZU_NOTFOUND || up->zu_state == ZU_BAD)
228 return (ENXIO);
229
230 /*
231 * Now get serious
232 */
233 p_sema(&up->zu_ocsema, PZOPEN);
234
235 (void)p_lock(&up->zu_lock, SPLZD);
236 /*
237 * check to see if still good drive.
238 */
239 if (up->zu_state == ZU_BAD) {
240 v_lock(&up->zu_lock, SPL0);
241 v_sema(&up->zu_ocsema);
242 return (ENXIO);
243 }
244 up->zu_nopen++;
245 retval = 0;
246 if (up->zu_nopen > 1) {
247 /*
248 * Already opened at least once.
249 */
250 if (up->zu_state == ZU_NO_RW) {
251 /*
252 * Only one formatter at a time please...
253 */
254 retval = EACCES;
255 } else if (zdparts[up->zu_drive_type][ZDPART(dev)].p_length == 0) {
256 /*
257 * Good drive but fail open if partition table is
258 * invalid.
259 */
260 retval = ENXIO;
261 } else if ((mode & FWRITE) && (up->zu_cfg & ZD_READONLY)) {
262 /*
263 * Fail open for write on a write-protected drive.
264 */
265 retval = EACCES;
266 }
267 v_lock(&up->zu_lock, SPL0);
268 if (retval != 0)
269 --up->zu_nopen;
270 v_sema(&up->zu_ocsema);
271 return (retval);
272 }
273
274 /*
275 * First open!
276 * Drop lock, we don't need as no other I/O can be in progress
277 * on this drive.
278 */
279 v_lock(&up->zu_lock, SPL0);
280
281 up->zu_state = ZU_GOOD; /* assume good */
282 oldcfg = up->zu_cfg;
283 if ((retval = zdprobe_drive(dev, up)) != 0) {
284 /*
285 * Error whilst attempting probe!
286 */
287 goto out;
288 }
289 /*
290 * Error if drive still not there or not online.
291 */
292 if (up->zu_cfg == ZD_NOTFOUND || /* Not there */
293 (up->zu_cfg & ZD_ONLINE) != ZD_ONLINE) { /* Offline */
294 if ((oldcfg & ZD_ONLINE) == ZD_ONLINE) {
295 /*
296 * It had been online.
297 */
298 disk_offline();
299 }
300 retval = ENXIO;
301 goto out;
302 }
303
304 if (oldcfg == ZD_NOTFOUND || ((oldcfg & ZD_ONLINE) != ZD_ONLINE)) {
305 /*
306 * It had been offline.
307 */
308 disk_online();
309 }
310
311 if ((mode & FWRITE) && (up->zu_cfg & ZD_READONLY)) {
312 /*
313 * Fail open for write on a write-protected drive.
314 */
315 retval = EACCES;
316 goto out;
317 }
318
319 dd = zdget_chancfg(dev, up);
320 if (dd == NULL) {
321 retval = EIO;
322 goto out;
323 }
324 zdv = &zdc_conf->zc_dev[ZDUNIT(dev)];
325 /*
326 * Does channel configuration match the drive configuration.
327 * If bound drive_type and mismatch, then drive is marked to
328 * disallow normal read/write operations.
329 */
330 if (dd->zdd_sectors == 0 ||
331 (zdv->zdv_drive_type != ANY &&
332 zdv->zdv_drive_type != dd->zdd_drive_type)) {
333 up->zu_state = ZU_NO_RW;
334 printf("zd%d: drive type mismatch - check configuration.\n",
335 up - zdunit);
336 goto out;
337 }
338 /*
339 * If the drive is not formatted or is formatted differently than
340 * the other drives on the channel, then cannot read the bad block
341 * list. In this case, only format operations via ioctl will be
342 * allowed. Read and write operations will return error.
343 */
344 if ((up->zu_cfg & (ZD_FORMATTED|ZD_MATCH)) != (ZD_FORMATTED|ZD_MATCH)) {
345 up->zu_state = ZU_NO_RW;
346 printf("zd%d: warning: %s.\n", up - zdunit,
347 ((up->zu_cfg & ZD_FORMATTED) != ZD_FORMATTED)
348 ? "drive unformatted"
349 : "drive/channel mismatch");
350 goto out;
351 }
352 if (dd->zdd_drive_type >= zdntypes) {
353 /*
354 * Unknown drive type. Check zdparts[] in binary conf file.
355 */
356 up->zu_state = ZU_NO_RW; /* allow reformat */
357 printf("zd%d: unknown drive type - check configuration.\n",
358 up - zdunit);
359 goto out;
360 }
361
362 up->zu_drive_type = dd->zdd_drive_type;
363 if (zdparts[up->zu_drive_type][ZDPART(dev)].p_length == 0) {
364 /*
365 * Good drive but fail open if partition table is invalid.
366 */
367 retval = ENXIO;
368 goto out;
369 }
370
371 /*
372 * Online and formatted drive - get bad block list.
373 * If cannot correctly read bad block list - only allow ioctl
374 * operations.
375 */
376 if (zdgetbad(dev, up) < 0) {
377 printf("zd%d: Cannot read bad block list.\n", up - zdunit);
378 up->zu_state = ZU_NO_RW;
379 }
380
381 out:
382 if (retval != 0)
383 --up->zu_nopen;
384 v_sema(&up->zu_ocsema);
385 return (retval);
386 }
387
388 /*
389 * zdclose
390 * Close the device.
391 * If last close, free memory holding bad block list.
392 */
393 /*ARGSUSED*/
394 zdclose(dev, flag)
395 dev_t dev;
396 int flag;
397 {
398 register struct zd_unit *up;
399 register int size;
400
401 up = &zdunit[ZDUNIT(dev)];
402 #ifdef DEBUG
403 if (zddebug)
404 printf("C");
405 #endif DEBUG
406 p_sema(&up->zu_ocsema, PZOPEN);
407 if (--up->zu_nopen == 0) {
408 /*
409 * Last close!
410 * Free memory allocated to hold bad block list.
411 * If drive has removable media, the next open may
412 * have different bad block list.
413 */
414 if (up->zu_zdbad != NULL) {
415 size = (up->zu_zdbad->bz_nsnf * sizeof(struct bz_bad))
416 + sizeof(struct zdbad) - sizeof(struct bz_bad);
417 size = roundup(size, DEV_BSIZE);
418 kmem_free(kernel_map, (vm_offset_t)up->zu_zdbad, size);
419 up->zu_zdbad = NULL;
420 }
421 }
422 v_sema(&up->zu_ocsema);
423 }
424
425 /*
426 * zdprobe_drive
427 * Probe for the status of a particular drive then update
428 * appropriate fields in controller and unit structures.
429 */
430 int
431 zdprobe_drive(dev, up)
432 dev_t dev;
433 register struct zd_unit *up;
434 {
435 register struct buf *bp; /* ioctl buffer */
436 register struct cb *cbp; /* cb argument */
437 int error;
438
439 bp = &up->zu_ioctl;
440 cbp = &up->zu_ioctlcb;
441 #ifndef MACH
442 bufalloc(bp); /* will always get since 1st open */
443 #endif MACH
444 bp->b_flags = B_IOCTL;
445 bp->b_bcount = 0; /* data in CB */
446 bp->b_un.b_addr = NULL;
447 bp->b_dev = dev;
448 bp->b_blkno = 0;
449 bp->b_error = 0;
450 #ifndef MACH_KERNEL
451 bp->b_proc = u.u_procp;
452 #endif MACH_KERNEL
453 #ifndef MACH
454 bp->b_iotype = B_FILIO;
455 BIODONE(bp) = 0;
456 #endif MACH
457 /* Fill out CB */
458 cbp->cb_cmd = ZDC_PROBEDRIVE;
459 /*
460 * Insert at head of list and zdstart!
461 */
462 (void)p_lock(&up->zu_lock, SPLZD);
463 bp->av_forw = NULL;
464 up->zu_bhead.av_forw = bp;
465 zdstart(up);
466 v_lock(&up->zu_lock, SPL0);
467 biowait(bp);
468 #ifdef MACH_KERNEL
469 error = bp->b_error;
470 #else MACH_KERNEL
471 error = geterror(bp);
472 #endif MACH_KERNEL
473 if (error) {
474 #ifndef MACH
475 buffree(bp);
476 #endif MACH
477 return (error);
478 }
479 /*
480 * extract drive cfg data.
481 */
482 up->zu_cfg = ((struct probe_cb *)cbp)->pcb_drivecfg[up->zu_drive];
483 zdctrlr[up->zu_ctrlr].zdc_drivecfg[up->zu_drive] = up->zu_cfg;
484 #ifndef MACH
485 buffree(bp);
486 #endif MACH
487 return (0);
488 }
489
490 /*
491 * zdget_chancfg
492 * Get the channel configuration for the channel on which this
493 * drive resides. Fills in channel configuration in controller structure.
494 */
495 struct zdcdd *
496 zdget_chancfg(dev, up)
497 dev_t dev;
498 register struct zd_unit *up;
499 {
500 register struct buf *bp; /* ioctl buffer */
501 register struct cb *cbp; /* cb argument */
502 struct zdcdd *dd; /* channel configuration data */
503 int chan; /* Channel A (0) or channel B (1) */
504
505 bp = &up->zu_ioctl;
506 cbp = &up->zu_ioctlcb;
507 #ifndef MACH
508 bufalloc(bp); /* will always get since 1st open */
509 #endif MACH
510 if (kmem_alloc(kernel_map,
511 (vm_offset_t *)&bp->b_un.b_addr,
512 sizeof(struct zdcdd)) != KERN_SUCCESS)
513 panic("zdget_chancfg");
514 bzero(bp->b_un.b_addr, sizeof(struct zdcdd));
515 bp->b_flags = B_READ | B_IOCTL;
516 bp->b_bcount = sizeof(struct zdcdd);
517 bp->b_dev = dev;
518 bp->b_blkno = 0;
519 bp->b_error = 0;
520 #ifndef MACH_KERNEL
521 bp->b_proc = u.u_procp;
522 #endif MACH_KERNEL
523 #ifndef MACH
524 bp->b_iotype = B_FILIO;
525 BIODONE(bp) = 0;
526 #endif MACH
527 /* Fill out CB */
528 cbp->cb_cmd = ZDC_GET_CHANCFG;
529 cbp->cb_addr = KVTOPHYS(bp->b_un.b_addr, u_int);
530 cbp->cb_count = sizeof(struct zdcdd);
531 /*
532 * Insert at head of list and zdstart!
533 */
534 (void)p_lock(&up->zu_lock, SPLZD);
535 bp->av_forw = NULL;
536 up->zu_bhead.av_forw = bp;
537 zdstart(up);
538 v_lock(&up->zu_lock, SPL0);
539 biowait(bp);
540 if (bp->b_flags & B_ERROR) {
541 kmem_free(kernel_map, bp->b_un.b_addr, sizeof(struct zdcdd));
542 #ifndef MACH
543 buffree(bp);
544 #endif MACH
545 return (NULL);
546 }
547 /*
548 * Extract Channel configuration data.
549 */
550 chan = up->zu_drive & 1;
551 dd = (chan) ? &zdctrlr[up->zu_ctrlr].zdc_chanB
552 : &zdctrlr[up->zu_ctrlr].zdc_chanA;
553 bcopy(bp->b_un.b_addr, (caddr_t)dd, sizeof(struct zdcdd));
554 kmem_free(kernel_map, bp->b_un.b_addr, sizeof(struct zdcdd));
555 #ifndef MACH
556 buffree(bp);
557 #endif MACH
558 /*
559 * On the first get of the channel configuration set the
560 * dma throttle for the channel. Make sure that the configuration
561 * is valid.
562 */
563 if (dd->zdd_sectors != 0 &&
564 (zdctrlr[up->zu_ctrlr].zdc_dma_throttle & (1 << chan)) == 0)
565 set_dma_throttle(&zdctrlr[up->zu_ctrlr], dd, chan);
566 return (dd);
567 }
568
569 /*
570 * set_dma_throttle
571 * If 1st open on channel, set the dma throttle
572 */
573 /*ARGSUSED*/
574 set_dma_throttle(ctlrp, dd, chan)
575 register struct zdc_ctlr *ctlrp; /* controller */
576 struct zdcdd *dd; /* channel configuration data */
577 int chan; /* channel A (0) or B (1) */
578 {
579 register int throttle; /* throttle count */
580 spl_t s_ipl;
581
582 s_ipl = p_lock(&ctlrp->zdc_ctlrlock, SPLHI);
583 if ((ctlrp->zdc_dma_throttle & (1 << chan)) == 0) {
584 throttle = zdc_AB_throttle;
585 if (throttle > SLB_TVAL)
586 throttle = SLB_TVAL;
587 wrslave(ctlrp->zdc_slicaddr, (u_char)(SL_G_CHAN0 + chan),
588 (u_char)(SLB_TH_ENB | throttle));
589 ctlrp->zdc_dma_throttle |= (1 << chan);
590 }
591 v_lock(&ctlrp->zdc_ctlrlock, s_ipl);
592 }
593
594 /*
595 * getchksum
596 * Calculate bad block list checksum
597 */
598 static
599 getchksum(lptr, nelem, seed)
600 register long *lptr;
601 register int nelem;
602 long seed;
603 {
604 register long sum;
605
606 sum = seed;
607 while (nelem-- > 0) {
608 sum ^= *lptr;
609 ++lptr;
610 }
611 return (sum);
612 }
613
614 /*
615 * zdgetbad
616 * - get the bad block list for this unit.
617 * Return:
618 * 0 - success
619 * -1 - failure
620 */
621 int
622 zdgetbad(dev, up)
623 dev_t dev;
624 struct zd_unit *up;
625 {
626 register struct cb *cbp;
627 register struct bz_bad *fbzp, *tbzp;
628 register struct buf *bp; /* ioctl buffer */
629 register int size;
630 struct zdbad *zdp; /* bad block list */
631 struct zdcdd *dd; /* disk description */
632 int zdpsize;
633 int block;
634 caddr_t addr;
635 static struct zdbad null_bbl; /* fake bad block list */
636
637 /*
638 * Initialize a fake bad block list in case we receive a
639 * SNF failure whilst reading the bad block list!
640 */
641 null_bbl.bz_nelem = 0;
642 null_bbl.bz_nsnf = 0;
643 up->zu_zdbad = &null_bbl;
644
645 dd = (up->zu_drive & 1) ? &zdctrlr[up->zu_ctrlr].zdc_chanB
646 : &zdctrlr[up->zu_ctrlr].zdc_chanA;
647 size = 1; /* get 1 for starters */
648 if (kmem_alloc(kernel_map,
649 (vm_offset_t *)&zdp,
650 DEV_BSIZE) != KERN_SUCCESS)
651 panic("zdgetbad");
652
653 /*
654 * Read bad block list.
655 */
656 bp = &up->zu_ioctl;
657 #ifndef MACH
658 bufalloc(bp);
659 #endif MACH
660 bp->b_dev = dev;
661 bp->b_blkno = 0;
662 #ifndef MACH_KERNEL
663 bp->b_proc = u.u_procp;
664 #endif MACH_KERNEL
665 #ifndef MACH
666 bp->b_iotype = B_FILIO;
667 #endif MACH
668 cbp = &up->zu_ioctlcb;
669 cbp->cb_mod = 0;
670 cbp->cb_cmd = ZDC_READ;
671 cbp->cb_cyl = ZDD_DDCYL;
672 addr = (caddr_t)zdp;
673 for (block = 0; block < size; block++) {
674 cbp->cb_head = 0;
675 cbp->cb_sect = ZDD_NDDSECTORS + block;
676 while (cbp->cb_head < MIN(dd->zdd_tracks, BZ_NBADCOPY)) {
677 bp->b_bcount = DEV_BSIZE;
678 bp->b_flags = B_READ | B_IOCTL;
679 bp->b_un.b_addr = addr;
680 bp->b_error = 0;
681 #ifndef MACH
682 BIODONE(bp) = 0;
683 #endif MACH
684 cbp->cb_count = DEV_BSIZE;
685 cbp->cb_addr = KVTOPHYS(addr, u_int);
686 /*
687 * Queue and start I/O
688 */
689 (void)p_lock(&up->zu_lock, SPLZD);
690 bp->av_forw = NULL;
691 up->zu_bhead.av_forw = bp;
692 zdstart(up);
693 v_lock(&up->zu_lock, SPL0);
694 biowait(bp);
695 if ((bp->b_flags & B_ERROR) != B_ERROR)
696 break;
697 /*
698 * If could not read - try next track.
699 */
700 cbp->cb_head++;
701 cbp->cb_sect = block;
702 }
703
704 /*
705 * If cannot read the first block of bad block list.
706 * give up and return.
707 */
708 if (bp->b_flags & B_ERROR) {
709 printf("zd%d: Cannot read block %d of bad block list.\n",
710 up - zdunit, block);
711 if (block == 0)
712 kmem_free(kernel_map, (vm_offset_t)zdp, DEV_BSIZE);
713 else
714 kmem_free(kernel_map, (vm_offset_t)zdp,
715 dbtob(size));
716 #ifndef MACH
717 buffree(bp);
718 #endif MACH
719 up->zu_zdbad = (struct zdbad *)NULL;
720 return (-1);
721 }
722 if (block == 0) {
723 size = (zdp->bz_nelem * sizeof(struct bz_bad))
724 + sizeof(struct zdbad) - sizeof(struct bz_bad);
725 size = howmany(size, DEV_BSIZE);
726 if (size > ((dd->zdd_sectors - ZDD_NDDSECTORS) >> 1)) {
727 printf("zd%d: Bad block list corrupted!\n",
728 up - zdunit);
729 kmem_free(kernel_map, (vm_offset_t)zdp,
730 DEV_BSIZE);
731 up->zu_zdbad = (struct zdbad *)NULL;
732 return (-1);
733 }
734 zdpsize = dbtob(size);
735 /*
736 * copy block 0 to new location in free memory, so
737 * that bad block list will be contiguous.
738 */
739 if (kmem_alloc(kernel_map,
740 (vm_offset_t *)&addr,
741 zdpsize) != KERN_SUCCESS)
742 panic("zdgetbad");
743 bcopy((caddr_t)zdp, addr, (unsigned)DEV_BSIZE);
744 kmem_free(kernel_map, (vm_offset_t)zdp, DEV_BSIZE);
745 zdp = (struct zdbad *)addr;
746 }
747 addr += DEV_BSIZE;
748 } /* end of for */
749
750 #ifndef MACH
751 /*
752 * done with I/O - free buf header.
753 */
754 buffree(bp);
755 #endif MACH
756
757 /*
758 * Confirm data integrity via checksum.
759 */
760 size = (zdp->bz_nelem * sizeof(struct bz_bad)) / sizeof(long);
761 if (zdp->bz_csn != getchksum((long *)zdp->bz_bad, size,
762 (long)(zdp->bz_nelem ^ zdp->bz_nsnf))) {
763 printf("zd%d: Checksum failed!\n", up - zdunit);
764 kmem_free(kernel_map, (vm_offset_t)zdp, zdpsize);
765 up->zu_zdbad = (struct zdbad *)NULL;
766 return (-1);
767 }
768
769 /*
770 * Copy only BZ_SNF entries into unit's bad block list.
771 *
772 * Calculate size of needed bad block list.
773 * That is, only BZ_SNF entries are needed.
774 */
775 size = (zdp->bz_nsnf * sizeof(struct bz_bad))
776 + sizeof(struct zdbad) - sizeof(struct bz_bad);
777 size = roundup(size, DEV_BSIZE);
778 if (kmem_alloc(kernel_map,
779 (vm_offset_t *)&up->zu_zdbad,
780 size) != KERN_SUCCESS)
781 panic("zdgetbad");
782 #ifdef DEBUG
783 bzero((caddr_t)up->zu_zdbad, (u_int)size);
784 #endif DEBUG
785 *up->zu_zdbad = *zdp;
786 tbzp = up->zu_zdbad->bz_bad;
787 for (fbzp = zdp->bz_bad; fbzp < &zdp->bz_bad[zdp->bz_nelem]; fbzp++) {
788 if (fbzp->bz_rtype == BZ_SNF)
789 *tbzp++ = *fbzp;
790 }
791 kmem_free(kernel_map, (vm_offset_t)zdp, zdpsize);
792 return (0);
793 }
794
795 /*
796 * zdstrat
797 * zd disk read/write routine.
798 * Perform various checks and queue request and call start routine to
799 * initiate I/O to the device.
800 */
801 zdstrat(bp)
802 register struct buf *bp;
803 {
804 register struct zd_unit *up;
805 register struct zdcdd *dd; /* channel configuration */
806 register int sector;
807 register int nspc;
808 struct zdsize *part;
809 struct diskaddr diskaddress;
810 spl_t s_ipl;
811
812 #ifdef DEBUG
813 if (zddebug > 1)
814 printf("zdstrat(%c): bp=%x, dev=%x, cnt=%d, blk=%x, vaddr=%x\n",
815 (bp->b_flags & B_READ) ? 'R' : 'W',
816 bp, bp->b_dev, bp->b_bcount, bp->b_blkno,
817 bp->b_un.b_addr);
818 else if (zddebug)
819 printf("%c", (bp->b_flags & B_READ) ? 'R' : 'W');
820 #endif DEBUG
821
822 up = &zdunit[ZDUNIT(bp->b_dev)];
823 /*
824 * Error if NO_RW operations are permitted.
825 */
826 if (up->zu_state == ZU_NO_RW) {
827 bp->b_flags |= B_ERROR;
828 bp->b_error = EIO;
829 bp->b_resid = bp->b_bcount;
830 biodone(bp);
831 return;
832 }
833
834 part = &zdparts[up->zu_drive_type][ZDPART(bp->b_dev)];
835 /*
836 * Size and partitioning check.
837 *
838 * Fail request if bogus byte count, if address not aligned to
839 * ADDRALIGN boundary, or if transfer is not entirely within a
840 * disk partition.
841 */
842 if (bp->b_bcount <= 0
843 || ((bp->b_bcount & (DEV_BSIZE -1)) != 0) /* size */
844 #ifdef MACH_KERNEL
845 || (
846 #else MACH_KERNEL
847 #ifndef MACH
848 || ((bp->b_iotype == B_RAWIO) &&
849 #else MACH
850 || ((bp->b_flags & B_PHYS) &&
851 #endif MACH
852 #endif MACH_KERNEL
853 (((int)bp->b_un.b_addr & (ADDRALIGN - 1)) != 0)) /* alignment */
854 || (bp->b_blkno < 0) /* partition */
855 || ((bp->b_blkno + btodb(bp->b_bcount)) > part->p_length)) {
856 bp->b_flags |= B_ERROR;
857 bp->b_error = EINVAL;
858 bp->b_resid = bp->b_bcount;
859 biodone(bp);
860 return;
861 }
862
863 dd = (up->zu_drive & 1) ? &zdctrlr[up->zu_ctrlr].zdc_chanB
864 : &zdctrlr[up->zu_ctrlr].zdc_chanA;
865 nspc = dd->zdd_sectors * dd->zdd_tracks;
866 sector = bp->b_blkno;
867 #if 1
868 { /* gcc bug workaround */
869 int temp;
870 u_short temp2;
871 temp = sector / nspc + part->p_cyloff;
872 temp2 = temp & 0xFFFF;
873 diskaddress.da_cyl = temp2;
874 }
875 #else
876 diskaddress.da_cyl = sector / nspc + part->p_cyloff;
877 #endif
878 sector %= nspc;
879 diskaddress.da_head = sector / dd->zdd_sectors;
880 diskaddress.da_sect = sector % dd->zdd_sectors;
881 bp->b_diskaddr = *(long *)&diskaddress;
882 bp->b_psect = zdgetpsect(&diskaddress, dd);
883
884 s_ipl = p_lock(&up->zu_lock, SPLZD);
885 if (up->zu_state == ZU_BAD) {
886 v_lock(&up->zu_lock, s_ipl);
887 /*
888 * Controller/channel/Drive has gone bad!
889 */
890 bp->b_flags |= B_ERROR;
891 bp->b_error = EIO;
892 bp->b_resid = bp->b_bcount;
893 biodone(bp);
894 return;
895 }
896 disksort(&up->zu_bhead, bp);
897 zdstart(up);
898 v_lock(&up->zu_lock, s_ipl);
899 }
900
901 /*
902 * zdgetpsect
903 * Determine physical sector in track where the I/O transfer is to
904 * occur. Used by ZDC firmware for RPS optimization.
905 */
906 int
907 zdgetpsect(dp, dd)
908 register struct diskaddr *dp;
909 register struct zdcdd *dd;
910 {
911 if (dd->zdd_tskew == 1)
912 return (( ((dd->zdd_tracks - 1 + dd->zdd_cskew) * dp->da_cyl)
913 + dp->da_head + dp->da_sect)
914 % (dd->zdd_sectors + dd->zdd_spare));
915 /*
916 * track skew != 1
917 */
918 return (( (((dd->zdd_tskew*(dd->zdd_tracks-1)) + dd->zdd_cskew)
919 * dp->da_cyl)
920 + (dd->zdd_tskew*dp->da_head) + dp->da_sect)
921 % (dd->zdd_sectors + dd->zdd_spare));
922 }
923
924 /*
925 * zdfill_iovec
926 * - fill out cb_iovec for the I/O request.
927 *
928 * B_RAWIO, B_PTEIO, B_PTBIO cases must flush TLB to avoid stale mappings
929 * thru Usrptmap[], since this is callable from interrupt procedures (SGS only).
930 *
931 * Panics if bad pte found; "can't" happen.
932 */
933
934 #ifndef MACH
935
936 static u_int
937 zdfill_iovec(bp, iovstart)
938 #ifndef i386
939 register /* want optimial on 032's */
940 #endif
941 struct buf *bp;
942 u_int *iovstart;
943 {
944 register struct pte *pte;
945 register int count;
946 register u_int *iovp;
947 u_int retval;
948 unsigned offset;
949 extern struct pte *vtopte();
950
951 /*
952 * Source/target pte's are found differently based on type
953 * of IO operation.
954 */
955 switch(bp->b_iotype) {
956
957 case B_RAWIO: /* RAW IO */
958 /*
959 * In this case, must look into alignment of physical
960 * memory, since we can start on any ADDRALIGN boundary.
961 */
962 flush_tlb();
963 pte = vtopte(bp->b_proc, clbase(btop(bp->b_un.b_addr)));
964 count = (((int)bp->b_un.b_addr & CLOFSET) + bp->b_bcount
965 + CLOFSET) / CLBYTES;
966 retval = (u_int)bp->b_un.b_addr;
967 break;
968
969 case B_FILIO: /* file-sys IO */
970 /*
971 * Filesys/buffer-cache IO. These are always cluster aligned
972 * both physically and virtually.
973 * Note: also used when to kernel memory acquired via wmemall().
974 * For example, channel configuration buffer in zdget_chancfg().
975 */
976 pte = &Sysmap[btop(bp->b_un.b_addr)];
977 count = (bp->b_bcount + CLOFSET) / CLBYTES;
978 retval = (u_int)bp->b_un.b_addr;
979 break;
980
981 case B_PTEIO: /* swap/page IO */
982 /*
983 * Pte-based IO -- already know pte of 1st page, which
984 * is cluster aligned, and b_count is a multiple of CLBYTES.
985 */
986 flush_tlb();
987 pte = bp->b_un.b_pte;
988 count = (bp->b_bcount + CLOFSET) / CLBYTES;
989 retval = PTETOPHYS(*pte);
990 break;
991
992 case B_PTBIO: /* Page-Table IO */
993 /*
994 * Page-Table IO: like B_PTEIO, but can start/end with
995 * non-cluster aligned memory (but is always HW page
996 * aligned). Count is multiple of NBPG.
997 *
998 * Separate case for greater efficiency in B_PTEIO.
999 */
1000 flush_tlb();
1001 pte = bp->b_un.b_pte;
1002 retval = PTETOPHYS(*pte);
1003 offset = PTECLOFF(*pte);
1004 pte -= btop(offset);
1005 count = (offset + bp->b_bcount + CLOFSET) / CLBYTES;
1006 break;
1007
1008 default:
1009 panic("zdfill_iovec: bad b_iotype");
1010 /*NOTREACHED*/
1011 }
1012
1013 /*
1014 * Now translate PTEs and fill-in iovectors.
1015 */
1016 iovp = iovstart;
1017 while (count--) {
1018 *iovp++ = PTETOPHYS(*pte);
1019 pte += CLSIZE;
1020 }
1021 return (retval);
1022 }
1023
1024 #else MACH
1025
1026 #ifdef MACH_KERNEL
1027 /*
1028 * pure Mach kernel version.
1029 */
1030 static u_int
1031 zdfill_iovec(bp, iovp)
1032 register struct buf *bp;
1033 register u_int *iovp;
1034 {
1035 register pt_entry_t *pte;
1036 register int count;
1037 vm_offset_t start, end;
1038
1039 /*
1040 * In this case, must look into alignment of physical
1041 * memory, since we can start on any ADDRALIGN boundary.
1042 *
1043 * Since ptes mapping kernel address space are contiguous in
1044 * kernel address space, can bump pte inside loop.
1045 */
1046
1047 start = i386_trunc_page((vm_offset_t)bp->b_un.b_addr);
1048 end = i386_round_page((vm_offset_t)bp->b_un.b_addr + bp->b_bcount);
1049 pte = pmap_pte(kernel_pmap, start);
1050 count = i386_btop(end - start);
1051 while (count--) {
1052 *iovp++ = pte_to_pa(*pte);
1053 pte++;
1054 }
1055 return((u_int)bp->b_un.b_addr);
1056 }
1057 #else MACH_KERNEL
1058 /*
1059 * MACH version.
1060 */
1061 static u_int
1062 zdfill_iovec(bp, iovp)
1063 register struct buf *bp;
1064 register u_int *iovp;
1065 {
1066 register struct pte *pte;
1067 register int count;
1068
1069 if (bp->b_flags & B_PHYS) {
1070 /*
1071 * In this case, must look into alignment of physical
1072 * memory, since we can start on any ADDRALIGN boundary.
1073 *
1074 * Since pte's mapping user task can be dis-contiguous in
1075 * kernel address space, need to re-compute pte inside loop.
1076 */
1077 vm_offset_t addr;
1078 pmap_t map;
1079
1080 addr = ((vm_offset_t)bp->b_un.b_addr & ~CLOFSET) | VA_USER;
1081 map = vm_map_pmap(bp->b_proc->task->map);
1082 count = (((int)bp->b_un.b_addr & CLOFSET) + bp->b_bcount
1083 + CLOFSET) / CLBYTES;
1084 while (count--) {
1085 pte = (struct pte *) pmap_pte(map, addr);
1086 *iovp++ = PTETOPHYS(*pte);
1087 addr += CLBYTES;
1088 }
1089 } else {
1090 /*
1091 * Filesys/buffer-cache IO. These are always cluster aligned
1092 * both physically and virtually.
1093 * Note: also used on kernel memory acquired via wmemall().
1094 * For example, channel configuration buffer in zdget_chancfg().
1095 *
1096 * Since pte's mapping kernel address space are contiguous
1097 * virtually, can bump pte inside loop.
1098 */
1099 pte = &Sysmap[btop(bp->b_un.b_addr)];
1100 count = (bp->b_bcount + CLOFSET) / CLBYTES;
1101 while (count--) {
1102 *iovp++ = PTETOPHYS(*pte);
1103 pte += CLSIZE;
1104 }
1105 }
1106 return((u_int)bp->b_un.b_addr);
1107 }
1108 #endif MACH_KERNEL
1109 #endif MACH
1110
1111 /*
1112 * zdstart
1113 * - intitiate I/O request to controller.
1114 * If controller is busy just return. Otherwise stuff appropriate CB
1115 * with request and notify ZDC.
1116 *
1117 * Called with unit structure locked at SPLZD.
1118 */
1119 zdstart(up)
1120 register struct zd_unit *up;
1121 {
1122 register struct cb *cbp;
1123 register struct buf *bp;
1124 register struct zdc_ctlr *ctlrp;
1125 spl_t s_ipl;
1126
1127 #ifdef DEBUG
1128 if (zddebug)
1129 printf("S");
1130 #endif DEBUG
1131 bp = up->zu_bhead.av_forw;
1132 ctlrp = &zdctrlr[up->zu_ctrlr];
1133 cbp = up->zu_cbptr;
1134 if (cbp->cb_bp == NULL && cbp[1].cb_bp == NULL) {
1135 /*
1136 * Drive is idle.
1137 * If fp_lights - turn activity light on.
1138 * Get starting time.
1139 */
1140 if (fp_lights) {
1141 s_ipl = splhi();
1142 FP_IO_ACTIVE;
1143 splx(s_ipl);
1144 }
1145 up->zu_starttime = time;
1146 }
1147 if (cbp->cb_bp == NULL || cbp[1].cb_bp == NULL) {
1148 /*
1149 * Fill CB.
1150 */
1151 if (cbp->cb_bp)
1152 ++cbp;
1153 if (bp->b_flags & B_IOCTL) {
1154 /*
1155 * copy 1st half of cb (what fw will see)
1156 */
1157 bcopy((caddr_t)&up->zu_ioctlcb, (caddr_t)cbp, FWCBSIZE);
1158 if (cbp->cb_cmd != ZDC_READ_LRAM
1159 && cbp->cb_cmd != ZDC_WRITE_LRAM)
1160 cbp->cb_addr = zdfill_iovec(bp, cbp->cb_iovstart);
1161 } else {
1162 *(long *)&cbp->cb_diskaddr = bp->b_diskaddr;
1163 cbp->cb_psect = (u_char)bp->b_psect;
1164 cbp->cb_count = bp->b_bcount;
1165 cbp->cb_mod = 0;
1166 cbp->cb_cmd = (bp->b_flags & B_READ) ? ZDC_READ : ZDC_WRITE;
1167 cbp->cb_addr = zdfill_iovec(bp, cbp->cb_iovstart);
1168 #ifdef MACH_KERNEL
1169 bp->b_error = 0; /* was b_psect */
1170 #endif /* MACH_KERNEL */
1171 }
1172 bp->b_resid = bp->b_bcount;
1173 cbp->cb_transfrd = 0;
1174 cbp->cb_bp = bp;
1175 cbp->cb_errcnt = 0;
1176 cbp->cb_state = ZD_NORMAL;
1177 cbp->cb_iovec = KVTOPHYS(cbp->cb_iovstart, u_int *);
1178 /*
1179 * Notify ZDC of job request.
1180 */
1181 #ifdef DEBUG
1182 if (zddebug > 2)
1183 zddumpcb(cbp);
1184 #endif DEBUG
1185 NUDGE_ZDC(ctlrp, cbp, s_ipl);
1186 up->zu_bhead.av_forw = bp->av_forw;
1187 bp = bp->av_forw;
1188 cbp = up->zu_cbptr;
1189 }
1190 }
1191
1192 /*
1193 * zdintr
1194 * Normal request completion interrupt handler.
1195 */
1196 zdintr(vector)
1197 u_char vector;
1198 {
1199 register struct cb *cbp;
1200 register struct zd_unit *up;
1201 register struct buf *donebp;
1202 register struct zdc_ctlr *ctlrp;
1203 struct zdcdd *dd;
1204 int zdcvec;
1205 daddr_t blkno;
1206 int i;
1207 int partition;
1208 u_char val;
1209 spl_t s_ipl;
1210
1211 #ifdef DEBUG
1212 if (zddebug)
1213 printf("I");
1214 #endif DEBUG
1215 zdcvec = vector - base_cb_intr;
1216 ctlrp = &zdctrlr[zdcvec >> NCBZDCSHFT];
1217 cbp = ctlrp->zdc_cbp + (zdcvec & (NCBPERZDC-1));
1218 up = &zdunit[cbp->cb_unit];
1219 if (cbp->cb_bp == NULL) {
1220 if (ctlrp->zdc_state == ZDC_DEAD) {
1221 printf("zdc%d drive %d: Spurious interrupt from dead controller.\n",
1222 ctlrp - zdctrlr,
1223 (cbp - ctlrp->zdc_cbp) / NCBPERDRIVE);
1224 return;
1225 }
1226 if (cbp->cb_unit < 0) {
1227 printf("zdc%d drive %d: Interrupt from unknown unit.\n",
1228 ctlrp - zdctrlr,
1229 (cbp - ctlrp->zdc_cbp) / NCBPERDRIVE);
1230 return;
1231 }
1232 printf("zd%d: Spurious interrupt.\n", cbp->cb_unit);
1233 return;
1234 }
1235
1236 /*
1237 * Separate normal case from error cases for performance.
1238 */
1239 if (cbp->cb_compcode == ZDC_DONE) {
1240 if (cbp->cb_state == ZD_NORMAL) {
1241 donebp = cbp->cb_bp;
1242 donebp->b_resid = 0;
1243 goto donext;
1244 }
1245 if (cbp->cb_state & ZD_RESET) {
1246 /*
1247 * Reset completed.
1248 */
1249 cbp->cb_state &= ~ZD_RESET;
1250 if (cbp->cb_errcnt++ < zdcretry) {
1251 zdretry(cbp, up, ctlrp);
1252 return;
1253 }
1254 /*
1255 * Fail I/O request.
1256 */
1257 donebp = cbp->cb_bp;
1258 donebp->b_flags |= B_ERROR;
1259 donebp->b_error = EIO;
1260 goto donext;
1261 }
1262 if (cbp->cb_state & ZD_REVECTOR) {
1263 /*
1264 * Completed revector. Continue with rest of transfer.
1265 */
1266 zdcontinue(cbp, up, ctlrp);
1267 return;
1268 }
1269 }
1270
1271 /*
1272 * E R R O R O C C U R R E D !
1273 */
1274
1275 /*
1276 * If not doing retry reset or revectoring, update b_resid.
1277 */
1278 if (cbp->cb_state == ZD_NORMAL)
1279 cbp->cb_bp->b_resid = cbp->cb_count;
1280
1281 blkno = btodb(cbp->cb_bp->b_bcount - cbp->cb_bp->b_resid)
1282 + cbp->cb_bp->b_blkno;
1283
1284 if (cbp->cb_state & ZD_RESET) {
1285 /*
1286 * Error occurred during attempted reset for previous
1287 * error. Give up and shutdown the drive.
1288 */
1289 s_ipl = p_lock(&zdcprlock, SPLZD);
1290 printf("zd%d: Reset Failed.\n", cbp->cb_unit);
1291 if (cbp->cb_compcode >= zdncompcodes) {
1292 printf("zd%d: Bad cb_compcode 0x%x.\n",
1293 cbp->cb_unit, cbp->cb_compcode);
1294 cbp->cb_compcode = zdncompcodes - 1;
1295 }
1296 zd_hard_error(cbp, blkno);
1297 zddumpstatus(cbp);
1298 v_lock(&zdcprlock, s_ipl);
1299 zdshutdrive(up);
1300 } else switch (cbp->cb_compcode) {
1301
1302 /*
1303 * Command completed successfully but an ecc error occurred.
1304 */
1305 case ZDC_SOFTECC:
1306 case ZDC_CORRECC:
1307 /*
1308 * Corrected or Soft ECC error.
1309 */
1310 dd = (up->zu_drive & 1) ? &ctlrp->zdc_chanB : &ctlrp->zdc_chanA;
1311 blkno = cbp->cb_cyl
1312 - zdparts[up->zu_drive_type][ZDPART(cbp->cb_bp->b_dev)].p_cyloff;
1313 blkno *= (dd->zdd_sectors * dd->zdd_tracks);
1314 blkno += (cbp->cb_head * dd->zdd_sectors);
1315 blkno += cbp->cb_sect;
1316 s_ipl = p_lock(&zdcprlock, SPLZD);
1317 printf("zd%d%c: %s at (%d, %d, %d).\n",
1318 cbp->cb_unit, PARTCHR(cbp->cb_bp->b_dev),
1319 zd_compcodes[cbp->cb_compcode],
1320 cbp->cb_cyl, cbp->cb_head, cbp->cb_sect);
1321 printf("zd%d%c: Filesystem blkno = %d.\n", cbp->cb_unit,
1322 PARTCHR(cbp->cb_bp->b_dev), blkno);
1323 zddumpstatus(cbp);
1324 v_lock(&zdcprlock, s_ipl);
1325 if (cbp->cb_state & ZD_REVECTOR) {
1326 /*
1327 * Completed revector. Continue with rest of transfer.
1328 */
1329 zdcontinue(cbp, up, ctlrp);
1330 return;
1331 }
1332 donebp = cbp->cb_bp;
1333 goto donext; /* Not fatal */
1334
1335 /*
1336 * Fail the job immediately - no retries.
1337 */
1338 case ZDC_DRVPROT:
1339 case ZDC_ECC:
1340 s_ipl = p_lock(&zdcprlock, SPLZD);
1341 zd_hard_error(cbp, blkno);
1342 zddumpstatus(cbp);
1343 v_lock(&zdcprlock, s_ipl);
1344 break;
1345
1346 case ZDC_CH_RESET: /* Shutdown drive */
1347 case ZDC_BADDRV:
1348 case ZDC_DDC_STAT:
1349 s_ipl = p_lock(&zdcprlock, SPLZD);
1350 zd_hard_error(cbp, blkno);
1351 zddumpstatus(cbp);
1352 v_lock(&zdcprlock, s_ipl);
1353 zdshutdrive(up);
1354 break;
1355
1356 case ZDC_DMA_TO: /* Shutdown Channel */
1357 s_ipl = p_lock(&zdcprlock, SPLZD);
1358 zd_hard_error(cbp, blkno);
1359 v_lock(&zdcprlock, s_ipl);
1360 zdshutchan(ctlrp, up->zu_drive & 1);
1361 break;
1362
1363 case ZDC_NOCFG:
1364 if (cbp->cb_cmd == ZDC_GET_CHANCFG) {
1365 donebp = cbp->cb_bp;
1366 goto donext; /* Not an error */
1367 }
1368 /*
1369 * FW assumed insane...
1370 */
1371 case ZDC_REVECT: /* FW hosed - shutdown controller */
1372 case ZDC_ILLVECIO:
1373 case ZDC_ILLPGSZ:
1374 case ZDC_ILLDUMPADR:
1375 s_ipl = p_lock(&zdcprlock, SPLZD);
1376 zd_hard_error(cbp, blkno);
1377 zddumpstatus(cbp); /* for ZDC_REVECT */
1378 v_lock(&zdcprlock, s_ipl);
1379 zdshutctlr(ctlrp);
1380 break;
1381
1382 default:
1383 /*
1384 * Unknown completion code - controller bad?
1385 */
1386 s_ipl = p_lock(&zdcprlock, SPLZD);
1387 printf("zd%d: Bad cb_compcode 0x%x.\n",
1388 cbp->cb_unit, cbp->cb_compcode);
1389 cbp->cb_compcode = zdncompcodes - 1; /* nice message */
1390 zd_hard_error(cbp, blkno);
1391 v_lock(&zdcprlock, s_ipl);
1392 zdshutctlr(ctlrp);
1393 break;
1394
1395 case ZDC_ILLCMD:
1396 s_ipl = p_lock(&zdcprlock, SPLZD);
1397 zd_hard_error(cbp, blkno);
1398 if (cbp->cb_cmd == 0 || cbp->cb_cmd > ZDC_MAXCMD) {
1399 printf("zd%d: cb_cmd 0x%x corrupted.\n",
1400 cbp->cb_unit, cbp->cb_cmd);
1401 v_lock(&zdcprlock, s_ipl);
1402 panic("zdintr: cb corrupted");
1403 }
1404 v_lock(&zdcprlock, s_ipl);
1405 /*
1406 * Cb looks ok - assume controller unreliable
1407 */
1408 zdshutctlr(ctlrp);
1409 break;
1410
1411 case ZDC_ILLMOD:
1412 s_ipl = p_lock(&zdcprlock, SPLZD);
1413 zd_hard_error(cbp, blkno);
1414 switch(cbp->cb_cmd) {
1415
1416 case ZDC_READ:
1417 case ZDC_READ_SS:
1418 case ZDC_READ_HDRS:
1419 case ZDC_LONG_READ:
1420 case ZDC_REC_DATA:
1421 if (cbp->cb_mod != up->zu_ioctlcb.cb_mod) {
1422 printf("zd%d: cb_mod 0x%x corrupted.\n",
1423 cbp->cb_unit, cbp->cb_mod);
1424 v_lock(&zdcprlock, s_ipl);
1425 panic("zdintr: cb corrupted");
1426 }
1427 }
1428 v_lock(&zdcprlock, s_ipl);
1429 /*
1430 * Cb looks ok - assume controller unreliable
1431 */
1432 zdshutctlr(ctlrp);
1433 break;
1434
1435 case ZDC_ILLALIGN:
1436 s_ipl = p_lock(&zdcprlock, SPLZD);
1437 zd_hard_error(cbp, blkno);
1438 if ((cbp->cb_addr & (ADDRALIGN - 1)) != 0) {
1439 printf("zd%d: cb_addr 0x%x corrupted.\n",
1440 cbp->cb_unit, cbp->cb_addr);
1441 v_lock(&zdcprlock, s_ipl);
1442 panic("zdintr: cb corrupted");
1443 }
1444 v_lock(&zdcprlock, s_ipl);
1445 /*
1446 * Cb looks ok - assume controller unreliable
1447 */
1448 zdshutctlr(ctlrp);
1449 break;
1450
1451 case ZDC_ILLCNT:
1452 s_ipl = p_lock(&zdcprlock, SPLZD);
1453 zd_hard_error(cbp, blkno);
1454 if (cbp->cb_count == 0 || (cbp->cb_count & (CNTMULT-1)) != 0) {
1455 printf("zd%d: cb_count 0x%x corrupted.\n",
1456 cbp->cb_unit, cbp->cb_count);
1457 v_lock(&zdcprlock, s_ipl);
1458 panic("zdintr: cb corrupted");
1459 }
1460 v_lock(&zdcprlock, s_ipl);
1461 /*
1462 * Cb looks ok - assume controller unreliable
1463 */
1464 zdshutctlr(ctlrp);
1465 break;
1466
1467 case ZDC_ILLIOV:
1468 s_ipl = p_lock(&zdcprlock, SPLZD);
1469 zd_hard_error(cbp, blkno);
1470 if (((u_int)cbp->cb_iovec & (IOVALIGN - 1)) != 0) {
1471 printf("zd%d: cb_iovec 0x%x corrupted.\n",
1472 cbp->cb_unit, cbp->cb_iovec);
1473 v_lock(&zdcprlock, s_ipl);
1474 panic("zdintr: cb corrupted");
1475 }
1476 v_lock(&zdcprlock, s_ipl);
1477 /*
1478 * Cb looks ok - assume controller unreliable
1479 */
1480 zdshutctlr(ctlrp);
1481 break;
1482
1483 case ZDC_ILLCHS:
1484 s_ipl = p_lock(&zdcprlock, SPLZD);
1485 zd_hard_error(cbp, blkno);
1486 dd = (up->zu_drive & 1) ? &ctlrp->zdc_chanB : &ctlrp->zdc_chanA;
1487 if (cbp->cb_cyl >= dd->zdd_cyls ||
1488 cbp->cb_head >= dd->zdd_tracks ||
1489 cbp->cb_sect >= dd->zdd_sectors + dd->zdd_spare) {
1490 printf("zd%d: cb_diskaddr (%d, %d, %d) corrupted.\n",
1491 cbp->cb_unit,
1492 cbp->cb_cyl, cbp->cb_head, cbp->cb_sect);
1493 v_lock(&zdcprlock, s_ipl);
1494 panic("zdintr: cb corrupted");
1495 }
1496 v_lock(&zdcprlock, s_ipl);
1497 /*
1498 * Cb looks ok - assume controller unreliable
1499 */
1500 zdshutctlr(ctlrp);
1501 break;
1502
1503 case ZDC_CBREUSE:
1504 printf("zd%d: CBREUSE error cb = 0x%x\n", cbp->cb_unit, cbp);
1505 panic("zdc: ZDC_CBREUSE error");
1506
1507 case ZDC_ACCERR:
1508 s_ipl = splhi();
1509 val = rdslave(ctlrp->zdc_slicaddr,
1510 (u_char)((up->zu_drive & 1) ? SL_G_ACCERR1
1511 : SL_G_ACCERR0));
1512 printf("zd%d: Access error on transfer starting at physical address 0x%x.\n",
1513 cbp->cb_unit, cbp->cb_addr);
1514 access_error(val);
1515 val = ~val;
1516 if (((val & SLB_ATMSK) == SLB_AEFATAL) &&
1517 ((val & SLB_AEIO) != SLB_AEIO)) {
1518 /*
1519 * Uncorrectable memory error!
1520 * Clear access error to restart controller and
1521 * panic the system.
1522 */
1523 wrslave(ctlrp->zdc_slicaddr,
1524 (u_char)((up->zu_drive & 1) ? SL_G_ACCERR1
1525 : SL_G_ACCERR0),
1526 (u_char)0xbb);
1527 panic("zdc access error");
1528 }
1529 splx(s_ipl);
1530
1531 /*
1532 * Shutdown the channel and restart the controller.
1533 */
1534 zdshutchan(ctlrp, up->zu_drive & 1);
1535 s_ipl = splhi();
1536 wrslave(ctlrp->zdc_slicaddr,
1537 (u_char)((up->zu_drive & 1) ? SL_G_ACCERR1
1538 : SL_G_ACCERR0),
1539 (u_char)0xbb);
1540 splx(s_ipl);
1541 break;
1542
1543 case ZDC_CH_TO: /* Retry without reset */
1544 case ZDC_FDL:
1545 s_ipl = p_lock(&zdcprlock, SPLZD);
1546 if (cbp->cb_errcnt++ < zdcretry) {
1547 #ifdef DEBUG
1548 zddumpcb(cbp);
1549 #endif DEBUG
1550 printf("zd%d%c: Error (%s); cmd 0x%x at (%d, %d, %d).\n",
1551 cbp->cb_unit, PARTCHR(cbp->cb_bp->b_dev),
1552 zd_compcodes[cbp->cb_compcode],
1553 cbp->cb_cmd, cbp->cb_cyl, cbp->cb_head,
1554 cbp->cb_sect);
1555 printf("zd%d%c: Filesystem blkno = %d.\n", cbp->cb_unit,
1556 PARTCHR(cbp->cb_bp->b_dev), blkno);
1557 zddumpstatus(cbp);
1558 v_lock(&zdcprlock, s_ipl);
1559 zdretry(cbp, up, ctlrp);
1560 return;
1561 }
1562 /*
1563 * Exceeded retry count.
1564 * Shutdown the channel.
1565 */
1566 zd_hard_error(cbp, blkno);
1567 zddumpstatus(cbp);
1568 v_lock(&zdcprlock, s_ipl);
1569 zdshutchan(ctlrp, up->zu_drive & 1);
1570 break;
1571
1572 case ZDC_DRVFLT:
1573 /*
1574 * cb_count and cb_diskaddr are unreliable on drive fault
1575 * so retry entire request.
1576 */
1577 cbp->cb_bp->b_resid = cbp->cb_bp->b_bcount - cbp->cb_transfrd;
1578 blkno = btodb(cbp->cb_bp->b_bcount - cbp->cb_bp->b_resid)
1579 + cbp->cb_bp->b_blkno;
1580 dd = (up->zu_drive & 1) ? &ctlrp->zdc_chanB : &ctlrp->zdc_chanA;
1581 i = blkno;
1582 partition = ZDPART(cbp->cb_bp->b_dev);
1583 #if 1
1584 { /* gcc bug workaround */
1585 int temp;
1586 short temp2;
1587 temp =
1588 i / (dd->zdd_sectors * dd->zdd_tracks) +
1589 zdparts[up->zu_drive_type][partition].p_cyloff;
1590 temp2 = temp;
1591 cbp->cb_diskaddr.da_cyl = temp2;
1592 }
1593 #else
1594 cbp->cb_diskaddr.da_cyl =
1595 i / (dd->zdd_sectors * dd->zdd_tracks) +
1596 zdparts[up->zu_drive_type][partition].p_cyloff;
1597 #endif
1598 i %= (dd->zdd_sectors * dd->zdd_tracks);
1599 cbp->cb_diskaddr.da_head = i / dd->zdd_sectors;
1600 cbp->cb_diskaddr.da_sect = i % dd->zdd_sectors;
1601 /* Fall into */
1602 case ZDC_SEEKERR: /* reset and retry */
1603 case ZDC_SEEK_TO:
1604 s_ipl = p_lock(&zdcprlock, SPLZD);
1605 if (cbp->cb_errcnt < zdcretry) {
1606 #ifdef DEBUG
1607 zddumpcb(cbp);
1608 #endif DEBUG
1609 printf("zd%d%c: Error (%s); cmd 0x%x at (%d, %d, %d).\n",
1610 cbp->cb_unit, PARTCHR(cbp->cb_bp->b_dev),
1611 zd_compcodes[cbp->cb_compcode],
1612 cbp->cb_cmd, cbp->cb_cyl, cbp->cb_head,
1613 cbp->cb_sect);
1614 printf("zd%d%c: Filesystem blkno = %d.\n", cbp->cb_unit,
1615 PARTCHR(cbp->cb_bp->b_dev), blkno);
1616 zddumpstatus(cbp);
1617 v_lock(&zdcprlock, s_ipl);
1618 /*
1619 * reset drive
1620 */
1621 cbp->cb_state |= ZD_RESET;
1622 cbp->cb_cmd = ZDC_RESET;
1623 NUDGE_ZDC(ctlrp, cbp, s_ipl);
1624 return;
1625 }
1626
1627 /*
1628 * Exceeded retry count.
1629 * Shutdown the drive.
1630 */
1631 zd_hard_error(cbp, blkno);
1632 zddumpstatus(cbp);
1633 v_lock(&zdcprlock, s_ipl);
1634 zdshutdrive(up);
1635 break;
1636
1637 case ZDC_SNF: /* Revector request */
1638 if (zdrevector(cbp, up, ctlrp))
1639 return;
1640 /* else fall into... */
1641 case ZDC_HDR_ECC: /* Reset and retry */
1642 case ZDC_SO:
1643 case ZDC_NDS:
1644 s_ipl = p_lock(&zdcprlock, SPLZD);
1645 if (cbp->cb_errcnt == zdcretry)
1646 zd_hard_error(cbp, blkno);
1647 else {
1648 #ifdef DEBUG
1649 zddumpcb(cbp);
1650 #endif DEBUG
1651 printf("zd%d%c: Error (%s); cmd 0x%x at (%d, %d, %d).\n",
1652 cbp->cb_unit, PARTCHR(cbp->cb_bp->b_dev),
1653 zd_compcodes[cbp->cb_compcode],
1654 cbp->cb_cmd, cbp->cb_cyl, cbp->cb_head,
1655 cbp->cb_sect);
1656 printf("zd%d%c: Filesystem blkno = %d.\n", cbp->cb_unit,
1657 PARTCHR(cbp->cb_bp->b_dev), blkno);
1658 }
1659 zddumpstatus(cbp);
1660 v_lock(&zdcprlock, s_ipl);
1661 cbp->cb_state |= ZD_RESET;
1662 cbp->cb_cmd = ZDC_RESET;
1663 NUDGE_ZDC(ctlrp, cbp, s_ipl);
1664 return;
1665
1666 } /* end of switch */
1667
1668 /*
1669 * Fail this I/O request
1670 */
1671 donebp = cbp->cb_bp;
1672 donebp->b_flags |= B_ERROR;
1673 donebp->b_error = EIO;
1674
1675 donext:
1676 #ifdef DEBUG
1677 if (zddebug > 2)
1678 zddumpcb(cbp);
1679 #endif DEBUG
1680 if (donebp->b_flags & B_IOCTL) {
1681 bcopy((caddr_t)cbp, (caddr_t)&up->zu_ioctlcb, FWCBSIZE);
1682 }
1683 /*
1684 * If more requests - start them.
1685 */
1686 s_ipl = p_lock(&up->zu_lock, SPLZD);
1687 cbp->cb_bp = NULL;
1688 if (up->zu_bhead.av_forw != NULL) {
1689 zdstart(up);
1690 } else {
1691 if (up->zu_cbptr->cb_bp == NULL
1692 && up->zu_cbptr[1].cb_bp == NULL) {
1693 /*
1694 * Going idle.
1695 * Get elapsed time and decrement I/O activity.
1696 */
1697 #ifndef MACH
1698 if (up->zu_dkstats) {
1699 struct timeval elapsed;
1700
1701 elapsed = time;
1702 timevalsub(&elapsed, &up->zu_starttime);
1703 timevaladd(&up->zu_dkstats->dk_time, &elapsed);
1704 }
1705 #endif MACH
1706 if (fp_lights) {
1707 s_ipl = splhi();
1708 FP_IO_INACTIVE;
1709 splx(s_ipl);
1710 }
1711 }
1712 }
1713 v_lock(&up->zu_lock, s_ipl);
1714
1715 /*
1716 * Gather stats
1717 * Note: no attempt to mutex...
1718 */
1719 #ifndef MACH
1720 if (up->zu_dkstats) {
1721 up->zu_dkstats->dk_xfer++;
1722 up->zu_dkstats->dk_blks +=
1723 btodb(donebp->b_bcount - donebp->b_resid);
1724 }
1725 #endif MACH
1726 biodone(donebp);
1727 }
1728
1729 /*
1730 * zd_hard_error
1731 * report hard error
1732 */
1733 zd_hard_error(cbp, blkno)
1734 register struct cb *cbp;
1735 daddr_t blkno;
1736 {
1737 #ifdef DEBUG
1738 zddumpcb(cbp);
1739 #endif DEBUG
1740 printf("zd%d%c: Hard Error (%s); cmd 0x%x at (%d, %d, %d).\n",
1741 cbp->cb_unit, PARTCHR(cbp->cb_bp->b_dev),
1742 zd_compcodes[cbp->cb_compcode], cbp->cb_cmd,
1743 cbp->cb_cyl, cbp->cb_head, cbp->cb_sect);
1744 printf("zd%d%c: Filesystem blkno = %d.\n", cbp->cb_unit,
1745 PARTCHR(cbp->cb_bp->b_dev), blkno);
1746 }
1747
1748 /*
1749 * zdgetrpl()
1750 * Search bad block list for replacement sector for bad sector (SNF).
1751 *
1752 * Return:
1753 * pointer to replacement sector
1754 * otherwise NULL pointer if no replacement sector found.
1755 *
1756 */
1757 static struct diskaddr *
1758 zdgetrpl(badsect, zdp)
1759 register struct diskaddr *badsect;
1760 register struct zdbad *zdp;
1761 {
1762 register struct bz_bad *bb;
1763
1764 bb = zdp->bz_bad;
1765 for (bb = zdp->bz_bad; bb < &zdp->bz_bad[zdp->bz_nsnf]; bb++) {
1766 if (bb->bz_cyl < badsect->da_cyl)
1767 continue;
1768 if (bb->bz_cyl > badsect->da_cyl)
1769 break;
1770 /* cylinder matched */
1771 if (bb->bz_head < badsect->da_head)
1772 continue;
1773 if (bb->bz_head > badsect->da_head)
1774 break;
1775 /* head matched */
1776 if (bb->bz_sect == badsect->da_sect)
1777 return (&bb->bz_rpladdr);
1778 }
1779 return (NULL);
1780 }
1781
1782 /*
1783 * zdrevector
1784 * Attempt to revector the sector-not-found.
1785 * If the sector-not-found is in the bad block list perform the I/O on
1786 * its replacement sector. Then continue with the following sector if
1787 * necessary.
1788 *
1789 * Return values:
1790 * 0 - No replacement sector in bad block list.
1791 * 1 - Replacement sector found in bad block list.
1792 */
1793 int
1794 zdrevector(cbp, up, ctlrp)
1795 register struct cb *cbp;
1796 struct zd_unit *up;
1797 struct zdc_ctlr *ctlrp;
1798 {
1799 register struct zdcdd *dd; /* disk description */
1800 register struct diskaddr *replcmnt; /* replacement address */
1801 register int count; /* # bytes of iovecs */
1802 int transfrd; /* bytes already transferred */
1803 int cbcount;
1804 u_int *from;
1805 spl_t s_ipl;
1806
1807 #ifdef DEBUG
1808 if (zddebug)
1809 printf("zd%d: revectoring (%d, %d, %d)", cbp->cb_unit,
1810 cbp->cb_cyl, cbp->cb_head, cbp->cb_sect);
1811 #endif DEBUG
1812 /*
1813 * Determine if bad block is in bad block list.
1814 */
1815 replcmnt = zdgetrpl(&cbp->cb_diskaddr, up->zu_zdbad);
1816 if (replcmnt == NULL) {
1817 /*
1818 * Not in bad block list. Caller should retry
1819 * bad block.
1820 */
1821 #ifdef DEBUG
1822 if (zddebug)
1823 printf(": not in table.\n");
1824 #endif DEBUG
1825 return (0);
1826 }
1827
1828 /*
1829 * Save state of current request, do new request for replacement.
1830 */
1831 transfrd = cbp->cb_bp->b_bcount - cbp->cb_bp->b_resid;
1832 /* adjust for previously transferred sectors */
1833 transfrd -= cbp->cb_transfrd;
1834 from = cbp->cb_iovstart
1835 + i386_btop((cbp->cb_addr & (I386_PGBYTES-1)) + transfrd);
1836 cbp->cb_transfrd += transfrd;
1837 cbp->cb_addr += transfrd;
1838
1839 /*
1840 * figure number of iovecs to copy down.
1841 */
1842 count = 0;
1843 cbcount = cbp->cb_count;
1844 if (cbp->cb_addr & (I386_PGBYTES-1)) {
1845 ++count;
1846 cbcount -= I386_PGBYTES - (cbp->cb_addr & (I386_PGBYTES-1));
1847 }
1848 count += i386_btop(cbcount + (I386_PGBYTES-1));
1849 count *= sizeof(u_int *);
1850 cbp->cb_iovec = KVTOPHYS(cbp->cb_iovstart, u_int *);
1851 bcopy((caddr_t)from, (caddr_t)cbp->cb_iovstart, (unsigned)count);
1852
1853 dd = (up->zu_drive & 1) ? &ctlrp->zdc_chanB : &ctlrp->zdc_chanA;
1854 if (cbp->cb_count != DEV_BSIZE) {
1855 cbp->cb_state |= ZD_REVECTOR;
1856 if (++cbp->cb_sect == dd->zdd_sectors) {
1857 cbp->cb_sect = 0;
1858 if (++cbp->cb_head == dd->zdd_tracks) {
1859 cbp->cb_head = 0;
1860 cbp->cb_cyl++;
1861 }
1862 }
1863 *(int *)&cbp->cb_contaddr = *(int *)&cbp->cb_diskaddr;
1864 cbp->cb_contiovsz = count;
1865 }
1866 cbp->cb_count = DEV_BSIZE;
1867 cbp->cb_diskaddr = *replcmnt;
1868 cbp->cb_psect = zdgetpsect(&cbp->cb_diskaddr, dd);
1869 #ifdef DEBUG
1870 if (zddebug)
1871 printf(" to (%d, %d, %d).\n",
1872 cbp->cb_cyl, cbp->cb_head, cbp->cb_sect);
1873 #endif DEBUG
1874
1875 /*
1876 * Nudge controller.
1877 */
1878 NUDGE_ZDC(ctlrp, cbp, s_ipl);
1879 return (1);
1880 }
1881
1882 /*
1883 * zdcontinue
1884 * Continue rest of I/O request after the revectored sector.
1885 */
1886 zdcontinue(cbp, up, ctlrp)
1887 register struct cb *cbp;
1888 struct zd_unit *up;
1889 register struct zdc_ctlr *ctlrp;
1890 {
1891 u_int *from;
1892 spl_t s_ipl;
1893
1894 /*
1895 * Revectoring completed successfully.
1896 * Restart rest of I/O request.
1897 */
1898 cbp->cb_state &= ~ZD_REVECTOR;
1899 cbp->cb_bp->b_resid -= DEV_BSIZE;
1900 cbp->cb_transfrd += DEV_BSIZE;
1901 cbp->cb_errcnt = 0;
1902 cbp->cb_count = cbp->cb_bp->b_resid;
1903 cbp->cb_iovec = KVTOPHYS(cbp->cb_iovstart, u_int *);
1904 from = cbp->cb_iovstart
1905 + i386_btop((cbp->cb_addr & (I386_PGBYTES-1)) + DEV_BSIZE);
1906 cbp->cb_addr += DEV_BSIZE;
1907 if (from != cbp->cb_iovstart) {
1908 /*
1909 * Must start with next iovector.
1910 */
1911 bcopy((caddr_t)from, (caddr_t)cbp->cb_iovstart,
1912 (unsigned)(cbp->cb_contiovsz - sizeof(u_int *)));
1913 }
1914 *(int *)&cbp->cb_diskaddr = *(int *)&cbp->cb_contaddr;
1915 cbp->cb_psect = zdgetpsect(&cbp->cb_diskaddr,
1916 (up->zu_drive & 1) ? &ctlrp->zdc_chanB
1917 : &ctlrp->zdc_chanA);
1918 /*
1919 * Nudge controller.
1920 */
1921 NUDGE_ZDC(ctlrp, cbp, s_ipl);
1922 }
1923
1924 /*
1925 * zdretry
1926 * Retry the request.
1927 * If the request is a normal read/write request then retry the command
1928 * from where the error occurred. If B_IOCTL request, retry from the
1929 * initial CB.
1930 */
1931 zdretry(cbp, up, ctlrp)
1932 register struct cb *cbp;
1933 struct zd_unit *up;
1934 struct zdc_ctlr *ctlrp;
1935 {
1936 register int count; /* # iovecs remaining */
1937 register int transfrd; /* # bytes transferred */
1938 register int cbcount;
1939 u_int *from; /* 1st retry iovec */
1940 spl_t s_ipl;
1941
1942 /*
1943 * Retry job
1944 */
1945 if (cbp->cb_bp->b_flags & B_IOCTL) {
1946 /*
1947 * copy 1st half of cb (what fw will see)
1948 */
1949 bcopy((caddr_t)&up->zu_ioctlcb, (caddr_t)cbp, FWCBSIZE);
1950 } else {
1951 cbp->cb_count = cbp->cb_bp->b_resid;
1952 cbp->cb_cmd = (cbp->cb_bp->b_flags & B_READ) ? ZDC_READ : ZDC_WRITE;
1953 cbp->cb_sect &= ~ZD_AUTOBIT; /* drop Auto-revetor bit */
1954 cbp->cb_psect = zdgetpsect(&cbp->cb_diskaddr,
1955 (up->zu_drive & 1) ? &ctlrp->zdc_chanB
1956 : &ctlrp->zdc_chanA);
1957 transfrd = cbp->cb_bp->b_bcount - cbp->cb_count;
1958 transfrd -= cbp->cb_transfrd;
1959 from = cbp->cb_iovstart
1960 + i386_btop((cbp->cb_addr & (I386_PGBYTES-1)) + transfrd);
1961 cbp->cb_transfrd += transfrd;
1962 cbp->cb_addr += transfrd;
1963
1964 /*
1965 * determine number of iovecs remaining.
1966 */
1967 count = 0;
1968 cbcount = cbp->cb_count;
1969 if (cbp->cb_addr & (I386_PGBYTES-1)) {
1970 ++count;
1971 cbcount -= I386_PGBYTES - (cbp->cb_addr & (I386_PGBYTES-1));
1972 }
1973 count += i386_btop(cbcount + (I386_PGBYTES-1));
1974
1975 /*
1976 * Copy down iovecs to 32 byte aligned boundary.
1977 * That is, cb_iovstart.
1978 */
1979 bcopy((caddr_t)from, (caddr_t)cbp->cb_iovstart,
1980 (unsigned)(count * sizeof(u_int *)));
1981 }
1982 cbp->cb_iovec = KVTOPHYS(cbp->cb_iovstart, u_int *);
1983
1984 /*
1985 * Nudge controller.
1986 */
1987 NUDGE_ZDC(ctlrp, cbp, s_ipl);
1988 }
1989
1990 /*
1991 * zdc_cb_cleanup
1992 * Cleanup (cancel) jobs active on disabled controller.
1993 * Called as timeout routine to allow completed CB's to drain.
1994 * That is, those for which a completion interrupt was sent just
1995 * before the error interrupt occurred.
1996 */
1997 zdc_cb_cleanup(ctlrp)
1998 register struct zdc_ctlr *ctlrp;
1999 {
2000 register struct cb *cbp;
2001 register struct buf *bp;
2002 spl_t s_ipl;
2003
2004 /*
2005 * Controller dead. Fail all active I/O requests.
2006 */
2007 cbp = ctlrp->zdc_cbp;
2008 for (; cbp < &ctlrp->zdc_cbp[NCBPERZDC]; cbp++) {
2009 if (cbp->cb_bp != NULL) {
2010 bp = cbp->cb_bp;
2011 bp->b_flags |= B_ERROR;
2012 bp->b_error = EIO;
2013 bp->b_resid = bp->b_bcount;
2014 biodone(bp);
2015 bp = NULL;
2016 /*
2017 * Decrement I/O activity
2018 */
2019 if (fp_lights) {
2020 s_ipl = splhi();
2021 FP_IO_INACTIVE;
2022 splx(s_ipl);
2023 }
2024 }
2025 }
2026 }
2027
2028 /*
2029 * zdc_error
2030 * Controller error interrupt.
2031 */
2032 zdc_error(vector)
2033 u_char vector;
2034 {
2035 register int val;
2036 register struct zdc_ctlr *ctlrp;
2037 spl_t s_ipl;
2038
2039 ctlrp = &zdctrlr[vector - base_err_intr];
2040 s_ipl = splhi(); /* In case zdc_err_bin not splhi() */
2041 val = rdslave(ctlrp->zdc_slicaddr, SL_Z_STATUS);
2042 splx(s_ipl);
2043 if (((val & SLB_ZPARERR) != SLB_ZPARERR) &&
2044 ((val & ZDC_READY) == ZDC_READY)) {
2045 printf("zdc%d - stray error interrupt!\n", ctlrp - zdctrlr);
2046 return;
2047 }
2048 printf("zdc%d: controller interrupt - SL_Z_STATUS == 0x%x.\n",
2049 ctlrp - zdctrlr, val);
2050 if ((val & ZDC_ERRMASK) == ZDC_OBCB) {
2051 /*
2052 * Assume stray interrupt happened and tell fw to continue.
2053 */
2054 s_ipl = splhi(); /* in case zdc_err_bin not splhi() */
2055 mIntr(ctlrp->zdc_slicaddr, CLRERRBIN, 0xbb);
2056 splx(s_ipl);
2057 return;
2058 }
2059
2060 splx(SPLZD); /* Do the rest at SPLZD */
2061
2062 /*
2063 * Fail all queued I/O requests.
2064 */
2065 zdshutctlr(ctlrp);
2066
2067 /*
2068 * Allow completed CBs to drain then
2069 * fail all other "active" I/O requests.
2070 */
2071 timeout(zdc_cb_cleanup, (caddr_t)ctlrp, 5 * hz);
2072 }
2073
2074 /*
2075 * zdshutctlr
2076 * Fail all I/O requests queued to the drives on this controller.
2077 * Currently active I/O requests will finish asyncronously.
2078 * The controller is marked as ZDC_DEAD and all units on the
2079 * controller are marked as ZU_BAD.
2080 */
2081 zdshutctlr(ctlrp)
2082 register struct zdc_ctlr *ctlrp;
2083 {
2084 register struct cb *cbp;
2085
2086 printf("zdc%d: Controller disabled.\n", ctlrp - zdctrlr);
2087
2088 cbp = ctlrp->zdc_cbp;
2089 for (; cbp < &ctlrp->zdc_cbp[NCBPERZDC]; cbp += NCBPERDRIVE) {
2090 if (cbp->cb_unit >= 0)
2091 zdshutdrive(&zdunit[cbp->cb_unit]);
2092 }
2093 ctlrp->zdc_state = ZDC_DEAD;
2094 }
2095
2096 /*
2097 * zdshutchan
2098 * Fail all I/O requests queued to the drives on this channel.
2099 * Currently active I/O requests will finish asyncronously.
2100 * All units on the channel are marked as ZU_BAD.
2101 */
2102 zdshutchan(ctlrp, channel)
2103 register struct zdc_ctlr *ctlrp;
2104 int channel; /* 0 == Channel A, 1 == channel B */
2105 {
2106 register struct cb *cbp;
2107
2108 printf("zdc%d: Channel %c disabled.\n", ctlrp - zdctrlr,
2109 (channel == 0) ? 'A' : 'B');
2110
2111 cbp = &ctlrp->zdc_cbp[channel * NCBPERDRIVE];
2112 for (; cbp < &ctlrp->zdc_cbp[NCBPERZDC]; cbp += 2 * NCBPERDRIVE) {
2113 if (cbp->cb_unit >= 0)
2114 zdshutdrive(&zdunit[cbp->cb_unit]);
2115 }
2116 }
2117
2118 /*
2119 * zdshutdrive
2120 * Fail all I/O requests queued to the drive.
2121 * Currently active I/O requests will finish asyncronously.
2122 * The drive is marked as ZU_BAD.
2123 */
2124 zdshutdrive(up)
2125 register struct zd_unit *up;
2126 {
2127 register struct buf *bp, *nextbp;
2128 spl_t s_ipl;
2129
2130 /*
2131 * Lock the device and fail all jobs currently queued.
2132 */
2133 s_ipl = p_lock(&up->zu_lock, SPLZD);
2134 if (up->zu_state == ZU_BAD) {
2135 v_lock(&up->zu_lock, s_ipl);
2136 return;
2137 }
2138 printf("zd%d: Drive disabled.\n", up - zdunit);
2139 bp = up->zu_bhead.av_forw;
2140 while (bp != NULL) {
2141 bp->b_flags |= B_ERROR;
2142 bp->b_error = EIO;
2143 bp->b_resid = bp->b_bcount;
2144 nextbp = bp->av_forw;
2145 biodone(bp);
2146 bp = nextbp;
2147 }
2148 up->zu_bhead.av_forw = NULL;
2149 up->zu_state = ZU_BAD;
2150 v_lock(&up->zu_lock, s_ipl);
2151 /*
2152 * Turn on error light on front panel.
2153 */
2154 if (fp_lights) {
2155 s_ipl = splhi();
2156 FP_IO_ERROR;
2157 splx(s_ipl);
2158 }
2159 /*
2160 * It had been online and usable.
2161 */
2162 disk_offline();
2163 }
2164
2165 /*
2166 * zdminphys - correct for too large a request.
2167 *
2168 * Note correction for non-cluster-aligned transfers.
2169 */
2170 zdminphys(bp)
2171 struct buf *bp;
2172 {
2173 if (bp->b_bcount > ((zdc_iovpercb - 1) * I386_PGBYTES))
2174 bp->b_bcount = (zdc_iovpercb - 1) * I386_PGBYTES;
2175 }
2176
2177 zdread(dev, uio)
2178 dev_t dev;
2179 struct uio *uio;
2180 {
2181 #ifndef MACH
2182 int err, diff;
2183 off_t lim;
2184
2185 lim = zdparts[zdunit[ZDUNIT(dev)].zu_drive_type][ZDPART(dev)].p_length;
2186 lim = dbtob(lim);
2187 err = physck(lim, uio, B_READ, &diff);
2188 if (err != 0) {
2189 if (err == -1) /* not an error, but request of 0 bytes */
2190 err = 0;
2191 return (err);
2192 }
2193 err = physio(zdstrat, (struct buf *)0, dev, B_READ, zdminphys, uio);
2194 uio->uio_resid += diff;
2195 return (err);
2196 #else MACH
2197 return physio(zdstrat, &zdbuf, dev, B_READ, zdminphys, uio);
2198 #endif MACH
2199 }
2200
2201 zdwrite(dev, uio)
2202 dev_t dev;
2203 struct uio *uio;
2204 {
2205 #ifndef MACH
2206 int err, diff;
2207 off_t lim;
2208
2209 lim = zdparts[zdunit[ZDUNIT(dev)].zu_drive_type][ZDPART(dev)].p_length;
2210 lim = dbtob(lim);
2211 err = physck(lim, uio, B_WRITE, &diff);
2212 if (err != 0) {
2213 if (err == -1) /* not an error, but request of 0 bytes */
2214 err = 0;
2215 return (err);
2216 }
2217 err = physio(zdstrat, (struct buf *)0, dev, B_WRITE, zdminphys, uio);
2218 uio->uio_resid += diff;
2219 return (err);
2220 #else MACH
2221 return physio(zdstrat, &zdbuf, dev, B_WRITE, zdminphys, uio);
2222 #endif MACH
2223 }
2224
2225 /*
2226 * zdioctl
2227 * Currently the only ZIOCBCMDs that are supported are ZDC_READ_LRAM and
2228 * ZDC_WRITE_LRAM. The ioctl mechanism could be used to support
2229 * more functions to facilitate online formatting.
2230 */
2231 /*ARGSUSED*/
2232 zdioctl(dev, cmd, data, flag)
2233 dev_t dev;
2234 int cmd;
2235 caddr_t data;
2236 int flag;
2237 {
2238 #ifndef MACH
2239 register struct cb *cbp; /* cb argument */
2240 register struct buf *bp; /* ioctl buffer */
2241 register struct zd_unit *up; /* unit structure */
2242 int error;
2243 spl_t s_ipl;
2244
2245 up = &zdunit[ZDUNIT(dev)];
2246 bp = &up->zu_ioctl;
2247
2248 switch(cmd) {
2249
2250 case ZIOCBCMD:
2251 cbp = (struct cb *)data;
2252 switch(cbp->cb_cmd) {
2253
2254 case ZDC_GET_CHANCFG:
2255 if (cbp->cb_count != sizeof(struct zdcdd) ||
2256 (cbp->cb_addr & (ADDRALIGN-1)) != 0)
2257 return (EINVAL);
2258 if (!useracc((char *)cbp->cb_addr,
2259 (u_int)cbp->cb_count, B_WRITE))
2260 return (EFAULT);
2261 bufalloc(bp);
2262 bp->b_flags = B_READ;
2263 bp->b_bcount = cbp->cb_count;
2264 bp->b_un.b_addr = (caddr_t)cbp->cb_addr;
2265 break;
2266
2267 case ZDC_READ_SS:
2268 if (cbp->cb_count != ZDD_SS_SIZE ||
2269 (cbp->cb_addr & (ADDRALIGN-1)) != 0 ||
2270 cbp->cb_diskaddr.da_cyl != 0 ||
2271 cbp->cb_diskaddr.da_head != 0 ||
2272 cbp->cb_diskaddr.da_sect >= ZDD_NDDSECTORS)
2273 return (EINVAL);
2274 if (!useracc((char *)cbp->cb_addr,
2275 (u_int)cbp->cb_count, B_WRITE))
2276 return (EFAULT);
2277 bufalloc(bp);
2278 bp->b_flags = B_READ;
2279 bp->b_bcount = cbp->cb_count;
2280 bp->b_un.b_addr = (caddr_t)cbp->cb_addr;
2281 break;
2282
2283 case ZDC_WRITE_LRAM:
2284 if (!suser())
2285 return (EPERM);
2286 /* Fall into */
2287 case ZDC_READ_LRAM:
2288 /*
2289 * Check if LRAM address reasonable.
2290 */
2291 if (cbp->cb_addr >= (ZDC_LRAMSZ / sizeof(int)))
2292 return (EINVAL);
2293 bufalloc(bp);
2294 bp->b_flags = (cbp->cb_cmd == ZDC_READ_LRAM) ? B_READ
2295 : B_WRITE;
2296 bp->b_bcount = 0; /* data in CB */
2297 bp->b_un.b_addr = NULL;
2298 break;
2299
2300 default:
2301 return (EINVAL);
2302 }
2303
2304 /*
2305 * Do ioctl.
2306 */
2307 bcopy((caddr_t)cbp, (caddr_t)&up->zu_ioctlcb, FWCBSIZE);
2308 bp->b_flags |= B_IOCTL;
2309 bp->b_dev = dev;
2310 bp->b_blkno = 0;
2311 bp->b_error = 0;
2312 bp->b_proc = u.u_procp;
2313 bp->b_iotype = B_RAWIO;
2314 BIODONE(bp) = 0;
2315 ++u.u_procp->p_noswap;
2316 if (bp->b_bcount > 0) {
2317 /*
2318 * lock down pages
2319 */
2320 vslock(bp->b_un.b_addr, (int)bp->b_bcount,
2321 (bool_t)(bp->b_flags & B_READ));
2322 }
2323 s_ipl = p_lock(&up->zu_lock, SPLZD);
2324 if (up->zu_state == ZU_BAD) {
2325 v_lock(&up->zu_lock, s_ipl);
2326 /*
2327 * Controller/channel/Drive has gone bad!
2328 */
2329 buffree(bp);
2330 --u.u_procp->p_noswap;
2331 return (EIO);
2332 }
2333 /*
2334 * Insert at head of list and zdstart!
2335 */
2336 bp->av_forw = up->zu_bhead.av_forw;
2337 up->zu_bhead.av_forw = bp;
2338 zdstart(up);
2339 v_lock(&up->zu_lock, s_ipl);
2340 biowait(bp);
2341 --u.u_procp->p_noswap; /* re-swappable */
2342 error = geterror(bp);
2343 bcopy((caddr_t)&up->zu_ioctlcb, (caddr_t)cbp, FWCBSIZE);
2344 buffree(bp);
2345 return (error);
2346
2347 default:
2348 return (EINVAL);
2349 }
2350 #else MACH
2351 return EINVAL;
2352 #endif MACH
2353 }
2354
2355 #ifdef MACH_KERNEL
2356 /*
2357 * Get status routine
2358 */
2359 zdgetstat(dev, flavor, status, count)
2360 dev_t dev;
2361 int *status, *count;
2362 {
2363 if (flavor == DEV_GET_SIZE) {
2364 unsigned int length;
2365
2366 length = zdparts[
2367 zdunit[ ZDUNIT(dev) ].zu_drive_type
2368 ] [ ZDPART(dev) ].p_length;
2369 status[DEV_GET_SIZE_DEVICE_SIZE] = length * DEV_BSIZE;
2370 status[DEV_GET_SIZE_RECORD_SIZE] = DEV_BSIZE;
2371 *count = DEV_GET_SIZE_COUNT;
2372
2373 return D_SUCCESS;
2374 } else return D_INVALID_OPERATION;
2375 }
2376 #endif /*MACH_KERNEL*/
2377
2378 /*
2379 * Routine to return information to kernel.
2380 */
2381 int
2382 zd_devinfo(dev, flavor, info)
2383 int dev;
2384 int flavor;
2385 char *info;
2386 {
2387 register int result;
2388
2389 result = D_SUCCESS;
2390
2391 switch (flavor) {
2392 case D_INFO_BLOCK_SIZE:
2393 *((int *) info) = DEV_BSIZE;
2394 break;
2395 default:
2396 result = D_INVALID_OPERATION;
2397 }
2398
2399 return(result);
2400 }
2401
2402 /*
2403 * zdsize()
2404 * Used for swap-space partition calculation.
2405 */
2406 zdsize(dev)
2407 register dev_t dev;
2408 {
2409 register struct zd_unit *up;
2410
2411 up = &zdunit[ZDUNIT(dev)];
2412
2413 if (ZDUNIT(dev) >= zdc_conf->zc_nent
2414 || up->zu_state != ZU_GOOD
2415 || ((up->zu_cfg & (ZD_FORMATTED|ZD_MATCH)) != (ZD_FORMATTED|ZD_MATCH))
2416 || zdparts[up->zu_drive_type][ZDPART(dev)].p_length == 0)
2417 return (-1);
2418 return (zdparts[up->zu_drive_type][ZDPART(dev)].p_length);
2419 }
2420
2421 /*
2422 * Print out status bytes when appropriate.
2423 */
2424 zddumpstatus(cbp)
2425 register struct cb *cbp;
2426 {
2427 register int i;
2428
2429 if (cbp->cb_cmd == ZDC_INIT || cbp->cb_cmd == ZDC_PROBE ||
2430 cbp->cb_cmd == ZDC_PROBEDRIVE)
2431 return;
2432
2433 switch(cbp->cb_compcode) {
2434
2435 case ZDC_DRVPROT:
2436 case ZDC_DRVFLT:
2437 case ZDC_SEEKERR:
2438 case ZDC_HDR_ECC:
2439 case ZDC_SOFTECC:
2440 case ZDC_CORRECC:
2441 case ZDC_ECC:
2442 case ZDC_SNF:
2443 case ZDC_REVECT:
2444 case ZDC_SO:
2445 case ZDC_NDS:
2446 case ZDC_FDL:
2447 case ZDC_DDC_STAT:
2448 break;
2449
2450 default:
2451 if (cbp->cb_cmd == ZDC_READ_LRAM || cbp->cb_cmd == ZDC_WRITE_LRAM)
2452 break;
2453 return;
2454 }
2455 if (cbp->cb_bp != NULL)
2456 printf("zd%d%c: cb_status:", cbp->cb_unit,
2457 PARTCHR(cbp->cb_bp->b_dev));
2458 else
2459 printf("zd%d: cbstatus:", cbp->cb_unit);
2460 for (i=0; i < NSTATBYTES; i++)
2461 printf(" 0x%x", cbp->cb_status[i]);
2462 printf("\n");
2463 }
2464
2465 #ifdef DEBUG
2466 /*
2467 * Print out the contents of a cb.
2468 */
2469 zddumpcb(cbp)
2470 register struct cb *cbp;
2471 {
2472 register struct init_cb *icbp;
2473 register int i;
2474 register int count;
2475 int cbcount;
2476
2477 printf("zd%d: cb at 0x%x, cb_cmd 0x%x, cb_compcode 0x%x\n",
2478 cbp->cb_unit, cbp, cbp->cb_cmd, cbp->cb_compcode);
2479 if (cbp->cb_cmd == ZDC_INIT) {
2480 icbp = (struct init_cb *)cbp;
2481 printf("icb_ctrl 0x%x, icb_pagesize 0x%x, icb_dumpaddr 0x%x\n",
2482 icbp->icb_ctrl, icbp->icb_pagesize, icbp->icb_dumpaddr);
2483 printf("icb_dest 0x%x, icb_bin 0x%x, icb_vecbase 0x%x\n",
2484 icbp->icb_dest, icbp->icb_bin, icbp->icb_vecbase);
2485 printf("icb_errdest 0x%x, icb_errbin 0x%x, icb_errvector 0x%x\n\n",
2486 icbp->icb_errdest, icbp->icb_errbin,
2487 icbp->icb_errvector);
2488 return;
2489 }
2490 if (cbp->cb_cmd == ZDC_PROBE || cbp->cb_cmd == ZDC_PROBEDRIVE) {
2491 printf("pcb_drivecfg:");
2492 for (i = 0; i < ZDC_MAXDRIVES; i++)
2493 printf(" 0x%x",
2494 ((struct probe_cb *)cbp)->pcb_drivecfg[i]);
2495 printf("\n\n");
2496 return;
2497 }
2498 printf("cb_mod 0x%x, cb_diskaddr (%d, %d, %d), cb_psect 0x%x\n",
2499 cbp->cb_mod, cbp->cb_cyl, cbp->cb_head, cbp->cb_sect,
2500 cbp->cb_psect);
2501 printf("cb_addr 0x%x, cb_count 0x%x, cb_iovec 0x%x, cb_reqstat 0x%x\n",
2502 cbp->cb_addr, cbp->cb_count, cbp->cb_iovec, cbp->cb_reqstat);
2503 zddumpstatus(cbp);
2504 printf("cb_bp 0x%x, cb_errcnt 0x%x, cb_iovstart 0x%x, cb_state 0x%x\n",
2505 cbp->cb_bp, cbp->cb_errcnt, cbp->cb_iovstart, cbp->cb_state);
2506 printf("cb_contaddr 0x%x, cb_contiovsz 0x%x, cb_transfrd 0x%x\n",
2507 cbp->cb_contaddr, cbp->cb_contiovsz, cbp->cb_transfrd);
2508 if (cbp->cb_iovec != NULL) {
2509 count = 0;
2510 cbcount = cbp->cb_count;
2511 #ifdef MACH_KERNEL
2512 if (cbp->cb_addr != trunc_page(cbp->cb_addr)) {
2513 ++count;
2514 cbcount -= PAGE_SIZE -
2515 (cbp->cb_addr - trunc_page(cbp->cb_addr));
2516 }
2517 count += atop(round_page(cbcount));
2518 #else /* MACH_KERNEL */
2519 if (cbp->cb_addr & CLOFSET) {
2520 ++count;
2521 cbcount -= CLBYTES - (cbp->cb_addr & CLOFSET);
2522 }
2523 count += (cbcount + CLOFSET) >> CLSHIFT;
2524 #endif /* MACH_KERNEL */
2525 printf("iovecs:");
2526 for (i = 0; i < count; i++) {
2527 printf(" 0x%x", cbp->cb_iovstart[i]);
2528 if ((i % 8) == 7)
2529 printf("\n\t");
2530 }
2531 printf("\n");
2532 }
2533 printf("\n");
2534 }
2535 #endif DEBUG
Cache object: ca78b3c2a0bb68b3329056ee180d3f80
|