1
0
Files
irix-657m-src/stand/arcs/include/sys/dksc.h
2022-09-29 17:59:04 +03:00

343 lines
10 KiB
C

/**************************************************************************
* *
* Copyright (C) 1986, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#ident "$Revision: 3.42 $"
#ifndef OTYPCNT
# include <sys/open.h> /* for OTYP stuff */
#endif
/* SCSI disk minor # breakdown.
* 7 6 5 4 3 2 1 0
* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* + + + +
* + Target ID + LUN # + Partition +
* + + + +
* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
#define dev_to_softc(adap, targ, lu) (dksoftc[adap][targ][lu])
#define scsi_lu(dev) 0
/* these allow the dksc driver to work with different logical block size
devices. So all raw accesses will be OK; if/when block code is fixed,
block devices will just start working.
*/
#define dkCHKBB(bytes) ((bytes)%dk->dk_blksz)
#define dkBTOBB(bytes) ((bytes)/dk->dk_blksz) /* truncates! used where caller
should be checking for short count on return anyway. */
#define dkBBTOB(blks) ((blks)*dk->dk_blksz)
/* Only 1 LU supported per physical disk drive (LUN == 0) */
#define DK_MAXLU 1
/* partitions per drive */
#define DK_MAX_PART 16
/* values for dk_flags */
#define DK_WRTPROT 1 /* drive is write protected */
#define DK_SILENT_NOTREADY 2 /* set when doing test unit ready */
/* by powers of 2, allows tracking sizes up to 128 blocks */
#define NUM_BLK_STATS 8
struct blkstats {
uint bk_reads[NUM_BLK_STATS];
uint bk_writes[NUM_BLK_STATS];
};
/*
* Software state per disk drive.
*/
struct dksoftc {
struct volume_header dk_vh; /* Volume header info */
struct buf dk_buf; /* Local buffer */
sema_t dk_wait; /* Synchronous use waiters */
struct iobuf dk_tab; /* Strat routine queue header */
struct blkstats dk_blkstats; /* i/o stats */
scsisubchan_t *dk_subchan; /* SCSI Subchannel structure */
unsigned *dk_drivecap; /* drive size as returned by
readcapacity (2nd word is block
size at end of media) */
#define DK_DRIVECAP_SIZE 8
unsigned dk_blksz; /* logical (from drive) blocksize of device */
u_char *dk_sense_data; /* private buffer for sense data */
#define DK_SENSE_DATA_SIZE 24
ushort dk_openparts[OTYPCNT]; /* map of open partitions (counts
on DK_MAX_PART being 16 or less), one entry for
CHR, LYR, BLK, SWP, and MNT */
ushort dk_lyrcnt[DK_MAX_PART]; /* lyr open/closes are matched
pairs, so need a counter for it (ugh) */
ushort dk_flags;
lock_t dk_lock; /* Lock to protect structure fields */
u_char dk_cmd[SC_CLASS1_SZ]; /* the command packet */
u_char dk_selflags; /* flags for DIOCSELECT; see DIOCSELFLAGS */
u_char dk_retry; /* Retry count for cmds */
u_char *dk_inqtyp; /* devtype from first byte of inquiry data */
};
/*
* We only really need the first byte of inquiry data, but when we do SCSI
* inquiries on little-endian devices, the significant byte comes in as
* byte 3. This needs to be big enough to hold the significant data.
*/
#define DK_INQTYP_SIZE 4
#define dk_part(minor) (minor & (DK_MAX_PART - 1))
/*
* This structure is used by the mode select/get ioctls to determine
* where the data is to be sent to/recieved from.
*/
struct dk_ioctl_data {
caddr_t i_addr;
u_int i_len;
u_char i_page; /* Page code is used only on mode select */
};
/* Maximum amount of data allowed by an ioctl cmd */
#define MAX_IOCTL_DATA 4096
/* These are the possible page codes used by mode sense/get */
#define ERR_RECOV 0x1
#define CONN_PARMS 0x2
#define DEV_FORMAT 0x3
#define DEV_GEOMETRY 0x4
#define DEV_FDGEOMETRY 0x5 /* geometry for SMS flexible disks */
#define BLOCK_DESCRIP 0x7 /* TOSHIBA MK156FB only */
#define VERIFY_ERR 0x7 /* SCSI 2 Verify error recovery page */
#define CACHE_SCSI2 0x8 /* SCSI 2 cache control; Maxtor 8760, Hitachi 515C */
#define NOTCH_SCSI2 0xC /* SCSI 2 notch page */
#define CACHE_CONTR 0x38 /* CDC Wren IV/V/VI drives */
#define ALL 0x3f
/* These are the page control field values recognized by the mode sense cmd */
#define CURRENT 0
#define CHANGEABLE (0x1 << 6)
#define DEFAULT (0x2 << 6)
#define SAVED (0x3 << 6)
/*
* These are the pages of the drive parameter set/get commands.
* Note that all of the struct should be allocated to the full
* size of the union, since we determine their sizes at run time,
* due to the possiblity of different page sizes on different
* mfg drives. This is normally done by using ptrs to the structs,
* and setting them to point to the dk_pages member of a struct mode_sense_data.
* Any 'extra' bytes won't be changed by programs like fx, but most
* drives require that the pages being set by a mode select be
* the correct size and have valid data for bytes that aren't
* changed (usually retrieved via a mode sense into the same buffer).
*/
union dk_pages {
struct common {
u_char pg_code;
u_char pg_len;
u_char pg_maxlen[0x100-2]; /* make room for max possible page len */
} common;
struct err_recov {
u_char e_pgcode;
u_char e_pglen;
u_char e_err_bits;
u_char e_retry_count;
u_char e_rdretry;
u_char e_corrspan;
u_char e_headoffset;
u_char e_strobeoffset;
u_char e_rsv0;
u_char e_wrretry;
u_char e_rsv1;
u_char e_recovtime[2];
} err_recov;
struct connparms {
u_char c_pgcode;
u_char c_pglen;
u_char c_bfull;
u_char c_bempty;
u_char c_binacthi;
u_char c_binactlo;
u_char c_disconhi;
u_char c_disconlo;
u_char c_reserv[2];
} cparms;
struct dev_format {
u_char f_pgcode;
u_char f_pglen;
u_char f_trk_zone[2];
u_char f_altsec[2];
u_char f_alttrk_zone[2];
u_char f_alttrk_vol[2];
u_char f_sec_trac[2];
u_char f_bytes_sec[2];
u_char f_interleave[2];
u_char f_trkskew[2];
u_char f_cylskew[2];
u_char f_form_bits;
u_char f_reserved4[3];
} dev_format;
struct dev_geometry { /* page 4 for winchesters */
u_char g_pgcode;
u_char g_pglen;
u_char g_ncyl[3];
u_char g_nhead;
u_char g_wrprecomp[3];
u_char g_reducewrcur[3];
u_char g_steprate[2];
u_char g_landing[3];
u_char g_reserved1:7;
u_char g_spindlesync:1;
u_char g_rotatoff;
u_char g_reserved2;
u_char g_rotatrate[2];
u_char g_reserved3[2];
} dev_geometry;
struct dev_fdgeometry { /* page 5 for floppies */
u_char g_pgcode;
u_char g_pglen;
u_char g_trate[2];
u_char g_nhead;
u_char g_spt;
u_char g_bytes_sec[2];
u_char g_ncyl[2];
u_char g_wprcomp[2];
u_char g_wrcurr[2];
u_char g_steprate[2];
u_char g_steppulsewidth;
u_char g_headset[2];
u_char g_moton;
u_char g_motoff;
u_char g_trdy:1;
u_char g_ssn:1;
u_char g_mo:1;
u_char g_reserv0:5;
u_char g_reserv1:4;
u_char g_stpcyl:4;
u_char g_wrprecomp;
u_char g_headld;
u_char g_headunld;
u_char g_pin34:4;
u_char g_pin2:4;
u_char g_pin4:4;
u_char g_pin1:4; /* pin 1 TEAC, reserved on NCR */
u_char g_reserv2[4];
} dev_fdgeometry;
struct block_descrip { /* Toshiba 156 FB only */
u_char b_pgcode;
u_char b_pglen;
u_char b_reserved0;
u_char b_bdlen;
u_char b_density;
u_char b_reserved1[3];
u_int b_blen; /* This is actually a 3 byte val; high
byte reserved */
} block_descrip;
struct verify_err { /* scsi 2 error recovery params */
u_char v_pgcode;
u_char v_pglen;
u_char rsv0:4,
eer:1,
per:1,
dte:1,
dcr:1;
u_char v_retry;
u_char v_corrspan;
u_char v_rsv1[5];
u_char v_recovtime[2];
} verify_err;
struct cachectrl { /* CDC Wren IV/V/VI cache control */
u_char c_pgcode;
u_char c_pglen;
u_char c_ccen:1, c_wie:1, c_ssm:1, c_ce:1, c_ctsize:4;
u_char c_prefetch;
u_char c_maxpre;
u_char c_maxpremult;
u_char c_minpre;
u_char c_minpremult;
u_char c_reserv[8];
} cachctrl;
struct notch { /* info for 'zone bit recorded' devices */
u_char n_pgcode;
u_char n_pglen;
u_char n_nd:1;
u_char n_lpn:1;
u_char n_rsv0:6;
u_char n_rsv1;
u_char n_maxnotch[2];
u_char n_actnotch[2];
u_char n_startbound[2];
u_char n_endbound[2];
u_char n_pagesnotched[2];
} notch;
struct cachescsi2 { /* scsi 2 cache ctrl page */
u_char c_pgcode;
u_char c_pglen;
u_char c_rsrv:5;
u_char c_wce:1;
u_char c_mf:1;
u_char c_rcd:1;
u_char c_rdpri:4;
u_char c_wrpri:4;
u_char c_predislen[2];
u_char c_minpre[2];
u_char c_maxpre[2];
u_char c_maxpreceil[2];
u_char c_fsw:1; /* force seq write; not yet in rev 10H */
u_char c_rsrv2:1; /* not yet in rev 10H */
u_char c_dra:1; /* disable readahead; not yet in rev 10H */
u_char c_rsrv3:5; /* not yet in rev 10H */
u_char c_numseg;
u_char c_cachsize[2]; /* cache seg size; not yet in rev 10H */
u_char c_rsv5; /* not yet in rev 10H */
u_char c_ncachsize[3]; /* non-cache seg size; not yet in rev 10H */
} cachescsi2;
};
/* Error recovery flag byte bits for e_err_bits */
#define E_DCR 0x1
#define E_DTE 0x2
#define E_PER 0x4
#define E_RC 0x10
#define E_TB 0x20
#define E_ARRE 0x40
#define E_AWRE 0x80
/* The data structure of the mode sense command */
struct mode_sense_data {
u_char sense_len;
u_char mediatype;
u_char wprot:1, reserv0:2, dpofua:1, reserv1:4;
u_char bd_len;
u_char block_descrip[8]; /* note that this field will NOT be supplied
by some drives, so that dk_pages data may actually start at this
offset; check the bd_len value! */
union dk_pages dk_pages;
};
/* The structure of the mode select command */
struct mode_select_data {
u_char reserv0;
u_char mediatype;
u_char wprot:1, reserv1:7;
u_char blk_len; /* This will normally be set to 0 */
union dk_pages dk_pages;
};
struct defect_header {
u_char reserved0;
u_char format_bits;
u_char defect_listlen[2];
};
struct defect_entry {
u_char def_cyl[3];
u_char def_head;
u_char def_sector[4]; /* bytes from index, or sector */
};