?? idc.c
字號:
#ifndef lintstatic char *sccsid = "@(#)idc.c 4.1 ULTRIX 7/2/90";#endif lint/************************************************************************ * * * Copyright (c) 1984, 1986 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * idc.c 6.1 07/29/83 * * Modification history * * IDC/RL02/R80 disk driver * * 26-July-89 - Alan Frechette * Conditionalize out the dump code. * * 22-Feb-84 - tresvik * * Derived from 4.2BSD labeled: idc.c 6.1 83/07/29. * Changed printf to mprintf for hard and soft error reporting. * * 29-Oct-84 - reilly * * Added code for the disk partitioning scheme. -001 * * 2-Nov-84 - tresvik * * Changed std address from 0174400 to 0175606, where it really is. * This will prevent machine checks on 780's with RL11 controllers * on the bus. * * 30-Nov-84 - reilly * * Fixed up an error message. -001 * * 24-Sep-85 - reilly * * Added new ioctl request that will return the default partition * table. * * 18-Mar-86 - jaw * * br/cvec changed to NOT use registers. * * 9-Apr-86 - prs * * Added partial dump code support, and removed common dump code. * * 16-Apr-86 - ricky palmer * * Added new DEVIOCGET ioctl request code along with * soft and hard error counters. V2.0 * * 22-May-86 - Paul Shaughnessy * * Added saving of the u_area to the partial dump code. * * 13-Jun-86 - jaw * * Fix to uba reset and drivers. * * 11-Jul-86 - ricky palmer * * Added adpt and nexus fields to DEVIOCGET code. * * 26-Aug-86 - rsp (Ricky Palmer) * * Cleaned up devioctl code to (1) zero out devget structure * upon entry and (2) use strlen instead of fixed storage * for bcopy's. * * 25-Sep-86 - pmk * * Added code to detect OPI errors and drive not ready, because * of lost interrupt hangs. * * 16-Oct-86 - pmk * * Added code to detect drive not ready in the open routine to set * drive sc_flags to offline for devioctl. */#include "rb.h"#if NIDC > 0 || defined(BINARY)#ifdef IDCDEBUGint idcdebug = 0;#define printd if(idcdebug)printfint idctrb[1000];int *trp = idctrb;#define trace(a,b) {*trp++ = *(int*)a; *trp++ = (int)b; if(trp>&idctrb[998])trp=idctrb;}#endif IDCDEBUG#include "../h/dump.h"#include "../data/idc_data.c"#define dar_dar dar_l /* the whole disk address */#define dar_cyl dar_w[1] /* cylinder address */#define dar_trk dar_b[1] /* track */#define dar_sect dar_b[0] /* sector */#define sc_dar sc_un.dar_dar#define sc_cyl sc_un.dar_cyl#define sc_trk sc_un.dar_trk#define sc_sect sc_un.dar_sectint idcprobe(), idcslave(), idcattach(), idcdgo(), idcintr();u_short idcstd[] = { 0175606 };struct uba_driver idcdriver = { idcprobe, idcslave, idcattach, idcdgo, idcstd, "rb", idcdinfo, "idc", idcminfo, 0 };struct idcst { short nbps; short nsect; short ntrak; short nspc; short ncyl; struct size *sizes;} idcst[] = { 256, NRB02SECT, NRB02TRK, NRB02SECT*NRB02TRK, NRB02CYL, rb02_sizes, 512, NRB80SECT, NRB80TRK, NRB80SECT*NRB80TRK, NRB80CYL, rb80_sizes,};#define b_cylin b_resid#ifdef INTRLVEdaddr_t dkblock();#endif INTRLVEint idcwstart, idcwticks, idcwatch();/*ARGSUSED*/idcprobe(reg) caddr_t reg;{ register struct idcdevice *idcaddr; idcaddr = (struct idcdevice *)((caddr_t)uba_hd[0].uh_uba + 0x200); idcaddr->idccsr = IDC_ATTN|IDC_IE; while ((idcaddr->idccsr & IDC_CRDY) == 0) ; /* needs to timeout usin todr */ /* also should do a badaddr because */ /* we aren't using reg Why aren't we?*/ idcaddr->idccsr = IDC_ATTN|IDC_CRDY; return (sizeof (struct idcdevice));}/*ARGSUSED*/idcslave(ui, reg) struct uba_device *ui; caddr_t reg;{ register struct idcdevice *idcaddr; register struct idc_softc *sc = &idc_softc; idcaddr = (struct idcdevice *)((caddr_t)uba_hd[0].uh_uba + 0x200); ui->ui_type = 0; /* set drive to be offline until the first access occurs */ sc->sc_offline[ui->ui_unit] = 1; /* clear any attention bit */ idcaddr->idccsr = IDC_CRDY|(1<<(ui->ui_slave+16)); (void) idcwait(idcaddr, 0); /* setup for and get status of drive to see if it is there. */ /* this also resets the drive */ idcaddr->idcmpr = IDCGS_GETSTAT; idcaddr->idccsr = IDC_GETSTAT|(ui->ui_slave<<8); (void) idcwait(idcaddr, 0); /* * OPI means the drive really isn't there */ if (idcaddr->idccsr & IDC_OPI) return(0); /* * Read header to synchronize microcode. * This is accomplished by issuing a READ HEADER command to * the selected unit followed by two reads of the MPR register. */ idcaddr->idccsr = (ui->ui_slave<<8)|IDC_RHDR; (void) idcwait(idcaddr, 0); if (idcaddr->idcmpr == idcaddr->idcmpr); /* reads the MPR twice */ if (idcaddr->idccsr&IDC_R80) ui->ui_type = 1; return (1);}idcattach(ui) register struct uba_device *ui;{ register struct idc_softc *sc = &idc_softc; /* * Fix all addresses to correspond * to the "real" IDC address. */ ui->ui_mi->um_addr = ui->ui_addr = (caddr_t)uba_hd[0].uh_uba + 0x200; ui->ui_physaddr = (caddr_t)uba_hd[0].uh_physuba + 0x200; if (idcwstart == 0) { timeout(idcwatch, (caddr_t)0, hz); idcwstart++; } if (ui->ui_dk >= 0) { if (ui->ui_type) { dk_mspw[ui->ui_dk] = 1.0 / (60 * NRB80SECT * 256); bcopy(DEV_R80,sc->sc_device[ui->ui_unit], strlen(DEV_R80)); } else { dk_mspw[ui->ui_dk] = 1.0 / (60 * NRB02SECT * 128); bcopy(DEV_RL02,sc->sc_device[ui->ui_unit], strlen(DEV_RL02)); } sc->sc_softcnt[ui->ui_unit] = 0; sc->sc_hardcnt[ui->ui_unit] = 0; } idccyl[ui->ui_unit].dar_dar = -1; ui->ui_flags = 0;}idcopen(dev, flag) register dev_t dev; int flag;{ register int unit = minor(dev) >> 3; register struct uba_device *ui; register struct idc_softc *sc; register struct idcdevice *idcaddr; int savstat, savcsr; if (unit >= nNRB || (ui = idcdinfo[unit]) == 0 || ui->ui_alive == 0) { return (ENXIO); } idcaddr = (struct idcdevice *)ui->ui_addr; sc = &idc_softc; sc->sc_flags[unit] = 0; sc->sc_category_flags[unit] = 0; idcaddr->idcmpr = IDCGS_GETSTAT; idcaddr->idccsr = IDC_GETSTAT|(ui->ui_slave<<8); (void) idcwait(idcaddr, 0); savstat = idcaddr->idcmpr; savcsr = idcaddr->idccsr; if (savstat & IDCDS_WL) { sc->sc_flags[unit] |= DEV_WRTLCK; } if (!(savcsr & IDC_DRDY)) { sc->sc_flags[unit] |= DEV_OFFLINE; } if (savcsr & IDC_ERR) { mprintf("%s: unit# %d: drive error: csr=%b ds=%b\n", sc->sc_device[unit], unit, savcsr, IDCCSR_BITS, savstat, ui->ui_type?IDCRB80DS_BITS:IDCRB02DS_BITS); } idcaddr->idccsr = IDC_IE|IDC_CRDY|(1<<(ui->ui_slave+16)); /* * We only need to read the partition table if the volume is * not valid or the partition table is invalid. */ if ((sc->sc_flags[unit] & DEV_OFFLINE) || (idc_part[unit].pt_valid != PT_VALID)){ int nspc = idcst[ui->ui_type].nspc; int i, idcstrategy(); /* 001 */ for( i = 0; i <= 7; i++ ) { idc_part[unit].pt_part[i].pi_nblocks = idcst[ui->ui_type].sizes[i].nblocks; idc_part[unit].pt_part[i].pi_blkoff = idcst[ui->ui_type].sizes[i].cyloff * nspc; } idc_part[unit].pt_valid = PT_VALID; /*001 Validate the pt*/ /* * Default partition are now set. Call rsblk to set * the driver's partition tables, if any exists, from * the "a" partition superblock */ rsblk( idcstrategy, dev, &idc_part[unit] ); } return (0);}idcstrategy(bp) register struct buf *bp;{ register struct uba_device *ui; register struct idcst *st; register int unit = dkunit(bp); register struct pt *pt; /* 001 */ register struct idc_softc *sc = &idc_softc; struct buf *dp; int xunit = minor(bp->b_dev) & 07; long bn, sz; sz = (bp->b_bcount+511) >> 9; if (unit >= nNRB) goto bad; ui = idcdinfo[unit]; if (ui == 0 || ui->ui_alive == 0) goto bad; st = &idcst[ui->ui_type]; pt = &idc_part[unit]; if ( pt->pt_valid != PT_VALID ) /* 001 */ panic("idcstrategy: invalid partition table"); /* 001 */ if (bp->b_blkno < 0 || (bn = dkblock(bp))+sz > pt->pt_part[xunit].pi_nblocks) { sc->sc_flags[unit] |= DEV_EOM; goto bad; } if (ui->ui_type == 0) bn *= 2; bp->b_cylin = bn/st->nspc + pt->pt_part[xunit].pi_blkoff / st->nspc; /*001 */ (void) spl5();#ifdef IDCDEBUG trace("strt",bp);#endif IDCDEBUG dp = &idcutab[ui->ui_unit]; disksort(dp, bp); if (dp->b_active == 0) {#ifdef IDCDEBUG trace("!act",dp);#endif IDCDEBUG (void) idcustart(ui); bp = &ui->ui_mi->um_tab; if (bp->b_actf && bp->b_active == 0) (void) idcstart(ui->ui_mi); } (void) spl0(); return;bad: bp->b_flags |= B_ERROR; if (sc->sc_flags[unit] & DEV_EOM) { bp->b_error = ENOSPC; } iodone(bp); return;}idcustart(ui) register struct uba_device *ui;{ register struct idcdevice *idcaddr; register struct buf *bp; register struct uba_ctlr *um; register struct idcst *st; register struct idc_softc *sc; struct buf *dp; union idc_dar cyltrk; daddr_t bn; int unit; if (ui == 0) return (0); dk_busy &= ~(1<<ui->ui_dk); dp = &idcutab[ui->ui_unit]; um = ui->ui_mi; unit = ui->ui_slave; sc = &idc_softc;#ifdef IDCDEBUG trace("ust", dp);#endif IDCDEBUG idcaddr = (struct idcdevice *)um->um_addr; if (um->um_tab.b_active) { sc->sc_softas |= 1<<unit;#ifdef IDCDEBUG trace("umac",sc->sc_softas);#endif IDCDEBUG return (0); } if ((bp = dp->b_actf) == NULL) {#ifdef IDCDEBUG trace("!bp",0);#endif IDCDEBUG return (0); } if (dp->b_active) {#ifdef IDCDEBUG trace("dpac",dp->b_active);#endif IDCDEBUG goto done; } dp->b_active = 1; /* CHECK DRIVE READY? */ bn = dkblock(bp);#ifdef IDCDEBUG trace("seek", bn);#endif IDCDEBUG if (ui->ui_type == 0) bn *= 2; st = &idcst[ui->ui_type]; cyltrk.dar_cyl = bp->b_cylin; cyltrk.dar_trk = (bn / st->nsect) % st->ntrak; cyltrk.dar_sect = 0;#ifdef IDCDEBUG printd("idcustart, unit %d, cyltrk 0x%x\n", unit, cyltrk.dar_dar);#endif IDCDEBUG /*
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -