smartmontools  SVN Rev 4092
Utility to control and monitor storage systems with "S.M.A.R.T."
os_os2.cpp
Go to the documentation of this file.
1 /*
2  * os_os2.c
3  *
4  * Home page of code is: http://smartmontools.sourceforge.net
5  *
6  * Copyright (C) 2004-8 Yuri Dario <smartmontools-support@lists.sourceforge.net>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * You should have received a copy of the GNU General Public License
14  * (for example COPYING); if not, write to the Free Software Foundation,
15  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16  */
17 
18 /*
19  *
20  * Thanks to Daniela Engert for providing sample code for SMART ioctl access.
21  *
22  */
23 
24 // These are needed to define prototypes for the functions defined below
25 #include <errno.h>
26 #include "atacmds.h"
27 #include "scsicmds.h"
28 #include "utility.h"
29 
30 // This is to include whatever prototypes you define in os_generic.h
31 #include "os_os2.h"
32 
33 // Needed by '-V' option (CVS versioning) of smartd/smartctl
34 const char *os_XXXX_c_cvsid="$Id: os_os2.cpp 3806 2013-03-29 20:17:03Z chrfranke $" \
36 
37 // global handle to device driver
38 static HFILE hDevice;
39 
40 // Please eliminate the following block: both the two #includes and
41 // the 'unsupported()' function. They are only here to warn
42 // unsuspecting users that their Operating System is not supported! If
43 // you wish, you can use a similar warning mechanism for any of the
44 // functions in this file that you can not (or choose not to)
45 // implement.
46 
47 #include "config.h"
48 
49 typedef struct _IDEREGS {
50  UCHAR bFeaturesReg;
53  UCHAR bCylLowReg;
54  UCHAR bCylHighReg;
56  UCHAR bCommandReg;
57  UCHAR bReserved;
59 
60 static void unsupported(int which){
61  static int warninggiven[4];
62 
63  if (which<0 || which>3)
64  return;
65 
66  if (!warninggiven[which]) {
67  char msg;
68  warninggiven[which]=1;
69 
70  switch (which) {
71  case 0:
72  msg="generate a list of devices";
73  break;
74  case 1:
75  msg="interface to Marvell-based SATA controllers";
76  break;
77  case 2:
78  msg="interface to 3ware-based RAID controllers";
79  break;
80  case 3:
81  msg="interface to SCSI devices";
82  break;
83  }
84  pout("Under OS/2, smartmontools can not %s\n");
85  }
86  return;
87 }
88 
89 // print examples for smartctl. You should modify this function so
90 // that the device paths are sensible for your OS, and to eliminate
91 // unsupported commands (eg, 3ware controllers).
93  printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
94 #ifdef HAVE_GETOPT_LONG
95  printf(
96  " smartctl -a /dev/hda (Prints all SMART information)\n\n"
97  " smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n"
98  " (Enables SMART on first disk)\n\n"
99  " smartctl -t long /dev/hda (Executes extended disk self-test)\n\n"
100  " smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n"
101  " (Prints Self-Test & Attribute errors)\n"
102  " smartctl -a --device=3ware,2 /dev/sda\n"
103  " (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
104  );
105 #else
106  printf(
107  " smartctl -a /dev/hda (Prints all SMART information)\n"
108  " smartctl -s on -o on -S on /dev/hda (Enables SMART on first disk)\n"
109  " smartctl -t long /dev/hda (Executes extended disk self-test)\n"
110  " smartctl -A -l selftest -q errorsonly /dev/hda\n"
111  " (Prints Self-Test & Attribute errors)\n"
112  " smartctl -a -d 3ware,2 /dev/sda\n"
113  " (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
114  );
115 #endif
116  return;
117 }
118 
119 static const char * skipdev(const char * s)
120 {
121  return (!strncmp(s, "/dev/", 5) ? s + 5 : s);
122 }
123 
124 // tries to guess device type given the name (a path). See utility.h
125 // for return values.
126 int guess_device_type (const char* dev_name) {
127 
128  //printf( "dev_name %s\n", dev_name);
129  dev_name = skipdev(dev_name);
130  if (!strncmp(dev_name, "hd", 2))
131  return CONTROLLER_ATA;
132  if (!strncmp(dev_name, "scsi", 4))
133  return CONTROLLER_SCSI;
134  return CONTROLLER_UNKNOWN;
135 }
136 
137 // makes a list of ATA or SCSI devices for the DEVICESCAN directive of
138 // smartd. Returns number N of devices, or -1 if out of
139 // memory. Allocates N+1 arrays: one of N pointers (devlist); the
140 // other N arrays each contain null-terminated character strings. In
141 // the case N==0, no arrays are allocated because the array of 0
142 // pointers has zero length, equivalent to calling malloc(0).
143 int make_device_names (char*** devlist, const char* name) {
144  unsupported(0);
145  return 0;
146 }
147 
148 // Like open(). Return non-negative integer handle, only used by the
149 // functions below. type=="ATA" or "SCSI". If you need to store
150 // extra information about your devices, create a private internal
151 // array within this file (see os_freebsd.cpp for an example). If you
152 // can not open the device (permission denied, does not exist, etc)
153 // set errno as open() does and return <0.
154 int deviceopen(const char *pathname, char *type){
155 
156  int fd;
157  APIRET rc;
158  ULONG ActionTaken;
159 
160  //printf( "deviceopen pathname %s\n", pathname);
161  rc = DosOpen ("\\DEV\\IBMS506$", &hDevice, &ActionTaken, 0, FILE_SYSTEM,
162  OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE |
163  OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READONLY, NULL);
164  if (rc) {
165  char errmsg[256];
166  snprintf(errmsg,256,"Smartctl open driver IBMS506$ failed (%d)", rc);
167  errmsg[255]='\0';
168  syserror(errmsg);
169  return -1;
170  }
171 
172  pathname = skipdev(pathname);
173  fd = tolower(pathname[2]) - 'a';
174 
175  return fd;
176 }
177 
178 // Like close(). Acts only on integer handles returned by
179 // deviceopen() above.
180 int deviceclose(int fd){
181 
182  DosClose( hDevice);
183  hDevice = NULL;
184 
185  return 0;
186 }
187 
188 static void print_ide_regs(const IDEREGS * r, int out)
189 {
190  pout("%s=0x%02x,%s=0x%02x, SC=0x%02x, NS=0x%02x, CL=0x%02x, CH=0x%02x, SEL=0x%02x\n",
191  (out?"STS":"CMD"), r->bCommandReg, (out?"ERR":" FR"), r->bFeaturesReg,
193 }
194 
195 //
196 // OS/2 direct ioctl interface to IBMS506$
197 //
198 int dani_ioctl( int device, int request, void* arg)
199 {
200  unsigned char* buff = (unsigned char*) arg;
201  APIRET rc;
203  ULONG PLen = 1;
204  ULONG DLen = 512; //sizeof (*buf);
205  UCHAR temp;
206  ULONG value = 0;
207  IDEREGS regs;
208 
209  //printf( "device %d, request 0x%x, arg[0] 0x%x, arg[2] 0x%x\n", device, request, buff[0], buff[2]);
210 
211  Parms.byPhysicalUnit = device;
212  switch( buff[0]) {
213  case WIN_IDENTIFY:
215  (PVOID)&Parms, PLen, &PLen, (PVOID)arg+4, DLen, &DLen);
216  if (rc != 0)
217  {
218  printf ("DANIS506 ATA GET HD Failed (%d,0x%x)\n", rc, rc);
219  return -1;
220  }
221  break;
222  case WIN_SMART:
223  switch( buff[2]) {
224  case SMART_STATUS:
225  DLen = sizeof(value);
226  // OS/2 already checks CL/CH in IBM1S506 code!! see s506rte.c (ddk)
227  // value: -1=not supported, 0=ok, 1=failing
228  rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_GETSTATUS,
229  (PVOID)&Parms, PLen, &PLen, (PVOID)&value, DLen, &DLen);
230  if (rc)
231  {
232  printf ("DANIS506 ATA GET SMART_STATUS failed (%d,0x%x)\n", rc, rc);
233  return -1;
234  }
235  buff[4] = (unsigned char)value;
236  break;
237  case SMART_READ_VALUES:
239  (PVOID)&Parms, PLen, &PLen, (PVOID)arg+4, DLen, &DLen);
240  if (rc)
241  {
242  printf ("DANIS506 ATA GET DSKSP_SMART_GET_ATTRIBUTES failed (%d,0x%x)\n", rc, rc);
243  return -1;
244  }
245  break;
246  case SMART_READ_THRESHOLDS:
248  (PVOID)&Parms, PLen, &PLen, (PVOID)arg+4, DLen, &DLen);
249  if (rc)
250  {
251  printf ("DANIS506 ATA GET DSKSP_SMART_GET_THRESHOLDS failed (%d,0x%x)\n", rc, rc);
252  return -1;
253  }
254  break;
255  case SMART_READ_LOG_SECTOR:
256  buff[4] = buff[1]; // copy select field
257  rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_READ_LOG,
258  (PVOID)&Parms, PLen, &PLen, (PVOID)arg+4, DLen, &DLen);
259  if (rc)
260  {
261  printf ("DANIS506 ATA GET DSKSP_SMART_READ_LOG failed (%d,0x%x)\n", rc, rc);
262  return -1;
263  }
264  break;
265  case SMART_ENABLE:
266  buff[0] = 1; // enable
267  DLen = 1;
268  rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_ONOFF,
269  (PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen);
270  if (rc) {
271  printf ("DANIS506 ATA GET DSKSP_SMART_ONOFF failed (%d,0x%x)\n", rc, rc);
272  return -1;
273  }
274  break;
275  case SMART_DISABLE:
276  buff[0] = 0; // disable
277  DLen = 1;
278  rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_ONOFF,
279  (PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen);
280  if (rc) {
281  printf ("DANIS506 ATA GET DSKSP_SMART_ONOFF failed (%d,0x%x)\n", rc, rc);
282  return -1;
283  }
284  break;
285 #if 0
286  case SMART_AUTO_OFFLINE:
287  buff[0] = buff[3]; // select field
288  DLen = 1;
289  rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_AUTO_OFFLINE,
290  (PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen);
291  if (rc) {
292  printf ("DANIS506 ATA GET DSKSP_SMART_ONOFF failed (%d,0x%x)\n", rc, rc);
293  return -1;
294  }
295  break;
296 #endif
297  case SMART_AUTOSAVE:
298  buff[0] = buff[3]; // select field
299  DLen = 1;
301  (PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen);
302  if (rc) {
303  printf ("DANIS506 ATA DSKSP_SMART_AUTOSAVE_ONOFF failed (%d,0x%x)\n", rc, rc);
304  return -1;
305  }
306  break;
307  case SMART_IMMEDIATE_OFFLINE:
308  buff[0] = buff[1]; // select field
309  DLen = 1;
310  rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_EOLI,
311  (PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen);
312  if (rc) {
313  printf ("DANIS506 ATA GET DSKSP_SMART_EXEC_OFFLINE failed (%d,0x%x)\n", rc, rc);
314  return -1;
315  }
316  break;
317 
318  default:
319  fprintf( stderr, "device %d, request 0x%x, arg[0] 0x%x, arg[2] 0x%x\n", device, request, buff[0], buff[2]);
320  fprintf( stderr, "unknown ioctl\n");
321  return -1;
322  break;
323  }
324  break;
325  //case WIN_PIDENTIFY:
326  // break;
327  default:
328  fprintf( stderr, "unknown ioctl\n");
329  return -1;
330  break;
331  }
332 
333  // ok
334  return 0;
335 }
336 
337 // Interface to ATA devices. See os_linux.cpp for the cannonical example.
338 // DETAILED DESCRIPTION OF ARGUMENTS
339 // device: is the integer handle provided by deviceopen()
340 // command: defines the different operations, see atacmds.h
341 // select: additional input data IF NEEDED (which log, which type of
342 // self-test).
343 // data: location to write output data, IF NEEDED (1 or 512 bytes).
344 // Note: not all commands use all arguments.
345 // RETURN VALUES (for all commands BUT command==STATUS_CHECK)
346 // -1 if the command failed
347 // 0 if the command succeeded,
348 // RETURN VALUES if command==STATUS_CHECK
349 // -1 if the command failed OR the disk SMART status can't be determined
350 // 0 if the command succeeded and disk SMART status is "OK"
351 // 1 if the command succeeded and disk SMART status is "FAILING"
352 
353 // huge value of buffer size needed because HDIO_DRIVE_CMD assumes
354 // that buff[3] is the data size. Since the ATA_SMART_AUTOSAVE and
355 // ATA_SMART_AUTO_OFFLINE use values of 0xf1 and 0xf8 we need the space.
356 // Otherwise a 4+512 byte buffer would be enough.
357 #define STRANGE_BUFFER_LENGTH (4+512*0xf8)
358 
359 int ata_command_interface(int device, smart_command_set command, int select, char *data){
360  unsigned char buff[STRANGE_BUFFER_LENGTH];
361  // positive: bytes to write to caller. negative: bytes to READ from
362  // caller. zero: non-data command
363  int copydata=0;
364 
365  const int HDIO_DRIVE_CMD_OFFSET = 4;
366 
367  // See struct hd_drive_cmd_hdr in hdreg.h. Before calling ioctl()
368  // buff[0]: ATA COMMAND CODE REGISTER
369  // buff[1]: ATA SECTOR NUMBER REGISTER == LBA LOW REGISTER
370  // buff[2]: ATA FEATURES REGISTER
371  // buff[3]: ATA SECTOR COUNT REGISTER
372 
373  // Note that on return:
374  // buff[2] contains the ATA SECTOR COUNT REGISTER
375 
376  // clear out buff. Large enough for HDIO_DRIVE_CMD (4+512 bytes)
377  memset(buff, 0, STRANGE_BUFFER_LENGTH);
378 
379  //printf( "command, select %d,%d\n", command, select);
380  buff[0]=ATA_SMART_CMD;
381  switch (command){
382  case CHECK_POWER_MODE:
383  buff[0]=ATA_CHECK_POWER_MODE;
384  copydata=1;
385  break;
386  case READ_VALUES:
387  buff[2]=ATA_SMART_READ_VALUES;
388  buff[3]=1;
389  copydata=512;
390  break;
391  case READ_THRESHOLDS:
393  buff[1]=buff[3]=1;
394  copydata=512;
395  break;
396  case READ_LOG:
398  buff[1]=select;
399  buff[3]=1;
400  copydata=512;
401  break;
402  case WRITE_LOG:
403  break;
404  case IDENTIFY:
405  buff[0]=ATA_IDENTIFY_DEVICE;
406  buff[3]=1;
407  copydata=512;
408  break;
409  case PIDENTIFY:
411  buff[3]=1;
412  copydata=512;
413  break;
414  case ENABLE:
415  buff[2]=ATA_SMART_ENABLE;
416  buff[1]=1;
417  break;
418  case DISABLE:
419  buff[2]=ATA_SMART_DISABLE;
420  buff[1]=1;
421  break;
422  case STATUS:
423  case STATUS_CHECK:
424  // this command only says if SMART is working. It could be
425  // replaced with STATUS_CHECK below.
426  buff[2]=ATA_SMART_STATUS;
427  buff[4]=0;
428  break;
429  case AUTO_OFFLINE:
430  buff[2]=ATA_SMART_AUTO_OFFLINE;
431  buff[3]=select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
432  break;
433  case AUTOSAVE:
434  buff[2]=ATA_SMART_AUTOSAVE;
435  buff[3]=select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
436  break;
437  case IMMEDIATE_OFFLINE:
439  buff[1]=select;
440  break;
441  //case STATUS_CHECK:
442  // // This command uses HDIO_DRIVE_TASK and has different syntax than
443  // // the other commands.
444  // buff[1]=ATA_SMART_STATUS;
445  // break;
446  default:
447  pout("Unrecognized command %d in linux_ata_command_interface()\n"
448  "Please contact " PACKAGE_BUGREPORT "\n", command);
449  errno=ENOSYS;
450  return -1;
451  }
452 
453 #if 0
454  // This command uses the HDIO_DRIVE_TASKFILE ioctl(). This is the
455  // only ioctl() that can be used to WRITE data to the disk.
456  if (command==WRITE_LOG) {
457  unsigned char task[sizeof(ide_task_request_t)+512];
458  ide_task_request_t *reqtask=(ide_task_request_t *) task;
459  task_struct_t *taskfile=(task_struct_t *) reqtask->io_ports;
460  int retval;
461 
462  memset(task, 0, sizeof(task));
463 
464  taskfile->data = 0;
466  taskfile->sector_count = 1;
467  taskfile->sector_number = select;
468  taskfile->low_cylinder = 0x4f;
469  taskfile->high_cylinder = 0xc2;
470  taskfile->device_head = 0;
471  taskfile->command = ATA_SMART_CMD;
472 
473  reqtask->data_phase = TASKFILE_OUT;
474  reqtask->req_cmd = IDE_DRIVE_TASK_OUT;
475  reqtask->out_size = 512;
476  reqtask->in_size = 0;
477 
478  // copy user data into the task request structure
479  memcpy(task+sizeof(ide_task_request_t), data, 512);
480 
481  if ((retval=dani_ioctl(device, HDIO_DRIVE_TASKFILE, task))) {
482  if (retval==-EINVAL)
483  pout("Kernel lacks HDIO_DRIVE_TASKFILE support; compile kernel with CONFIG_IDE_TASKFILE_IO set\n");
484  return -1;
485  }
486  return 0;
487  }
488 #endif // 0
489 
490  // We are now doing the HDIO_DRIVE_CMD type ioctl.
491  if ((dani_ioctl(device, HDIO_DRIVE_CMD, buff)))
492  return -1;
493 
494  // There are two different types of ioctls(). The HDIO_DRIVE_TASK
495  // one is this:
496  if (command==STATUS_CHECK){
497  int retval;
498 
499  // Cyl low and Cyl high unchanged means "Good SMART status"
500  if (buff[4]==0)
501  return 0;
502 
503  // These values mean "Bad SMART status"
504  if (buff[4]==1)
505  return 1;
506 
507  // We haven't gotten output that makes sense; print out some debugging info
508  syserror("Error SMART Status command failed");
509  pout("Please get assistance from " PACKAGE_HOMEPAGE "\n");
510  return -1;
511  }
512 
513  // CHECK POWER MODE command returns information in the Sector Count
514  // register (buff[3]). Copy to return data buffer.
515  if (command==CHECK_POWER_MODE)
516  buff[HDIO_DRIVE_CMD_OFFSET]=buff[2];
517 
518  // if the command returns data then copy it back
519  if (copydata)
520  memcpy(data, buff+HDIO_DRIVE_CMD_OFFSET, copydata);
521 
522  return 0;
523 }
524 
525 // Interface to SCSI devices. See os_linux.c
526 int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
527  unsupported(3);
528  return -ENOSYS;
529 }
#define ATA_SMART_READ_LOG_SECTOR
Definition: atacmds.h:100
#define ATA_SMART_WRITE_LOG_SECTOR
Definition: atacmds.h:101
UCHAR bReserved
Definition: os_os2.cpp:57
u16 s[6]
Definition: megaraid.h:97
#define ATACMDS_H_CVSID
Definition: atacmds.h:28
static void print_ide_regs(const IDEREGS *r, int out)
Definition: os_os2.cpp:188
UCHAR bSectorNumberReg
Definition: os_os2.cpp:52
#define IDE_DRIVE_TASK_OUT
Definition: os_linux.h:381
#define ATA_SMART_CMD
Definition: atacmds.h:75
int dani_ioctl(int device, int request, void *arg)
Definition: os_os2.cpp:198
static HFILE hDevice
Definition: os_os2.cpp:38
task_ioreg_t sector_count
Definition: os_linux.h:334
task_ioreg_t command
Definition: os_linux.h:339
#define ATA_SMART_DISABLE
Definition: atacmds.h:104
const char * os_XXXX_c_cvsid
Definition: os_os2.cpp:34
#define ATA_SMART_AUTOSAVE
Definition: atacmds.h:97
#define HDIO_DRIVE_TASKFILE
Definition: os_linux.h:384
#define snprintf
Definition: utility.h:68
#define DSKSP_SMART_GET_ATTRIBUTES
Definition: os_os2.h:41
UCHAR bSectorCountReg
Definition: os_os2.cpp:51
struct _IDEREGS * LPIDEREGS
int ata_command_interface(int device, smart_command_set command, int select, char *data)
Definition: os_os2.cpp:359
#define HDIO_DRIVE_CMD
Definition: os_linux.h:382
#define ATA_IDENTIFY_DEVICE
Definition: atacmds.h:72
#define ATA_IDENTIFY_PACKET_DEVICE
Definition: atacmds.h:73
#define SCSICMDS_H_CVSID
Definition: scsicmds.h:35
ptr_t data
Definition: megaraid.h:94
int deviceclose(int fd)
Definition: os_os2.cpp:180
static void unsupported(int which)
Definition: os_os2.cpp:60
#define ATA_CHECK_POWER_MODE
Definition: atacmds.h:71
#define DSKSP_SMART_ONOFF
Definition: os_os2.h:37
#define DSKSP_SMART_EOLI
Definition: os_os2.h:47
struct _IDEREGS IDEREGS
void syserror(const char *message)
Definition: utility.cpp:348
int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io *iop, int report)
Definition: os_os2.cpp:526
task_ioreg_t low_cylinder
Definition: os_linux.h:336
struct _IDEREGS * PIDEREGS
#define OS_XXXX_H_CVSID
Definition: os_os2.h:21
UCHAR bDriveHeadReg
Definition: os_os2.cpp:55
void pout(const char *fmt,...)
Definition: smartctl.cpp:1095
#define DSKSP_CAT_SMART
Definition: os_os2.h:36
UCHAR bCommandReg
Definition: os_os2.cpp:56
#define ATA_SMART_READ_VALUES
Definition: atacmds.h:95
#define DSKSP_SMART_GET_THRESHOLDS
Definition: os_os2.h:42
Definition: atacmds.h:55
#define ATA_SMART_AUTO_OFFLINE
Definition: atacmds.h:108
#define DSKSP_CAT_GENERIC
Definition: os_os2.h:52
smart_command_set
Definition: atacmds.h:48
void print_smartctl_examples()
Definition: os_os2.cpp:92
UCHAR bCylLowReg
Definition: os_os2.cpp:53
int guess_device_type(const char *dev_name)
Definition: os_os2.cpp:126
#define ATA_SMART_READ_THRESHOLDS
Definition: atacmds.h:96
task_ioreg_t feature
Definition: os_linux.h:333
UCHAR bFeaturesReg
Definition: os_os2.cpp:50
#define ATA_SMART_IMMEDIATE_OFFLINE
Definition: atacmds.h:99
#define DSKSP_SMART_GETSTATUS
Definition: os_os2.h:40
task_ioreg_t sector_number
Definition: os_linux.h:335
task_ioreg_t device_head
Definition: os_linux.h:338
task_ioreg_t data
Definition: os_linux.h:332
struct ide_task_request_s ide_task_request_t
#define DSKSP_SMART_READ_LOG
Definition: os_os2.h:43
int deviceopen(const char *pathname, char *type)
Definition: os_os2.cpp:154
int make_device_names(char ***devlist, const char *name)
Definition: os_os2.cpp:143
#define STRANGE_BUFFER_LENGTH
Definition: os_os2.cpp:357
UCHAR bCylHighReg
Definition: os_os2.cpp:54
#define ATA_SMART_ENABLE
Definition: atacmds.h:103
#define DSKSP_GET_INQUIRY_DATA
Definition: os_os2.h:53
#define TASKFILE_OUT
Definition: os_linux.h:377
#define DSKSP_SMART_AUTOSAVE_ONOFF
Definition: os_os2.h:38
task_ioreg_t high_cylinder
Definition: os_linux.h:337
Definition: atacmds.h:50
static const char * skipdev(const char *s)
Definition: os_os2.cpp:119
#define UTILITY_H_CVSID
Definition: utility.h:28
#define ATA_SMART_STATUS
Definition: atacmds.h:105