os_linux.cpp 102 KB
Newer Older
1
/*
2
 *  os_linux.cpp
3
 *
4
5
 * Home page of code is: http://smartmontools.sourceforge.net
 *
6
7
8
9
10
11
 * Copyright (C) 2003-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
 * Copyright (C) 2003-10 Doug Gilbert <dougg@torque.net>
 * Copyright (C) 2008    Hank Wu <hank@areca.com.tw>
 * Copyright (C) 2008    Oliver Bock <brevilo@users.sourceforge.net>
 * Copyright (C) 2008-10 Christian Franke <smartmontools-support@lists.sourceforge.net>
 * Copyright (C) 2008    Jordan Hargrave <jordan_hargrave@dell.com>
12
13
14
15
16
 *
 *  Parts of this file are derived from code that was
 *
 *  Written By: Adam Radford <linux@3ware.com>
 *  Modifications By: Joel Jacobson <linux@3ware.com>
17
 *                   Arnaldo Carvalho de Melo <acme@conectiva.com.br>
18
19
20
21
 *                    Brad Strand <linux@3ware.com>
 *
 *  Copyright (C) 1999-2003 3ware Inc.
 *
22
23
 *  Kernel compatablity By:     Andre Hedrick <andre@suse.com>
 *  Non-Copyright (C) 2000      Andre Hedrick <andre@suse.com>
24
25
 *
 * Other ars of this file are derived from code that was
26
 *
27
28
29
30
31
32
33
34
35
 * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
 * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * You should have received a copy of the GNU General Public License
36
 * (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
37
38
39
40
41
 *
 * This code was originally developed as a Senior Thesis by Michael Cornwell
 * at the Concurrent Systems Laboratory (now part of the Storage Systems
 * Research Center), Jack Baskin School of Engineering, University of
 * California, Santa Cruz. http://ssrc.soe.ucsc.edu/
42
 *
43
44
45
46
47
48
49
 */

// This file contains the linux-specific IOCTL parts of
// smartmontools. It includes one interface routine for ATA devices,
// one for SCSI devices, and one for ATA devices behind escalade
// controllers.

50
51
#include "config.h"

52
#include <errno.h>
chrfranke's avatar
chrfranke committed
53
#include <fcntl.h>
54
#include <glob.h>
55

56
#include <scsi/scsi.h>
57
#include <scsi/scsi_ioctl.h>
58
#include <scsi/sg.h>
59
60
#include <stdlib.h>
#include <string.h>
chrfranke's avatar
chrfranke committed
61
#include <sys/ioctl.h>
62
#include <sys/stat.h>
63
#include <sys/file.h>
64
#include <unistd.h>
65
#include <sys/uio.h>
jharg's avatar
jharg committed
66
#include <sys/types.h>
67
68
69
#ifndef makedev // old versions of types.h do not include sysmacros.h
#include <sys/sysmacros.h>
#endif
70
71
72
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif
73

74
#include "int64.h"
75
#include "atacmds.h"
76
#include "extern.h"
77
#include "os_linux.h"
78
#include "scsicmds.h"
79
#include "utility.h"
guidog's avatar
guidog committed
80
#include "extern.h"
81
#include "cciss.h"
82
#include "megaraid.h"
83

84
85
86
#include "dev_interface.h"
#include "dev_ata_cmd_set.h"

87
88
89
#ifndef ENOTSUP
#define ENOTSUP ENOSYS
#endif
guidog's avatar
guidog committed
90

91
92
#define ARGUSED(x) ((void)(x))

chrfranke's avatar
chrfranke committed
93
const char *os_XXXX_c_cvsid="$Id$" \
94
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_LINUX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
95

guidog's avatar
guidog committed
96
/* for passing global control variables */
97
// (con->reportscsiioctl only)
guidog's avatar
guidog committed
98
99
extern smartmonctrl *con;

100
101
102
103
104
105
106
107
108
109

