1/* $NetBSD: scsi_changer.h,v 1.11 1998/02/13 08:28:32 enami Exp $ */ 2 3/* 4 * Copyright (c) 1996 Jason R. Thorpe <thorpej@and.com> 5 * All rights reserved. 6 * 7 * Partially based on an autochanger driver written by Stefan Grefen 8 * and on an autochanger driver written by the Systems Programming Group 9 * at the University of Utah Computer Science Department. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgements: 21 * This product includes software developed by Jason R. Thorpe 22 * for And Communications, http://www.and.com/ 23 * 4. The name of the author may not be used to endorse or promote products 24 * derived from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 31 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 33 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 34 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 */ 38 39/* 40 * SCSI changer interface description 41 */ 42 43/* 44 * Partially derived from software written by Stefan Grefen 45 * (grefen@goofy.zdv.uni-mainz.de soon grefen@convex.com) 46 * based on the SCSI System by written Julian Elischer (julian@tfs.com) 47 * for TRW Financial Systems. 48 * 49 * TRW Financial Systems, in accordance with their agreement with Carnegie 50 * Mellon University, makes this software available to CMU to distribute 51 * or use in any manner that they see fit as long as this message is kept with 52 * the software. For this reason TFS also grants any other persons or 53 * organisations permission to use or modify this software. 54 * 55 * TFS supplies this software to be publicly redistributed 56 * on the understanding that TFS is not responsible for the correct 57 * functioning of this software in any circumstances. 58 * 59 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 60 */ 61 62#ifndef _SCSI_SCSI_CH_H 63#define _SCSI_SCSI_CH_H 1 64 65#include <sys/cdefs.h> 66 67/* 68 * SCSI command format 69 */ 70 71/* 72 * Exchange the medium in the source element with the medium 73 * located at the destination element. 74 */ 75struct scsi_exchange_medium { 76 u_int8_t opcode; 77#define EXCHANGE_MEDIUM 0xa6 78 u_int8_t byte2; 79 u_int8_t tea[2]; /* transport element address */ 80 u_int8_t src[2]; /* source address */ 81 u_int8_t fdst[2]; /* first destination address */ 82 u_int8_t sdst[2]; /* second destination address */ 83 u_int8_t invert; 84#define EXCHANGE_MEDIUM_INV1 0x01 85#define EXCHANGE_MEDIUM_INV2 0x02 86 u_int8_t control; 87}; 88 89/* 90 * Cause the medium changer to check all elements for medium and any 91 * other status relevant to the element. 92 */ 93struct scsi_initialize_element_status { 94 u_int8_t opcode; 95#define INITIALIZE_ELEMENT_STATUS 0x07 96 u_int8_t byte2; 97 u_int8_t reserved[3]; 98 u_int8_t control; 99}; 100 101/* 102 * Request the changer to move a unit of media from the source element 103 * to the destination element. 104 */ 105struct scsi_move_medium { 106 u_int8_t opcode; 107#define MOVE_MEDIUM 0xa5 108 u_int8_t byte2; 109 u_int8_t tea[2]; /* transport element address */ 110 u_int8_t src[2]; /* source element address */ 111 u_int8_t dst[2]; /* destination element address */ 112 u_int8_t reserved[2]; 113 u_int8_t invert; 114#define MOVE_MEDIUM_INVERT 0x01 115 u_int8_t control; 116}; 117 118/* 119 * Position the specified transport element (picker) in front of 120 * the destination element specified. 121 */ 122struct scsi_position_to_element { 123 u_int8_t opcode; 124#define POSITION_TO_ELEMENT 0x2b 125 u_int8_t byte2; 126 u_int8_t tea[2]; /* transport element address */ 127 u_int8_t dst[2]; /* destination element address */ 128 u_int8_t reserved[2]; 129 u_int8_t invert; 130#define POSITION_TO_ELEMENT_INVERT 0x01 131 u_int8_t control; 132}; 133 134/* 135 * Request that the changer report the status of its internal elements. 136 */ 137struct scsi_read_element_status { 138 u_int8_t opcode; 139#define READ_ELEMENT_STATUS 0xb8 140 u_int8_t byte2; 141#define READ_ELEMENT_STATUS_VOLTAG 0x10 /* report volume tag info */ 142 /* ...next 4 bits are an element type code... */ 143 u_int8_t sea[2]; /* starting element address */ 144 u_int8_t count[2]; /* number of elements */ 145 u_int8_t reserved0; 146 u_int8_t len[3]; /* length of data buffer */ 147 u_int8_t reserved1; 148 u_int8_t control; 149}; 150 151struct scsi_request_volume_element_address { 152 u_int8_t opcode; 153#define REQUEST_VOLUME_ELEMENT_ADDRESS 0xb5 154 u_int8_t byte2; 155#define REQUEST_VOLUME_ELEMENT_ADDRESS_VOLTAG 0x10 156 /* ...next 4 bits are an element type code... */ 157 u_int8_t eaddr[2]; /* element address */ 158 u_int8_t count[2]; /* number of elements */ 159 u_int8_t reserved0; 160 u_int8_t len[3]; /* length of data buffer */ 161 u_int8_t reserved1; 162 u_int8_t control; 163}; 164 165/* XXX scsi_release */ 166 167/* 168 * Changer-specific mode page numbers. 169 */ 170#define CH_ELEMENT_ADDR_ASSIGN_PAGE 0x1D 171#define CH_TRANS_GEOM_PARAMS_PAGE 0x1E 172#define CH_DEVICE_CAP_PAGE 0x1F 173 174/* 175 * Data returned by READ ELEMENT STATUS consists of an 8-byte header 176 * followed by one or more read_element_status_pages. 177 */ 178struct read_element_status_header { 179 u_int8_t fear[2]; /* first element address reported */ 180 u_int8_t count[2]; /* number of elements available */ 181 u_int8_t reserved; 182 u_int8_t nbytes[3]; /* byte count of all pages */ 183}; 184 185struct read_element_status_page_header { 186 u_int8_t type; /* element type code; see type codes below */ 187 u_int8_t flags; 188#define READ_ELEMENT_STATUS_AVOLTAG 0x40 189#define READ_ELEMENT_STATUS_PVOLTAG 0x80 190 u_int8_t edl[2]; /* element descriptor length */ 191 u_int8_t reserved; 192 u_int8_t nbytes[3]; /* byte count of all descriptors */ 193}; 194 195/* 196 * Format of a volume tag 197 */ 198 199struct volume_tag { 200 u_int8_t vif[32]; /* volume identification field */ 201 u_int8_t reserved[2]; 202 u_int8_t vsn[2]; /* volume sequence number */ 203}; 204 205struct read_element_status_descriptor { 206 u_int8_t eaddr[2]; /* element address */ 207 u_int8_t flags1; 208 209#define READ_ELEMENT_STATUS_FULL 0x01 210#define READ_ELEMENT_STATUS_IMPEXP 0x02 211#define READ_ELEMENT_STATUS_EXCEPT 0x04 212#define READ_ELEMENT_STATUS_ACCESS 0x08 213#define READ_ELEMENT_STATUS_EXENAB 0x10 214#define READ_ELEMENT_STATUS_INENAB 0x20 215 216#define READ_ELEMENT_STATUS_MT_MASK1 0x05 217#define READ_ELEMENT_STATUS_ST_MASK1 0x0c 218#define READ_ELEMENT_STATUS_IE_MASK1 0x3f 219#define READ_ELEMENT_STATUS_DT_MASK1 0x0c 220 221 u_int8_t reserved0; 222 u_int8_t sense_code; 223 u_int8_t sense_qual; 224 225 /* 226 * dt_scsi_flags and dt_scsi_addr are valid only on data transport 227 * elements. These bytes are undefined for all other element types. 228 */ 229 u_int8_t dt_scsi_flags; 230 231#define READ_ELEMENT_STATUS_DT_LUNMASK 0x07 232#define READ_ELEMENT_STATUS_DT_LUVALID 0x10 233#define READ_ELEMENT_STATUS_DT_IDVALID 0x20 234#define READ_ELEMENT_STATUS_DT_NOTBUS 0x80 235 236 u_int8_t dt_scsi_addr; 237 238 u_int8_t reserved1; 239 240 u_int8_t flags2; 241#define READ_ELEMENT_STATUS_INVERT 0x40 242#define READ_ELEMENT_STATUS_SVALID 0x80 243 u_int8_t ssea[2]; /* source storage element address */ 244 245 struct volume_tag pvoltag; /* omitted if PVOLTAG == 0 */ 246 struct volume_tag avoltag; /* omitted if AVOLTAG == 0 */ 247 248 /* Other data may follow */ 249}; 250 251/* XXX add data returned by REQUEST VOLUME ELEMENT ADDRESS */ 252 253/* Element type codes */ 254#define ELEMENT_TYPE_MASK 0x0f /* Note: these aren't bits */ 255#define ELEMENT_TYPE_ALL 0x00 256#define ELEMENT_TYPE_MT 0x01 257#define ELEMENT_TYPE_ST 0x02 258#define ELEMENT_TYPE_IE 0x03 259#define ELEMENT_TYPE_DT 0x04 260 261/* 262 * XXX The following definitions should be common to all SCSI device types. 263 */ 264#define PGCODE_MASK 0x3f /* valid page number bits in pg_code */ 265#define PGCODE_PS 0x80 /* indicates page is savable */ 266 267/* 268 * Send volume tag information to the changer 269 */ 270 271struct scsi_send_volume_tag { 272 u_int8_t opcode; 273#define SEND_VOLUME_TAG 0xb6 274 u_int8_t byte2; 275 u_int8_t ea[2]; /* element address */ 276 u_int8_t reserved2; 277 u_int8_t sac; /* send action code */ 278 279#define SEND_VOLUME_TAG_ASSERT_PRIMARY 0x08 280#define SEND_VOLUME_TAG_ASSERT_ALTERNATE 0x09 281#define SEND_VOLUME_TAG_REPLACE_PRIMARY 0x0a 282#define SEND_VOLUME_TAG_REPLACE_ALTERNATE 0x0b 283#define SEND_VOLUME_TAG_UNDEFINED_PRIMARY 0x0c 284#define SEND_VOLUME_TAG_UNDEFINED_ALTERNATE 0x0d 285 286 u_int8_t reserved4[2]; 287 u_int8_t pll[2]; /* parameter list length */ 288 u_int8_t reserved5; 289 u_int8_t control; 290}; 291 292/* 293 * Parameter format for SEND VOLUME TAG 294 */ 295 296struct scsi_send_volume_tag_parameters { 297 u_int8_t vitf[32]; /* volume tag identification template */ 298 u_int8_t reserved1[2]; 299 u_int8_t minvsn[2]; /* minimum volume sequence number */ 300 u_int8_t reserved2[2]; 301 u_int8_t maxvsn[2]; /* maximum volume sequence number */ 302}; 303 304/* 305 * Device capabilities page. 306 * 307 * This page defines characteristics of the elemenet types in the 308 * medium changer device. 309 * 310 * Note in the definitions below, the following abbreviations are 311 * used: 312 * MT Medium transport element (picker) 313 * ST Storage transport element (slot) 314 * IE Import/export element (portal) 315 * DT Data tranfer element (tape/disk drive) 316 */ 317struct page_device_capabilities { 318 u_int8_t pg_code; /* page code (0x1f) */ 319 u_int8_t pg_length; /* page length (0x12) */ 320 321 /* 322 * The STOR_xx bits indicate that an element of a given 323 * type may provide independent storage for a unit of 324 * media. The top four bits of this value are reserved. 325 */ 326 u_int8_t stor; 327#define STOR_MT 0x01 328#define STOR_ST 0x02 329#define STOR_IE 0x04 330#define STOR_DT 0x08 331 332 u_int8_t reserved0; 333 334 /* 335 * The MOVE_TO_yy bits indicate the changer supports 336 * moving a unit of medium from an element of a given type to an 337 * element of type yy. This is used to determine if a given 338 * MOVE MEDIUM command is legal. The top four bits of each 339 * of these values are reserved. 340 */ 341 u_int8_t move_from_mt; 342 u_int8_t move_from_st; 343 u_int8_t move_from_ie; 344 u_int8_t move_from_dt; 345#define MOVE_TO_MT 0x01 346#define MOVE_TO_ST 0x02 347#define MOVE_TO_IE 0x04 348#define MOVE_TO_DT 0x08 349 350 u_int8_t reserved1[4]; 351 352 /* 353 * Similar to above, but for EXCHANGE MEDIUM. 354 */ 355 u_int8_t exchange_with_mt; 356 u_int8_t exchange_with_st; 357 u_int8_t exchange_with_ie; 358 u_int8_t exchange_with_dt; 359#define EXCHANGE_WITH_MT 0x01 360#define EXCHANGE_WITH_ST 0x02 361#define EXCHANGE_WITH_IE 0x04 362#define EXCHANGE_WITH_DT 0x08 363}; 364 365/* 366 * Medium changer elemement address assignment page. 367 * 368 * Some of these fields can be a little confusing, so an explanation 369 * is in order. 370 * 371 * Each component within a a medium changer apparatus is called an 372 * "element". 373 * 374 * The "medium transport element address" is the address of the first 375 * picker (robotic arm). "Number of medium transport elements" tells 376 * us how many pickers exist in the changer. 377 * 378 * The "first storage element address" is the address of the first 379 * slot in the tape or disk magazine. "Number of storage elements" tells 380 * us how many slots exist in the changer. 381 * 382 * The "first import/export element address" is the address of the first 383 * medium portal accessible both by the medium changer and an outside 384 * human operator. This is where the changer might deposit tapes destined 385 * for some vault. The "number of import/export elements" tells us 386 * not many of these portals exist in the changer. NOTE: this number may 387 * be 0. 388 * 389 * The "first data transfer element address" is the address of the first 390 * tape or disk drive in the changer. "Number of data transfer elements" 391 * tells us how many drives exist in the changer. 392 */ 393struct page_element_address_assignment { 394 u_int8_t pg_code; /* page code (0x1d) */ 395 u_int8_t pg_length; /* page length (0x12) */ 396 397 /* Medium transport element address */ 398 u_int8_t mtea[2]; 399 400 /* Number of medium transport elements */ 401 u_int8_t nmte[2]; 402 403 /* First storage element address */ 404 u_int8_t fsea[2]; 405 406 /* Number of storage elements */ 407 u_int8_t nse[2]; 408 409 /* First import/export element address */ 410 u_int8_t fieea[2]; 411 412 /* Number of import/export elements */ 413 u_int8_t niee[2]; 414 415 /* First data transfer element address */ 416 u_int8_t fdtea[2]; 417 418 /* Number of data trafer elements */ 419 u_int8_t ndte[2]; 420 421 u_int8_t reserved[2]; 422}; 423 424/* 425 * Transport geometry parameters page. 426 * 427 * Defines whether each medium transport element is a member of a set of 428 * elements that share a common robotics subsystem and whether the element 429 * is capable of media rotation. One transport geometry descriptor is 430 * transferred for each medium transport element, beginning with the first 431 * medium transport element (other than the default transport element address 432 * of 0). 433 */ 434struct page_transport_geometry_parameters { 435 u_int8_t pg_code; /* page code (0x1e) */ 436 u_int8_t pg_length; /* page length; variable */ 437 438 /* Transport geometry descriptor(s) are here. */ 439 440 u_int8_t misc; 441#define CAN_ROTATE 0x01 442 443 /* Member number in transport element set. */ 444 u_int8_t member; 445}; 446 447__BEGIN_DECLS 448void scsi_move_medium(struct ccb_scsiio *csio, u_int32_t retries, 449 void (*cbfcnp)(struct cam_periph *, union ccb *), 450 u_int8_t tag_action, u_int32_t tea, u_int32_t src, 451 u_int32_t dst, int invert, u_int8_t sense_len, 452 u_int32_t timeout); 453 454void scsi_exchange_medium(struct ccb_scsiio *csio, u_int32_t retries, 455 void (*cbfcnp)(struct cam_periph *, union ccb *), 456 u_int8_t tag_action, u_int32_t tea, u_int32_t src, 457 u_int32_t dst1, u_int32_t dst2, int invert1, 458 int invert2, u_int8_t sense_len, u_int32_t timeout); 459 460void scsi_position_to_element(struct ccb_scsiio *csio, u_int32_t retries, 461 void (*cbfcnp)(struct cam_periph *, union ccb *), 462 u_int8_t tag_action, u_int32_t tea, u_int32_t dst, 463 int invert, u_int8_t sense_len, 464 u_int32_t timeout); 465 466void scsi_read_element_status(struct ccb_scsiio *csio, u_int32_t retries, 467 void (*cbfcnp)(struct cam_periph *, union ccb *), 468 u_int8_t tag_action, int voltag, u_int32_t sea, 469 u_int32_t count, u_int8_t *data_ptr, 470 u_int32_t dxfer_len, u_int8_t sense_len, 471 u_int32_t timeout); 472 473void scsi_initialize_element_status(struct ccb_scsiio *csio, u_int32_t retries, 474 void (*cbfcnp)(struct cam_periph *, union ccb *), 475 u_int8_t tag_action, u_int8_t sense_len, 476 u_int32_t timeout); 477void scsi_send_volume_tag(struct ccb_scsiio *csio, u_int32_t retries, 478 void (*cbfcnp)(struct cam_periph *, union ccb *), 479 u_int8_t tag_action, 480 u_int16_t element_address, 481 u_int8_t send_action_code, 482 struct scsi_send_volume_tag_parameters *parameters, 483 u_int8_t sense_len, u_int32_t timeout); 484__END_DECLS 485 486#endif /* _SCSI_SCSI_CH_H */
| 2/* $NetBSD: scsi_changer.h,v 1.11 1998/02/13 08:28:32 enami Exp $ */ 3 4/* 5 * Copyright (c) 1996 Jason R. Thorpe <thorpej@and.com> 6 * All rights reserved. 7 * 8 * Partially based on an autochanger driver written by Stefan Grefen 9 * and on an autochanger driver written by the Systems Programming Group 10 * at the University of Utah Computer Science Department. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgements: 22 * This product includes software developed by Jason R. Thorpe 23 * for And Communications, http://www.and.com/ 24 * 4. The name of the author may not be used to endorse or promote products 25 * derived from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 28 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 31 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 32 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 33 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 34 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 35 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 */ 39 40/* 41 * SCSI changer interface description 42 */ 43 44/* 45 * Partially derived from software written by Stefan Grefen 46 * (grefen@goofy.zdv.uni-mainz.de soon grefen@convex.com) 47 * based on the SCSI System by written Julian Elischer (julian@tfs.com) 48 * for TRW Financial Systems. 49 * 50 * TRW Financial Systems, in accordance with their agreement with Carnegie 51 * Mellon University, makes this software available to CMU to distribute 52 * or use in any manner that they see fit as long as this message is kept with 53 * the software. For this reason TFS also grants any other persons or 54 * organisations permission to use or modify this software. 55 * 56 * TFS supplies this software to be publicly redistributed 57 * on the understanding that TFS is not responsible for the correct 58 * functioning of this software in any circumstances. 59 * 60 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 61 */ 62 63#ifndef _SCSI_SCSI_CH_H 64#define _SCSI_SCSI_CH_H 1 65 66#include <sys/cdefs.h> 67 68/* 69 * SCSI command format 70 */ 71 72/* 73 * Exchange the medium in the source element with the medium 74 * located at the destination element. 75 */ 76struct scsi_exchange_medium { 77 u_int8_t opcode; 78#define EXCHANGE_MEDIUM 0xa6 79 u_int8_t byte2; 80 u_int8_t tea[2]; /* transport element address */ 81 u_int8_t src[2]; /* source address */ 82 u_int8_t fdst[2]; /* first destination address */ 83 u_int8_t sdst[2]; /* second destination address */ 84 u_int8_t invert; 85#define EXCHANGE_MEDIUM_INV1 0x01 86#define EXCHANGE_MEDIUM_INV2 0x02 87 u_int8_t control; 88}; 89 90/* 91 * Cause the medium changer to check all elements for medium and any 92 * other status relevant to the element. 93 */ 94struct scsi_initialize_element_status { 95 u_int8_t opcode; 96#define INITIALIZE_ELEMENT_STATUS 0x07 97 u_int8_t byte2; 98 u_int8_t reserved[3]; 99 u_int8_t control; 100}; 101 102/* 103 * Request the changer to move a unit of media from the source element 104 * to the destination element. 105 */ 106struct scsi_move_medium { 107 u_int8_t opcode; 108#define MOVE_MEDIUM 0xa5 109 u_int8_t byte2; 110 u_int8_t tea[2]; /* transport element address */ 111 u_int8_t src[2]; /* source element address */ 112 u_int8_t dst[2]; /* destination element address */ 113 u_int8_t reserved[2]; 114 u_int8_t invert; 115#define MOVE_MEDIUM_INVERT 0x01 116 u_int8_t control; 117}; 118 119/* 120 * Position the specified transport element (picker) in front of 121 * the destination element specified. 122 */ 123struct scsi_position_to_element { 124 u_int8_t opcode; 125#define POSITION_TO_ELEMENT 0x2b 126 u_int8_t byte2; 127 u_int8_t tea[2]; /* transport element address */ 128 u_int8_t dst[2]; /* destination element address */ 129 u_int8_t reserved[2]; 130 u_int8_t invert; 131#define POSITION_TO_ELEMENT_INVERT 0x01 132 u_int8_t control; 133}; 134 135/* 136 * Request that the changer report the status of its internal elements. 137 */ 138struct scsi_read_element_status { 139 u_int8_t opcode; 140#define READ_ELEMENT_STATUS 0xb8 141 u_int8_t byte2; 142#define READ_ELEMENT_STATUS_VOLTAG 0x10 /* report volume tag info */ 143 /* ...next 4 bits are an element type code... */ 144 u_int8_t sea[2]; /* starting element address */ 145 u_int8_t count[2]; /* number of elements */ 146 u_int8_t reserved0; 147 u_int8_t len[3]; /* length of data buffer */ 148 u_int8_t reserved1; 149 u_int8_t control; 150}; 151 152struct scsi_request_volume_element_address { 153 u_int8_t opcode; 154#define REQUEST_VOLUME_ELEMENT_ADDRESS 0xb5 155 u_int8_t byte2; 156#define REQUEST_VOLUME_ELEMENT_ADDRESS_VOLTAG 0x10 157 /* ...next 4 bits are an element type code... */ 158 u_int8_t eaddr[2]; /* element address */ 159 u_int8_t count[2]; /* number of elements */ 160 u_int8_t reserved0; 161 u_int8_t len[3]; /* length of data buffer */ 162 u_int8_t reserved1; 163 u_int8_t control; 164}; 165 166/* XXX scsi_release */ 167 168/* 169 * Changer-specific mode page numbers. 170 */ 171#define CH_ELEMENT_ADDR_ASSIGN_PAGE 0x1D 172#define CH_TRANS_GEOM_PARAMS_PAGE 0x1E 173#define CH_DEVICE_CAP_PAGE 0x1F 174 175/* 176 * Data returned by READ ELEMENT STATUS consists of an 8-byte header 177 * followed by one or more read_element_status_pages. 178 */ 179struct read_element_status_header { 180 u_int8_t fear[2]; /* first element address reported */ 181 u_int8_t count[2]; /* number of elements available */ 182 u_int8_t reserved; 183 u_int8_t nbytes[3]; /* byte count of all pages */ 184}; 185 186struct read_element_status_page_header { 187 u_int8_t type; /* element type code; see type codes below */ 188 u_int8_t flags; 189#define READ_ELEMENT_STATUS_AVOLTAG 0x40 190#define READ_ELEMENT_STATUS_PVOLTAG 0x80 191 u_int8_t edl[2]; /* element descriptor length */ 192 u_int8_t reserved; 193 u_int8_t nbytes[3]; /* byte count of all descriptors */ 194}; 195 196/* 197 * Format of a volume tag 198 */ 199 200struct volume_tag { 201 u_int8_t vif[32]; /* volume identification field */ 202 u_int8_t reserved[2]; 203 u_int8_t vsn[2]; /* volume sequence number */ 204}; 205 206struct read_element_status_descriptor { 207 u_int8_t eaddr[2]; /* element address */ 208 u_int8_t flags1; 209 210#define READ_ELEMENT_STATUS_FULL 0x01 211#define READ_ELEMENT_STATUS_IMPEXP 0x02 212#define READ_ELEMENT_STATUS_EXCEPT 0x04 213#define READ_ELEMENT_STATUS_ACCESS 0x08 214#define READ_ELEMENT_STATUS_EXENAB 0x10 215#define READ_ELEMENT_STATUS_INENAB 0x20 216 217#define READ_ELEMENT_STATUS_MT_MASK1 0x05 218#define READ_ELEMENT_STATUS_ST_MASK1 0x0c 219#define READ_ELEMENT_STATUS_IE_MASK1 0x3f 220#define READ_ELEMENT_STATUS_DT_MASK1 0x0c 221 222 u_int8_t reserved0; 223 u_int8_t sense_code; 224 u_int8_t sense_qual; 225 226 /* 227 * dt_scsi_flags and dt_scsi_addr are valid only on data transport 228 * elements. These bytes are undefined for all other element types. 229 */ 230 u_int8_t dt_scsi_flags; 231 232#define READ_ELEMENT_STATUS_DT_LUNMASK 0x07 233#define READ_ELEMENT_STATUS_DT_LUVALID 0x10 234#define READ_ELEMENT_STATUS_DT_IDVALID 0x20 235#define READ_ELEMENT_STATUS_DT_NOTBUS 0x80 236 237 u_int8_t dt_scsi_addr; 238 239 u_int8_t reserved1; 240 241 u_int8_t flags2; 242#define READ_ELEMENT_STATUS_INVERT 0x40 243#define READ_ELEMENT_STATUS_SVALID 0x80 244 u_int8_t ssea[2]; /* source storage element address */ 245 246 struct volume_tag pvoltag; /* omitted if PVOLTAG == 0 */ 247 struct volume_tag avoltag; /* omitted if AVOLTAG == 0 */ 248 249 /* Other data may follow */ 250}; 251 252/* XXX add data returned by REQUEST VOLUME ELEMENT ADDRESS */ 253 254/* Element type codes */ 255#define ELEMENT_TYPE_MASK 0x0f /* Note: these aren't bits */ 256#define ELEMENT_TYPE_ALL 0x00 257#define ELEMENT_TYPE_MT 0x01 258#define ELEMENT_TYPE_ST 0x02 259#define ELEMENT_TYPE_IE 0x03 260#define ELEMENT_TYPE_DT 0x04 261 262/* 263 * XXX The following definitions should be common to all SCSI device types. 264 */ 265#define PGCODE_MASK 0x3f /* valid page number bits in pg_code */ 266#define PGCODE_PS 0x80 /* indicates page is savable */ 267 268/* 269 * Send volume tag information to the changer 270 */ 271 272struct scsi_send_volume_tag { 273 u_int8_t opcode; 274#define SEND_VOLUME_TAG 0xb6 275 u_int8_t byte2; 276 u_int8_t ea[2]; /* element address */ 277 u_int8_t reserved2; 278 u_int8_t sac; /* send action code */ 279 280#define SEND_VOLUME_TAG_ASSERT_PRIMARY 0x08 281#define SEND_VOLUME_TAG_ASSERT_ALTERNATE 0x09 282#define SEND_VOLUME_TAG_REPLACE_PRIMARY 0x0a 283#define SEND_VOLUME_TAG_REPLACE_ALTERNATE 0x0b 284#define SEND_VOLUME_TAG_UNDEFINED_PRIMARY 0x0c 285#define SEND_VOLUME_TAG_UNDEFINED_ALTERNATE 0x0d 286 287 u_int8_t reserved4[2]; 288 u_int8_t pll[2]; /* parameter list length */ 289 u_int8_t reserved5; 290 u_int8_t control; 291}; 292 293/* 294 * Parameter format for SEND VOLUME TAG 295 */ 296 297struct scsi_send_volume_tag_parameters { 298 u_int8_t vitf[32]; /* volume tag identification template */ 299 u_int8_t reserved1[2]; 300 u_int8_t minvsn[2]; /* minimum volume sequence number */ 301 u_int8_t reserved2[2]; 302 u_int8_t maxvsn[2]; /* maximum volume sequence number */ 303}; 304 305/* 306 * Device capabilities page. 307 * 308 * This page defines characteristics of the elemenet types in the 309 * medium changer device. 310 * 311 * Note in the definitions below, the following abbreviations are 312 * used: 313 * MT Medium transport element (picker) 314 * ST Storage transport element (slot) 315 * IE Import/export element (portal) 316 * DT Data tranfer element (tape/disk drive) 317 */ 318struct page_device_capabilities { 319 u_int8_t pg_code; /* page code (0x1f) */ 320 u_int8_t pg_length; /* page length (0x12) */ 321 322 /* 323 * The STOR_xx bits indicate that an element of a given 324 * type may provide independent storage for a unit of 325 * media. The top four bits of this value are reserved. 326 */ 327 u_int8_t stor; 328#define STOR_MT 0x01 329#define STOR_ST 0x02 330#define STOR_IE 0x04 331#define STOR_DT 0x08 332 333 u_int8_t reserved0; 334 335 /* 336 * The MOVE_TO_yy bits indicate the changer supports 337 * moving a unit of medium from an element of a given type to an 338 * element of type yy. This is used to determine if a given 339 * MOVE MEDIUM command is legal. The top four bits of each 340 * of these values are reserved. 341 */ 342 u_int8_t move_from_mt; 343 u_int8_t move_from_st; 344 u_int8_t move_from_ie; 345 u_int8_t move_from_dt; 346#define MOVE_TO_MT 0x01 347#define MOVE_TO_ST 0x02 348#define MOVE_TO_IE 0x04 349#define MOVE_TO_DT 0x08 350 351 u_int8_t reserved1[4]; 352 353 /* 354 * Similar to above, but for EXCHANGE MEDIUM. 355 */ 356 u_int8_t exchange_with_mt; 357 u_int8_t exchange_with_st; 358 u_int8_t exchange_with_ie; 359 u_int8_t exchange_with_dt; 360#define EXCHANGE_WITH_MT 0x01 361#define EXCHANGE_WITH_ST 0x02 362#define EXCHANGE_WITH_IE 0x04 363#define EXCHANGE_WITH_DT 0x08 364}; 365 366/* 367 * Medium changer elemement address assignment page. 368 * 369 * Some of these fields can be a little confusing, so an explanation 370 * is in order. 371 * 372 * Each component within a a medium changer apparatus is called an 373 * "element". 374 * 375 * The "medium transport element address" is the address of the first 376 * picker (robotic arm). "Number of medium transport elements" tells 377 * us how many pickers exist in the changer. 378 * 379 * The "first storage element address" is the address of the first 380 * slot in the tape or disk magazine. "Number of storage elements" tells 381 * us how many slots exist in the changer. 382 * 383 * The "first import/export element address" is the address of the first 384 * medium portal accessible both by the medium changer and an outside 385 * human operator. This is where the changer might deposit tapes destined 386 * for some vault. The "number of import/export elements" tells us 387 * not many of these portals exist in the changer. NOTE: this number may 388 * be 0. 389 * 390 * The "first data transfer element address" is the address of the first 391 * tape or disk drive in the changer. "Number of data transfer elements" 392 * tells us how many drives exist in the changer. 393 */ 394struct page_element_address_assignment { 395 u_int8_t pg_code; /* page code (0x1d) */ 396 u_int8_t pg_length; /* page length (0x12) */ 397 398 /* Medium transport element address */ 399 u_int8_t mtea[2]; 400 401 /* Number of medium transport elements */ 402 u_int8_t nmte[2]; 403 404 /* First storage element address */ 405 u_int8_t fsea[2]; 406 407 /* Number of storage elements */ 408 u_int8_t nse[2]; 409 410 /* First import/export element address */ 411 u_int8_t fieea[2]; 412 413 /* Number of import/export elements */ 414 u_int8_t niee[2]; 415 416 /* First data transfer element address */ 417 u_int8_t fdtea[2]; 418 419 /* Number of data trafer elements */ 420 u_int8_t ndte[2]; 421 422 u_int8_t reserved[2]; 423}; 424 425/* 426 * Transport geometry parameters page. 427 * 428 * Defines whether each medium transport element is a member of a set of 429 * elements that share a common robotics subsystem and whether the element 430 * is capable of media rotation. One transport geometry descriptor is 431 * transferred for each medium transport element, beginning with the first 432 * medium transport element (other than the default transport element address 433 * of 0). 434 */ 435struct page_transport_geometry_parameters { 436 u_int8_t pg_code; /* page code (0x1e) */ 437 u_int8_t pg_length; /* page length; variable */ 438 439 /* Transport geometry descriptor(s) are here. */ 440 441 u_int8_t misc; 442#define CAN_ROTATE 0x01 443 444 /* Member number in transport element set. */ 445 u_int8_t member; 446}; 447 448__BEGIN_DECLS 449void scsi_move_medium(struct ccb_scsiio *csio, u_int32_t retries, 450 void (*cbfcnp)(struct cam_periph *, union ccb *), 451 u_int8_t tag_action, u_int32_t tea, u_int32_t src, 452 u_int32_t dst, int invert, u_int8_t sense_len, 453 u_int32_t timeout); 454 455void scsi_exchange_medium(struct ccb_scsiio *csio, u_int32_t retries, 456 void (*cbfcnp)(struct cam_periph *, union ccb *), 457 u_int8_t tag_action, u_int32_t tea, u_int32_t src, 458 u_int32_t dst1, u_int32_t dst2, int invert1, 459 int invert2, u_int8_t sense_len, u_int32_t timeout); 460 461void scsi_position_to_element(struct ccb_scsiio *csio, u_int32_t retries, 462 void (*cbfcnp)(struct cam_periph *, union ccb *), 463 u_int8_t tag_action, u_int32_t tea, u_int32_t dst, 464 int invert, u_int8_t sense_len, 465 u_int32_t timeout); 466 467void scsi_read_element_status(struct ccb_scsiio *csio, u_int32_t retries, 468 void (*cbfcnp)(struct cam_periph *, union ccb *), 469 u_int8_t tag_action, int voltag, u_int32_t sea, 470 u_int32_t count, u_int8_t *data_ptr, 471 u_int32_t dxfer_len, u_int8_t sense_len, 472 u_int32_t timeout); 473 474void scsi_initialize_element_status(struct ccb_scsiio *csio, u_int32_t retries, 475 void (*cbfcnp)(struct cam_periph *, union ccb *), 476 u_int8_t tag_action, u_int8_t sense_len, 477 u_int32_t timeout); 478void scsi_send_volume_tag(struct ccb_scsiio *csio, u_int32_t retries, 479 void (*cbfcnp)(struct cam_periph *, union ccb *), 480 u_int8_t tag_action, 481 u_int16_t element_address, 482 u_int8_t send_action_code, 483 struct scsi_send_volume_tag_parameters *parameters, 484 u_int8_t sense_len, u_int32_t timeout); 485__END_DECLS 486 487#endif /* _SCSI_SCSI_CH_H */
|