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