namespace os_linux { // No need to publish anything, name provided for Doxygen

/////////////////////////////////////////////////////////////////////////////
/// Shared open/close routines

class linux_smart_device
: virtual public /*implements*/ smart_device
{
public:
110
  explicit linux_smart_device(int flags, int retry_flags = -1)
111
    : smart_device(never_called),
112
113
114
      m_fd(-1),
      m_flags(flags), m_retry_flags(retry_flags)
      { }
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

  virtual ~linux_smart_device() throw();

  virtual bool is_open() const;

  virtual bool open();

  virtual bool close();

protected:
  /// Return filedesc for derived classes.
  int get_fd() const
    { return m_fd; }

private:
  int m_fd; ///< filedesc, -1 if not open.
131
132
  int m_flags; ///< Flags for ::open()
  int m_retry_flags; ///< Flags to retry ::open(), -1 if no retry
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
};


linux_smart_device::~linux_smart_device() throw()
{
  if (m_fd >= 0)
    ::close(m_fd);
}

bool linux_smart_device::is_open() const
{
  return (m_fd >= 0);
}

bool linux_smart_device::open()
{
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  m_fd = ::open(get_dev_name(), m_flags);

  if (m_fd < 0 && errno == EROFS && m_retry_flags != -1)
    // Retry
    m_fd = ::open(get_dev_name(), m_retry_flags);

  if (m_fd < 0) {
    if (errno == EBUSY && (m_flags & O_EXCL))
      // device is locked
      return set_err(EBUSY,
        "The requested controller is used exclusively by another process!\n"
        "(e.g. smartctl or smartd)\n"
        "Please quit the impeding process or try again later...");
    return set_err((errno==ENOENT || errno==ENOTDIR) ? ENODEV : errno);
163
  }
guidog's avatar
guidog committed
164

165
  if (m_fd >= 0) {
166
167
168
169
    // sets FD_CLOEXEC on the opened device file descriptor.  The
    // descriptor is otherwise leaked to other applications (mail
    // sender) which may be considered a security risk and may result
    // in AVC messages on SELinux-enabled systems.
170
171
    if (-1 == fcntl(m_fd, F_SETFD, FD_CLOEXEC))
      // TODO: Provide an error printing routine in class smart_interface
172
      pout("fcntl(set  FD_CLOEXEC) failed, errno=%d [%s]\n", errno, strerror(errno));
173
  }
174
175

  return true;
176
177
}

178
// equivalent to close(file descriptor)
179
180
181
182
183
184
bool linux_smart_device::close()
{
  int fd = m_fd; m_fd = -1;
  if (::close(fd) < 0)
    return set_err(errno);
  return true;
185
186
}

187
188
189
// examples for smartctl
static const char  smartctl_examples[] =
		  "=================================================== SMARTCTL EXAMPLES =====\n\n"
190
191
192
193
194
195
196
197
198
199
200
201
202
		  "  smartctl --all /dev/hda                    (Prints all SMART information)\n\n"
		  "  smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n"
		  "                                              (Enables SMART on first disk)\n\n"
		  "  smartctl --test=long /dev/hda          (Executes extended disk self-test)\n\n"
		  "  smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n"
		  "                                      (Prints Self-Test & Attribute errors)\n"
		  "  smartctl --all --device=3ware,2 /dev/sda\n"
		  "  smartctl --all --device=3ware,2 /dev/twe0\n"
		  "  smartctl --all --device=3ware,2 /dev/twa0\n"
		  "          (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
		  "  smartctl --all --device=hpt,1/1/3 /dev/sda\n"
		  "          (Prints all SMART info for the SATA disk attached to the 3rd PMPort\n"
		  "           of the 1st channel on the 1st HighPoint RAID controller)\n"
203
		  "  smartctl --all --device=areca,3 /dev/sg2\n"
204
		  "          (Prints all SMART info for 3rd ATA disk on Areca RAID controller)\n"
205
  ;
206

207

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/////////////////////////////////////////////////////////////////////////////
/// Linux ATA support

class linux_ata_device
: public /*implements*/ ata_device_with_command_set,
  public /*extends*/ linux_smart_device
{
public:
  linux_ata_device(smart_interface * intf, const char * dev_name, const char * req_type);

protected:
  virtual int ata_command_interface(smart_command_set command, int select, char * data);
};

linux_ata_device::linux_ata_device(smart_interface * intf, const char * dev_name, const char * req_type)
: smart_device(intf, dev_name, "ata", req_type),
224
  linux_smart_device(O_RDONLY | O_NONBLOCK)
225
226
227
{
}

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
// PURPOSE
//   This is an interface routine meant to isolate the OS dependent
//   parts of the code, and to provide a debugging interface.  Each
//   different port and OS needs to provide it's own interface.  This
//   is the linux one.
// DETAILED DESCRIPTION OF ARGUMENTS
//   device: is the file descriptor provided by open()
//   command: defines the different operations.
//   select: additional input data if needed (which log, which type of
//           self-test).
//   data:   location to write output data, if needed (512 bytes).
//   Note: not all commands use all arguments.
// RETURN VALUES
//  -1 if the command failed
//   0 if the command succeeded,
243
//   STATUS_CHECK routine:
244
245
246
247
248
//  -1 if the command failed
//   0 if the command succeeded and disk SMART status is "OK"
//   1 if the command succeeded and disk SMART status is "FAILING"


249
#define BUFFER_LENGTH (4+512)
250

251
252
int linux_ata_device::ata_command_interface(smart_command_set command, int select, char * data)
{
253
  unsigned char buff[BUFFER_LENGTH];
254
255
256
  // positive: bytes to write to caller.  negative: bytes to READ from
  // caller. zero: non-data command
  int copydata=0;
257
258
259

  const int HDIO_DRIVE_CMD_OFFSET = 4;

260
  // See struct hd_drive_cmd_hdr in hdreg.h.  Before calling ioctl()
261
262
263
264
  // buff[0]: ATA COMMAND CODE REGISTER
  // buff[1]: ATA SECTOR NUMBER REGISTER == LBA LOW REGISTER
  // buff[2]: ATA FEATURES REGISTER
  // buff[3]: ATA SECTOR COUNT REGISTER
265
266
267

  // Note that on return:
  // buff[2] contains the ATA SECTOR COUNT REGISTER
268

269
  // clear out buff.  Large enough for HDIO_DRIVE_CMD (4+512 bytes)
270
  memset(buff, 0, BUFFER_LENGTH);
271

272
  buff[0]=ATA_SMART_CMD;
273
  switch (command){
274
275
276
277
  case CHECK_POWER_MODE:
    buff[0]=ATA_CHECK_POWER_MODE;
    copydata=1;
    break;
278
  case READ_VALUES:
279
    buff[2]=ATA_SMART_READ_VALUES;
280
281
    buff[3]=1;
    copydata=512;
282
283
    break;
  case READ_THRESHOLDS:
284
    buff[2]=ATA_SMART_READ_THRESHOLDS;
285
286
    buff[1]=buff[3]=1;
    copydata=512;
287
288
    break;
  case READ_LOG:
289
    buff[2]=ATA_SMART_READ_LOG_SECTOR;
290
    buff[1]=select;
291
292
    buff[3]=1;
    copydata=512;
293
    break;
294
295
  case WRITE_LOG:
    break;
296
  case IDENTIFY:
297
    buff[0]=ATA_IDENTIFY_DEVICE;
298
299
    buff[3]=1;
    copydata=512;
300
301
    break;
  case PIDENTIFY:
302
    buff[0]=ATA_IDENTIFY_PACKET_DEVICE;
303
304
    buff[3]=1;
    copydata=512;
305
306
    break;
  case ENABLE:
307
    buff[2]=ATA_SMART_ENABLE;
308
309
310
    buff[1]=1;
    break;
  case DISABLE:
311
    buff[2]=ATA_SMART_DISABLE;
312
313
314
315
316
    buff[1]=1;
    break;
  case STATUS:
    // this command only says if SMART is working.  It could be
    // replaced with STATUS_CHECK below.
317
    buff[2]=ATA_SMART_STATUS;
318
319
    break;
  case AUTO_OFFLINE:
320
321
    // NOTE: According to ATAPI 4 and UP, this command is obsolete
    // select == 241 for enable but no data transfer.  Use TASK ioctl.
322
323
    buff[1]=ATA_SMART_AUTO_OFFLINE;
    buff[2]=select;
324
325
    break;
  case AUTOSAVE:
326
    // select == 248 for enable but no data transfer.  Use TASK ioctl.
327
328
    buff[1]=ATA_SMART_AUTOSAVE;
    buff[2]=select;
329
330
    break;
  case IMMEDIATE_OFFLINE:
331
    buff[2]=ATA_SMART_IMMEDIATE_OFFLINE;
332
333
334
335
336
    buff[1]=select;
    break;
  case STATUS_CHECK:
    // This command uses HDIO_DRIVE_TASK and has different syntax than
    // the other commands.
337
    buff[1]=ATA_SMART_STATUS;
338
339
    break;
  default:
340
    pout("Unrecognized command %d in linux_ata_command_interface()\n"
341
         "Please contact " PACKAGE_BUGREPORT "\n", command);
342
343
    errno=ENOSYS;
    return -1;
344
  }
345

346
347
  // This command uses the HDIO_DRIVE_TASKFILE ioctl(). This is the
  // only ioctl() that can be used to WRITE data to the disk.
348
  if (command==WRITE_LOG) {
349
350
351
352
353
354
    unsigned char task[sizeof(ide_task_request_t)+512];
    ide_task_request_t *reqtask=(ide_task_request_t *) task;
    task_struct_t      *taskfile=(task_struct_t *) reqtask->io_ports;
    int retval;

    memset(task,      0, sizeof(task));
355

356
357
358
359
    taskfile->data           = 0;
    taskfile->feature        = ATA_SMART_WRITE_LOG_SECTOR;
    taskfile->sector_count   = 1;
    taskfile->sector_number  = select;
360
    taskfile->low_cylinder   = 0x4f;
361
362
363
    taskfile->high_cylinder  = 0xc2;
    taskfile->device_head    = 0;
    taskfile->command        = ATA_SMART_CMD;
364

365
366
367
368
    reqtask->data_phase      = TASKFILE_OUT;
    reqtask->req_cmd         = IDE_DRIVE_TASK_OUT;
    reqtask->out_size        = 512;
    reqtask->in_size         = 0;
369

370
371
    // copy user data into the task request structure
    memcpy(task+sizeof(ide_task_request_t), data, 512);
372

373
    if ((retval=ioctl(get_fd(), HDIO_DRIVE_TASKFILE, task))) {
374
      if (retval==-EINVAL)
375
        pout("Kernel lacks HDIO_DRIVE_TASKFILE support; compile kernel with CONFIG_IDE_TASKFILE_IO set\n");
376
377
378
379
      return -1;
    }
    return 0;
  }
380

381
382
  // There are two different types of ioctls().  The HDIO_DRIVE_TASK
  // one is this:
383
  if (command==STATUS_CHECK || command==AUTOSAVE || command==AUTO_OFFLINE){
384
    int retval;
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399

    // NOT DOCUMENTED in /usr/src/linux/include/linux/hdreg.h. You
    // have to read the IDE driver source code.  Sigh.
    // buff[0]: ATA COMMAND CODE REGISTER
    // buff[1]: ATA FEATURES REGISTER
    // buff[2]: ATA SECTOR_COUNT
    // buff[3]: ATA SECTOR NUMBER
    // buff[4]: ATA CYL LO REGISTER
    // buff[5]: ATA CYL HI REGISTER
    // buff[6]: ATA DEVICE HEAD

    unsigned const char normal_lo=0x4f, normal_hi=0xc2;
    unsigned const char failed_lo=0xf4, failed_hi=0x2c;
    buff[4]=normal_lo;
    buff[5]=normal_hi;
400

401
    if ((retval=ioctl(get_fd(), HDIO_DRIVE_TASK, buff))) {
402
      if (retval==-EINVAL) {
403
404
        pout("Error SMART Status command via HDIO_DRIVE_TASK failed");
        pout("Rebuild older linux 2.2 kernels with HDIO_DRIVE_TASK support added\n");
405
406
      }
      else
407
        syserror("Error SMART Status command failed");
408
      return -1;
409
    }
410

411
412
413
    // Cyl low and Cyl high unchanged means "Good SMART status"
    if (buff[4]==normal_lo && buff[5]==normal_hi)
      return 0;
414

415
416
417
    // These values mean "Bad SMART status"
    if (buff[4]==failed_lo && buff[5]==failed_hi)
      return 1;
418

419
420
    // We haven't gotten output that makes sense; print out some debugging info
    syserror("Error SMART Status command failed");
421
    pout("Please get assistance from " PACKAGE_HOMEPAGE "\n");
422
    pout("Register values returned from SMART Status command are:\n");
423
424
    pout("ST =0x%02x\n",(int)buff[0]);
    pout("ERR=0x%02x\n",(int)buff[1]);
425
426
427
428
429
    pout("NS =0x%02x\n",(int)buff[2]);
    pout("SC =0x%02x\n",(int)buff[3]);
    pout("CL =0x%02x\n",(int)buff[4]);
    pout("CH =0x%02x\n",(int)buff[5]);
    pout("SEL=0x%02x\n",(int)buff[6]);
430
    return -1;
431
  }
432

433
#if 1
434
  // Note to people doing ports to other OSes -- don't worry about
435
436
437
438
439
440
  // this block -- you can safely ignore it.  I have put it here
  // because under linux when you do IDENTIFY DEVICE to a packet
  // device, it generates an ugly kernel syslog error message.  This
  // is harmless but frightens users.  So this block detects packet
  // devices and make IDENTIFY DEVICE fail "nicely" without a syslog
  // error message.
441
  //
442
443
444
445
446
447
448
  // If you read only the ATA specs, it appears as if a packet device
  // *might* respond to the IDENTIFY DEVICE command.  This is
  // misleading - it's because around the time that SFF-8020 was
  // incorporated into the ATA-3/4 standard, the ATA authors were
  // sloppy. See SFF-8020 and you will see that ATAPI devices have
  // *always* had IDENTIFY PACKET DEVICE as a mandatory part of their
  // command set, and return 'Command Aborted' to IDENTIFY DEVICE.
449
  if (command==IDENTIFY || command==PIDENTIFY){
450
    unsigned short deviceid[256];
451
452
453
454
    // check the device identity, as seen when the system was booted
    // or the device was FIRST registered.  This will not be current
    // if the user has subsequently changed some of the parameters. If
    // device is a packet device, swap the command interpretations.
455
    if (!ioctl(get_fd(), HDIO_GET_IDENTITY, deviceid) && (deviceid[0] & 0x8000))
456
      buff[0]=(command==IDENTIFY)?ATA_IDENTIFY_PACKET_DEVICE:ATA_IDENTIFY_DEVICE;
457
458
  }
#endif
459

460
  // We are now doing the HDIO_DRIVE_CMD type ioctl.
461
  if ((ioctl(get_fd(), HDIO_DRIVE_CMD, buff)))
462
463
    return -1;

464
465
466
467
468
469
  // CHECK POWER MODE command returns information in the Sector Count
  // register (buff[3]).  Copy to return data buffer.
  if (command==CHECK_POWER_MODE)
    buff[HDIO_DRIVE_CMD_OFFSET]=buff[2];

  // if the command returns data then copy it back
470
  if (copydata)
471
    memcpy(data, buff+HDIO_DRIVE_CMD_OFFSET, copydata);
472
473

  return 0;
474
475
}

476
477
478
479
480
481
482
483
484
485
486
487
488
489
// >>>>>> Start of general SCSI specific linux code

/* Linux specific code.
 * Historically smartmontools (and smartsuite before it) used the
 * SCSI_IOCTL_SEND_COMMAND ioctl which is available to all linux device
 * nodes that use the SCSI subsystem. A better interface has been available
 * via the SCSI generic (sg) driver but this involves the extra step of
 * mapping disk devices (e.g. /dev/sda) to the corresponding sg device
 * (e.g. /dev/sg2). In the linux kernel 2.6 series most of the facilities of
 * the sg driver have become available via the SG_IO ioctl which is available
 * on all SCSI devices (on SCSI tape devices from lk 2.6.6).
 * So the strategy below is to find out if the SG_IO ioctl is available and
 * if so use it; failing that use the older SCSI_IOCTL_SEND_COMMAND ioctl.
 * Should work in 2.0, 2.2, 2.4 and 2.6 series linux kernels. */
490
491
492

#define MAX_DXFER_LEN 1024      /* can be increased if necessary */
#define SEND_IOCTL_RESP_SENSE_LEN 16    /* ioctl limitation */
493
494
495
#define SG_IO_RESP_SENSE_LEN 64 /* large enough see buffer */
#define LSCSI_DRIVER_MASK  0xf /* mask out "suggestions" */
#define LSCSI_DRIVER_SENSE  0x8 /* alternate CHECK CONDITION indication */
496
#define LSCSI_DID_ERROR 0x7 /* Need to work around aacraid driver quirk */
497
498
499
500
#define LSCSI_DRIVER_TIMEOUT  0x6
#define LSCSI_DID_TIME_OUT  0x3
#define LSCSI_DID_BUS_BUSY  0x2
#define LSCSI_DID_NO_CONNECT  0x1
501
502
503
504

#ifndef SCSI_IOCTL_SEND_COMMAND
#define SCSI_IOCTL_SEND_COMMAND 1
#endif
505
506
507
508
509

#define SG_IO_PRESENT_UNKNOWN 0
#define SG_IO_PRESENT_YES 1
#define SG_IO_PRESENT_NO 2

510
static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
511
                         int unknown);
