1 /*        $NetBSD: scsireg.h,v 1.6 2024/05/09 15:11:11 tsutsui Exp $  */
2 
3 /*
4  * Copyright (c) 1990, 1993
5  *        The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Van Jacobson of Lawrence Berkeley Laboratory.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *        @(#)scsireg.h       8.1 (Berkeley) 6/10/93
35  */
36 
37 /*
38  * HP 98265A SCSI Interface Hardware Description.
39  */
40 
41 #include <sys/ioccom.h>
42 
43 struct scsidevice {
44           u_char    p0,  scsi_id;
45 #define                       ID_MASK             0x1f
46 #define                       SCSI_ID             0x07
47 #define                       ID_WORD_DMA         0x20
48           u_char    p2,  scsi_csr;
49 #define                       CSR_IE              0x80
50 #define                       CSR_IR              0x40
51 #define                       SCSI_IPL(csr)       ((((csr)>>4)&3)+3)
52 #define                       CSR_DMA32 0x08
53 #define                       CSR_DMAIN 0x04
54 #define                       CSR_DE1             0x02
55 #define                       CSR_DE0             0x01
56           u_char    p4,  scsi_wrap;
57 #define                       WRAP_REQ  0x80
58 #define                       WRAP_ACK  0x40
59 #define                       WRAP_BSY  0x08
60 #define                       WRAP_MSG  0x04
61 #define                       WRAP_CD             0x02
62 #define                       WRAP_IO             0x01
63           u_char    p6,  scsi_hconf;
64 #define                       HCONF_TP  0x80
65 #define                       SCSI_SYNC_XFER(hconf) (((hconf)>>5)&3)
66 #define                       HCONF_SD  0x10
67 #define                       HCONF_PARITY        0x08
68           u_char    p8[24];
69           u_char    p32, scsi_bdid;
70           u_char    p34, scsi_sctl;
71 #define                       SCTL_DISABLE        0x80
72 #define                       SCTL_CTRLRST        0x40
73 #define                       SCTL_DIAG 0x20
74 #define                       SCTL_ABRT_ENAB      0x10
75 #define                       SCTL_PARITY_ENAB 0x08
76 #define                       SCTL_SEL_ENAB       0x04
77 #define                       SCTL_RESEL_ENAB     0x02
78 #define                       SCTL_INTR_ENAB      0x01
79           u_char    p36, scsi_scmd;
80 #define                       SCMD_RST  0x10
81 #define                       SCMD_ICPT_XFR       0x08
82 #define                       SCMD_PROG_XFR       0x04
83 #define                       SCMD_PAD  0x01      /* if initiator */
84 #define                       SCMD_PERR_STOP      0x01      /* if target */
85                               /* command codes */
86 #define                       SCMD_BUS_REL        0x00
87 #define                       SCMD_SELECT         0x20
88 #define                       SCMD_RST_ATN        0x40
89 #define                       SCMD_SET_ATN        0x60
90 #define                       SCMD_XFR  0x80
91 #define                       SCMD_XFR_PAUSE      0xa0
92 #define                       SCMD_RST_ACK        0xc0
93 #define                       SCMD_SET_ACK        0xe0
94           u_char    p38, scsi_tmod;
95 #define                       TMOD_SYNC 0x80
96           u_char    p40, scsi_ints;
97 #define                       INTS_SEL  0x80
98 #define                       INTS_RESEL          0x40
99 #define                       INTS_DISCON         0x20
100 #define                       INTS_CMD_DONE       0x10
101 #define                       INTS_SRV_REQ        0x08
102 #define                       INTS_TIMEOUT        0x04
103 #define                       INTS_HARD_ERR       0x02
104 #define                       INTS_RST  0x01
105           u_char    p42, scsi_psns;
106 #define                       PSNS_REQ  0x80
107 #define                       PSNS_ACK  0x40
108 #define                       PSNS_ATN  0x20
109 #define                       PSNS_SEL  0x10
110 #define                       PSNS_BSY  0x08
111           u_char    p44, scsi_ssts;
112 #define                       SSTS_INITIATOR      0x80
113 #define                       SSTS_TARGET         0x40
114 #define                       SSTS_BUSY 0x20
115 #define                       SSTS_XFR  0x10
116 #define                       SSTS_ACTIVE         (SSTS_INITIATOR|SSTS_XFR)
117 #define                       SSTS_RST  0x08
118 #define                       SSTS_TCZERO         0x04
119 #define                       SSTS_DREG_FULL      0x02
120 #define                       SSTS_DREG_EMPTY     0x01
121           u_char    p46, scsi_serr;
122 #define                       SERR_SCSI_PAR       0x80
123 #define                       SERR_SPC_PAR        0x40
124 #define                       SERR_TC_PAR         0x08
125 #define                       SERR_PHASE_ERR      0x04
126 #define                       SERR_SHORT_XFR      0x02
127 #define                       SERR_OFFSET         0x01
128           u_char    p48, scsi_pctl;
129 #define                       PCTL_BFINT_ENAB     0x80
130           u_char    p50, scsi_mbc;
131           u_char    p52, scsi_dreg;
132           u_char    p54, scsi_temp;
133           u_char    p56, scsi_tch;
134           u_char    p58, scsi_tcm;
135           u_char    p60, scsi_tcl;
136           u_char    p62, scsi_exbf;
137 };
138 
139 /* psns/pctl phase lines as bits */
140 #define   PHASE_MSG 0x04
141 #define   PHASE_CD  0x02                /* =1 if 'command' */
142 #define   PHASE_IO  0x01                /* =1 if data inbound */
143 /* Phase lines as values */
144 #define   PHASE               0x07                /* mask for psns/pctl phase */
145 #define   DATA_OUT_PHASE      0x00
146 #define   DATA_IN_PHASE       0x01
147 #define   CMD_PHASE 0x02
148 #define   STATUS_PHASE        0x03
149 #define   BUS_FREE_PHASE      0x04
150 #define   ARB_SEL_PHASE       0x05      /* Fuji chip combines arbitration with sel. */
151 #define   MESG_OUT_PHASE      0x06
152 #define   MESG_IN_PHASE       0x07
153 
154 /* SCSI Messages */
155 
156 #define   MSG_CMD_COMPLETE    0x00
157 #define MSG_EXT_MESSAGE                 0x01
158 #define   MSG_SAVE_DATA_PTR   0x02
159 #define   MSG_RESTORE_PTR               0x03
160 #define   MSG_DISCONNECT                0x04
161 #define   MSG_INIT_DETECT_ERROR         0x05
162 #define   MSG_ABORT           0x06
163 #define   MSG_REJECT                    0x07
164 #define   MSG_NOOP            0x08
165 #define   MSG_PARITY_ERROR    0x09
166 #define   MSG_BUS_DEVICE_RESET          0x0C
167 #define   MSG_IDENTIFY                  0x80
168 #define   MSG_IDENTIFY_DR               0xc0      /* (disconnect/reconnect allowed) */
169 #define   MSG_SYNC_REQ                  0x01
170 
171 /* SCSI Commands */
172 
173 #define CMD_TEST_UNIT_READY   0x00
174 #define CMD_REQUEST_SENSE     0x03
175 #define   CMD_INQUIRY                   0x12
176 #define CMD_SEND_DIAGNOSTIC   0x1D
177 
178 #define CMD_REWIND            0x01
179 #define CMD_REZERO            0x01
180 #define CMD_FORMAT_UNIT                 0x04
181 #define CMD_READ_BLOCK_LIMITS 0x05
182 #define CMD_REASSIGN_BLOCKS   0x07
183 #define CMD_READ              0x08
184 #define CMD_WRITE             0x0A
185 #define CMD_WRITE_FILEMARK    0x10
186 #define CMD_SPACE             0x11
187 #define CMD_MODE_SELECT                 0x15
188 #define CMD_RELEASE_UNIT      0x17
189 #define CMD_ERASE             0x19
190 #define CMD_MODE_SENSE                  0x1A
191 #define CMD_LOADUNLOAD                  0x1B
192 #define CMD_RECEIVE_DIAG      0x1C
193 #define CMD_SEND_DIAG                   0x1D
194 #define CMD_P_A_MEDIA_REMOVAL 0x1E
195 #define CMD_READ_CAPACITY     0x25
196 #define CMD_READ_EXT                    0x28
197 #define CMD_WRITE_EXT                   0x2A
198 #define CMD_READ_DEFECT_DATA  0x37
199 #define             SD_MANUFAC_DEFECTS  0x14000000
200 #define             SD_GROWN_DEFECTS    0x0c000000
201 #define CMD_READ_BUFFER                 0x3B
202 #define CMD_WRITE_BUFFER      0x3C
203 #define CMD_READ_FULL                   0xF0
204 #define CMD_MEDIA_TEST                  0xF1
205 #define CMD_ACCESS_LOG                  0xF2
206 #define CMD_WRITE_FULL                  0xFC
207 #define CMD_MANAGE_PRIMARY    0xFD
208 #define CMD_EXECUTE_DATA      0xFE
209 
210 /* SCSI status bits */
211 
212 #define   STS_CHECKCOND       0x02      /* Check Condition (ie., read sense) */
213 #define   STS_CONDMET         0x04      /* Condition Met (ie., search worked) */
214 #define   STS_BUSY  0x08
215 #define   STS_INTERMED        0x10      /* Intermediate status sent */
216 #define   STS_EXT             0x80      /* Extended status valid */
217 
218 /* command descriptor blocks */
219 
220 struct scsi_cdb6 {
221           u_char    cmd;                /* command code */
222           u_char    lun:  3,  /* logical unit on ctlr */
223                     lbah: 5;  /* msb of read/write logical block addr */
224           u_char    lbam;               /* middle byte of l.b.a. */
225           u_char    lbal;               /* lsb of l.b.a. */
226           u_char    len;                /* transfer length */
227           u_char    xtra;
228 };
229 
230 struct scsi_cdb10 {
231           u_char    cmd;                /* command code */
232           u_char    lun: 3,             /* logical unit on ctlr */
233                        : 4,
234                     rel: 1;             /* l.b.a. is relative addr if =1 */
235           u_char    lbah;               /* msb of read/write logical block addr */
236           u_char    lbahm;              /* high middle byte of l.b.a. */
237           u_char    lbalm;              /* low middle byte of l.b.a. */
238           u_char    lbal;               /* lsb of l.b.a. */
239           u_char    reserved;
240           u_char    lenh;               /* msb transfer length */
241           u_char    lenl;               /* lsb transfer length */
242           u_char    xtra;
243 };
244 
245 /* basic sense data */
246 
247 struct scsi_sense {
248           u_char    valid: 1, /* l.b.a. is valid */
249                     class: 3,
250                     code:  4;
251           u_char    vu:    4, /* vendor unique */
252                     lbah:  4;
253           u_char    lbam;
254           u_char    lbal;
255 };
256 
257 struct scsi_xsense {
258           u_char    valid: 1, /* l.b.a. is valid */
259                     class: 3,
260                     code:  4;
261           u_char    segment;
262           u_char    filemark: 1,
263                     eom:      1,
264                     ili:      1,        /* illegal length indicator */
265                     rsvd:       1,
266                     key:        4;
267           u_char    info1;
268           u_char    info2;
269           u_char    info3;
270           u_char    info4;
271           u_char    len;                /* additional sense length */
272 };
273 
274 /* inquiry data */
275 struct scsi_inquiry {
276           u_char    type;
277 #define SID_TYPE    0x1f
278 #define T_DIRECT    0x00
279 #define T_CDROM               0x05
280           u_char    qual;
281           u_char    version;
282           u_char    rsvd;
283           u_char    len;
284           char      class[3];
285           char      vendor_id[8];
286           char      product_id[16];
287           char      rev[4];
288 };
289 
290 struct scsi_format_parms {              /* physical BFI format */
291           u_short   reserved;
292           u_short   list_len;
293           struct defect {
294                     unsigned cyl  : 24;
295                     unsigned head : 8;
296                     long      bytes_from_index;
297           } defect[127];
298 };
299 
300 #ifdef _KERNEL
301 extern struct scsi_format_parms format_parms;
302 #endif
303 
304 struct scsi_reassign_parms {
305           u_short   reserved;
306           u_short   list_len; /* length in bytes of defects only */
307           struct new_defect {
308                     unsigned lba;       /* logical block address */
309           } new_defect[2];
310 };
311 
312 #ifdef _KERNEL
313 extern struct scsi_reassign_parms reassign_parms;
314 #endif
315 
316 struct scsi_modesel_hdr {
317           u_char    rsvd1;
318           u_char    media_type;
319           u_char    rsvd2;
320           u_char    block_desc_len;
321           u_int     density             : 8;
322           u_int     number_blocks       :24;
323           u_int     rsvd3               : 8;
324           u_int     block_length        :24;
325 };
326 
327 struct scsi_modesense_hdr {
328           u_char    len;
329           u_char    media_type;
330           u_char    wp    : 1;
331           u_char    rsvd1 : 7;
332           u_char    block_desc_len;
333           u_int     density             : 8;
334           u_int     number_blocks       :24;
335           u_int     rsvd2               : 8;
336           u_int     block_length        :24;
337 };
338 
339 /*
340  * Mode Select / Mode sense "pages"
341  */
342 
343 /*
344  * Page One - Error Recovery Parameters
345  */
346 struct scsi_err_recovery {
347           u_char    page_savable        : 1;      /* save parameters */
348           u_char    reserved  : 1;
349           u_char    page_code : 6;      /* = 0x01 */
350           u_char    page_length;                  /* = 6 */
351           u_char    awre                : 1;      /* auto write realloc enabled */
352           u_char    arre                : 1;      /* auto read realloc enabled */
353           u_char    tb                  : 1;      /* transfer block */
354           u_char    rc                  : 1;      /* read continuous */
355           u_char    eec                 : 1;      /* enable early correction */
356           u_char    per                 : 1;      /* post error */
357           u_char    dte                 : 1;      /* disable transfer on error */
358           u_char    dcr                 : 1;      /* disable correction */
359           u_char    retry_count;
360           u_char    correction_span;
361           u_char    head_offset_count;
362           u_char    strobe_offset_count;
363           u_char    recovery_time_limit;
364 };
365 
366 /*
367  * Page Two - Disconnect / Reconnect Control Parameters
368  */
369 struct scsi_disco_reco {
370           u_char    page_savable        : 1;      /* save parameters */
371           u_char    rsvd                : 1;
372           u_char    page_code : 6;      /* = 0x02 */
373           u_char    page_length;                  /* = 10 */
374           u_char    buffer_full_ratio;  /* write, how full before reconnect? */
375           u_char    buffer_empty_ratio; /* read, how full before reconnect? */
376 
377           u_short   bus_inactivity_limit;         /* how much bus time for busy */
378           u_short   disconnect_time_limit;        /* min to remain disconnected */
379           u_short   connect_time_limit; /* min to remain connected */
380           u_short   reserved_1;
381 };
382 
383 /*
384  * Page Three - Direct Access Device Format Parameters
385  */
386 struct scsi_format {
387           u_char    page_savable        : 1;      /* save parameters */
388           u_char    rsvd                : 1;
389           u_char    page_code : 6;      /* = 0x03 */
390           u_char    page_length;                  /* = 22 */
391           u_short   tracks_per_zone;    /*  Handling of Defects Fields */
392           u_short   alt_sect_zone;
393           u_short alt_tracks_zone;
394           u_short   alt_tracks_vol;
395           u_short   sect_track;                   /* Track Format Field */
396           u_short data_sect;            /* Sector Format Fields */
397           u_short   interleave;
398           u_short   track_skew_factor;
399           u_short   cyl_skew_factor;
400           u_char    ssec                : 1;      /* Drive Type Field */
401           u_char    hsec                : 1;
402           u_char    rmb                 : 1;
403           u_char    surf                : 1;
404           u_char    ins                 : 1;
405           u_char    reserved_1          : 3;
406           u_char    reserved_2;
407           u_char    reserved_3;
408           u_char    reserved_4;
409 };
410 
411 /*
412  * Page Four - Rigid Disk Drive Geometry Parameters
413  */
414 struct scsi_geometry {
415           u_char    page_savable        : 1;      /* save parameters */
416           u_char    rsvd                : 1;
417           u_char    page_code : 6;      /* = 0x04 */
418           u_char    page_length;                  /* = 18 */
419           u_char    cyl_ub;                       /* number of cylinders */
420           u_char    cyl_mb;
421           u_char    cyl_lb;
422           u_char    heads;                        /* number of heads */
423           u_char    precomp_cyl_ub;               /* cylinder to start precomp */
424           u_char    precomp_cyl_mb;
425           u_char    precomp_cyl_lb;
426           u_char    current_cyl_ub;               /* cyl to start reduced current */
427           u_char    current_cyl_mb;
428           u_char    current_cyl_lb;
429           u_short   step_rate;                    /* drive step rate */
430           u_char    landing_cyl_ub;               /* landing zone cylinder */
431           u_char    landing_cyl_mb;
432           u_char    landing_cyl_lb;
433           u_char    reserved_1;
434           u_char    reserved_2;
435           u_char    reserved_3;
436 };
437 
438 /*
439  * Page 0x38 - Cache Control Parameters
440  */
441 struct scsi_cache {
442           u_char    page_savable        : 1;      /* save parameters */
443           u_char    rsvd                : 1;
444           u_char    page_code : 6;      /* = 0x38 */
445           u_char    page_length;                  /* = 14 */
446           u_char rsvd_1       : 1;
447           u_char wie          : 1;                /* write index enable */
448           u_char rsvd_2       : 1;
449           u_char ce : 1;                /* cache enable */
450           u_char table_size : 4;
451           u_char    prefetch_threshold;
452           u_char    maximum_threshold;
453           u_char    maximumprefetch_multiplier;
454           u_char    minimum_threshold;
455           u_char    minimum_prefetch_multiplier;
456           u_char    reserved[8];
457 };
458 
459 /*
460  * Control for SCSI "format" mode.
461  *
462  * "Format" mode allows a privileged process to issue direct SCSI
463  * commands to a drive (it is intended primarily to allow on-line
464  * formatting).  SDIOCSFORMAT with a non-zero arg will put the drive
465  * into format mode; a zero arg will take it out.  When in format
466  * mode, only the process that issued the SDIOCFORMAT can read or
467  * write the drive.
468  *
469  * In format mode, process is expected to
470  *        - do SDIOCSCSICOMMAND to supply cdb for next SCSI op
471  *        - do read or write as appropriate for cdb
472  *        - if i/o error, optionally do SDIOCSENSE to get completion
473  *          status and sense data from last scsi operation.
474  */
475 
476 struct scsi_fmt_cdb {
477           int len;            /* cdb length (in bytes) */
478           u_char cdb[28];               /* cdb to use on next read/write */
479 };
480 
481 struct scsi_fmt_sense {
482           u_int status;                 /* completion status of last op */
483           u_char sense[28];   /* sense data (if any) from last op */
484 };
485 
486 #define   SDIOCSFORMAT                  _IOW('S', 0x1, int)
487 #define   SDIOCGFORMAT                  _IOR('S', 0x2, int)
488 #define   SDIOCSCSICOMMAND    _IOW('S', 0x3, struct scsi_fmt_cdb)
489 #define   SDIOCSENSE                    _IOR('S', 0x4, struct scsi_fmt_sense)
490