Annotation of embedaddon/smartmontools/os_linux.h, revision 1.1.1.2

1.1       misho       1: /* 
                      2:  *  os_linux.h
                      3:  * 
                      4:  * Home page of code is: http://smartmontools.sourceforge.net
                      5:  *
                      6:  * Copyright (C) 2003-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
                      7:  *
                      8:  * Derived from code that was
                      9:  *
                     10:  *  Written By: Adam Radford <linux@3ware.com>
                     11:  *  Modifications By: Joel Jacobson <linux@3ware.com>
                     12:  *                    Arnaldo Carvalho de Melo <acme@conectiva.com.br>
                     13:  *                    Brad Strand <linux@3ware.com>
                     14:  *
                     15:  *  Copyright (C) 1999-2003 3ware Inc.
                     16:  *
                     17:  *  Kernel compatablity By:     Andre Hedrick <andre@suse.com>
                     18:  *  Non-Copyright (C) 2000      Andre Hedrick <andre@suse.com>
                     19:  *
                     20:  *
                     21:  * This program is free software; you can redistribute it and/or modify
                     22:  * it under the terms of the GNU General Public License as published by
                     23:  * the Free Software Foundation; either version 2, or (at your option)
                     24:  * any later version.
                     25:  *
                     26:  * You should have received a copy of the GNU General Public License
1.1.1.2 ! misho      27:  * (for example COPYING); if not, write to the Free Software Foundation,
        !            28:  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1.1       misho      29:  *
                     30:  * This code was originally developed as a Senior Thesis by Michael Cornwell
                     31:  * at the Concurrent Systems Laboratory (now part of the Storage Systems
                     32:  * Research Center), Jack Baskin School of Engineering, University of
                     33:  * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
                     34:  * 
                     35:  */
                     36: 
                     37: 
                     38: #ifndef OS_LINUX_H_
                     39: #define OS_LINUX_H_
                     40: 