512
513
514
515
516
517
518
519
static int sisc_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report);

static int sg_io_state = SG_IO_PRESENT_UNKNOWN;

/* Preferred implementation for issuing SCSI commands in linux. This
 * function uses the SG_IO ioctl. Return 0 if command issued successfully
 * (various status values should still be checked). If the SCSI command
 * cannot be issued then a negative errno value is returned. */
520
static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
521
                         int unknown)
522
523
{
#ifndef SG_IO
524
    ARGUSED(dev_fd); ARGUSED(iop); ARGUSED(report);
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
    return -ENOTTY;
#else
    struct sg_io_hdr io_hdr;

    if (report > 0) {
        int k, j;
        const unsigned char * ucp = iop->cmnd;
        const char * np;
        char buff[256];
        const int sz = (int)sizeof(buff);

        np = scsi_get_opcode_name(ucp[0]);
        j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
        for (k = 0; k < (int)iop->cmnd_len; ++k)
            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
540
        if ((report > 1) &&
541
542
543
544
545
546
            (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
            int trunc = (iop->dxfer_len > 256) ? 1 : 0;

            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n  Outgoing "
                          "data, len=%d%s:\n", (int)iop->dxfer_len,
                          (trunc ? " [only first 256 bytes shown]" : ""));
547
            dStrHex((const char *)iop->dxferp,
548
                    (trunc ? 256 : iop->dxfer_len) , 1);
549
550
551
        }
        else
            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
552
        pout("%s", buff);
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
    }
    memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
    io_hdr.interface_id = 'S';
    io_hdr.cmd_len = iop->cmnd_len;
    io_hdr.mx_sb_len = iop->max_sense_len;
    io_hdr.dxfer_len = iop->dxfer_len;
    io_hdr.dxferp = iop->dxferp;
    io_hdr.cmdp = iop->cmnd;
    io_hdr.sbp = iop->sensep;
    /* sg_io_hdr interface timeout has millisecond units. Timeout of 0
       defaults to 60 seconds. */
    io_hdr.timeout = ((0 == iop->timeout) ? 60 : iop->timeout) * 1000;
    switch (iop->dxfer_dir) {
        case DXFER_NONE:
            io_hdr.dxfer_direction = SG_DXFER_NONE;
            break;
        case DXFER_FROM_DEVICE:
            io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
            break;
        case DXFER_TO_DEVICE:
            io_hdr.dxfer_direction = SG_DXFER_TO_DEV;
            break;
        default:
            pout("do_scsi_cmnd_io: bad dxfer_dir\n");
            return -EINVAL;
    }
    iop->resp_sense_len = 0;
    iop->scsi_status = 0;
    iop->resid = 0;
    if (ioctl(dev_fd, SG_IO, &io_hdr) < 0) {
583
        if (report && (! unknown))
584
            pout("  SG_IO ioctl failed, errno=%d [%s]\n", errno,
585
                 strerror(errno));
586
587
        return -errno;
    }
588
589
    iop->resid = io_hdr.resid;
    iop->scsi_status = io_hdr.status;
590
591
    if (report > 0) {
        pout("  scsi_status=0x%x, host_status=0x%x, driver_status=0x%x\n"
592
             "  info=0x%x  duration=%d milliseconds  resid=%d\n", io_hdr.status,
593
             io_hdr.host_status, io_hdr.driver_status, io_hdr.info,
594
             io_hdr.duration, io_hdr.resid);
595
596
        if (report > 1) {
            if (DXFER_FROM_DEVICE == iop->dxfer_dir) {
597
598
599
600
601
602
603
604
605
606
607
                int trunc, len;

		len = iop->dxfer_len - iop->resid;
		trunc = (len > 256) ? 1 : 0;
                if (len > 0) {
                    pout("  Incoming data, len=%d%s:\n", len,
                         (trunc ? " [only first 256 bytes shown]" : ""));
                    dStrHex((const char*)iop->dxferp, (trunc ? 256 : len),
                            1);
                } else
                    pout("  Incoming data trimmed to nothing by resid\n");
608
609
610
611
612
            }
        }
    }

    if (io_hdr.info | SG_INFO_CHECK) { /* error or warning */
613
        int masked_driver_status = (LSCSI_DRIVER_MASK & io_hdr.driver_status);
614

615
        if (0 != io_hdr.host_status) {
616
617
618
619
            if ((LSCSI_DID_NO_CONNECT == io_hdr.host_status) ||
                (LSCSI_DID_BUS_BUSY == io_hdr.host_status) ||
                (LSCSI_DID_TIME_OUT == io_hdr.host_status))
                return -ETIMEDOUT;
620
            else
621
622
623
624
               /* Check for DID_ERROR - workaround for aacraid driver quirk */
               if (LSCSI_DID_ERROR != io_hdr.host_status) {
                       return -EIO; /* catch all if not DID_ERR */
               }
625
626
627
628
        }
        if (0 != masked_driver_status) {
            if (LSCSI_DRIVER_TIMEOUT == masked_driver_status)
                return -ETIMEDOUT;
629
630
631
            else if (LSCSI_DRIVER_SENSE != masked_driver_status)
                return -EIO;
        }
632
        if (LSCSI_DRIVER_SENSE == masked_driver_status)
633
634
            iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
        iop->resp_sense_len = io_hdr.sb_len_wr;
635
        if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) &&
636
637
638
            iop->sensep && (iop->resp_sense_len > 0)) {
            if (report > 1) {
                pout("  >>> Sense buffer, len=%d:\n",
639
                     (int)iop->resp_sense_len);
640
641
642
643
644
                dStrHex((const char *)iop->sensep, iop->resp_sense_len , 1);
            }
        }
        if (report) {
            if (SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) {
645
646
647
648
649
650
651
652
                if ((iop->sensep[0] & 0x7f) > 0x71)
                    pout("  status=%x: [desc] sense_key=%x asc=%x ascq=%x\n",
                         iop->scsi_status, iop->sensep[1] & 0xf,
                         iop->sensep[2], iop->sensep[3]);
                else
                    pout("  status=%x: sense_key=%x asc=%x ascq=%x\n",
                         iop->scsi_status, iop->sensep[2] & 0xf,
                         iop->sensep[12], iop->sensep[13]);
653
654
655
656
657
658
            }
            else
                pout("  status=0x%x\n", iop->scsi_status);
        }
    }
    return 0;
