📄 sd.c
字号:
/* * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * from: $Hdr: sd.c,v 4.300 91/06/27 20:42:56 root Rel41 $ SONY * * @(#)sd.c 8.2 (Berkeley) 9/23/93 */#define dkblock(bp) bp->b_blkno/* * Copyright (c) 1987-1991 by SONY Corporation. */#include "sd.h"#if NSD > 0#include <sys/param.h>#include <sys/buf.h>#include <sys/proc.h>#include <sys/user.h>#include <sys/dkstat.h>#include <sys/uio.h>#include <sys/kernel.h>#include <sys/reboot.h>#include <sys/ioctl.h>#include <sys/systm.h>#include <sys/mtio.h>#include <sys/stat.h>#include <sys/disklabel.h>#include <vm/vm.h>#include <sys/syslog.h>#include <ufs/ffs/fs.h># include <machine/cpu.h>#ifdef IPC_MRX# include "../iop/iopvar.h"# include "../ipc/newsipc.h"#endif#ifdef CPU_SINGLE# include <news3400/hbdev/hbvar.h># include <news3400/iodev/ioptohb.h>#endif#include <news3400/iodev/scsireg.h>#include <news3400/iodev/scu.h>#include <news3400/iodev/dkio.h>#include <news3400/iodev/sdreg.h>#define sce_sdecode sce_hdecode#define dev2unit(x) ((minor(x) & ~0x80) >> 3)#define dev2part(x) (minor(x) & 0x7)/* /sys/sys/file.h */#define FREAD 00001 /* descriptor read/receive'able */#define FWRITE 00002 /* descriptor write/send'able */#define PART_A 0#define PART_B 1#define PART_C 2#define PART_D 3#define PART_E 4#define PART_F 5#define PART_G 6#define PART_H 7#define MAXPROBERETRY 100#define NRETRY 10#define MAXHRDERR 100#define MAXRETRYCNT 16#define SDBSIZE1K (DEV_BSIZE * 2)#define MAXSDPHYS ((NSCMAP - 1) * NBPG)#define D100MSEC 100000#if OD_STOPTIME < 1# define OD_STOPTIME 5#endif /* OD_STOPTIME < 1 */#define FORMAT_MODE_CORRUPTED 0x31#define ONLY_ONE 1/************** PARTITIONS *************************************/#define PART_UNUSED (0)#define PART_SPEC (-1)#define PART_CALCF (-2)#define PART_CALCG (-3)struct defpart { int range_min; int range_max; int partsize[PNUM];};struct defpart defpart_std[] = { { 0, /* range_min */ 20, /* range_max */ PART_SPEC, /* A: */ PART_UNUSED, /* B: */ PART_SPEC, /* C: */ PART_UNUSED, /* D: */ PART_UNUSED, /* E: */ PART_UNUSED, /* F: */ PART_UNUSED, /* G: */ PART_UNUSED, /* H: */ }, { 20, /* range_min */ 61, /* range_max */ 15884, /* A: */ 10032, /* B: */ PART_SPEC, /* C: */ 15884, /* D: */ PART_UNUSED, /* E: */ PART_CALCF, /* F: */ PART_CALCG, /* G: */ PART_UNUSED, /* H: */ }, { 61, /* range_min */ 206, /* range_max */ 15884, /* A: */ 33440, /* B: */ PART_SPEC, /* C: */ 15884, /* D: */ 55936, /* E: */ PART_CALCF, /* F: */ PART_CALCG, /* G: */ PART_UNUSED, /* H: */ }, { 206, /* range_min */ 356, /* range_max */ 15884, /* A: */ 33440, /* B: */ PART_SPEC, /* C: */ 15884, /* D: */ 55936, /* E: */ PART_CALCF, /* F: */ PART_CALCG, /* G: */ 291346, /* H: */ }, { 356, /* range_min */ 99999999, /* range_max */ 15884, /* A: */ 66880, /* B: */ PART_SPEC, /* C: */ 15884, /* D: */ 307200, /* E: */ PART_CALCF, /* F: */ PART_CALCG, /* G: */ 291346, /* H: */ }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }};/************* ADDITIONAL SENSE ERROR CODES *************************/struct msg_list { int ml_code; /* message code */ int ml_msglvl; /* message level */ char *ml_msgstr; /* message string */};#define sdskeylist skeyliststruct msg_list ecodelist_mo[] = { { 0x80, 0, NULL }, { 0x81, 0, NULL }, { 0x82, 0, NULL }, { 0x83, 0, NULL }, { -1, 0, NULL }};/************** Ref. sd_var.c ********************************/extern struct iop/**/_ctlr *sdminfo[];extern struct iop/**/_device *sddinfo[];extern struct iop/**/_device *sdip[][MAXSLAVE];extern struct buf rsdbuf[]; /* buffer for raw I/O */extern struct buf csdbuf[]; /* buffer for controll */extern struct buf sdutab[]; /* per drive buffers */extern struct sdc_softc sdc_softc[];extern struct sdd_softc sdd_softc[];extern u_char sd_b_openf[][PNUM];extern u_char sd_c_openf[][PNUM];extern struct scsi kernscsi[];extern struct sdst sdstdrv[];extern struct disklabel sdlabel[];extern struct size sdsizedrv[][PNUM];extern u_char sdc_rsense[][RSEN_CNT];extern struct sync_param sd_sync_param[];extern int nsd;extern int nsdc;/************** Ref. sddefs.c *********************************/extern struct sddevinfo sddevinfo[];/**************************************************************/extern struct msg_list skeylist[];extern struct msg_list ecodelist[];extern int boothowto;extern int rsense_msg_disp; /* RSENSE-message display flag */extern int mo_disp_format; /* MO format mode display flag */int sd_ignore_error;static int re_init_done;static u_char sdwork[2340]; /* buffer for error recovery */static u_char sdtmp[DEV_BSIZE]; /* buffer for temporary */#ifdef mipsvolatile static int sdtmp_stat = 0; /* status of sdtmp */#elsestatic int sdtmp_stat = 0; /* status of sdtmp */#endifchar pname[] = "abcdefgh";struct scsi *get_scsi();struct sc_map *get_sc_map();struct sc_inq *get_sc_inq();int sdprobe(), sdslave(), sdattach(), sddgo(), sdintr();int sdwstart, sdwatch(), sdstop(); /* Have started guardian */void sdexec();static sd_check(), sd_tstdrv(), sd_other_pages(), sd_err_rcv(), sd_synctr_on();static disklabel2sdst(), sdst2disklabel(), sd_scu_exec();#ifdef CPU_SINGLEstruct hb_driver sdcdriver = {sdprobe, sdslave, sdattach, sddgo, sdintr, "sd", sddinfo, "sdc", sdminfo};#elsestruct iop_driver sdcdriver = {sdprobe, sdslave, sdattach, sddgo, "sd", sddinfo, "sdc", sdminfo};#endif/*ARGSUSED*/sdprobe(im) struct iop/**/_ctlr *im;{ static int sdd_init = 0; register struct sc_inq *sci; register int ctlr; register int fw; int i; if (sdd_init == 0) { sdd_init++; for (i = 0; i < nsd; i++) sdd_softc[i].sdd_start = -2; } sci = get_sc_inq(im->im_intr); ctlr = im->im_ctlr; /* * Check device type * 0x00: Direct access device. * 0x01: Sequential access device. * 0x04: Write-once read-multiple device. * 0x05: Read-only Direct-access device. * 0x7f: Specified device is nonexistent. */ fw = sdc_softc[ctlr].sdc_firmware & ~SDCFW_DEVMASK; switch (sci->sci_devtype) { case 0x00: /* * Assumed that the device is HD. * Later, distinguish MO from HD. */ sdc_softc[ctlr].sdc_firmware = fw | SDCFW_HD; break; default: /* * device type mis-match */ return (0); } /* * Set interrupt handler routine */ if (set_inthandler(im, sdintr) == 0) return (0); return (1);}/*ARGSUSED*/sdslave(ii, reg, intr) register struct iop/**/_device *ii; caddr_t reg; int intr;{ register struct scsi *sc; sc = get_scsi(intr); sdip[ii->ii_ctlr][ii->ii_slave] = ii; ii->ii_intr = intr; /* * check what the device is. */ if ((ii->ii_type = sd_check(ii, sc)) < 0) goto bad_slave; /* * set up ERROR RECOVERY PARAMETERS */ if (sd_err_rcv(ii, sc) < 0) goto bad_slave; /* * set up OTHER PARAMETERS */ if (sd_other_pages(ii, sc) < 0) goto bad_slave; /* * set up Synchronous Transfer */ sd_synctr_on(ii, sc); return (1);bad_slave: /* * no such slave */ ii->ii_intr = -1; return (0);}identity_check(sci, capacity, unit) register struct sc_inq *sci; int capacity; int unit;{ register struct sddevinfo *sdi; register u_char *id_name; register int index; register int i; int id_pass; id_name = sci->sci_vendid; while (*id_name == ' ') id_name++; index = UNKNOWN_DISK; id_pass = 0; for (sdi = sddevinfo; sdi->id_len >= 0; sdi++) { /* * check vendor & product ID */ if (strncmp(id_name, sdi->id_name, sdi->id_len) != 0) continue; id_pass = sdi - sddevinfo; /* * check revision */ if (strncmp(sdi->revs, sci->sci_revision, 4) == 0) index = id_pass; else { for (i = 0; i < 4; i++) { if (*(sdi->revs + i) == '?') continue; if (*(sdi->revs + i) != sci->sci_revision[i]) break; } if (i < 4) continue; } /* * check capacity */ if (capacity == -1) break; if (sdi->capacity == -1) { printf("sd%d: capacity=0x%x(%d)\n", unit, capacity, capacity); break; } if (capacity == sdi->capacity) break; } if (index == 0) index = id_pass; return (index);}search_index(type) register int type;{ register struct sddevinfo *sdi; register int i; int index; index = UNKNOWN_DISK; i = 0; for (sdi = sddevinfo; sdi->id_len > 0; sdi++) { if (sdi->type == type) { index = i; break; } i++; } return (index);}staticsd_check(ii, sc) register struct iop/**/_device *ii; register struct scsi *sc;{ register struct sc_inq *sci; register struct sc_rcap *scr; register int intr; register int slave; register int unit; struct sdc_softc *sdc; struct sdd_softc *sdd; struct sc_extnd *sce; int retrycnt; int index; int media_in; intr = ii->ii_intr; slave = ii->ii_slave; unit = ii->ii_unit; sdc = &sdc_softc[ii->ii_ctlr]; sdd = &sdd_softc[unit]; scr = (struct sc_rcap *)sc->sc_param; sce = (struct sc_extnd *)&sdc_rsense[ii->ii_ctlr][0]; /* * check if the logical unit is ready. * (by TEST UNIT READY command) */ media_in = sd_tstdrv(ii, sc); if (media_in < 0) return (-3); /* * Get controller and drive information. * (by INQUIRY command) */ retrycnt = 0; sci = get_sc_inq(intr);loop_inq: if (retrycnt++ > MAXPROBERETRY) return (-1); scop_inquiry(intr, sc, slave, SCSI_INTDIS, sizeof(struct sc_inq), sci); sc->sc_tstatus &= TGSTMASK; if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD) { bzero((caddr_t)sce, RSEN_CNT); scop_rsense(intr, sc, slave, SCSI_INTDIS, RSEN_CNT, (caddr_t)sce); sc->sc_tstatus &= TGSTMASK; if (sc->sc_istatus != INST_EP || sc->sc_tstatus != TGST_GOOD) return (-1); if (sce->sce_extend != 0x70) goto loop_inq; switch (sce->sce_sdecode) { case 0x04: /* Drive Not Ready */ case 0x28: /* Medium Changed */ case 0x29: /* Power On or Reset or Bus Device Reset */ case 0x2a: /* Mode Select Parameter Changed */ break; default: return (-1); } DELAY(D100MSEC); /* wait 100 ms. */ goto loop_inq; } index = identity_check(sci, -1, unit); switch (sddevinfo[index].type) { case SMO_S501: case SMO_S501_ISO: case SMO_S501_ISO2: sdc->sdc_firmware = SDCFW_MO | (sdc->sdc_firmware & ~SDCFW_DEVMASK); break; defaults: break; } if (sci->sci_qual & 0x80) { /* * removable medium device */ sdc->sdc_firmware |= SDCFW_RMB;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -