summaryrefslogtreecommitdiffstats
path: root/os_linux.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 17:14:45 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 17:14:45 +0000
commit43e8530e93493bb978c446a2023134bdd4277e50 (patch)
treee8c0d3c0c394b17381f48fb2d288f166b4f22440 /os_linux.h
parentInitial commit. (diff)
downloadsmartmontools-43e8530e93493bb978c446a2023134bdd4277e50.tar.xz
smartmontools-43e8530e93493bb978c446a2023134bdd4277e50.zip
Adding upstream version 7.4.upstream/7.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'os_linux.h')
-rw-r--r--os_linux.h375
1 files changed, 375 insertions, 0 deletions
diff --git a/os_linux.h b/os_linux.h
new file mode 100644
index 0000000..0b9636e
--- /dev/null
+++ b/os_linux.h
@@ -0,0 +1,375 @@
+/*
+ * os_linux.h
+ *
+ * Home page of code is: http://www.smartmontools.org
+ *
+ * Copyright (C) 2003-8 Bruce Allen
+ *
+ * Derived from code that was
+ *
+ * Written By: Adam Radford <linux@3ware.com>
+ * Modifications By: Joel Jacobson <linux@3ware.com>
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * Brad Strand <linux@3ware.com>
+ *
+ * Copyright (C) 1999-2003 3ware Inc.
+ *
+ * Kernel compatibility By: Andre Hedrick <andre@suse.com>
+ * Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+
+#ifndef OS_LINUX_H_
+#define OS_LINUX_H_
+
+#define OS_LINUX_H_CVSID "$Id: os_linux.h 4842 2018-12-02 16:07:26Z chrfranke $\n"
+
+/*
+ The following definitions/macros/prototypes are used for three
+ different interfaces, referred to as "the three cases" below.
+ CONTROLLER_3WARE_678K -- 6000, 7000, and 8000 controllers via /dev/sd?
+ CONTROLLER_3WARE_678K_CHAR -- 6000, 7000, and 8000 controllers via /dev/twe?
+ CONTROLLER_3WARE_9000_CHAR -- 9000 controllers via /dev/twa?
+*/
+
+// USED FOR ALL THREE CASES
+
+#define u32 unsigned int
+#define TW_OP_ATA_PASSTHRU 0x11
+#define MAX(x,y) ( (x)>(y)?(x):(y) )
+
+#pragma pack(1)
+/* Scatter gather list entry */
+typedef struct TAG_TW_SG_Entry {
+ unsigned int address;
+ unsigned int length;
+} TW_SG_Entry;
+
+/* Command header for ATA pass-thru. Note that for different
+ drivers/interfaces the length of sg_list (here TW_ATA_PASS_SGL_MAX)
+ is different. But it can be taken as same for all three cases
+ because it's never used to define any other structures, and we
+ never use anything in the sg_list or beyond! */
+
+#define TW_ATA_PASS_SGL_MAX 60
+
+typedef struct TAG_TW_Passthru {
+ struct {
+ unsigned char opcode:5;
+ unsigned char sgloff:3;
+ } byte0;
+ unsigned char size;
+ unsigned char request_id;
+ unsigned char unit;
+ unsigned char status; // On return, contains 3ware STATUS register
+ unsigned char flags;
+ unsigned short param;
+ unsigned short features; // On return, contains ATA ERROR register
+ unsigned short sector_count;
+ unsigned short sector_num;
+ unsigned short cylinder_lo;
+ unsigned short cylinder_hi;
+ unsigned char drive_head;
+ unsigned char command; // On return, contains ATA STATUS register
+ TW_SG_Entry sg_list[TW_ATA_PASS_SGL_MAX];
+ unsigned char padding[12];
+} TW_Passthru;
+
+// the following are for the SCSI interface only
+
+// Ioctl buffer: Note that this defn has changed in kernel tree...
+// Total size is 1041 bytes -- this is really weird
+
+#define TW_IOCTL 0x80
+#define TW_ATA_PASSTHRU 0x1e
+
+// Adam -- should this be #pramga packed? Otherwise table_id gets
+// moved for byte alignment. Without packing, input passthru for SCSI
+// ioctl is 31 bytes in. With packing it is 30 bytes in.
+typedef struct TAG_TW_Ioctl {
+ int input_length;
+ int output_length;
+ unsigned char cdb[16];
+ unsigned char opcode;
+ // This one byte of padding is missing from the typedefs in the
+ // kernel code, but it is indeed present. We put it explicitly
+ // here, so that the structure can be packed. Adam agrees with
+ // this.
+ unsigned char packing;
+ unsigned short table_id;
+ unsigned char parameter_id;
+ unsigned char parameter_size_bytes;
+ unsigned char unit_index;
+ // Size up to here is 30 bytes + 1 padding!
+ unsigned char input_data[499];
+ // Reserve lots of extra space for commands that set Sector Count
+ // register to large values
+ unsigned char output_data[512]; // starts 530 bytes in!
+ // two more padding bytes here if structure NOT packed.
+} TW_Ioctl;
+
+/* Ioctl buffer output -- SCSI interface only! */
+typedef struct TAG_TW_Output {
+ int padding[2];
+ char output_data[512];
+} TW_Output;
+
+// What follows is needed for 9000 char interface only
+
+#define TW_IOCTL_FIRMWARE_PASS_THROUGH 0x108
+#define TW_MAX_SGL_LENGTH_9000 61
+
+typedef struct TAG_TW_Ioctl_Driver_Command_9000 {
+ unsigned int control_code;
+ unsigned int status;
+ unsigned int unique_id;
+ unsigned int sequence_id;
+ unsigned int os_specific;
+ unsigned int buffer_length;
+} TW_Ioctl_Driver_Command_9000;
+
+/* Command Packet */
+typedef struct TW_Command_9000 {
+ /* First DWORD */
+ struct {
+ unsigned char opcode:5;
+ unsigned char sgl_offset:3;
+ } byte0;
+ unsigned char size;
+ unsigned char request_id;
+ struct {
+ unsigned char unit:4;
+ unsigned char host_id:4;
+ } byte3;
+ /* Second DWORD */
+ unsigned char status;
+ unsigned char flags;
+ union {
+ unsigned short block_count;
+ unsigned short parameter_count;
+ unsigned short message_credits;
+ } byte6;
+ union {
+ struct {
+ u32 lba;
+ TW_SG_Entry sgl[TW_MAX_SGL_LENGTH_9000];
+ u32 padding;
+ } io;
+ struct {
+ TW_SG_Entry sgl[TW_MAX_SGL_LENGTH_9000];
+ u32 padding[2];
+ } param;
+ struct {
+ u32 response_queue_pointer;
+ u32 padding[125]; /* pad entire structure to 512 bytes */
+ } init_connection;
+ struct {
+ char version[504];
+ } ioctl_miniport_version;
+ } byte8;
+} TW_Command_9000;
+
+/* Command Packet for 9000+ controllers */
+typedef struct TAG_TW_Command_Apache {
+ struct {
+ unsigned char opcode:5;
+ unsigned char reserved:3;
+ } command;
+ unsigned char unit;
+ unsigned short request_id;
+ unsigned char sense_length;
+ unsigned char sgl_offset;
+ unsigned short sgl_entries;
+ unsigned char cdb[16];
+ TW_SG_Entry sg_list[TW_MAX_SGL_LENGTH_9000];
+} TW_Command_Apache;
+
+/* New command packet header */
+typedef struct TAG_TW_Command_Apache_Header {
+ unsigned char sense_data[18];
+ struct {
+ char reserved[4];
+ unsigned short error;
+ unsigned char status;
+ struct {
+ unsigned char severity:3;
+ unsigned char reserved:5;
+ } substatus_block;
+ } status_block;
+ unsigned char err_specific_desc[102];
+} TW_Command_Apache_Header;
+
+/* This struct is a union of the 2 command packets */
+typedef struct TAG_TW_Command_Full_9000 {
+ TW_Command_Apache_Header header;
+ union {
+ TW_Command_9000 oldcommand;
+ TW_Command_Apache newcommand;
+ } command;
+ unsigned char padding[384]; /* Pad to 1024 bytes */
+} TW_Command_Full_9000;
+
+typedef struct TAG_TW_Ioctl_Apache {
+ TW_Ioctl_Driver_Command_9000 driver_command;
+ char padding[488];
+ TW_Command_Full_9000 firmware_command;
+ char data_buffer[1];
+ // three bytes of padding here if structure not packed!
+} TW_Ioctl_Buf_Apache;
+
+
+
+// START OF DEFINITIONS FOR THE CHARACTER INTERFACE TO THE
+// 6000/7000/8000 drivers
+
+#define TW_MAX_SGL_LENGTH 62
+#define TW_CMD_PACKET_WITH_DATA 0x1f
+
+/* Command Packet */
+typedef struct TW_Command {
+ /* First DWORD */
+ struct {
+ unsigned char opcode:5;
+ unsigned char sgl_offset:3;
+ } byte0;
+ unsigned char size;
+ unsigned char request_id;
+ struct {
+ unsigned char unit:4;
+ unsigned char host_id:4;
+ } byte3;
+ /* Second DWORD */
+ unsigned char status;
+ unsigned char flags;
+ union {
+ unsigned short block_count;
+ unsigned short parameter_count;
+ unsigned short message_credits;
+ } byte6;
+ union {
+ struct {
+ u32 lba;
+ TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
+ u32 padding; /* pad to 512 bytes */
+ } io;
+ struct {
+ TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
+ u32 padding[2];
+ } param;
+ struct {
+ u32 response_queue_pointer;
+ u32 padding[125];
+ } init_connection;
+ struct {
+ char version[504];
+ } ioctl_miniport_version;
+ } byte8;
+} TW_Command;
+
+typedef struct TAG_TW_New_Ioctl {
+ unsigned int data_buffer_length;
+ unsigned char padding [508];
+ TW_Command firmware_command;
+ char data_buffer[1];
+ // three bytes of padding here
+} TW_New_Ioctl;
+#pragma pack()
+
+#if 0
+// Useful for checking/understanding packing of 3ware data structures
+// above.
+void my(int x, char *y){
+ printf("The size of %30s is: %5d\n",y, x);
+ return;
+}
+
+int main() {
+ TW_Ioctl tmp;
+ my(sizeof(TW_SG_Entry),"TW_SG_Entry");
+ my(sizeof(TW_Passthru),"TW_Passthru");
+ my(sizeof(TW_Ioctl),"TW_Ioctl");
+ my(sizeof(TW_Output),"TW_Output");
+ my(sizeof(TW_Ioctl_Driver_Command_9000),"TW_Ioctl_Driver_Command_9000");
+ my(sizeof(TW_Command_9000),"TW_Command_9000");
+ my(sizeof(TW_Command_Apache),"TW_Command_Apache");
+ my(sizeof(TW_Command_Apache_Header),"TW_Command_Apache_Header");
+ my(sizeof(TW_Command_Full_9000),"TW_Command_Full_9000");
+ my(sizeof(TW_Ioctl_Buf_Apache),"TW_Ioctl_Buf_Apache");
+ my(sizeof(TW_Command),"TW_Command");
+ my(sizeof(TW_New_Ioctl),"TW_New_Ioctl");
+ printf("TW_Ioctl.table_id - start = %d (irrelevant)\n",
+ (void *)&tmp.table_id - (void *)&tmp);
+ printf("TW_Ioctl.input_data - start = %d (input passthru location)\n",
+ (void *)&tmp.input_data - (void *)&tmp);
+ printf("TW_Ioctl.output_data - start = %d (irrelevant)\n",
+ (void *)&tmp.output_data - (void *)&tmp);
+ return 0;
+}
+#endif
+
+// The following definitions are from hdreg.h in the kernel source
+// tree. They don't carry any Copyright statements, but I think they
+// are primarily from Mark Lord and Andre Hedrick.
+typedef unsigned char task_ioreg_t;
+
+typedef struct hd_drive_task_hdr {
+ task_ioreg_t data;
+ task_ioreg_t feature;
+ task_ioreg_t sector_count;
+ task_ioreg_t sector_number;
+ task_ioreg_t low_cylinder;
+ task_ioreg_t high_cylinder;
+ task_ioreg_t device_head;
+ task_ioreg_t command;
+} task_struct_t;
+
+typedef union ide_reg_valid_s {
+ unsigned all : 16;
+ struct {
+ unsigned data : 1;
+ unsigned error_feature : 1;
+ unsigned sector : 1;
+ unsigned nsector : 1;
+ unsigned lcyl : 1;
+ unsigned hcyl : 1;
+ unsigned select : 1;
+ unsigned status_command : 1;
+ unsigned data_hob : 1;
+ unsigned error_feature_hob : 1;
+ unsigned sector_hob : 1;
+ unsigned nsector_hob : 1;
+ unsigned lcyl_hob : 1;
+ unsigned hcyl_hob : 1;
+ unsigned select_hob : 1;
+ unsigned control_hob : 1;
+ } b;
+} ide_reg_valid_t;
+
+typedef struct ide_task_request_s {
+ task_ioreg_t io_ports[8];
+ task_ioreg_t hob_ports[8];
+ ide_reg_valid_t out_flags;
+ ide_reg_valid_t in_flags;
+ int data_phase;
+ int req_cmd;
+ unsigned long out_size;
+ unsigned long in_size;
+} ide_task_request_t;
+
+#define TASKFILE_NO_DATA 0x0000
+#define TASKFILE_IN 0x0001
+#define TASKFILE_OUT 0x0004
+#define HDIO_DRIVE_TASK_HDR_SIZE 8*sizeof(task_ioreg_t)
+#define IDE_DRIVE_TASK_NO_DATA 0
+#define IDE_DRIVE_TASK_IN 2
+#define IDE_DRIVE_TASK_OUT 3
+#define HDIO_DRIVE_CMD 0x031f
+#define HDIO_DRIVE_TASK 0x031e
+#define HDIO_DRIVE_TASKFILE 0x031d
+#define HDIO_GET_IDENTITY 0x030d
+
+#define HPTIO_CTL 0x03ff // ioctl interface for HighPoint raid device
+
+#endif /* OS_LINUX_H_ */