File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / smartmontools / os_linux.h
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 01:17:35 2013 UTC (10 years, 10 months ago) by misho
Branches: smartmontools, elwix, MAIN
CVS tags: v6_2, v6_1p0, v6_1, HEAD
6.1

    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
   27:  * (for example COPYING); if not, write to the Free Software Foundation,
   28:  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
   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: 
   41: #define OS_LINUX_H_CVSID "$Id: os_linux.h,v 1.1.1.2 2013/07/22 01:17:35 misho Exp $\n"
   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>