10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*2148Spd144616 * Common Development and Distribution License (the "License"). 6*2148Spd144616 * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*2148Spd144616 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #ifndef _SYS_SCSI_IMPL_COMMANDS_H 270Sstevel@tonic-gate #define _SYS_SCSI_IMPL_COMMANDS_H 280Sstevel@tonic-gate 290Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 300Sstevel@tonic-gate 310Sstevel@tonic-gate #ifdef __cplusplus 320Sstevel@tonic-gate extern "C" { 330Sstevel@tonic-gate #endif 340Sstevel@tonic-gate 350Sstevel@tonic-gate /* 360Sstevel@tonic-gate * Implementation dependent command definitions. 370Sstevel@tonic-gate * This file is included by <sys/scsi/generic/commands.h> 380Sstevel@tonic-gate */ 390Sstevel@tonic-gate 400Sstevel@tonic-gate /* 410Sstevel@tonic-gate * Implementation dependent view of a SCSI command descriptor block 420Sstevel@tonic-gate */ 430Sstevel@tonic-gate 440Sstevel@tonic-gate /* 450Sstevel@tonic-gate * Standard SCSI control blocks definitions. 460Sstevel@tonic-gate * 470Sstevel@tonic-gate * These go in or out over the SCSI bus. 480Sstevel@tonic-gate * 490Sstevel@tonic-gate * The first 8 bits of the command block are the same for all 500Sstevel@tonic-gate * defined command groups. The first byte is an operation which consists 510Sstevel@tonic-gate * of a command code component and a group code component. 520Sstevel@tonic-gate * 530Sstevel@tonic-gate * The group code determines the length of the rest of the command. 540Sstevel@tonic-gate * Group 0 commands are 6 bytes, Group 1 and 2 are 10 bytes, Group 4 550Sstevel@tonic-gate * are 16 bytes, and Group 5 are 12 bytes. Groups 3 is Reserved. 560Sstevel@tonic-gate * Groups 6 and 7 are Vendor Unique. 570Sstevel@tonic-gate * 580Sstevel@tonic-gate */ 590Sstevel@tonic-gate #define CDB_SIZE CDB_GROUP5 /* deprecated, do not use */ 600Sstevel@tonic-gate #define SCSI_CDB_SIZE CDB_GROUP4 /* sizeof (union scsi_cdb) */ 610Sstevel@tonic-gate 620Sstevel@tonic-gate union scsi_cdb { /* scsi command description block */ 630Sstevel@tonic-gate struct { 640Sstevel@tonic-gate uchar_t cmd; /* cmd code (byte 0) */ 650Sstevel@tonic-gate #if defined(_BIT_FIELDS_LTOH) 660Sstevel@tonic-gate uchar_t tag :5; /* rest of byte 1 */ 670Sstevel@tonic-gate uchar_t lun :3; /* lun (byte 1) (reserved in SCSI-3) */ 680Sstevel@tonic-gate #elif defined(_BIT_FIELDS_HTOL) 690Sstevel@tonic-gate uchar_t lun :3, /* lun (byte 1) (reserved in SCSI-3) */ 700Sstevel@tonic-gate tag :5; /* rest of byte 1 */ 710Sstevel@tonic-gate #else 720Sstevel@tonic-gate #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 730Sstevel@tonic-gate #endif /* _BIT_FIELDS_LTOH */ 740Sstevel@tonic-gate union { 750Sstevel@tonic-gate 760Sstevel@tonic-gate uchar_t scsi[SCSI_CDB_SIZE-2]; 770Sstevel@tonic-gate /* 780Sstevel@tonic-gate * G R O U P 0 F O R M A T (6 bytes) 790Sstevel@tonic-gate */ 800Sstevel@tonic-gate #define scc_cmd cdb_un.cmd 810Sstevel@tonic-gate #define scc_lun cdb_un.lun 820Sstevel@tonic-gate #define g0_addr2 cdb_un.tag 830Sstevel@tonic-gate #define g0_addr1 cdb_un.sg.g0.addr1 840Sstevel@tonic-gate #define g0_addr0 cdb_un.sg.g0.addr0 850Sstevel@tonic-gate #define g0_count0 cdb_un.sg.g0.count0 860Sstevel@tonic-gate #define g0_vu_1 cdb_un.sg.g0.vu_57 870Sstevel@tonic-gate #define g0_vu_0 cdb_un.sg.g0.vu_56 880Sstevel@tonic-gate #define g0_naca cdb_un.sg.g0.naca 890Sstevel@tonic-gate #define g0_flag cdb_un.sg.g0.flag 900Sstevel@tonic-gate #define g0_link cdb_un.sg.g0.link 910Sstevel@tonic-gate /* 920Sstevel@tonic-gate * defines for SCSI tape cdb. 930Sstevel@tonic-gate */ 940Sstevel@tonic-gate #define t_code cdb_un.tag 950Sstevel@tonic-gate #define high_count cdb_un.sg.g0.addr1 960Sstevel@tonic-gate #define mid_count cdb_un.sg.g0.addr0 970Sstevel@tonic-gate #define low_count cdb_un.sg.g0.count0 980Sstevel@tonic-gate struct scsi_g0 { 990Sstevel@tonic-gate uchar_t addr1; /* middle part of address */ 1000Sstevel@tonic-gate uchar_t addr0; /* low part of address */ 1010Sstevel@tonic-gate uchar_t count0; /* usually block count */ 1020Sstevel@tonic-gate #if defined(_BIT_FIELDS_LTOH) 1030Sstevel@tonic-gate uchar_t link :1; /* another command follows */ 1040Sstevel@tonic-gate uchar_t flag :1; /* interrupt when done */ 1050Sstevel@tonic-gate uchar_t naca :1; /* normal ACA */ 1060Sstevel@tonic-gate uchar_t rsvd :3; /* reserved */ 1070Sstevel@tonic-gate uchar_t vu_56 :1; /* vendor unique (byte 5 bit6) */ 1080Sstevel@tonic-gate uchar_t vu_57 :1; /* vendor unique (byte 5 bit7) */ 1090Sstevel@tonic-gate #elif defined(_BIT_FIELDS_HTOL) 1100Sstevel@tonic-gate uchar_t vu_57 :1; /* vendor unique (byte 5 bit 7) */ 1110Sstevel@tonic-gate uchar_t vu_56 :1; /* vendor unique (byte 5 bit 6) */ 1120Sstevel@tonic-gate uchar_t rsvd :3; /* reserved */ 1130Sstevel@tonic-gate uchar_t naca :1; /* normal ACA */ 1140Sstevel@tonic-gate uchar_t flag :1; /* interrupt when done */ 1150Sstevel@tonic-gate uchar_t link :1; /* another command follows */ 1160Sstevel@tonic-gate #else 1170Sstevel@tonic-gate #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 1180Sstevel@tonic-gate #endif /* _BIT_FIELDS_LTOH */ 1190Sstevel@tonic-gate } g0; 1200Sstevel@tonic-gate 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate /* 1230Sstevel@tonic-gate * G R O U P 1, 2 F O R M A T (10 byte) 1240Sstevel@tonic-gate */ 1250Sstevel@tonic-gate #define g1_reladdr cdb_un.tag 1260Sstevel@tonic-gate #define g1_rsvd0 cdb_un.sg.g1.rsvd1 1270Sstevel@tonic-gate #define g1_addr3 cdb_un.sg.g1.addr3 /* msb */ 1280Sstevel@tonic-gate #define g1_addr2 cdb_un.sg.g1.addr2 1290Sstevel@tonic-gate #define g1_addr1 cdb_un.sg.g1.addr1 1300Sstevel@tonic-gate #define g1_addr0 cdb_un.sg.g1.addr0 /* lsb */ 1310Sstevel@tonic-gate #define g1_count1 cdb_un.sg.g1.count1 /* msb */ 1320Sstevel@tonic-gate #define g1_count0 cdb_un.sg.g1.count0 /* lsb */ 1330Sstevel@tonic-gate #define g1_vu_1 cdb_un.sg.g1.vu_97 1340Sstevel@tonic-gate #define g1_vu_0 cdb_un.sg.g1.vu_96 1350Sstevel@tonic-gate #define g1_naca cdb_un.sg.g1.naca 1360Sstevel@tonic-gate #define g1_flag cdb_un.sg.g1.flag 1370Sstevel@tonic-gate #define g1_link cdb_un.sg.g1.link 1380Sstevel@tonic-gate struct scsi_g1 { 1390Sstevel@tonic-gate uchar_t addr3; /* most sig. byte of address */ 1400Sstevel@tonic-gate uchar_t addr2; 1410Sstevel@tonic-gate uchar_t addr1; 1420Sstevel@tonic-gate uchar_t addr0; 1430Sstevel@tonic-gate uchar_t rsvd1; /* reserved (byte 6) */ 1440Sstevel@tonic-gate uchar_t count1; /* transfer length (msb) */ 1450Sstevel@tonic-gate uchar_t count0; /* transfer length (lsb) */ 1460Sstevel@tonic-gate #if defined(_BIT_FIELDS_LTOH) 1470Sstevel@tonic-gate uchar_t link :1; /* another command follows */ 1480Sstevel@tonic-gate uchar_t flag :1; /* interrupt when done */ 1490Sstevel@tonic-gate uchar_t naca :1; /* normal ACA */ 1500Sstevel@tonic-gate uchar_t rsvd0 :3; /* reserved */ 1510Sstevel@tonic-gate uchar_t vu_96 :1; /* vendor unique (byte 9 bit6) */ 1520Sstevel@tonic-gate uchar_t vu_97 :1; /* vendor unique (byte 9 bit7) */ 1530Sstevel@tonic-gate #elif defined(_BIT_FIELDS_HTOL) 1540Sstevel@tonic-gate uchar_t vu_97 :1; /* vendor unique (byte 9 bit 7) */ 1550Sstevel@tonic-gate uchar_t vu_96 :1; /* vendor unique (byte 9 bit 6) */ 1560Sstevel@tonic-gate uchar_t rsvd0 :3; /* reserved */ 1570Sstevel@tonic-gate uchar_t naca :1; /* normal ACA */ 1580Sstevel@tonic-gate uchar_t flag :1; /* interrupt when done */ 1590Sstevel@tonic-gate uchar_t link :1; /* another command follows */ 1600Sstevel@tonic-gate #else 1610Sstevel@tonic-gate #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 1620Sstevel@tonic-gate #endif /* _BIT_FIELDS_LTOH */ 1630Sstevel@tonic-gate } g1; 1640Sstevel@tonic-gate 1650Sstevel@tonic-gate /* 1660Sstevel@tonic-gate * G R O U P 4 F O R M A T (16 byte) 1670Sstevel@tonic-gate */ 1680Sstevel@tonic-gate #define g4_reladdr cdb_un.tag 1690Sstevel@tonic-gate #define g4_addr3 cdb_un.sg.g4.addr3 /* msb */ 1700Sstevel@tonic-gate #define g4_addr2 cdb_un.sg.g4.addr2 1710Sstevel@tonic-gate #define g4_addr1 cdb_un.sg.g4.addr1 1720Sstevel@tonic-gate #define g4_addr0 cdb_un.sg.g4.addr0 /* lsb */ 1730Sstevel@tonic-gate #define g4_addtl_cdb_data3 cdb_un.sg.g4.addtl_cdb_data3 1740Sstevel@tonic-gate #define g4_addtl_cdb_data2 cdb_un.sg.g4.addtl_cdb_data2 1750Sstevel@tonic-gate #define g4_addtl_cdb_data1 cdb_un.sg.g4.addtl_cdb_data1 1760Sstevel@tonic-gate #define g4_addtl_cdb_data0 cdb_un.sg.g4.addtl_cdb_data0 1770Sstevel@tonic-gate #define g4_count3 cdb_un.sg.g4.count3 /* msb */ 1780Sstevel@tonic-gate #define g4_count2 cdb_un.sg.g4.count2 1790Sstevel@tonic-gate #define g4_count1 cdb_un.sg.g4.count1 1800Sstevel@tonic-gate #define g4_count0 cdb_un.sg.g4.count0 /* lsb */ 1810Sstevel@tonic-gate #define g4_rsvd0 cdb_un.sg.g4.rsvd1 1820Sstevel@tonic-gate #define g4_vu_1 cdb_un.sg.g4.vu_157 1830Sstevel@tonic-gate #define g4_vu_0 cdb_un.sg.g4.vu_156 1840Sstevel@tonic-gate #define g4_naca cdb_un.sg.g4.naca 1850Sstevel@tonic-gate #define g4_flag cdb_un.sg.g4.flag 1860Sstevel@tonic-gate #define g4_link cdb_un.sg.g4.link 1870Sstevel@tonic-gate struct scsi_g4 { 1880Sstevel@tonic-gate uchar_t addr3; /* most sig. byte of address */ 1890Sstevel@tonic-gate uchar_t addr2; 1900Sstevel@tonic-gate uchar_t addr1; 1910Sstevel@tonic-gate uchar_t addr0; 1920Sstevel@tonic-gate uchar_t addtl_cdb_data3; 1930Sstevel@tonic-gate uchar_t addtl_cdb_data2; 1940Sstevel@tonic-gate uchar_t addtl_cdb_data1; 1950Sstevel@tonic-gate uchar_t addtl_cdb_data0; 1960Sstevel@tonic-gate uchar_t count3; /* transfer length (msb) */ 1970Sstevel@tonic-gate uchar_t count2; 1980Sstevel@tonic-gate uchar_t count1; 1990Sstevel@tonic-gate uchar_t count0; /* transfer length (lsb) */ 2000Sstevel@tonic-gate uchar_t rsvd1; /* reserved */ 2010Sstevel@tonic-gate #if defined(_BIT_FIELDS_LTOH) 2020Sstevel@tonic-gate uchar_t link :1; /* another command follows */ 2030Sstevel@tonic-gate uchar_t flag :1; /* interrupt when done */ 2040Sstevel@tonic-gate uchar_t naca :1; /* normal ACA */ 2050Sstevel@tonic-gate uchar_t rsvd0 :3; /* reserved */ 2060Sstevel@tonic-gate uchar_t vu_156 :1; /* vendor unique (byte 15 bit6) */ 2070Sstevel@tonic-gate uchar_t vu_157 :1; /* vendor unique (byte 15 bit7) */ 2080Sstevel@tonic-gate #elif defined(_BIT_FIELDS_HTOL) 2090Sstevel@tonic-gate uchar_t vu_157 :1; /* vendor unique (byte 15 bit 7) */ 2100Sstevel@tonic-gate uchar_t vu_156 :1; /* vendor unique (byte 15 bit 6) */ 2110Sstevel@tonic-gate uchar_t rsvd0 :3; /* reserved */ 2120Sstevel@tonic-gate uchar_t naca :1; /* normal ACA */ 2130Sstevel@tonic-gate uchar_t flag :1; /* interrupt when done */ 2140Sstevel@tonic-gate uchar_t link :1; /* another command follows */ 2150Sstevel@tonic-gate #else 2160Sstevel@tonic-gate #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 2170Sstevel@tonic-gate #endif /* _BIT_FIELDS_LTOH */ 2180Sstevel@tonic-gate } g4; 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate /* 2210Sstevel@tonic-gate * G R O U P 5 F O R M A T (12 byte) 2220Sstevel@tonic-gate */ 2230Sstevel@tonic-gate #define scc5_reladdr cdb_un.tag 2240Sstevel@tonic-gate #define scc5_addr3 cdb_un.sg.g5.addr3 /* msb */ 2250Sstevel@tonic-gate #define scc5_addr2 cdb_un.sg.g5.addr2 2260Sstevel@tonic-gate #define scc5_addr1 cdb_un.sg.g5.addr1 2270Sstevel@tonic-gate #define scc5_addr0 cdb_un.sg.g5.addr0 /* lsb */ 2280Sstevel@tonic-gate #define scc5_count3 cdb_un.sg.g5.count3 /* msb */ 2290Sstevel@tonic-gate #define scc5_count2 cdb_un.sg.g5.count2 2300Sstevel@tonic-gate #define scc5_count1 cdb_un.sg.g5.count1 2310Sstevel@tonic-gate #define scc5_count0 cdb_un.sg.g5.count0 /* lsb */ 2320Sstevel@tonic-gate #define scc5_rsvd0 cdb_un.sg.g5.rsvd1 2330Sstevel@tonic-gate #define scc5_vu_1 cdb_un.sg.g5.v117 2340Sstevel@tonic-gate #define scc5_vu_0 cdb_un.sg.g5.v116 2350Sstevel@tonic-gate #define scc5_naca cdb_un.sg.g5.naca 2360Sstevel@tonic-gate #define scc5_flag cdb_un.sg.g5.flag 2370Sstevel@tonic-gate #define scc5_link cdb_un.sg.g5.link 2380Sstevel@tonic-gate struct scsi_g5 { 2390Sstevel@tonic-gate uchar_t addr3; /* most sig. byte of address */ 2400Sstevel@tonic-gate uchar_t addr2; 2410Sstevel@tonic-gate uchar_t addr1; 2420Sstevel@tonic-gate uchar_t addr0; 2430Sstevel@tonic-gate uchar_t count3; /* most sig. byte of count */ 2440Sstevel@tonic-gate uchar_t count2; 2450Sstevel@tonic-gate uchar_t count1; 2460Sstevel@tonic-gate uchar_t count0; 2470Sstevel@tonic-gate uchar_t rsvd1; /* reserved */ 2480Sstevel@tonic-gate #if defined(_BIT_FIELDS_LTOH) 2490Sstevel@tonic-gate uchar_t link :1; /* another command follows */ 2500Sstevel@tonic-gate uchar_t flag :1; /* interrupt when done */ 2510Sstevel@tonic-gate uchar_t naca :1; /* normal ACA */ 2520Sstevel@tonic-gate uchar_t rsvd0 :3; /* reserved */ 2530Sstevel@tonic-gate uchar_t vu_116 :1; /* vendor unique (byte 11 bit6) */ 2540Sstevel@tonic-gate uchar_t vu_117 :1; /* vendor unique (byte 11 bit7) */ 2550Sstevel@tonic-gate #elif defined(_BIT_FIELDS_HTOL) 2560Sstevel@tonic-gate uchar_t vu_117 :1; /* vendor unique (byte 11 bit 7) */ 2570Sstevel@tonic-gate uchar_t vu_116 :1; /* vendor unique (byte 11 bit 6) */ 2580Sstevel@tonic-gate uchar_t rsvd0 :3; /* reserved */ 2590Sstevel@tonic-gate uchar_t naca :1; /* normal ACA */ 2600Sstevel@tonic-gate uchar_t flag :1; /* interrupt when done */ 2610Sstevel@tonic-gate uchar_t link :1; /* another command follows */ 2620Sstevel@tonic-gate #else 2630Sstevel@tonic-gate #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 2640Sstevel@tonic-gate #endif /* _BIT_FIELDS_LTOH */ 2650Sstevel@tonic-gate } g5; 2660Sstevel@tonic-gate }sg; 2670Sstevel@tonic-gate } cdb_un; 2680Sstevel@tonic-gate uchar_t cdb_opaque[SCSI_CDB_SIZE]; /* addressed as opaque char array */ 2690Sstevel@tonic-gate uint_t cdb_long[SCSI_CDB_SIZE / sizeof (uint_t)]; /* as a word array */ 2700Sstevel@tonic-gate }; 2710Sstevel@tonic-gate 2720Sstevel@tonic-gate 2730Sstevel@tonic-gate /* 2740Sstevel@tonic-gate * Various useful Macros for SCSI commands 2750Sstevel@tonic-gate */ 2760Sstevel@tonic-gate 2770Sstevel@tonic-gate /* 278*2148Spd144616 * defines for getting/setting fields in data received from or destined for 279*2148Spd144616 * a SCSI device. These macros are necessary (in place of BE16/BE32/BE64) 280*2148Spd144616 * because the address to be read or written may not be on a proper alignment. 281*2148Spd144616 */ 282*2148Spd144616 283*2148Spd144616 #define SCSI_READ16(Sr16_Addr) \ 284*2148Spd144616 (((uint16_t)*((uint8_t *)(Sr16_Addr)) << 8) | \ 285*2148Spd144616 ((uint16_t)*((uint8_t *)((Sr16_Addr)+1)))) 286*2148Spd144616 287*2148Spd144616 #define SCSI_READ32(Sr32_Addr) \ 288*2148Spd144616 (((uint32_t)*((uint8_t *)(Sr32_Addr)) << 24) | \ 289*2148Spd144616 ((uint32_t)*((uint8_t *)((Sr32_Addr)+1)) << 16) | \ 290*2148Spd144616 ((uint32_t)*((uint8_t *)((Sr32_Addr)+2)) << 8) | \ 291*2148Spd144616 ((uint32_t)*((uint8_t *)((Sr32_Addr)+3)))) 292*2148Spd144616 293*2148Spd144616 #define SCSI_READ64(Sr64_Addr) \ 294*2148Spd144616 (((uint64_t)*((uint8_t *)(Sr64_Addr)) << 56) | \ 295*2148Spd144616 ((uint64_t)*((uint8_t *)((Sr64_Addr)+1)) << 48) | \ 296*2148Spd144616 ((uint64_t)*((uint8_t *)((Sr64_Addr)+2)) << 40) | \ 297*2148Spd144616 ((uint64_t)*((uint8_t *)((Sr64_Addr)+3)) << 32) | \ 298*2148Spd144616 ((uint64_t)*((uint8_t *)((Sr64_Addr)+4)) << 24) | \ 299*2148Spd144616 ((uint64_t)*((uint8_t *)((Sr64_Addr)+5)) << 16) | \ 300*2148Spd144616 ((uint64_t)*((uint8_t *)((Sr64_Addr)+6)) << 8) | \ 301*2148Spd144616 ((uint64_t)*((uint8_t *)((Sr64_Addr)+7)))) 302*2148Spd144616 303*2148Spd144616 #define SCSI_WRITE16(Sr16_Addr, Sr16_Val) \ 304*2148Spd144616 *((uint8_t *)(Sr16_Addr)) = (((uint16_t)(Sr16_Val) >> 8) & 0xff); \ 305*2148Spd144616 *(((uint8_t *)(Sr16_Addr))+1) = ((uint16_t)(Sr16_Val) & 0xff); 306*2148Spd144616 307*2148Spd144616 #define SCSI_WRITE32(Sr32_Addr, Sr32_Val) \ 308*2148Spd144616 *(uint8_t *)(Sr32_Addr) = (((uint32_t)(Sr32_Val) >> 24) & 0xff); \ 309*2148Spd144616 *(((uint8_t *)(Sr32_Addr))+1) = \ 310*2148Spd144616 (((uint32_t)(Sr32_Val) >> 16) & 0xff); \ 311*2148Spd144616 *(((uint8_t *)(Sr32_Addr))+2) = (((uint32_t)(Sr32_Val) >> 8) & 0xff); \ 312*2148Spd144616 *(((uint8_t *)(Sr32_Addr))+3) = (((uint32_t)(Sr32_Val)) & 0xff); 313*2148Spd144616 314*2148Spd144616 #define SCSI_WRITE64(Sr64_Addr, Sr64_Val) \ 315*2148Spd144616 *(uint8_t *)(Sr64_Addr) = (((uint64_t)(Sr64_Val) >> 56) & 0xff); \ 316*2148Spd144616 *(((uint8_t *)(Sr64_Addr))+1) = \ 317*2148Spd144616 (((uint64_t)(Sr64_Val) >> 48) & 0xff); \ 318*2148Spd144616 *(((uint8_t *)(Sr64_Addr))+2) = \ 319*2148Spd144616 (((uint64_t)(Sr64_Val) >> 40) & 0xff); \ 320*2148Spd144616 *(((uint8_t *)(Sr64_Addr))+3) = \ 321*2148Spd144616 (((uint64_t)(Sr64_Val) >> 32) & 0xff); \ 322*2148Spd144616 *(((uint8_t *)(Sr64_Addr))+4) = \ 323*2148Spd144616 (((uint64_t)(Sr64_Val) >> 24) & 0xff); \ 324*2148Spd144616 *(((uint8_t *)(Sr64_Addr))+5) = \ 325*2148Spd144616 (((uint64_t)(Sr64_Val) >> 16) & 0xff); \ 326*2148Spd144616 *(((uint8_t *)(Sr64_Addr))+6) = \ 327*2148Spd144616 (((uint64_t)(Sr64_Val) >> 8) & 0xff); \ 328*2148Spd144616 *(((uint8_t *)(Sr64_Addr))+7) = (((uint64_t)(Sr64_Val)) & 0xff); 329*2148Spd144616 330*2148Spd144616 /* 3310Sstevel@tonic-gate * defines for getting/setting fields within the various command groups 3320Sstevel@tonic-gate */ 3330Sstevel@tonic-gate 3340Sstevel@tonic-gate #define GETCMD(cdb) ((cdb)->scc_cmd & 0x1F) 3350Sstevel@tonic-gate #define GETGROUP(cdb) (CDB_GROUPID((cdb)->scc_cmd)) 3360Sstevel@tonic-gate 3370Sstevel@tonic-gate #define FORMG0COUNT(cdb, cnt) (cdb)->g0_count0 = (cnt) 3380Sstevel@tonic-gate 3390Sstevel@tonic-gate #define FORMG0ADDR(cdb, addr) (cdb)->g0_addr2 = (addr) >> 16; \ 3400Sstevel@tonic-gate (cdb)->g0_addr1 = ((addr) >> 8) & 0xFF; \ 3410Sstevel@tonic-gate (cdb)->g0_addr0 = (addr) & 0xFF 3420Sstevel@tonic-gate 3430Sstevel@tonic-gate #define GETG0ADDR(cdb) (((cdb)->g0_addr2 & 0x1F) << 16) + \ 3440Sstevel@tonic-gate ((cdb)->g0_addr1 << 8) + ((cdb)->g0_addr0) 3450Sstevel@tonic-gate 3460Sstevel@tonic-gate #define GETG0TAG(cdb) ((cdb)->g0_addr2) 3470Sstevel@tonic-gate 3480Sstevel@tonic-gate #define FORMG0COUNT_S(cdb, cnt) (cdb)->high_count = (cnt) >> 16; \ 3490Sstevel@tonic-gate (cdb)->mid_count = ((cnt) >> 8) & 0xFF; \ 3500Sstevel@tonic-gate (cdb)->low_count = (cnt) & 0xFF 3510Sstevel@tonic-gate 3520Sstevel@tonic-gate #define FORMG1COUNT(cdb, cnt) (cdb)->g1_count1 = ((cnt) >> 8); \ 3530Sstevel@tonic-gate (cdb)->g1_count0 = (cnt) & 0xFF 3540Sstevel@tonic-gate 3550Sstevel@tonic-gate #define FORMG1ADDR(cdb, addr) (cdb)->g1_addr3 = (addr) >> 24; \ 3560Sstevel@tonic-gate (cdb)->g1_addr2 = ((addr) >> 16) & 0xFF; \ 3570Sstevel@tonic-gate (cdb)->g1_addr1 = ((addr) >> 8) & 0xFF; \ 3580Sstevel@tonic-gate (cdb)->g1_addr0 = (addr) & 0xFF 3590Sstevel@tonic-gate 3600Sstevel@tonic-gate #define GETG1ADDR(cdb) ((cdb)->g1_addr3 << 24) + \ 3610Sstevel@tonic-gate ((cdb)->g1_addr2 << 16) + \ 3620Sstevel@tonic-gate ((cdb)->g1_addr1 << 8) + \ 3630Sstevel@tonic-gate ((cdb)->g1_addr0) 3640Sstevel@tonic-gate 3650Sstevel@tonic-gate #define GETG1TAG(cdb) (cdb)->g1_reladdr 3660Sstevel@tonic-gate 3670Sstevel@tonic-gate #define FORMG4COUNT(cdb, cnt) (cdb)->g4_count3 = ((cnt) >> 24); \ 3680Sstevel@tonic-gate (cdb)->g4_count2 = ((cnt) >> 16) & 0xFF; \ 3690Sstevel@tonic-gate (cdb)->g4_count1 = ((cnt) >> 8) & 0xFF; \ 3700Sstevel@tonic-gate (cdb)->g4_count0 = (cnt) & 0xFF 3710Sstevel@tonic-gate 3720Sstevel@tonic-gate #define FORMG4LONGADDR(cdb, addr) (cdb)->g4_addr3 = (addr) >> 56; \ 3730Sstevel@tonic-gate (cdb)->g4_addr2 = \ 3740Sstevel@tonic-gate ((addr) >> 48) & 0xFF; \ 3750Sstevel@tonic-gate (cdb)->g4_addr1 = \ 3760Sstevel@tonic-gate ((addr) >> 40) & 0xFF; \ 3770Sstevel@tonic-gate (cdb)->g4_addr0 = \ 3780Sstevel@tonic-gate ((addr) >> 32) & 0xFF; \ 3790Sstevel@tonic-gate (cdb)->g4_addtl_cdb_data3 = \ 3800Sstevel@tonic-gate ((addr) >> 24) & 0xFF; \ 3810Sstevel@tonic-gate (cdb)->g4_addtl_cdb_data2 = \ 3820Sstevel@tonic-gate ((addr) >> 16) & 0xFF; \ 3830Sstevel@tonic-gate (cdb)->g4_addtl_cdb_data1 = \ 3840Sstevel@tonic-gate ((addr) >> 8) & 0xFF; \ 3850Sstevel@tonic-gate (cdb)->g4_addtl_cdb_data0 = \ 3860Sstevel@tonic-gate (addr) & 0xFF 3870Sstevel@tonic-gate 3880Sstevel@tonic-gate #define FORMG4ADDR(cdb, addr) (cdb)->g4_addr3 = (addr) >> 24; \ 3890Sstevel@tonic-gate (cdb)->g4_addr2 = ((addr) >> 16) & 0xFF; \ 3900Sstevel@tonic-gate (cdb)->g4_addr1 = ((addr) >> 8) & 0xFF; \ 3910Sstevel@tonic-gate (cdb)->g4_addr0 = (addr) & 0xFF 3920Sstevel@tonic-gate 3930Sstevel@tonic-gate #define FORMG4ADDTL(cdb, addtl_cdb_data) (cdb)->g4_addtl_cdb_data3 = \ 3940Sstevel@tonic-gate (addtl_cdb_data) >> 24; \ 3950Sstevel@tonic-gate (cdb)->g4_addtl_cdb_data2 = \ 3960Sstevel@tonic-gate ((addtl_cdb_data) >> 16) & 0xFF; \ 3970Sstevel@tonic-gate (cdb)->g4_addtl_cdb_data1 = \ 3980Sstevel@tonic-gate ((addtl_cdb_data) >> 8) & 0xFF; \ 3990Sstevel@tonic-gate (cdb)->g4_addtl_cdb_data0 = \ 4000Sstevel@tonic-gate (addtl_cdb_data) & 0xFF 4010Sstevel@tonic-gate 4020Sstevel@tonic-gate #define GETG4ADDR(cdb) ((cdb)->g4_addr3 << 24) + \ 4030Sstevel@tonic-gate ((cdb)->g4_addr2 << 16) + \ 4040Sstevel@tonic-gate ((cdb)->g4_addr1 << 8) + \ 4050Sstevel@tonic-gate ((cdb)->g4_addr0) 4060Sstevel@tonic-gate 4070Sstevel@tonic-gate #define GETG4ADDRTL(cdb) (((cdb)->g4_addtl_cdb_data3 << 24) + \ 4080Sstevel@tonic-gate ((cdb)->g4_addtl_cdb_data2 << 16) + \ 4090Sstevel@tonic-gate ((cdb)->g4_addtl_cdb_data1 << 8) + \ 4100Sstevel@tonic-gate (cdb)->g4_addtl_cdb_data0) 4110Sstevel@tonic-gate 4120Sstevel@tonic-gate #define GETG4TAG(cdb) (cdb)->g4_reladdr 4130Sstevel@tonic-gate 4140Sstevel@tonic-gate #define FORMG5COUNT(cdb, cnt) (cdb)->scc5_count3 = ((cnt) >> 24); \ 4150Sstevel@tonic-gate (cdb)->scc5_count2 = ((cnt) >> 16) & 0xFF; \ 4160Sstevel@tonic-gate (cdb)->scc5_count1 = ((cnt) >> 8) & 0xFF; \ 4170Sstevel@tonic-gate (cdb)->scc5_count0 = (cnt) & 0xFF 4180Sstevel@tonic-gate 4190Sstevel@tonic-gate #define FORMG5ADDR(cdb, addr) (cdb)->scc5_addr3 = (addr) >> 24; \ 4200Sstevel@tonic-gate (cdb)->scc5_addr2 = ((addr) >> 16) & 0xFF; \ 4210Sstevel@tonic-gate (cdb)->scc5_addr1 = ((addr) >> 8) & 0xFF; \ 4220Sstevel@tonic-gate (cdb)->scc5_addr0 = (addr) & 0xFF 4230Sstevel@tonic-gate 4240Sstevel@tonic-gate #define GETG5ADDR(cdb) ((cdb)->scc5_addr3 << 24) + \ 4250Sstevel@tonic-gate ((cdb)->scc5_addr2 << 16) + \ 4260Sstevel@tonic-gate ((cdb)->scc5_addr1 << 8) + \ 4270Sstevel@tonic-gate ((cdb)->scc5_addr0) 4280Sstevel@tonic-gate 4290Sstevel@tonic-gate #define GETG5TAG(cdb) (cdb)->scc5_reladdr 4300Sstevel@tonic-gate 4310Sstevel@tonic-gate 4320Sstevel@tonic-gate /* 4330Sstevel@tonic-gate * Shorthand macros for forming commands 4340Sstevel@tonic-gate * 4350Sstevel@tonic-gate * Works only with pre-SCSI-3 because they put lun as part of CDB. 4360Sstevel@tonic-gate * scsi_setup_cdb() is the recommended interface. 4370Sstevel@tonic-gate */ 4380Sstevel@tonic-gate 4390Sstevel@tonic-gate #define MAKECOM_COMMON(pktp, devp, flag, cmd) \ 4400Sstevel@tonic-gate (pktp)->pkt_address = (devp)->sd_address, \ 4410Sstevel@tonic-gate (pktp)->pkt_flags = (flag), \ 4420Sstevel@tonic-gate ((union scsi_cdb *)(pktp)->pkt_cdbp)->scc_cmd = (cmd), \ 4430Sstevel@tonic-gate ((union scsi_cdb *)(pktp)->pkt_cdbp)->scc_lun = \ 4440Sstevel@tonic-gate (pktp)->pkt_address.a_lun 4450Sstevel@tonic-gate 4460Sstevel@tonic-gate #define MAKECOM_G0(pktp, devp, flag, cmd, addr, cnt) \ 4470Sstevel@tonic-gate MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \ 4480Sstevel@tonic-gate FORMG0ADDR(((union scsi_cdb *)(pktp)->pkt_cdbp), (addr)), \ 4490Sstevel@tonic-gate FORMG0COUNT(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt)) 4500Sstevel@tonic-gate 4510Sstevel@tonic-gate #define MAKECOM_G0_S(pktp, devp, flag, cmd, cnt, fixbit) \ 4520Sstevel@tonic-gate MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \ 4530Sstevel@tonic-gate FORMG0COUNT_S(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt)), \ 4540Sstevel@tonic-gate ((union scsi_cdb *)(pktp)->pkt_cdbp)->t_code = (fixbit) 4550Sstevel@tonic-gate 4560Sstevel@tonic-gate #define MAKECOM_G1(pktp, devp, flag, cmd, addr, cnt) \ 4570Sstevel@tonic-gate MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \ 4580Sstevel@tonic-gate FORMG1ADDR(((union scsi_cdb *)(pktp)->pkt_cdbp), (addr)), \ 4590Sstevel@tonic-gate FORMG1COUNT(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt)) 4600Sstevel@tonic-gate 4610Sstevel@tonic-gate #define MAKECOM_G5(pktp, devp, flag, cmd, addr, cnt) \ 4620Sstevel@tonic-gate MAKECOM_COMMON((pktp), (devp), (flag), (cmd)), \ 4630Sstevel@tonic-gate FORMG5ADDR(((union scsi_cdb *)(pktp)->pkt_cdbp), (addr)), \ 4640Sstevel@tonic-gate FORMG5COUNT(((union scsi_cdb *)(pktp)->pkt_cdbp), (cnt)) 4650Sstevel@tonic-gate 4660Sstevel@tonic-gate 4670Sstevel@tonic-gate /* 4680Sstevel@tonic-gate * Direct access disk format defines and parameters. 4690Sstevel@tonic-gate * 4700Sstevel@tonic-gate * This is still pretty ugly and is mostly derived 4710Sstevel@tonic-gate * from Emulex MD21 specific formatting. 4720Sstevel@tonic-gate */ 4730Sstevel@tonic-gate 4740Sstevel@tonic-gate #define fmt_parm_bits g0_addr2 /* for format options */ 4750Sstevel@tonic-gate #define fmt_interleave g0_count0 /* for encode interleave */ 4760Sstevel@tonic-gate #define defect_list_descrip g1_addr3 /* list description bits */ 4770Sstevel@tonic-gate 4780Sstevel@tonic-gate /* 4790Sstevel@tonic-gate * defines for value of fmt_parm_bits. 4800Sstevel@tonic-gate */ 4810Sstevel@tonic-gate 4820Sstevel@tonic-gate #define FPB_BFI 0x04 /* bytes-from-index fmt */ 4830Sstevel@tonic-gate #define FPB_CMPLT 0x08 /* full defect list provided */ 4840Sstevel@tonic-gate #define FPB_DATA 0x10 /* defect list data provided */ 4850Sstevel@tonic-gate 4860Sstevel@tonic-gate /* 4870Sstevel@tonic-gate * Defines for value of defect_list_descrip. 4880Sstevel@tonic-gate */ 4890Sstevel@tonic-gate 4900Sstevel@tonic-gate #define DLD_MAN_DEF_LIST 0x10 /* manufacturer's defect list */ 4910Sstevel@tonic-gate #define DLD_GROWN_DEF_LIST 0x08 /* grown defect list */ 4920Sstevel@tonic-gate #define DLD_BLOCK_FORMAT 0x00 /* block format */ 4930Sstevel@tonic-gate #define DLD_BFI_FORMAT 0x04 /* bytes-from-index format */ 4940Sstevel@tonic-gate #define DLD_PS_FORMAT 0x05 /* physical sector format */ 4950Sstevel@tonic-gate 4960Sstevel@tonic-gate 4970Sstevel@tonic-gate /* 4980Sstevel@tonic-gate * Disk defect list - used by format command. 4990Sstevel@tonic-gate */ 5000Sstevel@tonic-gate #define RDEF_ALL 0 /* read all defects */ 5010Sstevel@tonic-gate #define RDEF_MANUF 1 /* read manufacturer's defects */ 5020Sstevel@tonic-gate #define RDEF_CKLEN 2 /* check length of manufacturer's list */ 5030Sstevel@tonic-gate #define ST506_NDEFECT 127 /* must fit in 1K controller buffer... */ 5040Sstevel@tonic-gate #define ESDI_NDEFECT ST506_NDEFECT 5050Sstevel@tonic-gate 5060Sstevel@tonic-gate struct scsi_bfi_defect { /* defect in bytes from index format */ 5070Sstevel@tonic-gate unsigned cyl : 24; 5080Sstevel@tonic-gate unsigned head : 8; 5090Sstevel@tonic-gate int bytes_from_index; 5100Sstevel@tonic-gate }; 5110Sstevel@tonic-gate 5120Sstevel@tonic-gate struct scsi_format_params { /* BFI format list */ 5130Sstevel@tonic-gate ushort_t reserved; 5140Sstevel@tonic-gate ushort_t length; 5150Sstevel@tonic-gate struct scsi_bfi_defect list[ESDI_NDEFECT]; 5160Sstevel@tonic-gate }; 5170Sstevel@tonic-gate 5180Sstevel@tonic-gate /* 5190Sstevel@tonic-gate * Defect list returned by READ_DEFECT_LIST command. 5200Sstevel@tonic-gate */ 5210Sstevel@tonic-gate struct scsi_defect_hdr { /* For getting defect list size */ 5220Sstevel@tonic-gate uchar_t reserved; 5230Sstevel@tonic-gate uchar_t descriptor; 5240Sstevel@tonic-gate ushort_t length; 5250Sstevel@tonic-gate }; 5260Sstevel@tonic-gate 5270Sstevel@tonic-gate struct scsi_defect_list { /* BFI format list */ 5280Sstevel@tonic-gate uchar_t reserved; 5290Sstevel@tonic-gate uchar_t descriptor; 5300Sstevel@tonic-gate ushort_t length; 5310Sstevel@tonic-gate struct scsi_bfi_defect list[ESDI_NDEFECT]; 5320Sstevel@tonic-gate }; 5330Sstevel@tonic-gate 5340Sstevel@tonic-gate /* 5350Sstevel@tonic-gate * 5360Sstevel@tonic-gate * Direct Access device Reassign Block parameter 5370Sstevel@tonic-gate * 5380Sstevel@tonic-gate * Defect list format used by reassign block command (logical block format). 5390Sstevel@tonic-gate * 5400Sstevel@tonic-gate * This defect list is limited to 1 defect, as that is the only way we use it. 5410Sstevel@tonic-gate * 5420Sstevel@tonic-gate */ 5430Sstevel@tonic-gate 5440Sstevel@tonic-gate struct scsi_reassign_blk { 5450Sstevel@tonic-gate ushort_t reserved; 5460Sstevel@tonic-gate ushort_t length; /* defect length in bytes (defects * 4) */ 5470Sstevel@tonic-gate uint_t defect; /* Logical block address of defect */ 5480Sstevel@tonic-gate }; 5490Sstevel@tonic-gate 5500Sstevel@tonic-gate /* 5510Sstevel@tonic-gate * Direct Access Device Capacity Structure -- 8 byte version 5520Sstevel@tonic-gate */ 5530Sstevel@tonic-gate 5540Sstevel@tonic-gate struct scsi_capacity { 5550Sstevel@tonic-gate uint_t capacity; 5560Sstevel@tonic-gate uint_t lbasize; 5570Sstevel@tonic-gate }; 5580Sstevel@tonic-gate 5590Sstevel@tonic-gate /* 5600Sstevel@tonic-gate * Direct Access Device Capacity Structure -- 16 byte version 5610Sstevel@tonic-gate */ 5620Sstevel@tonic-gate 5630Sstevel@tonic-gate struct scsi_capacity_16 { 5640Sstevel@tonic-gate uint64_t sc_capacity; 5650Sstevel@tonic-gate uint_t sc_lbasize; 5660Sstevel@tonic-gate #if defined(_BIT_FIELDS_LTOH) 5670Sstevel@tonic-gate uchar_t sc_rto_en :1; 5680Sstevel@tonic-gate uchar_t sc_prot_en :1; 5690Sstevel@tonic-gate uchar_t sc_rsvd0 :6; 5700Sstevel@tonic-gate #elif defined(_BIT_FIELDS_HTOL) 5710Sstevel@tonic-gate uchar_t sc_rsvd0 :6; 5720Sstevel@tonic-gate uchar_t sc_prot_en :1; 5730Sstevel@tonic-gate uchar_t sc_rto_en :1; 5740Sstevel@tonic-gate #else 5750Sstevel@tonic-gate #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 5760Sstevel@tonic-gate #endif /* _BIT_FIELDS_LTOH */ 5770Sstevel@tonic-gate uchar_t sc_rsvd1[19]; 5780Sstevel@tonic-gate }; 5790Sstevel@tonic-gate 5800Sstevel@tonic-gate #ifdef _KERNEL 5810Sstevel@tonic-gate 5820Sstevel@tonic-gate /* 5830Sstevel@tonic-gate * Functional versions of the above macros, and other functions. 5840Sstevel@tonic-gate * the makecom functions have been deprecated. Please use 5850Sstevel@tonic-gate * scsi_setup_cdb() 5860Sstevel@tonic-gate */ 5870Sstevel@tonic-gate 5880Sstevel@tonic-gate #ifdef __STDC__ 5890Sstevel@tonic-gate extern void makecom_g0(struct scsi_pkt *pkt, struct scsi_device *devp, 5900Sstevel@tonic-gate int flag, int cmd, int addr, int cnt); 5910Sstevel@tonic-gate extern void makecom_g0_s(struct scsi_pkt *pkt, struct scsi_device *devp, 5920Sstevel@tonic-gate int flag, int cmd, int cnt, int fixbit); 5930Sstevel@tonic-gate extern void makecom_g1(struct scsi_pkt *pkt, struct scsi_device *devp, 5940Sstevel@tonic-gate int flag, int cmd, int addr, int cnt); 5950Sstevel@tonic-gate extern void makecom_g5(struct scsi_pkt *pkt, struct scsi_device *devp, 5960Sstevel@tonic-gate int flag, int cmd, int addr, int cnt); 5970Sstevel@tonic-gate extern int scsi_setup_cdb(union scsi_cdb *cdbp, uchar_t cmd, uint_t addr, 5980Sstevel@tonic-gate uint_t cnt, uint_t addtl_cdb_data); 5990Sstevel@tonic-gate 6000Sstevel@tonic-gate #else /* __STDC__ */ 6010Sstevel@tonic-gate 6020Sstevel@tonic-gate extern void makecom_g0(); 6030Sstevel@tonic-gate extern void makecom_g0_s(); 6040Sstevel@tonic-gate extern void makecom_g1(); 6050Sstevel@tonic-gate extern void makecom_g5(); 6060Sstevel@tonic-gate extern int scsi_setup_cdb(); 6070Sstevel@tonic-gate 6080Sstevel@tonic-gate #endif /* __STDC__ */ 6090Sstevel@tonic-gate 6100Sstevel@tonic-gate #endif /* _KERNEL */ 6110Sstevel@tonic-gate 6120Sstevel@tonic-gate #ifdef __cplusplus 6130Sstevel@tonic-gate } 6140Sstevel@tonic-gate #endif 6150Sstevel@tonic-gate 6160Sstevel@tonic-gate #endif /* _SYS_SCSI_IMPL_COMMANDS_H */ 617