659
#endif
660
}
661
662
663
664
665
666
667
668

struct linux_ioctl_send_command
{
    int inbufsize;
    int outbufsize;
    UINT8 buff[MAX_DXFER_LEN + 16];
};

669
/* The Linux SCSI_IOCTL_SEND_COMMAND ioctl is primitive and it doesn't
670
671
672
 * support: CDB length (guesses it from opcode), resid and timeout.
 * Patches in Linux 2.4.21 and 2.5.70 to extend SEND DIAGNOSTIC timeout
 * to 2 hours in order to allow long foreground extended self tests. */
673
static int sisc_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
674
675
676
677
678
679
680
681
{
    struct linux_ioctl_send_command wrk;
    int status, buff_offset;
    size_t len;

    memcpy(wrk.buff, iop->cmnd, iop->cmnd_len);
    buff_offset = iop->cmnd_len;
    if (report > 0) {
682
        int k, j;
683
684
        const unsigned char * ucp = iop->cmnd;
        const char * np;
685
        char buff[256];
dpgilbert's avatar
dpgilbert committed
686
        const int sz = (int)sizeof(buff);
687
688

        np = scsi_get_opcode_name(ucp[0]);
689
        j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
dpgilbert's avatar
dpgilbert committed
690
        for (k = 0; k < (int)iop->cmnd_len; ++k)
691
            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
692
        if ((report > 1) &&
693
694
695
            (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
            int trunc = (iop->dxfer_len > 256) ? 1 : 0;

696
697
698
            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n  Outgoing "
                          "data, len=%d%s:\n", (int)iop->dxfer_len,
                          (trunc ? " [only first 256 bytes shown]" : ""));
699
            dStrHex((const char *)iop->dxferp,
700
                    (trunc ? 256 : iop->dxfer_len) , 1);
701
702
        }
        else
703
            j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
704
        pout("%s", buff);
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
    }
    switch (iop->dxfer_dir) {
        case DXFER_NONE:
            wrk.inbufsize = 0;
            wrk.outbufsize = 0;
            break;
        case DXFER_FROM_DEVICE:
            wrk.inbufsize = 0;
            if (iop->dxfer_len > MAX_DXFER_LEN)
                return -EINVAL;
            wrk.outbufsize = iop->dxfer_len;
            break;
        case DXFER_TO_DEVICE:
            if (iop->dxfer_len > MAX_DXFER_LEN)
                return -EINVAL;
            memcpy(wrk.buff + buff_offset, iop->dxferp, iop->dxfer_len);
            wrk.inbufsize = iop->dxfer_len;
            wrk.outbufsize = 0;
            break;
        default:
            pout("do_scsi_cmnd_io: bad dxfer_dir\n");
            return -EINVAL;
    }
    iop->resp_sense_len = 0;
    iop->scsi_status = 0;
    iop->resid = 0;
731
    status = ioctl(dev_fd, SCSI_IOCTL_SEND_COMMAND, &wrk);
732
733
    if (-1 == status) {
        if (report)
734
735
            pout("  SCSI_IOCTL_SEND_COMMAND ioctl failed, errno=%d [%s]\n",
                 errno, strerror(errno));
736
737
738
739
740
741
742
743
744
745
746
747
        return -errno;
    }
    if (0 == status) {
        if (report > 0)
            pout("  status=0\n");
        if (DXFER_FROM_DEVICE == iop->dxfer_dir) {
            memcpy(iop->dxferp, wrk.buff, iop->dxfer_len);
            if (report > 1) {
                int trunc = (iop->dxfer_len > 256) ? 1 : 0;

                pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
                     (trunc ? " [only first 256 bytes shown]" : ""));
748
                dStrHex((const char*)iop->dxferp,
749
                        (trunc ? 256 : iop->dxfer_len) , 1);
750
751
752
753
754
            }
        }
        return 0;
    }
    iop->scsi_status = status & 0x7e; /* bits 0 and 7 used to be for vendors */
