|
smartmontools SVN Rev 3317
Utility to control and monitor storage systems with "S.M.A.R.T."
|
00001 /* 00002 * os_linux.h 00003 * 00004 * Home page of code is: http://smartmontools.sourceforge.net 00005 * 00006 * Copyright (C) 2003-8 Bruce Allen <smartmontools-support@lists.sourceforge.net> 00007 * 00008 * Derived from code that was 00009 * 00010 * Written By: Adam Radford <linux@3ware.com> 00011 * Modifications By: Joel Jacobson <linux@3ware.com> 00012 * Arnaldo Carvalho de Melo <acme@conectiva.com.br> 00013 * Brad Strand <linux@3ware.com> 00014 * 00015 * Copyright (C) 1999-2003 3ware Inc. 00016 * 00017 * Kernel compatablity By: Andre Hedrick <andre@suse.com> 00018 * Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com> 00019 * 00020 * 00021 * This program is free software; you can redistribute it and/or modify 00022 * it under the terms of the GNU General Public License as published by 00023 * the Free Software Foundation; either version 2, or (at your option) 00024 * any later version. 00025 * 00026 * You should have received a copy of the GNU General Public License 00027 * (for example COPYING); if not, write to the Free Software Foundation, 00028 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00029 * 00030 * This code was originally developed as a Senior Thesis by Michael Cornwell 00031 * at the Concurrent Systems Laboratory (now part of the Storage Systems 00032 * Research Center), Jack Baskin School of Engineering, University of 00033 * California, Santa Cruz. http://ssrc.soe.ucsc.edu/ 00034 * 00035 */ 00036 00037 00038 #ifndef OS_LINUX_H_ 00039 #define OS_LINUX_H_ 00040 00041 #define OS_LINUX_H_CVSID "$Id: os_linux.h 3728 2012-12-13 17:57:50Z chrfranke $\n" 00042 00043 /* 00044 The following definitions/macros/prototypes are used for three 00045 different interfaces, referred to as "the three cases" below. 00046 CONTROLLER_3WARE_678K -- 6000, 7000, and 8000 controllers via /dev/sd? 00047 CONTROLLER_3WARE_678K_CHAR -- 6000, 7000, and 8000 controllers via /dev/twe? 00048 CONTROLLER_3WARE_9000_CHAR -- 9000 controllers via /dev/twa? 00049 */ 00050 00051 // USED FOR ALL THREE CASES 00052 00053 #define u32 unsigned int 00054 #define TW_OP_ATA_PASSTHRU 0x11 00055 #define MAX(x,y) ( (x)>(y)?(x):(y) ) 00056 00057 #pragma pack(1) 00058 /* Scatter gather list entry */ 00059 typedef struct TAG_TW_SG_Entry { 00060 unsigned int address; 00061 unsigned int length; 00062 } TW_SG_Entry; 00063 00064 /* Command header for ATA pass-thru. Note that for different 00065 drivers/interfaces the length of sg_list (here TW_ATA_PASS_SGL_MAX) 00066 is different. But it can be taken as same for all three cases 00067 because it's never used to define any other structures, and we 00068 never use anything in the sg_list or beyond! */ 00069 00070 #define TW_ATA_PASS_SGL_MAX 60 00071 00072 typedef struct TAG_TW_Passthru { 00073 struct { 00074 unsigned char opcode:5; 00075 unsigned char sgloff:3; 00076 } byte0; 00077 unsigned char size; 00078 unsigned char request_id; 00079 unsigned char unit; 00080 unsigned char status; // On return, contains 3ware STATUS register 00081 unsigned char flags; 00082 unsigned short param; 00083 unsigned short features; // On return, contains ATA ERROR register 00084 unsigned short sector_count; 00085 unsigned short sector_num; 00086 unsigned short cylinder_lo; 00087 unsigned short cylinder_hi; 00088 unsigned char drive_head; 00089 unsigned char command; // On return, contains ATA STATUS register 00090 TW_SG_Entry sg_list[TW_ATA_PASS_SGL_MAX]; 00091 unsigned char padding[12]; 00092 } TW_Passthru; 00093 00094 // the following are for the SCSI interface only 00095 00096 // Ioctl buffer: Note that this defn has changed in kernel tree... 00097 // Total size is 1041 bytes -- this is really weird 00098 00099 #define TW_IOCTL 0x80 00100 #define TW_ATA_PASSTHRU 0x1e 00101 00102 // Adam -- should this be #pramga packed? Otherwise table_id gets 00103 // moved for byte alignment. Without packing, input passthru for SCSI 00104 // ioctl is 31 bytes in. With packing it is 30 bytes in. 00105 typedef struct TAG_TW_Ioctl { 00106 int input_length; 00107 int output_length; 00108 unsigned char cdb[16]; 00109 unsigned char opcode; 00110 // This one byte of padding is missing from the typedefs in the 00111 // kernel code, but it is indeed present. We put it explicitly 00112 // here, so that the structure can be packed. Adam agrees with 00113 // this. 00114 unsigned char packing; 00115 unsigned short table_id; 00116 unsigned char parameter_id; 00117 unsigned char parameter_size_bytes; 00118 unsigned char unit_index; 00119 // Size up to here is 30 bytes + 1 padding! 00120 unsigned char input_data[499]; 00121 // Reserve lots of extra space for commands that set Sector Count 00122 // register to large values 00123 unsigned char output_data[512]; // starts 530 bytes in! 00124 // two more padding bytes here if structure NOT packed. 00125 } TW_Ioctl; 00126 00127 /* Ioctl buffer output -- SCSI interface only! */ 00128 typedef struct TAG_TW_Output { 00129 int padding[2]; 00130 char output_data[512]; 00131 } TW_Output; 00132 00133 // What follows is needed for 9000 char interface only 00134 00135 #define TW_IOCTL_FIRMWARE_PASS_THROUGH 0x108 00136 #define TW_MAX_SGL_LENGTH_9000 61 00137 00138 typedef struct TAG_TW_Ioctl_Driver_Command_9000 { 00139 unsigned int control_code; 00140 unsigned int status; 00141 unsigned int unique_id; 00142 unsigned int sequence_id; 00143 unsigned int os_specific; 00144 unsigned int buffer_length; 00145 } TW_Ioctl_Driver_Command_9000; 00146 00147 /* Command Packet */ 00148 typedef struct TW_Command_9000 { 00149 /* First DWORD */ 00150 struct { 00151 unsigned char opcode:5; 00152 unsigned char sgl_offset:3; 00153 } byte0; 00154 unsigned char size; 00155 unsigned char request_id; 00156 struct { 00157 unsigned char unit:4; 00158 unsigned char host_id:4; 00159 } byte3; 00160 /* Second DWORD */ 00161 unsigned char status; 00162 unsigned char flags; 00163 union { 00164 unsigned short block_count; 00165 unsigned short parameter_count; 00166 unsigned short message_credits; 00167 } byte6; 00168 union { 00169 struct { 00170 u32 lba; 00171 TW_SG_Entry sgl[TW_MAX_SGL_LENGTH_9000]; 00172 u32 padding; 00173 } io; 00174 struct { 00175 TW_SG_Entry sgl[TW_MAX_SGL_LENGTH_9000]; 00176 u32 padding[2]; 00177 } param; 00178 struct { 00179 u32 response_queue_pointer; 00180 u32 padding[125]; /* pad entire structure to 512 bytes */ 00181 } init_connection; 00182 struct { 00183 char version[504]; 00184 } ioctl_miniport_version; 00185 } byte8; 00186 } TW_Command_9000; 00187 00188 /* Command Packet for 9000+ controllers */ 00189 typedef struct TAG_TW_Command_Apache { 00190 struct { 00191 unsigned char opcode:5; 00192 unsigned char reserved:3; 00193 } command; 00194 unsigned char unit; 00195 unsigned short request_id; 00196 unsigned char sense_length; 00197 unsigned char sgl_offset; 00198 unsigned short sgl_entries; 00199 unsigned char cdb[16]; 00200 TW_SG_Entry sg_list[TW_MAX_SGL_LENGTH_9000]; 00201 } TW_Command_Apache; 00202 00203 /* New command packet header */ 00204 typedef struct TAG_TW_Command_Apache_Header { 00205 unsigned char sense_data[18]; 00206 struct { 00207 char reserved[4]; 00208 unsigned short error; 00209 unsigned char status; 00210 struct { 00211 unsigned char severity:3; 00212 unsigned char reserved:5; 00213 } substatus_block; 00214 } status_block; 00215 unsigned char err_specific_desc[102]; 00216 } TW_Command_Apache_Header; 00217 00218 /* This struct is a union of the 2 command packets */ 00219 typedef struct TAG_TW_Command_Full_9000 { 00220 TW_Command_Apache_Header header; 00221 union { 00222 TW_Command_9000 oldcommand; 00223 TW_Command_Apache newcommand; 00224 } command; 00225 unsigned char padding[384]; /* Pad to 1024 bytes */ 00226 } TW_Command_Full_9000; 00227 00228 typedef struct TAG_TW_Ioctl_Apache { 00229 TW_Ioctl_Driver_Command_9000 driver_command; 00230 char padding[488]; 00231 TW_Command_Full_9000 firmware_command; 00232 char data_buffer[1]; 00233 // three bytes of padding here if structure not packed! 00234 } TW_Ioctl_Buf_Apache; 00235 00236 00237 00238 // START OF DEFINITIONS FOR THE CHARACTER INTERFACE TO THE 00239 // 6000/7000/8000 drivers 00240 00241 #define TW_MAX_SGL_LENGTH 62 00242 #define TW_CMD_PACKET_WITH_DATA 0x1f 00243 00244 /* Command Packet */ 00245 typedef struct TW_Command { 00246 /* First DWORD */ 00247 struct { 00248 unsigned char opcode:5; 00249 unsigned char sgl_offset:3; 00250 } byte0; 00251 unsigned char size; 00252 unsigned char request_id; 00253 struct { 00254 unsigned char unit:4; 00255 unsigned char host_id:4; 00256 } byte3; 00257 /* Second DWORD */ 00258 unsigned char status; 00259 unsigned char flags; 00260 union { 00261 unsigned short block_count; 00262 unsigned short parameter_count; 00263 unsigned short message_credits; 00264 } byte6; 00265 union { 00266 struct { 00267 u32 lba; 00268 TW_SG_Entry sgl[TW_MAX_SGL_LENGTH]; 00269 u32 padding; /* pad to 512 bytes */ 00270 } io; 00271 struct { 00272 TW_SG_Entry sgl[TW_MAX_SGL_LENGTH]; 00273 u32 padding[2]; 00274 } param; 00275 struct { 00276 u32 response_queue_pointer; 00277 u32 padding[125]; 00278 } init_connection; 00279 struct { 00280 char version[504]; 00281 } ioctl_miniport_version; 00282 } byte8; 00283 } TW_Command; 00284 00285 typedef struct TAG_TW_New_Ioctl { 00286 unsigned int data_buffer_length; 00287 unsigned char padding [508]; 00288 TW_Command firmware_command; 00289 char data_buffer[1]; 00290 // three bytes of padding here 00291 } TW_New_Ioctl; 00292 #pragma pack() 00293 00294 #if 0 00295 // Useful for checking/understanding packing of 3ware data structures 00296 // above. 00297 void my(int x, char *y){ 00298 printf("The size of %30s is: %5d\n",y, x); 00299 return; 00300 } 00301 00302 int main() { 00303 TW_Ioctl tmp; 00304 my(sizeof(TW_SG_Entry),"TW_SG_Entry"); 00305 my(sizeof(TW_Passthru),"TW_Passthru"); 00306 my(sizeof(TW_Ioctl),"TW_Ioctl"); 00307 my(sizeof(TW_Output),"TW_Output"); 00308 my(sizeof(TW_Ioctl_Driver_Command_9000),"TW_Ioctl_Driver_Command_9000"); 00309 my(sizeof(TW_Command_9000),"TW_Command_9000"); 00310 my(sizeof(TW_Command_Apache),"TW_Command_Apache"); 00311 my(sizeof(TW_Command_Apache_Header),"TW_Command_Apache_Header"); 00312 my(sizeof(TW_Command_Full_9000),"TW_Command_Full_9000"); 00313 my(sizeof(TW_Ioctl_Buf_Apache),"TW_Ioctl_Buf_Apache"); 00314 my(sizeof(TW_Command),"TW_Command"); 00315 my(sizeof(TW_New_Ioctl),"TW_New_Ioctl"); 00316 printf("TW_Ioctl.table_id - start = %d (irrelevant)\n", 00317 (void *)&tmp.table_id - (void *)&tmp); 00318 printf("TW_Ioctl.input_data - start = %d (input passthru location)\n", 00319 (void *)&tmp.input_data - (void *)&tmp); 00320 printf("TW_Ioctl.output_data - start = %d (irrelevant)\n", 00321 (void *)&tmp.output_data - (void *)&tmp); 00322 return 0; 00323 } 00324 #endif 00325 00326 // The following definitions are from hdreg.h in the kernel source 00327 // tree. They don't carry any Copyright statements, but I think they 00328 // are primarily from Mark Lord and Andre Hedrick. 00329 typedef unsigned char task_ioreg_t; 00330 00331 typedef struct hd_drive_task_hdr { 00332 task_ioreg_t data; 00333 task_ioreg_t feature; 00334 task_ioreg_t sector_count; 00335 task_ioreg_t sector_number; 00336 task_ioreg_t low_cylinder; 00337 task_ioreg_t high_cylinder; 00338 task_ioreg_t device_head; 00339 task_ioreg_t command; 00340 } task_struct_t; 00341 00342 typedef union ide_reg_valid_s { 00343 unsigned all : 16; 00344 struct { 00345 unsigned data : 1; 00346 unsigned error_feature : 1; 00347 unsigned sector : 1; 00348 unsigned nsector : 1; 00349 unsigned lcyl : 1; 00350 unsigned hcyl : 1; 00351 unsigned select : 1; 00352 unsigned status_command : 1; 00353 unsigned data_hob : 1; 00354 unsigned error_feature_hob : 1; 00355 unsigned sector_hob : 1; 00356 unsigned nsector_hob : 1; 00357 unsigned lcyl_hob : 1; 00358 unsigned hcyl_hob : 1; 00359 unsigned select_hob : 1; 00360 unsigned control_hob : 1; 00361 } b; 00362 } ide_reg_valid_t; 00363 00364 typedef struct ide_task_request_s { 00365 task_ioreg_t io_ports[8]; 00366 task_ioreg_t hob_ports[8]; 00367 ide_reg_valid_t out_flags; 00368 ide_reg_valid_t in_flags; 00369 int data_phase; 00370 int req_cmd; 00371 unsigned long out_size; 00372 unsigned long in_size; 00373 } ide_task_request_t; 00374 00375 #define TASKFILE_NO_DATA 0x0000 00376 #define TASKFILE_IN 0x0001 00377 #define TASKFILE_OUT 0x0004 00378 #define HDIO_DRIVE_TASK_HDR_SIZE 8*sizeof(task_ioreg_t) 00379 #define IDE_DRIVE_TASK_NO_DATA 0 00380 #define IDE_DRIVE_TASK_IN 2 00381 #define IDE_DRIVE_TASK_OUT 3 00382 #define HDIO_DRIVE_CMD 0x031f 00383 #define HDIO_DRIVE_TASK 0x031e 00384 #define HDIO_DRIVE_TASKFILE 0x031d 00385 #define HDIO_GET_IDENTITY 0x030d 00386 00387 #define HPTIO_CTL 0x03ff // ioctl interface for HighPoint raid device 00388 00389 #endif /* OS_LINUX_H_ */
1.7.4