1.1.1.2 ! misho      41: #define OS_LINUX_H_CVSID "$Id: os_linux.h 3728 2012-12-13 17:57:50Z chrfranke $\n"
1.1       misho      42: 
                     43: /* 
                     44:    The following definitions/macros/prototypes are used for three
                     45:    different interfaces, referred to as "the three cases" below.
                     46:    CONTROLLER_3WARE_678K      -- 6000, 7000, and 8000 controllers via /dev/sd?
                     47:    CONTROLLER_3WARE_678K_CHAR -- 6000, 7000, and 8000 controllers via /dev/twe?
                     48:    CONTROLLER_3WARE_9000_CHAR -- 9000 controllers via /dev/twa?
                     49: */
                     50: 
                     51: // USED FOR ALL THREE CASES
                     52: 
                     53: #define u32 unsigned int
                     54: #define TW_OP_ATA_PASSTHRU 0x11
                     55: #define MAX(x,y) ( (x)>(y)?(x):(y) )
                     56: 
                     57: #pragma pack(1)
                     58: /* Scatter gather list entry */
                     59: typedef struct TAG_TW_SG_Entry {
                     60:   unsigned int address;
                     61:   unsigned int length;
                     62: } TW_SG_Entry;
                     63: 
                     64: /* Command header for ATA pass-thru.  Note that for different
                     65:    drivers/interfaces the length of sg_list (here TW_ATA_PASS_SGL_MAX)
                     66:    is different.  But it can be taken as same for all three cases
                     67:    because it's never used to define any other structures, and we
                     68:    never use anything in the sg_list or beyond! */
                     69: 
                     70: #define TW_ATA_PASS_SGL_MAX      60
                     71: 
                     72: typedef struct TAG_TW_Passthru {
                     73:   struct {
                     74:     unsigned char opcode:5;
                     75:     unsigned char sgloff:3;
                     76:   } byte0;
                     77:   unsigned char size;
                     78:   unsigned char request_id;
                     79:   unsigned char unit;
                     80:   unsigned char status;  // On return, contains 3ware STATUS register
                     81:   unsigned char flags;
                     82:   unsigned short param;
                     83:   unsigned short features;  // On return, contains ATA ERROR register
                     84:   unsigned short sector_count;
                     85:   unsigned short sector_num;
                     86:   unsigned short cylinder_lo;
                     87:   unsigned short cylinder_hi;
                     88:   unsigned char drive_head;
                     89:   unsigned char command; // On return, contains ATA STATUS register
                     90:   TW_SG_Entry sg_list[TW_ATA_PASS_SGL_MAX];
                     91:   unsigned char padding[12];
                     92: } TW_Passthru;
                     93: 
                     94: // the following are for the SCSI interface only 
                     95: 
                     96: // Ioctl buffer: Note that this defn has changed in kernel tree...
                     97: // Total size is 1041 bytes -- this is really weird
                     98: 
                     99: #define TW_IOCTL                 0x80
                    100: #define TW_ATA_PASSTHRU          0x1e
                    101: 
                    102: // Adam -- should this be #pramga packed? Otherwise table_id gets
                    103: // moved for byte alignment.  Without packing, input passthru for SCSI
                    104: // ioctl is 31 bytes in.  With packing it is 30 bytes in.
                    105: typedef struct TAG_TW_Ioctl { 
                    106:   int input_length;
                    107:   int output_length;
                    108:   unsigned char cdb[16];
                    109:   unsigned char opcode;
                    110:   // This one byte of padding is missing from the typedefs in the
                    111:   // kernel code, but it is indeed present.  We put it explicitly
                    112:   // here, so that the structure can be packed.  Adam agrees with
                    113:   // this.
                    114:   unsigned char packing;
                    115:   unsigned short table_id;
                    116:   unsigned char parameter_id;
                    117:   unsigned char parameter_size_bytes;
                    118:   unsigned char unit_index;
                    119:   // Size up to here is 30 bytes + 1 padding!
                    120:   unsigned char input_data[499];
                    121:   // Reserve lots of extra space for commands that set Sector Count
                    122:   // register to large values
                    123:   unsigned char output_data[512]; // starts 530 bytes in!
                    124:   // two more padding bytes here if structure NOT packed.
                    125: } TW_Ioctl;
                    126: 
                    127: /* Ioctl buffer output -- SCSI interface only! */
                    128: typedef struct TAG_TW_Output {
                    129:   int padding[2];
                    130:   char output_data[512];
                    131: } TW_Output; 
                    132: 
                    133: // What follows is needed for 9000 char interface only
                    134: 
                    135: #define TW_IOCTL_FIRMWARE_PASS_THROUGH 0x108
                    136: #define TW_MAX_SGL_LENGTH_9000 61
                    137: 
                    138: typedef struct TAG_TW_Ioctl_Driver_Command_9000 {
                    139:   unsigned int control_code;
                    140:   unsigned int status;
                    141:   unsigned int unique_id;
                    142:   unsigned int sequence_id;
                    143:   unsigned int os_specific;
                    144:   unsigned int buffer_length;
                    145: } TW_Ioctl_Driver_Command_9000;
                    146: 
                    147: /* Command Packet */
                    148: typedef struct TW_Command_9000 {
                    149:   /* First DWORD */
                    150:   struct {
                    151:     unsigned char opcode:5;
                    152:     unsigned char sgl_offset:3;
                    153:   } byte0;
                    154:   unsigned char size;
                    155:   unsigned char request_id;
                    156:   struct {
                    157:     unsigned char unit:4;
                    158:     unsigned char host_id:4;
                    159:   } byte3;
                    160:   /* Second DWORD */
                    161:   unsigned char status;
                    162:   unsigned char flags;
                    163:   union {
                    164:     unsigned short block_count;
                    165:     unsigned short parameter_count;
                    166:     unsigned short message_credits;
                    167:   } byte6;
                    168:   union {
                    169:     struct {
                    170:       u32 lba;
                    171:       TW_SG_Entry sgl[TW_MAX_SGL_LENGTH_9000];
                    172:       u32 padding;
                    173:     } io;
                    174:     struct {
                    175:       TW_SG_Entry sgl[TW_MAX_SGL_LENGTH_9000];
                    176:       u32 padding[2];
                    177:     } param;
                    178:     struct {
                    179:       u32 response_queue_pointer;
                    180:       u32 padding[125]; /* pad entire structure to 512 bytes */
                    181:     } init_connection;
                    182:     struct {
                    183:       char version[504];
                    184:     } ioctl_miniport_version;
                    185:   } byte8;
                    186: } TW_Command_9000;
                    187: 
                    188: /* Command Packet for 9000+ controllers */
                    189: typedef struct TAG_TW_Command_Apache {
                    190:   struct {
                    191:     unsigned char opcode:5;
                    192:     unsigned char reserved:3;
                    193:   } command;
                    194:   unsigned char   unit;
                    195:   unsigned short  request_id;
                    196:   unsigned char   sense_length;
                    197:   unsigned char   sgl_offset;
                    198:   unsigned short  sgl_entries;
                    199:   unsigned char   cdb[16];
                    200:   TW_SG_Entry     sg_list[TW_MAX_SGL_LENGTH_9000];
                    201: } TW_Command_Apache;
                    202: 
                    203: /* New command packet header */
                    204: typedef struct TAG_TW_Command_Apache_Header {
                    205:   unsigned char sense_data[18];
                    206:   struct {
                    207:     char reserved[4];
                    208:     unsigned short error;
                    209:     unsigned char status;
                    210:     struct {
                    211:       unsigned char severity:3;
                    212:       unsigned char reserved:5;
                    213:     } substatus_block;
                    214:   } status_block;
                    215:   unsigned char err_specific_desc[102];
                    216: } TW_Command_Apache_Header;
                    217: 
                    218: /* This struct is a union of the 2 command packets */
                    219: typedef struct TAG_TW_Command_Full_9000 {
                    220:   TW_Command_Apache_Header header;
                    221:   union {
                    222:     TW_Command_9000   oldcommand;
                    223:     TW_Command_Apache newcommand;
                    224:   } command;
                    225:   unsigned char padding[384]; /* Pad to 1024 bytes */
                    226: } TW_Command_Full_9000;
                    227: 
                    228: typedef struct TAG_TW_Ioctl_Apache {
                    229:   TW_Ioctl_Driver_Command_9000 driver_command;
                    230:   char                         padding[488];
                    231:   TW_Command_Full_9000         firmware_command;
                    232:   char                         data_buffer[1];
                    233:   // three bytes of padding here if structure not packed!
                    234: } TW_Ioctl_Buf_Apache;
                    235: 
                    236: 
                    237: 
                    238: // START OF DEFINITIONS FOR THE CHARACTER INTERFACE TO THE
                    239: // 6000/7000/8000 drivers
                    240: 
                    241: #define TW_MAX_SGL_LENGTH        62
                    242: #define TW_CMD_PACKET_WITH_DATA 0x1f
                    243: 
                    244: /* Command Packet */
                    245: typedef struct TW_Command {
                    246:   /* First DWORD */
                    247:   struct {
                    248:     unsigned char opcode:5;
                    249:     unsigned char sgl_offset:3;
                    250:   } byte0;
                    251:   unsigned char size;
                    252:   unsigned char request_id;
                    253:   struct {
                    254:     unsigned char unit:4;
                    255:     unsigned char host_id:4;
                    256:   } byte3;
                    257:   /* Second DWORD */
                    258:   unsigned char status;
                    259:   unsigned char flags;
                    260:   union {
                    261:     unsigned short block_count;
                    262:     unsigned short parameter_count;
                    263:     unsigned short message_credits;
                    264:   } byte6;
                    265:   union {
                    266:     struct {
                    267:       u32 lba;
                    268:       TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
                    269:       u32 padding;     /* pad to 512 bytes */
                    270:     } io;
                    271:     struct {
                    272:       TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
                    273:       u32 padding[2];
                    274:     } param;
                    275:     struct {
                    276:       u32 response_queue_pointer;
                    277:       u32 padding[125];
                    278:     } init_connection;
                    279:     struct {
                    280:       char version[504];
                    281:     } ioctl_miniport_version;
                    282:   } byte8;
                    283: } TW_Command;
                    284: 
                    285: typedef struct TAG_TW_New_Ioctl {
                    286:   unsigned int  data_buffer_length;
                    287:   unsigned char padding [508];
                    288:   TW_Command    firmware_command;
                    289:   char          data_buffer[1];
                    290:   // three bytes of padding here
                    291: } TW_New_Ioctl;
                    292: #pragma pack()
                    293: 
                    294: #if 0
                    295: // Useful for checking/understanding packing of 3ware data structures
                    296: // above.
                    297: void my(int x, char *y){
                    298:   printf("The size of %30s is: %5d\n",y, x);
                    299:   return;
                    300: }
                    301: 
                    302: int main() {
                    303:   TW_Ioctl tmp;
                    304:   my(sizeof(TW_SG_Entry),"TW_SG_Entry");
                    305:   my(sizeof(TW_Passthru),"TW_Passthru");
                    306:   my(sizeof(TW_Ioctl),"TW_Ioctl");
                    307:   my(sizeof(TW_Output),"TW_Output");
                    308:   my(sizeof(TW_Ioctl_Driver_Command_9000),"TW_Ioctl_Driver_Command_9000");
                    309:   my(sizeof(TW_Command_9000),"TW_Command_9000");
                    310:   my(sizeof(TW_Command_Apache),"TW_Command_Apache");
                    311:   my(sizeof(TW_Command_Apache_Header),"TW_Command_Apache_Header");
                    312:   my(sizeof(TW_Command_Full_9000),"TW_Command_Full_9000");
                    313:   my(sizeof(TW_Ioctl_Buf_Apache),"TW_Ioctl_Buf_Apache");
                    314:   my(sizeof(TW_Command),"TW_Command");
                    315:   my(sizeof(TW_New_Ioctl),"TW_New_Ioctl");                                                                
                    316:   printf("TW_Ioctl.table_id - start = %d (irrelevant)\n",
                    317:          (void *)&tmp.table_id - (void *)&tmp);
                    318:   printf("TW_Ioctl.input_data - start = %d (input passthru location)\n",
                    319:          (void *)&tmp.input_data - (void *)&tmp);
                    320:   printf("TW_Ioctl.output_data - start = %d (irrelevant)\n",
                    321:          (void *)&tmp.output_data - (void *)&tmp);
                    322:   return 0;
                    323: }
                    324: #endif
                    325: 
                    326: // The following definitions are from hdreg.h in the kernel source
                    327: // tree.  They don't carry any Copyright statements, but I think they
                    328: // are primarily from Mark Lord and Andre Hedrick.
                    329: typedef unsigned char task_ioreg_t;
                    330: 
                    331: typedef struct hd_drive_task_hdr {
                    332:   task_ioreg_t data;
                    333:   task_ioreg_t feature;
                    334:   task_ioreg_t sector_count;
                    335:   task_ioreg_t sector_number;
                    336:   task_ioreg_t low_cylinder;
                    337:   task_ioreg_t high_cylinder;
                    338:   task_ioreg_t device_head;
                    339:   task_ioreg_t command;
                    340: } task_struct_t;
                    341: 
                    342: typedef union ide_reg_valid_s {
                    343:   unsigned all                 : 16;
                    344:   struct {
                    345:     unsigned data              : 1;
                    346:     unsigned error_feature     : 1;
                    347:     unsigned sector            : 1;
                    348:     unsigned nsector           : 1;
                    349:     unsigned lcyl              : 1;
                    350:     unsigned hcyl              : 1;
                    351:     unsigned select            : 1;
                    352:     unsigned status_command    : 1;
                    353:     unsigned data_hob          : 1;
                    354:     unsigned error_feature_hob : 1;
                    355:     unsigned sector_hob                : 1;
                    356:     unsigned nsector_hob       : 1;
                    357:     unsigned lcyl_hob          : 1;
                    358:     unsigned hcyl_hob          : 1;
                    359:     unsigned select_hob                : 1;
                    360:     unsigned control_hob       : 1;
                    361:   } b;
                    362: } ide_reg_valid_t;
                    363: 
                    364: typedef struct ide_task_request_s {
                    365:   task_ioreg_t    io_ports[8];
                    366:   task_ioreg_t    hob_ports[8];
                    367:   ide_reg_valid_t  out_flags;
                    368:   ide_reg_valid_t  in_flags;
                    369:   int             data_phase;
                    370:   int             req_cmd;
                    371:   unsigned long           out_size;
                    372:   unsigned long           in_size;
                    373: } ide_task_request_t;
                    374: 
                    375: #define TASKFILE_NO_DATA         0x0000
                    376: #define TASKFILE_IN              0x0001
                    377: #define TASKFILE_OUT             0x0004
                    378: #define HDIO_DRIVE_TASK_HDR_SIZE  8*sizeof(task_ioreg_t)
                    379: #define IDE_DRIVE_TASK_NO_DATA        0
                    380: #define IDE_DRIVE_TASK_IN             2
                    381: #define IDE_DRIVE_TASK_OUT            3
                    382: #define HDIO_DRIVE_CMD            0x031f
                    383: #define HDIO_DRIVE_TASK           0x031e
                    384: #define HDIO_DRIVE_TASKFILE       0x031d
                    385: #define HDIO_GET_IDENTITY         0x030d
                    386: 
                    387: #define HPTIO_CTL                       0x03ff // ioctl interface for HighPoint raid device
                    388: 
                    389: #endif /* OS_LINUX_H_ */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>