755
    if (LSCSI_DRIVER_SENSE == ((status >> 24) & 0xf))
756
757
758
        iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
    len = (SEND_IOCTL_RESP_SENSE_LEN < iop->max_sense_len) ?
                SEND_IOCTL_RESP_SENSE_LEN : iop->max_sense_len;
759
    if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) &&
760
761
762
763
764
        iop->sensep && (len > 0)) {
        memcpy(iop->sensep, wrk.buff, len);
        iop->resp_sense_len = len;
        if (report > 1) {
            pout("  >>> Sense buffer, len=%d:\n", (int)len);
765
            dStrHex((const char *)wrk.buff, len , 1);
766
767
768
769
770
771
772
773
774
775
776
777
778
779
        }
    }
    if (report) {
        if (SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) {
            pout("  status=%x: sense_key=%x asc=%x ascq=%x\n", status & 0xff,
                 wrk.buff[2] & 0xf, wrk.buff[12], wrk.buff[13]);
        }
        else
            pout("  status=0x%x\n", status);
    }
    if (iop->scsi_status > 0)
        return 0;
    else {
        if (report > 0)
780
            pout("  ioctl status=0x%x but scsi status=0, fail with EIO\n",
781
782
783
784
785
                 status);
        return -EIO;      /* give up, assume no device there */
    }
}

786
787
/* SCSI command transmission interface function, linux version.
 * Returns 0 if SCSI command successfully launched and response
788
 * received. Even when 0 is returned the caller should check
789
790
791
792
 * scsi_cmnd_io::scsi_status for SCSI defined errors and warnings
 * (e.g. CHECK CONDITION). If the SCSI command could not be issued
 * (e.g. device not present or timeout) or some other problem
 * (e.g. timeout) then returns a negative errno value */
guidog's avatar
guidog committed
793
794
static int do_normal_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop,
                                  int report)
795
796
797
798
799
800
{
    int res;

    /* implementation relies on static sg_io_state variable. If not
     * previously set tries the SG_IO ioctl. If that succeeds assume
     * that SG_IO ioctl functional. If it fails with an errno value
801
     * other than ENODEV (no device) or permission then assume
802
803
804
805
     * SCSI_IOCTL_SEND_COMMAND is the only option. */
    switch (sg_io_state) {
    case SG_IO_PRESENT_UNKNOWN:
        /* ignore report argument */
806
807
808
809
810
        if (0 == (res = sg_io_cmnd_io(dev_fd, iop, report, 1))) {
            sg_io_state = SG_IO_PRESENT_YES;
            return 0;
        } else if ((-ENODEV == res) || (-EACCES == res) || (-EPERM == res))
            return res;         /* wait until we see a device */
811
        sg_io_state = SG_IO_PRESENT_NO;
812
        /* drop through by design */
813
    case SG_IO_PRESENT_NO:
814
        return sisc_cmnd_io(dev_fd, iop, report);
815
    case SG_IO_PRESENT_YES:
816
        return sg_io_cmnd_io(dev_fd, iop, report, 0);
817
    default:
818
        pout(">>>> do_scsi_cmnd_io: bad sg_io_state=%d\n", sg_io_state);
819
820
        sg_io_state = SG_IO_PRESENT_UNKNOWN;
        return -EIO;    /* report error and reset state */
821
822
823
    }
}

824
825
826
827
828
829
830
831
832
833
// >>>>>> End of general SCSI specific linux code

/////////////////////////////////////////////////////////////////////////////
/// Standard SCSI support

class linux_scsi_device
: public /*implements*/ scsi_device,
  public /*extends*/ linux_smart_device
{
public:
834
835
  linux_scsi_device(smart_interface * intf, const char * dev_name,
                    const char * req_type, bool scanning = false);
836
837
838
839

  virtual smart_device * autodetect_open();

  virtual bool scsi_pass_through(scsi_cmnd_io * iop);
840
841
842

private:
  bool m_scanning; ///< true if created within scan_smart_devices
843
844
845
};

linux_scsi_device::linux_scsi_device(smart_interface * intf,
846
  const char * dev_name, const char * req_type, bool scanning /*= false*/)
847
: smart_device(intf, dev_name, "scsi", req_type),
848
849
850
  // If opened with O_RDWR, a SATA disk in standby mode
  // may spin-up after device close().
  linux_smart_device(O_RDONLY | O_NONBLOCK),
851
  m_scanning(scanning)
852
853
854
855
856
857
858
859
860
861
862
863
{
}


bool linux_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
{
  int status = do_normal_scsi_cmnd_io(get_fd(), iop, con->reportscsiioctl);
  if (status < 0)
      return set_err(-status);
  return true;
}

864
865
/////////////////////////////////////////////////////////////////////////////
/// LSI MegaRAID support
jharg's avatar
jharg committed
866

867
868
869
870
871
872
873
874
class linux_megaraid_device
: public /* implements */ scsi_device,
  public /* extends */ linux_smart_device
{
public:
  linux_megaraid_device(smart_interface *intf, const char *name, 
    unsigned int bus, unsigned int tgt);

jharg's avatar
jharg committed
875
876
877
878
  virtual ~linux_megaraid_device() throw();

  virtual smart_device * autodetect_open();

879
880
881
882
883
884
885
886
887
888
889
890
  virtual bool open();
  virtual bool close();
 
  virtual bool scsi_pass_through(scsi_cmnd_io *iop);

private:
  unsigned int m_disknum;
  unsigned int m_busnum;
  unsigned int m_hba;
  int m_fd;

  bool (linux_megaraid_device::*pt_cmd)(int cdblen, void *cdb, int dataLen, void *data,
jharg's avatar
jharg committed
891
    int senseLen, void *sense, int report);
892
  bool megasas_cmd(int cdbLen, void *cdb, int dataLen, void *data,
jharg's avatar
jharg committed
893
    int senseLen, void *sense, int report);
894
  bool megadev_cmd(int cdbLen, void *cdb, int dataLen, void *data,
jharg's avatar
jharg committed
895
    int senseLen, void *sense, int report);
896
897
898
899
900
901
};

linux_megaraid_device::linux_megaraid_device(smart_interface *intf,
  const char *dev_name, unsigned int bus, unsigned int tgt)
 : smart_device(intf, dev_name, "megaraid", "megaraid"),
   linux_smart_device(O_RDWR | O_NONBLOCK),
jharg's avatar
jharg committed
902
903
   m_disknum(tgt), m_busnum(bus), m_hba(0),
   m_fd(-1), pt_cmd(0)
904
905
906
907
{
  set_info().info_name = strprintf("%s [megaraid_disk_%02d]", dev_name, m_disknum);
}

jharg's avatar
jharg committed
908
909
910
911
912
913
914
915
linux_megaraid_device::~linux_megaraid_device() throw()
{
  if (m_fd >= 0)
    ::close(m_fd);
}

smart_device * linux_megaraid_device::autodetect_open()
{
916
917
  int report = con->reportscsiioctl; 

jharg's avatar
jharg committed
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
  // Open device
  if (!open())
    return this;

  // The code below is based on smartd.cpp:SCSIFilterKnown()
  if (strcmp(get_req_type(), "megaraid"))
    return this;

  // Get INQUIRY
  unsigned char req_buff[64] = {0, };
  int req_len = 36;
  if (scsiStdInquiry(this, req_buff, req_len)) {
      close();
      set_err(EIO, "INQUIRY failed");
      return this;
  }

  int avail_len = req_buff[4] + 5;
  int len = (avail_len < req_len ? avail_len : req_len);
  if (len < 36)
      return this;

940
941
  if (report)
    printf("Got MegaRAID inquiry.. %s\n", req_buff+8);
jharg's avatar
jharg committed
942
943

  // Use INQUIRY to detect type
944
  {
jharg's avatar
jharg committed
945
    // SAT or USB ?
946
    ata_device * newdev = smi()->autodetect_sat_device(this, req_buff, len);
jharg's avatar
jharg committed
947
948
949
950
951
952
953
954
955
956
    if (newdev)
      // NOTE: 'this' is now owned by '*newdev'
      return newdev;
  }

  // Nothing special found
  return this;
}


957
958
bool linux_megaraid_device::open()
{
jharg's avatar
jharg committed
959
960
961
  char line[128];
  int   mjr, n1;
  FILE *fp;
962
  int report = con->reportscsiioctl; 
jharg's avatar
jharg committed
963

964
965
966
967
  if (!linux_smart_device::open())
    return false;

  /* Get device HBA */
jharg's avatar
jharg committed
968
  struct sg_scsi_id sgid;
969
970
971
972
  if (ioctl(get_fd(), SG_GET_SCSI_ID, &sgid) == 0) {
    m_hba = sgid.host_no;
  }
  else if (ioctl(get_fd(), SCSI_IOCTL_GET_BUS_NUMBER, &m_hba) != 0) {
jharg's avatar
jharg committed
973
974
    int err = errno;
    linux_smart_device::close();
975
    return set_err(err, "can't get bus number");
jharg's avatar
jharg committed
976
977
978
979
980
981
982
983
  }

  /* Perform mknod of device ioctl node */
  fp = fopen("/proc/devices", "r");
  while (fgets(line, sizeof(line), fp) != NULL) {
  	n1=0;
  	if (sscanf(line, "%d megaraid_sas_ioctl%n", &mjr, &n1) == 1 && n1 == 22) {
	   n1=mknod("/dev/megaraid_sas_ioctl_node", S_IFCHR, makedev(mjr, 0));
984
985
	   if(report > 0)
	     printf("Creating /dev/megaraid_sas_ioctl_node = %d\n", n1 >= 0 ? 0 : errno);
jharg's avatar
jharg committed
986
987
988
989
990
	   if (n1 >= 0 || errno == EEXIST)
	      break;
	}
	else if (sscanf(line, "%d megadev%n", &mjr, &n1) == 1 && n1 == 11) {
	   n1=mknod("/dev/megadev0", S_IFCHR, makedev(mjr, 0));
991
992
	   if(report > 0)
	     printf("Creating /dev/megadev0 = %d\n", n1 >= 0 ? 0 : errno);
jharg's avatar
jharg committed
993
994
995
	   if (n1 >= 0 || errno == EEXIST)
	      break;
	}
996
  }
jharg's avatar
jharg committed
997
  fclose(fp);
998
999
1000

  /* Open Device IOCTL node */
  if ((m_fd = ::open("/dev/megaraid_sas_ioctl_node", O_RDWR)) >= 0) {