smartmontools SVN Rev 5645
Utility to control and monitor storage systems with "S.M.A.R.T."
os_linux.cpp
Go to the documentation of this file.
1/*
2 * os_linux.cpp
3 *
4 * Home page of code is: https://www.smartmontools.org
5 *
6 * Copyright (C) 2003-11 Bruce Allen
7 * Copyright (C) 2003-11 Doug Gilbert <dgilbert@interlog.com>
8 * Copyright (C) 2008-22 Christian Franke
9 *
10 * Original AACRaid code:
11 * Copyright (C) 2014 Raghava Aditya <raghava.aditya@pmcs.com>
12 *
13 * Original Areca code:
14 * Copyright (C) 2008-12 Hank Wu <hank@areca.com.tw>
15 * Copyright (C) 2008 Oliver Bock <brevilo@users.sourceforge.net>
16 *
17 * Original MegaRAID code:
18 * Copyright (C) 2008 Jordan Hargrave <jordan_hargrave@dell.com>
19 *
20 * 3ware code was derived from code that was:
21 *
22 * Written By: Adam Radford <linux@3ware.com>
23 * Modifications By: Joel Jacobson <linux@3ware.com>
24 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
25 * Brad Strand <linux@3ware.com>
26 *
27 * Copyright (C) 1999-2003 3ware Inc.
28 *
29 * Kernel compatibility By: Andre Hedrick <andre@suse.com>
30 * Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com>
31 *
32 * Other ars of this file are derived from code that was
33 *
34 * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
35 * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
36 *
37 * SPDX-License-Identifier: GPL-2.0-or-later
38 */
39
40#include "config.h"
41
42#include <errno.h>
43#include <fcntl.h>
44#include <glob.h>
45
46#include <scsi/scsi.h>
47#include <scsi/scsi_ioctl.h>
48#include <scsi/sg.h>
49#include <linux/bsg.h>
50#include <stdlib.h>
51#include <string.h>
52#include <sys/ioctl.h>
53#include <sys/stat.h>
54#include <sys/utsname.h>
55#include <unistd.h>
56#include <stddef.h> // for offsetof()
57#include <sys/uio.h>
58#include <sys/types.h>
59#include <dirent.h>
60#ifdef HAVE_SYS_SYSMACROS_H
61// glibc 2.25: The inclusion of <sys/sysmacros.h> by <sys/types.h> is
62// deprecated. A warning is printed if major(), minor() or makedev()
63// is used but <sys/sysmacros.h> is not included.
64#include <sys/sysmacros.h>
65#endif
66#ifdef HAVE_LIBSELINUX
67#include <selinux/selinux.h>
68#endif
69
70#include "atacmds.h"
71#include "os_linux.h"
72#include "scsicmds.h"
73#include "utility.h"
74#include "cciss.h"
75#include "megaraid.h"
76#include "sssraid.h"
77#include "aacraid.h"
78#include "nvmecmds.h"
79
80#include "dev_interface.h"
81#include "dev_ata_cmd_set.h"
82#include "dev_areca.h"
83
84// "include/uapi/linux/nvme_ioctl.h" from Linux kernel sources
85#include "linux_nvme_ioctl.h" // nvme_passthru_cmd, NVME_IOCTL_ADMIN_CMD
86
87#ifndef ENOTSUP
88#define ENOTSUP ENOSYS
89#endif
90
91#define ARGUSED(x) ((void)(x))
92
93const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp 5457 2023-02-17 16:21:30Z chrfranke $"
95extern unsigned char failuretest_permissive;
96
97namespace os_linux { // No need to publish anything, name provided for Doxygen
98
99/////////////////////////////////////////////////////////////////////////////
100/// Shared open/close routines
101
103: virtual public /*implements*/ smart_device
104{
105public:
106 explicit linux_smart_device(int flags, int retry_flags = -1)
108 m_fd(-1),
109 m_flags(flags), m_retry_flags(retry_flags)
110 { }
111
112 virtual ~linux_smart_device();
113
114 virtual bool is_open() const override;
115
116 virtual bool open() override;
117
118 virtual bool close() override;
119
120protected:
121 /// Return filedesc for derived classes.
122 int get_fd() const
123 { return m_fd; }
124
125 void set_fd(int fd)
126 { m_fd = fd; }
127
128private:
129 int m_fd; ///< filedesc, -1 if not open.
130 int m_flags; ///< Flags for ::open()
131 int m_retry_flags; ///< Flags to retry ::open(), -1 if no retry
132};
133
135{
136 if (m_fd >= 0)
137 ::close(m_fd);
138}
139
141{
142 return (m_fd >= 0);
143}
144
146{
148
149 if (m_fd < 0 && errno == EROFS && m_retry_flags != -1)
150 // Retry
152
153 if (m_fd < 0) {
154 if (errno == EBUSY && (m_flags & O_EXCL))
155 // device is locked
156 return set_err(EBUSY,
157 "The requested controller is used exclusively by another process!\n"
158 "(e.g. smartctl or smartd)\n"
159 "Please quit the impeding process or try again later...");
160 return set_err((errno==ENOENT || errno==ENOTDIR) ? ENODEV : errno);
161 }
162
163 if (m_fd >= 0) {
164 // sets FD_CLOEXEC on the opened device file descriptor. The
165 // descriptor is otherwise leaked to other applications (mail
166 // sender) which may be considered a security risk and may result
167 // in AVC messages on SELinux-enabled systems.
168 if (-1 == fcntl(m_fd, F_SETFD, FD_CLOEXEC))
169 // TODO: Provide an error printing routine in class smart_interface
170 pout("fcntl(set FD_CLOEXEC) failed, errno=%d [%s]\n", errno, strerror(errno));
171 }
172
173 return true;
174}
175
176// equivalent to close(file descriptor)
178{
179 int fd = m_fd; m_fd = -1;
180 if (::close(fd) < 0)
181 return set_err(errno);
182 return true;
183}
184
185// examples for smartctl
186static const char smartctl_examples[] =
187 "=================================================== SMARTCTL EXAMPLES =====\n\n"
188 " smartctl --all /dev/sda (Prints all SMART information)\n\n"
189 " smartctl --smart=on --offlineauto=on --saveauto=on /dev/sda\n"
190 " (Enables SMART on first disk)\n\n"
191 " smartctl --test=long /dev/sda (Executes extended disk self-test)\n\n"
192 " smartctl --attributes --log=selftest --quietmode=errorsonly /dev/sda\n"
193 " (Prints Self-Test & Attribute errors)\n"
194 " smartctl --all --device=3ware,2 /dev/sda\n"
195 " smartctl --all --device=3ware,2 /dev/twe0\n"
196 " smartctl --all --device=3ware,2 /dev/twa0\n"
197 " smartctl --all --device=3ware,2 /dev/twl0\n"
198 " (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
199 " smartctl --all --device=hpt,1/1/3 /dev/sda\n"
200 " (Prints all SMART info for the SATA disk attached to the 3rd PMPort\n"
201 " of the 1st channel on the 1st HighPoint RAID controller)\n"
202 " smartctl --all --device=areca,3/1 /dev/sg2\n"
203 " (Prints all SMART info for 3rd ATA disk of the 1st enclosure\n"
204 " on Areca RAID controller)\n"
205 ;
206
207/////////////////////////////////////////////////////////////////////////////
208/// Linux ATA support
209
211: public /*implements*/ ata_device_with_command_set,
212 public /*extends*/ linux_smart_device
213{
214public:
215 linux_ata_device(smart_interface * intf, const char * dev_name, const char * req_type);
216
217protected:
218 virtual int ata_command_interface(smart_command_set command, int select, char * data) override;
219};
220
221linux_ata_device::linux_ata_device(smart_interface * intf, const char * dev_name, const char * req_type)
222: smart_device(intf, dev_name, "ata", req_type),
223 linux_smart_device(O_RDONLY | O_NONBLOCK)
224{
225}
226
227// PURPOSE
228// This is an interface routine meant to isolate the OS dependent
229// parts of the code, and to provide a debugging interface. Each
230// different port and OS needs to provide it's own interface. This
231// is the linux one.
232// DETAILED DESCRIPTION OF ARGUMENTS
233// device: is the file descriptor provided by open()
234// command: defines the different operations.
235// select: additional input data if needed (which log, which type of
236// self-test).
237// data: location to write output data, if needed (512 bytes).
238// Note: not all commands use all arguments.
239// RETURN VALUES
240// -1 if the command failed
241// 0 if the command succeeded,
242// STATUS_CHECK routine:
243// -1 if the command failed
244// 0 if the command succeeded and disk SMART status is "OK"
245// 1 if the command succeeded and disk SMART status is "FAILING"
246
247#define BUFFER_LENGTH (4+512)
248
250{
251 unsigned char buff[BUFFER_LENGTH];
252 // positive: bytes to write to caller. negative: bytes to READ from
253 // caller. zero: non-data command
254 int copydata=0;
255
256 const int HDIO_DRIVE_CMD_OFFSET = 4;
257
258 // See struct hd_drive_cmd_hdr in hdreg.h. Before calling ioctl()
259 // buff[0]: ATA COMMAND CODE REGISTER
260 // buff[1]: ATA SECTOR NUMBER REGISTER == LBA LOW REGISTER
261 // buff[2]: ATA FEATURES REGISTER
262 // buff[3]: ATA SECTOR COUNT REGISTER
263
264 // Note that on return:
265 // buff[2] contains the ATA SECTOR COUNT REGISTER
266
267 // clear out buff. Large enough for HDIO_DRIVE_CMD (4+512 bytes)
268 memset(buff, 0, BUFFER_LENGTH);
269
270 buff[0]=ATA_SMART_CMD;
271 switch (command){
272 case CHECK_POWER_MODE:
273 buff[0]=ATA_CHECK_POWER_MODE;
274 copydata=1;
275 break;
276 case READ_VALUES:
277 buff[2]=ATA_SMART_READ_VALUES;
278 buff[3]=1;
279 copydata=512;
280 break;
281 case READ_THRESHOLDS:
283 buff[1]=buff[3]=1;
284 copydata=512;
285 break;
286 case READ_LOG:
288 buff[1]=select;
289 buff[3]=1;
290 copydata=512;
291 break;
292 case WRITE_LOG:
293 break;
294 case IDENTIFY:
295 buff[0]=ATA_IDENTIFY_DEVICE;
296 buff[3]=1;
297 copydata=512;
298 break;
299 case PIDENTIFY:
301 buff[3]=1;
302 copydata=512;
303 break;
304 case ENABLE:
305 buff[2]=ATA_SMART_ENABLE;
306 buff[1]=1;
307 break;
308 case DISABLE:
309 buff[2]=ATA_SMART_DISABLE;
310 buff[1]=1;
311 break;
312 case STATUS:
313 // this command only says if SMART is working. It could be
314 // replaced with STATUS_CHECK below.
315 buff[2]=ATA_SMART_STATUS;
316 break;
317 case AUTO_OFFLINE:
318 // NOTE: According to ATAPI 4 and UP, this command is obsolete
319 // select == 241 for enable but no data transfer. Use TASK ioctl.
321 buff[2]=select;
322 break;
323 case AUTOSAVE:
324 // select == 248 for enable but no data transfer. Use TASK ioctl.
325 buff[1]=ATA_SMART_AUTOSAVE;
326 buff[2]=select;
327 break;
330 buff[1]=select;
331 break;
332 case STATUS_CHECK:
333 // This command uses HDIO_DRIVE_TASK and has different syntax than
334 // the other commands.
335 buff[1]=ATA_SMART_STATUS;
336 break;
337 default:
338 pout("Unrecognized command %d in linux_ata_command_interface()\n"
339 "Please contact " PACKAGE_BUGREPORT "\n", command);
340 errno=ENOSYS;
341 return -1;
342 }
343
344 // This command uses the HDIO_DRIVE_TASKFILE ioctl(). This is the
345 // only ioctl() that can be used to WRITE data to the disk.
346 if (command==WRITE_LOG) {
347 unsigned char task[sizeof(ide_task_request_t)+512];
348 ide_task_request_t *reqtask=(ide_task_request_t *) task;
349 task_struct_t *taskfile=(task_struct_t *) reqtask->io_ports;
350
351 memset(task, 0, sizeof(task));
352
353 taskfile->data = 0;
355 taskfile->sector_count = 1;
356 taskfile->sector_number = select;
357 taskfile->low_cylinder = 0x4f;
358 taskfile->high_cylinder = 0xc2;
359 taskfile->device_head = 0;
360 taskfile->command = ATA_SMART_CMD;
361
362 reqtask->data_phase = TASKFILE_OUT;
363 reqtask->req_cmd = IDE_DRIVE_TASK_OUT;
364 reqtask->out_size = 512;
365 reqtask->in_size = 0;
366
367 // copy user data into the task request structure
368 memcpy(task+sizeof(ide_task_request_t), data, 512);
369
370 if (ioctl(get_fd(), HDIO_DRIVE_TASKFILE, task)) {
371 if (errno==EINVAL)
372 pout("Kernel lacks HDIO_DRIVE_TASKFILE support; compile kernel with CONFIG_IDE_TASK_IOCTL set\n");
373 return -1;
374 }
375 return 0;
376 }
377
378 // There are two different types of ioctls(). The HDIO_DRIVE_TASK
379 // one is this:
380 if (command==STATUS_CHECK || command==AUTOSAVE || command==AUTO_OFFLINE){
381 // NOT DOCUMENTED in /usr/src/linux/include/linux/hdreg.h. You
382 // have to read the IDE driver source code. Sigh.
383 // buff[0]: ATA COMMAND CODE REGISTER
384 // buff[1]: ATA FEATURES REGISTER
385 // buff[2]: ATA SECTOR_COUNT
386 // buff[3]: ATA SECTOR NUMBER
387 // buff[4]: ATA CYL LO REGISTER
388 // buff[5]: ATA CYL HI REGISTER
389 // buff[6]: ATA DEVICE HEAD
390
391 unsigned const char normal_lo=0x4f, normal_hi=0xc2;
392 unsigned const char failed_lo=0xf4, failed_hi=0x2c;
393 buff[4]=normal_lo;
394 buff[5]=normal_hi;
395
396 if (ioctl(get_fd(), HDIO_DRIVE_TASK, buff)) {
397 if (errno==EINVAL) {
398 pout("Error SMART Status command via HDIO_DRIVE_TASK failed");
399 pout("Rebuild older linux 2.2 kernels with HDIO_DRIVE_TASK support added\n");
400 }
401 else
402 syserror("Error SMART Status command failed");
403 return -1;
404 }
405
406 // Cyl low and Cyl high unchanged means "Good SMART status"
407 if (buff[4]==normal_lo && buff[5]==normal_hi)
408 return 0;
409
410 // These values mean "Bad SMART status"
411 if (buff[4]==failed_lo && buff[5]==failed_hi)
412 return 1;
413
414 // We haven't gotten output that makes sense; print out some debugging info
415 syserror("Error SMART Status command failed");
416 pout("Please get assistance from " PACKAGE_URL "\n");
417 pout("Register values returned from SMART Status command are:\n");
418 pout("ST =0x%02x\n",(int)buff[0]);
419 pout("ERR=0x%02x\n",(int)buff[1]);
420 pout("NS =0x%02x\n",(int)buff[2]);
421 pout("SC =0x%02x\n",(int)buff[3]);
422 pout("CL =0x%02x\n",(int)buff[4]);
423 pout("CH =0x%02x\n",(int)buff[5]);
424 pout("SEL=0x%02x\n",(int)buff[6]);
425 return -1;
426 }
427
428#if 1
429 // Note to people doing ports to other OSes -- don't worry about
430 // this block -- you can safely ignore it. I have put it here
431 // because under linux when you do IDENTIFY DEVICE to a packet
432 // device, it generates an ugly kernel syslog error message. This
433 // is harmless but frightens users. So this block detects packet
434 // devices and make IDENTIFY DEVICE fail "nicely" without a syslog
435 // error message.
436 //
437 // If you read only the ATA specs, it appears as if a packet device
438 // *might* respond to the IDENTIFY DEVICE command. This is
439 // misleading - it's because around the time that SFF-8020 was
440 // incorporated into the ATA-3/4 standard, the ATA authors were
441 // sloppy. See SFF-8020 and you will see that ATAPI devices have
442 // *always* had IDENTIFY PACKET DEVICE as a mandatory part of their
443 // command set, and return 'Command Aborted' to IDENTIFY DEVICE.
444 if (command==IDENTIFY || command==PIDENTIFY){
445 unsigned short deviceid[256];
446 // check the device identity, as seen when the system was booted
447 // or the device was FIRST registered. This will not be current
448 // if the user has subsequently changed some of the parameters. If
449 // device is a packet device, swap the command interpretations.
450 if (!ioctl(get_fd(), HDIO_GET_IDENTITY, deviceid) && (deviceid[0] & 0x8000))
452 }
453#endif
454
455 // We are now doing the HDIO_DRIVE_CMD type ioctl.
456 if ((ioctl(get_fd(), HDIO_DRIVE_CMD, buff)))
457 return -1;
458
459 // CHECK POWER MODE command returns information in the Sector Count
460 // register (buff[3]). Copy to return data buffer.
461 if (command==CHECK_POWER_MODE)
462 buff[HDIO_DRIVE_CMD_OFFSET]=buff[2];
463
464 // if the command returns data then copy it back
465 if (copydata)
466 memcpy(data, buff+HDIO_DRIVE_CMD_OFFSET, copydata);
467
468 return 0;
469}
470
471// >>>>>> Start of general SCSI specific linux code
472
473/* Linux specific code.
474 * Historically smartmontools (and smartsuite before it) used the
475 * SCSI_IOCTL_SEND_COMMAND ioctl which is available to all linux device
476 * nodes that use the SCSI subsystem. A better interface has been available
477 * via the SCSI generic (sg) driver but this involves the extra step of
478 * mapping disk devices (e.g. /dev/sda) to the corresponding sg device
479 * (e.g. /dev/sg2). In the linux kernel 2.6 series most of the facilities of
480 * the sg driver have become available via the SG_IO ioctl which is available
481 * on all SCSI devices (on SCSI tape devices from lk 2.6.6). Now in lk 5.17
482 * the SCSI_IOCTL_SEND_COMMAND ioctl is still present but deprecated sending
483 * a warning to the log the first time (after power up) it is used. The SG_IO
484 * Version 3 interface is the most widely used (circa lk 5.17 in 2022) and is
485 * available on the primary block device name (e.g. /dev/sdc) for all SCSI
486 * disks (and tapes) including all USB attached storage and all ATA/SATA
487 * storage. */
488
489#define MAX_DXFER_LEN 1024 /* can be increased if necessary */
490#define SEND_IOCTL_RESP_SENSE_LEN 16 /* ioctl limitation */
491#define SG_IO_RESP_SENSE_LEN 64 /* large enough see buffer */
492#define LSCSI_DRIVER_MASK 0xf /* mask out "suggestions" */
493#define LSCSI_DRIVER_SENSE 0x8 /* alternate CHECK CONDITION indication */
494#define LSCSI_DID_ERROR 0x7 /* Need to work around aacraid driver quirk */
495#define LSCSI_DRIVER_TIMEOUT 0x6
496#define LSCSI_DID_TIME_OUT 0x3
497#define LSCSI_DID_BUS_BUSY 0x2
498#define LSCSI_DID_NO_CONNECT 0x1
499
500
506};
507
509
510
511/* Preferred implementation for issuing SCSI commands in linux. This
512 * function uses the SG_IO ioctl. Return 0 if command issued successfully
513 * (various status values should still be checked). If the SCSI command
514 * cannot be issued then a negative errno value is returned. */
515static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
516 enum lk_sg_io_ifc_t sg_io_ifc)
517{
518 /* we are filling structures for both versions, but using only one requested */
519 struct sg_io_hdr io_hdr_v3;
520 struct sg_io_v4 io_hdr_v4;
521
522#ifdef SCSI_CDB_CHECK
523 bool ok = is_scsi_cdb(iop->cmnd, iop->cmnd_len);
524 if (! ok) {
525 int n = iop->cmnd_len;
526 const unsigned char * ucp = iop->cmnd;
527
528 pout(">>>>>>>> %s: cdb seems invalid, opcode=0x%x, len=%d, cdb:\n",
529 __func__, ((n > 0) ? ucp[0] : 0), n);
530 if (n > 0) {
531 if (n > 16)
532 pout(" <<truncating to first 16 bytes>>\n");
533 dStrHex((const uint8_t *)ucp, ((n > 16) ? 16 : n), 1);
534 }
535 }
536#endif
537
538#if 0
539 if (report > 0) {
540 int k, j;
541 const unsigned char * ucp = iop->cmnd;
542 const char * np;
543 char buff[256];
544 const int sz = (int)sizeof(buff);
545
546 pout(">>>> %s: sg_io_ifc=%d\n", __func__, (int)sg_io_ifc);
547 np = scsi_get_opcode_name(ucp);
548 j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
549 for (k = 0; k < (int)iop->cmnd_len; ++k)
550 j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
551 if ((report > 1) &&
552 (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
553 int trunc = (iop->dxfer_len > 256) ? 1 : 0;
554
555 snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n Outgoing "
556 "data, len=%d%s:\n", (int)iop->dxfer_len,
557 (trunc ? " [only first 256 bytes shown]" : ""));
558 dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
559 }
560 else
561 snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
562 pout("%s", buff);
563 pout("%s\n", buff);
564 }
565#endif
566
567 memset(&io_hdr_v3, 0, sizeof(struct sg_io_hdr));
568 memset(&io_hdr_v4, 0, sizeof(struct sg_io_v4));
569
570 io_hdr_v3.interface_id = 'S';
571 io_hdr_v3.cmd_len = iop->cmnd_len;
572 io_hdr_v3.mx_sb_len = iop->max_sense_len;
573 io_hdr_v3.dxfer_len = iop->dxfer_len;
574 io_hdr_v3.dxferp = iop->dxferp;
575 io_hdr_v3.cmdp = iop->cmnd;
576 io_hdr_v3.sbp = iop->sensep;
577 /* sg_io_hdr interface timeout has millisecond units. Timeout of 0
578 defaults to 60 seconds. */
579 io_hdr_v3.timeout = ((0 == iop->timeout) ? 60 : iop->timeout) * 1000;
580
581 io_hdr_v4.guard = 'Q';
582 io_hdr_v4.request_len = iop->cmnd_len;
583 io_hdr_v4.request = __u64(iop->cmnd);
584 io_hdr_v4.max_response_len = iop->max_sense_len;
585 io_hdr_v4.response = __u64(iop->sensep);
586 io_hdr_v4.timeout = ((0 == iop->timeout) ? 60 : iop->timeout) * 1000; // msec
587
588 switch (iop->dxfer_dir) {
589 case DXFER_NONE:
590 io_hdr_v3.dxfer_direction = SG_DXFER_NONE;
591 break;
593 io_hdr_v3.dxfer_direction = SG_DXFER_FROM_DEV;
594 io_hdr_v4.din_xfer_len = iop->dxfer_len;
595 io_hdr_v4.din_xferp = __u64(iop->dxferp);
596 break;
597 case DXFER_TO_DEVICE:
598 io_hdr_v3.dxfer_direction = SG_DXFER_TO_DEV;
599 io_hdr_v4.dout_xfer_len = iop->dxfer_len;
600 io_hdr_v4.dout_xferp = __u64(iop->dxferp);
601 break;
602 default:
603 pout("do_scsi_cmnd_io: bad dxfer_dir\n");
604 return -EINVAL;
605 }
606
607 iop->resp_sense_len = 0;
608 iop->scsi_status = 0;
609 iop->resid = 0;
610
611 void * io_hdr = NULL;
612
613 switch (sg_io_ifc) {
614 case SG_IO_USE_V3:
615 io_hdr = &io_hdr_v3;
616 break;
617 case SG_IO_USE_V4:
618 io_hdr = &io_hdr_v4;
619 break;
620 default:
621 // should never be reached
622 errno = EOPNOTSUPP;
623 return -errno;
624 }
625
626 if (ioctl(dev_fd, SG_IO, io_hdr) < 0) {
627 if (report)
628 pout(" SG_IO ioctl failed, errno=%d [%s], SG_IO_V%d\n", errno,
629 strerror(errno), (int)sg_io_ifc);
630 return -errno;
631 }
632
633 unsigned int sg_driver_status = 0, sg_transport_status = 0, sg_info = 0,
634 sg_duration = 0;
635
636 if (sg_io_ifc == SG_IO_USE_V3) {
637 iop->resid = io_hdr_v3.resid;
638 iop->scsi_status = io_hdr_v3.status;
639 sg_driver_status = io_hdr_v3.driver_status;
640 sg_transport_status = io_hdr_v3.host_status;
641 sg_info = io_hdr_v3.info;
642 iop->resp_sense_len = io_hdr_v3.sb_len_wr;
643 sg_duration = io_hdr_v3.duration;
644 }
645
646 if (sg_io_ifc == SG_IO_USE_V4) {
647 switch (iop->dxfer_dir) {
648 case DXFER_NONE:
649 iop->resid = 0;
650 break;
652 iop->resid = io_hdr_v4.din_resid;
653 break;
654 case DXFER_TO_DEVICE:
655 iop->resid = io_hdr_v4.dout_resid;
656 break;
657 }
658 iop->scsi_status = io_hdr_v4.device_status;
659 sg_driver_status = io_hdr_v4.driver_status;
660 sg_transport_status = io_hdr_v4.transport_status;
661 sg_info = io_hdr_v4.info;
662 iop->resp_sense_len = io_hdr_v4.response_len;
663 sg_duration = io_hdr_v4.duration;
664 }
665 if (sg_duration) { } // silence warning
666
667#if 0
668 if (report > 0) {
669 pout(" scsi_status=0x%x, sg_transport_status=0x%x, sg_driver_status=0x%x\n"
670 " sg_info=0x%x sg_duration=%d milliseconds resid=%d\n", iop->scsi_status,
671 sg_transport_status, sg_driver_status, sg_info,
672 sg_duration, iop->resid);
673
674 if (report > 1) {
675 if (DXFER_FROM_DEVICE == iop->dxfer_dir) {
676 int trunc, len;
677
678 len = iop->dxfer_len - iop->resid;
679 trunc = (len > 256) ? 1 : 0;
680 if (len > 0) {
681 pout(" Incoming data, len=%d%s:\n", len,
682 (trunc ? " [only first 256 bytes shown]" : ""));
683 dStrHex(iop->dxferp, (trunc ? 256 : len), 1);
684 } else
685 pout(" Incoming data trimmed to nothing by resid\n");
686 }
687 }
688 }
689#endif
690
691 if (sg_info & SG_INFO_CHECK) { /* error or warning */
692 int masked_driver_status = (LSCSI_DRIVER_MASK & sg_driver_status);
693
694 if (0 != sg_transport_status) {
695 if ((LSCSI_DID_NO_CONNECT == sg_transport_status) ||
696 (LSCSI_DID_BUS_BUSY == sg_transport_status) ||
697 (LSCSI_DID_TIME_OUT == sg_transport_status))
698 return -ETIMEDOUT;
699 else
700 /* Check for DID_ERROR - workaround for aacraid driver quirk */
701 if (LSCSI_DID_ERROR != sg_transport_status) {
702 return -EIO; /* catch all if not DID_ERR */
703 }
704 }
705 if (0 != masked_driver_status) {
706 if (LSCSI_DRIVER_TIMEOUT == masked_driver_status)
707 return -ETIMEDOUT;
708 else if (LSCSI_DRIVER_SENSE != masked_driver_status)
709 return -EIO;
710 }
711 if (LSCSI_DRIVER_SENSE == masked_driver_status)
714 iop->sensep && (iop->resp_sense_len > 0)) {
715 if (report > 1) {
716 pout(" >>> Sense buffer, len=%d:\n",
717 (int)iop->resp_sense_len);
718 dStrHex(iop->sensep, iop->resp_sense_len , 1);
719 }
720 }
721 if (report) {
722 if (SCSI_STATUS_CHECK_CONDITION == iop->scsi_status && iop->sensep) {
723 if ((iop->sensep[0] & 0x7f) > 0x71)
724 pout(" status=%x: [desc] sense_key=%x asc=%x ascq=%x\n",
725 iop->scsi_status, iop->sensep[1] & 0xf,
726 iop->sensep[2], iop->sensep[3]);
727 else
728 pout(" status=%x: sense_key=%x asc=%x ascq=%x\n",
729 iop->scsi_status, iop->sensep[2] & 0xf,
730 iop->sensep[12], iop->sensep[13]);
731 }
732 else
733 pout(" status=0x%x\n", iop->scsi_status);
734 }
735 }
736 return 0;
737}
738
739/* SCSI command transmission interface function, linux version.
740 * Returns 0 if SCSI command successfully launched and response
741 * received. Even when 0 is returned the caller should check
742 * scsi_cmnd_io::scsi_status for SCSI defined errors and warnings
743 * (e.g. CHECK CONDITION). If the SCSI command could not be issued
744 * (e.g. device not present or timeout) or some other problem
745 * (e.g. timeout) then returns a negative errno value */
746static int do_normal_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop,
747 int report)
748{
749 int res;
750
751 /* implementation relies on static sg_io_interface variable. If not
752 * previously set tries the SG_IO ioctl. If that succeeds assume
753 * that SG_IO ioctl functional. If it fails with an errno value
754 * other than ENODEV (no device) or a permissions problem then
755 * assume the SG_IO_USE_V3 interface. */
756 switch (sg_io_interface) {
757 case SG_IO_USE_DETECT:
758 /* ignore report argument */
759 /* Try SG_IO V3 first */
760 if (0 == (res = sg_io_cmnd_io(dev_fd, iop, report, SG_IO_USE_V3))) {
762 return 0;
763 } else if ((-ENODEV == res) || (-EACCES == res) || (-EPERM == res))
764 return res; /* wait until we see a device */
765 /* See if we can use SG_IO V4 * */
766 if (0 == (res = sg_io_cmnd_io(dev_fd, iop, report, SG_IO_USE_V4))) {
768 return 0;
769 } else if ((-ENODEV == res) || (-EACCES == res) || (-EPERM == res))
770 return res; /* wait until we see a device */
772 /* FALLTHRU */
773 case SG_IO_UNSUPP:
774 /* previously called SCSI_IOCTL_SEND_COMMAND ioctl which has now
775 * been removed. The SG_IO_USE_V3 is most widely used now in Linux
776 * (circa 2022), try it again. */
778 /* FALLTHRU */
779 case SG_IO_USE_V3:
780 case SG_IO_USE_V4:
781 /* use SG_IO V3 or V4 ioctl, depending on availabiliy */
782 return sg_io_cmnd_io(dev_fd, iop, report, sg_io_interface);
783 default:
784 pout(">>>> do_scsi_cmnd_io: bad sg_io_interface=%d\n",
785 (int)sg_io_interface);
787 return -EIO; /* report error and reset state */
788 }
789}
790
791// >>>>>> End of general SCSI specific linux code
792
793/////////////////////////////////////////////////////////////////////////////
794/// Standard SCSI support
795
797: public /*implements*/ scsi_device,
798 public /*extends*/ linux_smart_device
799{
800public:
801 linux_scsi_device(smart_interface * intf, const char * dev_name,
802 const char * req_type, bool scanning = false);
803
804 virtual smart_device * autodetect_open() override;
805
806 virtual bool scsi_pass_through(scsi_cmnd_io * iop) override;
807
808private:
809 bool m_scanning; ///< true if created within scan_smart_devices
810};
811
813 const char * dev_name, const char * req_type, bool scanning /*= false*/)
814: smart_device(intf, dev_name, "scsi", req_type),
815 // If opened with O_RDWR, a SATA disk in standby mode
816 // may spin-up after device close().
817 linux_smart_device(O_RDONLY | O_NONBLOCK),
818 m_scanning(scanning)
819{
820}
821
823{
824 int status = do_normal_scsi_cmnd_io(get_fd(), iop, scsi_debugmode);
825 if (status < 0)
826 return set_err(-status);
827 return true;
828}
829
830/////////////////////////////////////////////////////////////////////////////
831/// PMC AacRAID support
832
834:public scsi_device,
835 public /*extends */ linux_smart_device
836{
837public:
838 linux_aacraid_device(smart_interface *intf, const char *dev_name,
839 unsigned int host, unsigned int channel, unsigned int device);
840
841 virtual ~linux_aacraid_device();
842
843 virtual bool open() override;
844
845 virtual bool scsi_pass_through(scsi_cmnd_io *iop) override;
846
847private:
848 //Device Host number
849 int aHost;
850
851 //Channel(Lun) of the device
852 int aLun;
853
854 //Id of the device
855 int aId;
856
857};
858
860 const char *dev_name, unsigned int host, unsigned int channel, unsigned int device)
861 : smart_device(intf,dev_name,"aacraid","aacraid"),
862 linux_smart_device(O_RDWR|O_NONBLOCK),
863 aHost(host), aLun(channel), aId(device)
864{
865 set_info().info_name = strprintf("%s [aacraid_disk_%02d_%02d_%d]",dev_name,aHost,aLun,aId);
866 set_info().dev_type = strprintf("aacraid,%d,%d,%d",aHost,aLun,aId);
867}
868
870{
871}
872
874{
875 //Create the character device name based on the host number
876 //Required for get stats from disks connected to different controllers
877 char dev_name[128];
878 snprintf(dev_name, sizeof(dev_name), "/dev/aac%d", aHost);
879
880 //Initial open of dev name to check if it exists
881 int afd = ::open(dev_name,O_RDWR);
882
883 if(afd < 0 && errno == ENOENT) {
884
885 FILE *fp = fopen("/proc/devices","r");
886 if(NULL == fp)
887 return set_err(errno,"cannot open /proc/devices:%s",
888 strerror(errno));
889
890 char line[256];
891 int mjr = -1;
892
893 while(fgets(line,sizeof(line),fp) !=NULL) {
894 int nc = -1;
895 if(sscanf(line,"%d aac%n",&mjr,&nc) == 1
896 && nc > 0 && '\n' == line[nc])
897 break;
898 mjr = -1;
899 }
900
901 //work with /proc/devices is done
902 fclose(fp);
903
904 if (mjr < 0)
905 return set_err(ENOENT, "aac entry not found in /proc/devices");
906
907 //Create misc device file in /dev/ used for communication with driver
908 if(mknod(dev_name, S_IFCHR|0600, makedev(mjr,aHost)))
909 return set_err(errno,"cannot create %s:%s",dev_name,strerror(errno));
910
911 afd = ::open(dev_name,O_RDWR);
912 }
913
914 if(afd < 0)
915 return set_err(errno,"cannot open %s:%s",dev_name,strerror(errno));
916
917 set_fd(afd);
918 return true;
919}
920
922{
923 int report = scsi_debugmode;
924
925 if (report > 0) {
926 int k, j;
927 const unsigned char * ucp = iop->cmnd;
928 const char * np;
929 char buff[256];
930 const int sz = (int)sizeof(buff);
931
932 np = scsi_get_opcode_name(ucp);
933 j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
934 for (k = 0; k < (int)iop->cmnd_len; ++k)
935 j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
936 if ((report > 1) &&
937 (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
938 int trunc = (iop->dxfer_len > 256) ? 1 : 0;
939
940 snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n Outgoing "
941 "data, len=%d%s:\n", (int)iop->dxfer_len,
942 (trunc ? " [only first 256 bytes shown]" : ""));
943 dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
944 }
945 else
946 snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
947
948 pout("%s", buff);
949 }
950
951
952 //return test commands
953 if (iop->cmnd[0] == 0x00)
954 return true;
955
956 user_aac_reply *pReply;
957
958 #ifdef ENVIRONMENT64
959 // Create user 64 bit request
960 user_aac_srb64 *pSrb;
961 uint8_t aBuff[sizeof(user_aac_srb64) + sizeof(user_aac_reply)] = {0,};
962
963 pSrb = (user_aac_srb64*)aBuff;
964 pSrb->count = sizeof(user_aac_srb64) - sizeof(user_sgentry64);
965
966 #elif defined(ENVIRONMENT32)
967 //Create user 32 bit request
968 user_aac_srb32 *pSrb;
969 uint8_t aBuff[sizeof(user_aac_srb32) + sizeof(user_aac_reply)] = {0,};
970
971 pSrb = (user_aac_srb32*)aBuff;
972 pSrb->count = sizeof(user_aac_srb32) - sizeof(user_sgentry32);
973 #endif
974
976 //channel is 0 always
977 pSrb->channel = 0;
978 pSrb->id = aId;
979 pSrb->lun = aLun;
980 pSrb->timeout = 0;
981
982 pSrb->retry_limit = 0;
983 pSrb->cdb_size = iop->cmnd_len;
984
985 switch(iop->dxfer_dir) {
986 case DXFER_NONE:
987 pSrb->flags = SRB_NoDataXfer;
988 break;
990 pSrb->flags = SRB_DataIn;
991 break;
992 case DXFER_TO_DEVICE:
993 pSrb->flags = SRB_DataOut;
994 break;
995 default:
996 pout("aacraid: bad dxfer_dir\n");
997 return set_err(EINVAL, "aacraid: bad dxfer_dir\n");
998 }
999
1000 if(iop->dxfer_len > 0) {
1001
1002 #ifdef ENVIRONMENT64
1003 pSrb->sg64.count = 1;
1004 pSrb->sg64.sg64[0].addr64.lo32 = ((intptr_t)iop->dxferp) &
1005 0x00000000ffffffff;
1006 pSrb->sg64.sg64[0].addr64.hi32 = ((intptr_t)iop->dxferp) >> 32;
1007
1008 pSrb->sg64.sg64[0].length = (uint32_t)iop->dxfer_len;
1009 pSrb->count += pSrb->sg64.count * sizeof(user_sgentry64);
1010 #elif defined(ENVIRONMENT32)
1011 pSrb->sg32.count = 1;
1012 pSrb->sg32.sg32[0].addr32 = (intptr_t)iop->dxferp;
1013
1014 pSrb->sg32.sg32[0].length = (uint32_t)iop->dxfer_len;
1015 pSrb->count += pSrb->sg32.count * sizeof(user_sgentry32);
1016 #endif
1017
1018 }
1019
1020 pReply = (user_aac_reply*)(aBuff+pSrb->count);
1021
1022 memcpy(pSrb->cdb,iop->cmnd,iop->cmnd_len);
1023
1024 int rc = 0;
1025 errno = 0;
1026 rc = ioctl(get_fd(),FSACTL_SEND_RAW_SRB,pSrb);
1027
1028 if (rc != 0)
1029 return set_err(errno, "aacraid send_raw_srb: %d.%d = %s",
1030 aLun, aId, strerror(errno));
1031
1032/* see kernel aacraid.h and MSDN SCSI_REQUEST_BLOCK documentation */
1033#define SRB_STATUS_SUCCESS 0x1
1034#define SRB_STATUS_ERROR 0x4
1035#define SRB_STATUS_NO_DEVICE 0x08
1036#define SRB_STATUS_SELECTION_TIMEOUT 0x0a
1037#define SRB_STATUS_AUTOSENSE_VALID 0x80
1038
1039 iop->scsi_status = pReply->scsi_status;
1040
1043 memcpy(iop->sensep, pReply->sense_data, pReply->sense_data_size);
1044 iop->resp_sense_len = pReply->sense_data_size;
1045 return true; /* request completed with sense data */
1046 }
1047
1048 switch (pReply->srb_status & 0x3f) {
1049
1050 case SRB_STATUS_SUCCESS:
1051 return true; /* request completed successfully */
1052
1054 return set_err(EIO, "aacraid: Device %d %d does not exist", aLun, aId);
1055
1057 return set_err(EIO, "aacraid: Device %d %d not responding", aLun, aId);
1058
1059 default:
1060 return set_err(EIO, "aacraid result: %d.%d = 0x%x",
1061 aLun, aId, pReply->srb_status);
1062 }
1063}
1064
1065
1066/////////////////////////////////////////////////////////////////////////////
1067/// LSI MegaRAID support
1068
1070: public /* implements */ scsi_device,
1071 public /* extends */ linux_smart_device
1072{
1073public:
1074 linux_megaraid_device(smart_interface *intf, const char *name,
1075 unsigned int tgt);
1076
1077 virtual ~linux_megaraid_device();
1078
1079 virtual smart_device * autodetect_open() override;
1080
1081 virtual bool open() override;
1082 virtual bool close() override;
1083
1084 virtual bool scsi_pass_through(scsi_cmnd_io *iop) override;
1085
1086private:
1087 unsigned int m_disknum;
1088 unsigned int m_hba;
1089 int m_fd;
1090
1091 bool (linux_megaraid_device::*pt_cmd)(int cdblen, void *cdb, int dataLen, void *data,
1092 int senseLen, void *sense, int report, int direction);
1093 bool megasas_cmd(int cdbLen, void *cdb, int dataLen, void *data,
1094 int senseLen, void *sense, int report, int direction);
1095 bool megadev_cmd(int cdbLen, void *cdb, int dataLen, void *data,
1096 int senseLen, void *sense, int report, int direction);
1097};
1098
1100 const char *dev_name, unsigned int tgt)
1101 : smart_device(intf, dev_name, "megaraid", "megaraid"),
1102 linux_smart_device(O_RDWR | O_NONBLOCK),
1103 m_disknum(tgt), m_hba(0),
1104 m_fd(-1), pt_cmd(0)
1105{
1106 set_info().info_name = strprintf("%s [megaraid_disk_%02d]", dev_name, m_disknum);
1107 set_info().dev_type = strprintf("megaraid,%d", tgt);
1108}
1109
1111{
1112 if (m_fd >= 0)
1113 ::close(m_fd);
1114}
1115
1117{
1118 int report = scsi_debugmode;
1119
1120 // Open device
1121 if (!open())
1122 return this;
1123
1124 // The code below is based on smartd.cpp:SCSIFilterKnown()
1125 if (strcmp(get_req_type(), "megaraid"))
1126 return this;
1127
1128 // Get INQUIRY
1129 unsigned char req_buff[64] = {0, };
1130 int req_len = 36;
1131 if (scsiStdInquiry(this, req_buff, req_len)) {
1132 close();
1133 set_err(EIO, "INQUIRY failed");
1134 return this;
1135 }
1136
1137 int avail_len = req_buff[4] + 5;
1138 int len = (avail_len < req_len ? avail_len : req_len);
1139 if (len < 36)
1140 return this;
1141
1142 if (report)
1143 pout("Got MegaRAID inquiry.. %s\n", req_buff+8);
1144
1145 // Use INQUIRY to detect type
1146 {
1147 // SAT?
1148 ata_device * newdev = smi()->autodetect_sat_device(this, req_buff, len);
1149 if (newdev) // NOTE: 'this' is now owned by '*newdev'
1150 return newdev;
1151 }
1152
1153 // Nothing special found
1154 return this;
1155}
1156
1158{
1159 int mjr;
1160 int report = scsi_debugmode;
1161
1162 if (sscanf(get_dev_name(), "/dev/bus/%u", &m_hba) == 0) {
1164 return false;
1165 /* Get device HBA */
1166 struct sg_scsi_id sgid;
1167 if (ioctl(get_fd(), SG_GET_SCSI_ID, &sgid) == 0) {
1168 m_hba = sgid.host_no;
1169 }
1170 else if (ioctl(get_fd(), SCSI_IOCTL_GET_BUS_NUMBER, &m_hba) != 0) {
1171 int err = errno;
1173 return set_err(err, "can't get bus number");
1174 } // we don't need this device anymore
1176 }
1177 /* Perform mknod of device ioctl node */
1178 FILE * fp = fopen("/proc/devices", "r");
1179 if (fp) {
1180 char line[128];
1181 while (fgets(line, sizeof(line), fp) != NULL) {
1182 int n1 = 0;
1183 if (sscanf(line, "%d megaraid_sas_ioctl%n", &mjr, &n1) == 1 && n1 == 22) {
1184 n1=mknod("/dev/megaraid_sas_ioctl_node", S_IFCHR|0600, makedev(mjr, 0));
1185 if(report > 0)
1186 pout("Creating /dev/megaraid_sas_ioctl_node = %d\n", n1 >= 0 ? 0 : errno);
1187 if (n1 >= 0 || errno == EEXIST)
1188 break;
1189 }
1190 else if (sscanf(line, "%d megadev%n", &mjr, &n1) == 1 && n1 == 11) {
1191 n1=mknod("/dev/megadev0", S_IFCHR|0600, makedev(mjr, 0));
1192 if(report > 0)
1193 pout("Creating /dev/megadev0 = %d\n", n1 >= 0 ? 0 : errno);
1194 if (n1 >= 0 || errno == EEXIST)
1195 break;
1196 }
1197 }
1198 fclose(fp);
1199 }
1200
1201 /* Open Device IOCTL node */
1202 if ((m_fd = ::open("/dev/megaraid_sas_ioctl_node", O_RDWR)) >= 0) {
1204 }
1205 else if ((m_fd = ::open("/dev/megadev0", O_RDWR)) >= 0) {
1207 }
1208 else {
1209 int err = errno;
1211 return set_err(err, "cannot open /dev/megaraid_sas_ioctl_node or /dev/megadev0");
1212 }
1213 set_fd(m_fd);
1214 return true;
1215}
1216
1218{
1219 if (m_fd >= 0)
1220 ::close(m_fd);
1221 m_fd = -1; m_hba = 0; pt_cmd = 0;
1222 set_fd(m_fd);
1223 return true;
1224}
1225
1227{
1228 int report = scsi_debugmode;
1229
1230 if (report > 0) {
1231 int k, j;
1232 const unsigned char * ucp = iop->cmnd;
1233 const char * np;
1234 char buff[256];
1235 const int sz = (int)sizeof(buff);
1236
1237 np = scsi_get_opcode_name(ucp);
1238 j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
1239 for (k = 0; k < (int)iop->cmnd_len; ++k)
1240 j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
1241 if ((report > 1) &&
1242 (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
1243 int trunc = (iop->dxfer_len > 256) ? 1 : 0;
1244
1245 snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n Outgoing "
1246 "data, len=%d%s:\n", (int)iop->dxfer_len,
1247 (trunc ? " [only first 256 bytes shown]" : ""));
1248 dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
1249 }
1250 else
1251 snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
1252 pout("%s", buff);
1253 }
1254
1255 // Controller rejects Test Unit Ready
1256 if (iop->cmnd[0] == 0x00)
1257 return true;
1258
1259 if (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12 || iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16) {
1260 // Controller does not return ATA output registers in SAT sense data
1261 if (iop->cmnd[2] & (1 << 5)) // chk_cond
1262 return set_err(ENOSYS, "ATA return descriptor not supported by controller firmware");
1263 }
1264 // SMART WRITE LOG SECTOR causing media errors
1265 if ((iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16 // SAT16 WRITE LOG
1266 && iop->cmnd[14] == ATA_SMART_CMD && iop->cmnd[3]==0 && iop->cmnd[4] == ATA_SMART_WRITE_LOG_SECTOR) ||
1267 (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12 // SAT12 WRITE LOG
1268 && iop->cmnd[9] == ATA_SMART_CMD && iop->cmnd[3] == ATA_SMART_WRITE_LOG_SECTOR))
1269 {
1271 return set_err(ENOSYS, "SMART WRITE LOG SECTOR may cause problems, try with -T permissive to force");
1272 }
1273 if (pt_cmd == NULL)
1274 return false;
1275 return (this->*pt_cmd)(iop->cmnd_len, iop->cmnd,
1276 iop->dxfer_len, iop->dxferp,
1277 iop->max_sense_len, iop->sensep, report, iop->dxfer_dir);
1278}
1279
1280/* Issue passthrough scsi command to PERC5/6 controllers */
1282 int dataLen, void *data,
1283 int /*senseLen*/, void * /*sense*/, int /*report*/, int dxfer_dir)
1284{
1285 struct megasas_pthru_frame *pthru;
1286 struct megasas_iocpacket uio;
1287
1288 memset(&uio, 0, sizeof(uio));
1289 pthru = &uio.frame.pthru;
1291 pthru->cmd_status = 0xFF;
1292 pthru->scsi_status = 0x0;
1293 pthru->target_id = m_disknum;
1294 pthru->lun = 0;
1295 pthru->cdb_len = cdbLen;
1296 pthru->timeout = 0;
1297 switch (dxfer_dir) {
1298 case DXFER_NONE:
1299 pthru->flags = MFI_FRAME_DIR_NONE;
1300 break;
1301 case DXFER_FROM_DEVICE:
1302 pthru->flags = MFI_FRAME_DIR_READ;
1303 break;
1304 case DXFER_TO_DEVICE:
1305 pthru->flags = MFI_FRAME_DIR_WRITE;
1306 break;
1307 default:
1308 pout("megasas_cmd: bad dxfer_dir\n");
1309 return set_err(EINVAL, "megasas_cmd: bad dxfer_dir\n");
1310 }
1311
1312 if (dataLen > 0) {
1313 pthru->sge_count = 1;
1314 pthru->data_xfer_len = dataLen;
1315 pthru->sgl.sge32[0].phys_addr = (intptr_t)data;
1316 pthru->sgl.sge32[0].length = (uint32_t)dataLen;
1317 }
1318 memcpy(pthru->cdb, cdb, cdbLen);
1319
1320 uio.host_no = m_hba;
1321 if (dataLen > 0) {
1322 uio.sge_count = 1;
1323 uio.sgl_off = offsetof(struct megasas_pthru_frame, sgl);
1324 uio.sgl[0].iov_base = data;
1325 uio.sgl[0].iov_len = dataLen;
1326 }
1327
1328 errno = 0;
1329 int rc = ioctl(m_fd, MEGASAS_IOC_FIRMWARE, &uio);
1330 if (pthru->cmd_status || rc != 0) {
1331 if (pthru->cmd_status == 12) {
1332 return set_err(EIO, "megasas_cmd: Device %d does not exist\n", m_disknum);
1333 }
1334 return set_err((errno ? errno : EIO), "megasas_cmd result: %d.%d = %d/%d",
1335 m_hba, m_disknum, errno,
1336 pthru->cmd_status);
1337 }
1338 return true;
1339}
1340
1341/* Issue passthrough scsi commands to PERC2/3/4 controllers */
1343 int dataLen, void *data,
1344 int /*senseLen*/, void * /*sense*/, int /*report*/, int /* dir */)
1345{
1346 struct uioctl_t uio;
1347 int rc;
1348
1349 /* Don't issue to the controller */
1350 if (m_disknum == 7)
1351 return false;
1352
1353 memset(&uio, 0, sizeof(uio));
1354 uio.inlen = dataLen;
1355 uio.outlen = dataLen;
1356
1357 memset(data, 0, dataLen);
1358 uio.ui.fcs.opcode = 0x80; // M_RD_IOCTL_CMD
1359 uio.ui.fcs.adapno = MKADAP(m_hba);
1360
1361 uio.data.pointer = (uint8_t *)data;
1362
1363 uio.mbox.cmd = MEGA_MBOXCMD_PASSTHRU;
1364 uio.mbox.xferaddr = (intptr_t)&uio.pthru;
1365
1366 uio.pthru.ars = 1;
1367 uio.pthru.timeout = 2;
1368 uio.pthru.channel = 0;
1369 uio.pthru.target = m_disknum;
1370 uio.pthru.cdblen = cdbLen;
1371 uio.pthru.reqsenselen = MAX_REQ_SENSE_LEN;
1372 uio.pthru.dataxferaddr = (intptr_t)data;
1373 uio.pthru.dataxferlen = dataLen;
1374 memcpy(uio.pthru.cdb, cdb, cdbLen);
1375
1376 rc=ioctl(m_fd, MEGAIOCCMD, &uio);
1377 if (uio.pthru.scsistatus || rc != 0) {
1378 return set_err((errno ? errno : EIO), "megadev_cmd result: %d.%d = %d/%d",
1379 m_hba, m_disknum, errno,
1380 uio.pthru.scsistatus);
1381 }
1382 return true;
1383}
1384
1385/////////////////////////////////////////////////////////////////////////////
1386/// 3SNIC RAID support
1387
1389: public /* implements */ scsi_device,
1390 public /* extends */ linux_smart_device
1391{
1392public:
1393 linux_sssraid_device(smart_interface *intf, const char *name,
1394 unsigned int eid, unsigned int sid);
1395
1396 virtual bool scsi_pass_through(scsi_cmnd_io *iop) override;
1397
1398private:
1399 unsigned int m_eid;
1400 unsigned int m_sid;
1401
1402 bool scsi_cmd(scsi_cmnd_io *iop);
1403};
1404
1406 const char *dev_name, unsigned int eid, unsigned int sid)
1407 : smart_device(intf, dev_name, "sssraid", "sssraid"),
1408 linux_smart_device(O_RDWR | O_NONBLOCK),
1409 m_eid(eid), m_sid(sid)
1410{
1411 set_info().info_name = strprintf("%s [sssraid_disk_%02d_%02d]", dev_name, eid, sid);
1412 set_info().dev_type = strprintf("sssraid,%d,%d", eid, sid);
1413}
1414
1416{
1417 int report = scsi_debugmode;
1418 if (report > 0) {
1419 int k, j;
1420 const unsigned char * ucp = iop->cmnd;
1421 const char * np;
1422 char buff[256];
1423 const int sz = (int)sizeof(buff);
1424
1425 np = scsi_get_opcode_name(ucp);
1426 j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
1427 for (k = 0; k < (int)iop->cmnd_len; ++k)
1428 j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
1429 if ((report > 1) && (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
1430 int trunc = (iop->dxfer_len > 256) ? 1 : 0;
1431
1432 snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n Outgoing "
1433 "data, len=%d%s:\n", (int)iop->dxfer_len,
1434 (trunc ? " [only first 256 bytes shown]" : ""));
1435 dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
1436 }
1437 else
1438 snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
1439 pout("%s", buff);
1440 }
1441
1442 bool r = scsi_cmd(iop);
1443 return r;
1444}
1445
1446/* Issue passthrough scsi commands to sssraid controllers */
1448{
1449 struct sg_io_v4 io_hdr_v4{};
1450 struct cmd_scsi_passthrough scsi_param{};
1451 unsigned char sense_buff[96] = { 0 };
1452 struct bsg_ioctl_cmd bsg_param{};
1453 scsi_param.sense_buffer = sense_buff;
1454 scsi_param.sense_buffer_len = 96;
1455 scsi_param.cdb_len = iop->cmnd_len;
1456 memcpy(scsi_param.cdb, iop->cmnd, iop->cmnd_len);
1457 scsi_param.loc.enc_id = m_eid;
1458 scsi_param.loc.slot_id = m_sid;
1459
1460 io_hdr_v4.guard = 'Q';
1461 io_hdr_v4.protocol = BSG_PROTOCOL_SCSI;
1462 io_hdr_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_TRANSPORT;
1463 io_hdr_v4.response = (uintptr_t)sense_buff;
1464 io_hdr_v4.max_response_len = ADM_SCSI_CDB_SENSE_MAX_LEN;
1465 io_hdr_v4.request_len = sizeof(struct bsg_ioctl_cmd);
1466 io_hdr_v4.request = (uintptr_t)(&bsg_param);
1468
1469 switch (iop->dxfer_dir) {
1470 case DXFER_NONE:
1471 bsg_param.ioctl_pthru.opcode = ADM_RAID_SET;
1472 break;
1473 case DXFER_FROM_DEVICE:
1474 io_hdr_v4.din_xferp = (uintptr_t)iop->dxferp;
1475 io_hdr_v4.din_xfer_len = iop->dxfer_len;
1476 bsg_param.ioctl_pthru.opcode = ADM_RAID_READ;
1477 break;
1478 case DXFER_TO_DEVICE:
1479 io_hdr_v4.dout_xferp = (uintptr_t)iop->dxferp;
1480 io_hdr_v4.dout_xfer_len = iop->dxfer_len;
1481 bsg_param.ioctl_pthru.opcode = ADM_RAID_WRITE;
1482 break;
1483 default:
1484 pout("scsi_cmd: bad dxfer_dir\n");
1485 return set_err(EINVAL, "scsi_cmd: bad dxfer_dir\n");
1486 }
1487
1491 bsg_param.ioctl_pthru.addr = (uintptr_t)iop->dxferp;
1492 bsg_param.ioctl_pthru.data_len = iop->dxfer_len;
1493
1494 bsg_param.ioctl_pthru.info_0.cdb_len = scsi_param.cdb_len;
1495 bsg_param.ioctl_pthru.sense_addr = (uintptr_t)scsi_param.sense_buffer;
1496 bsg_param.ioctl_pthru.info_0.res_sense_len = scsi_param.sense_buffer_len;
1497 io_hdr_v4.response = (uintptr_t)scsi_param.sense_buffer;
1498 io_hdr_v4.response_len = scsi_param.sense_buffer_len;
1499 bsg_param.ioctl_pthru.info_3.eid = scsi_param.loc.enc_id;
1500 bsg_param.ioctl_pthru.info_3.sid = scsi_param.loc.slot_id;
1501 bsg_param.ioctl_pthru.info_4.did = scsi_param.loc.did;
1502 bsg_param.ioctl_pthru.info_4.did_flag = scsi_param.loc.flag;
1503
1504 memcpy(&bsg_param.ioctl_pthru.cdw16, scsi_param.cdb, scsi_param.cdb_len);
1505
1506 int r = ioctl(get_fd(), SG_IO, &io_hdr_v4);
1507 if (r != 0) {
1508 return set_err((errno ? errno : EIO), "scsi_cmd ioctl failed: %d %d,%d",
1509 errno, scsi_param.loc.enc_id, scsi_param.loc.slot_id);
1510 }
1511
1512 iop->scsi_status = io_hdr_v4.device_status;
1513
1514 int len = ( iop->max_sense_len < io_hdr_v4.max_response_len ) ?
1515 iop->max_sense_len : io_hdr_v4.max_response_len;
1516
1517 if (iop->sensep && len > 0) {
1518 memcpy(iop->sensep, reinterpret_cast<void *>(io_hdr_v4.response), len);
1519 iop->resp_sense_len = len;
1520 }
1521
1522 return true;
1523}
1524
1525/////////////////////////////////////////////////////////////////////////////
1526/// CCISS RAID support
1527
1528#ifdef HAVE_LINUX_CCISS_IOCTL_H
1529
1530class linux_cciss_device
1531: public /*implements*/ scsi_device,
1532 public /*extends*/ linux_smart_device
1533{
1534public:
1535 linux_cciss_device(smart_interface * intf, const char * name, unsigned char disknum);
1536
1537 virtual bool scsi_pass_through(scsi_cmnd_io * iop) override;
1538
1539private:
1540 unsigned char m_disknum; ///< Disk number.
1541};
1542
1543linux_cciss_device::linux_cciss_device(smart_interface * intf,
1544 const char * dev_name, unsigned char disknum)
1545: smart_device(intf, dev_name, "cciss", "cciss"),
1546 linux_smart_device(O_RDWR | O_NONBLOCK),
1547 m_disknum(disknum)
1548{
1549 set_info().info_name = strprintf("%s [cciss_disk_%02d]", dev_name, disknum);
1550}
1551
1552bool linux_cciss_device::scsi_pass_through(scsi_cmnd_io * iop)
1553{
1554 int status = cciss_io_interface(get_fd(), m_disknum, iop, scsi_debugmode);
1555 if (status < 0)
1556 return set_err(-status);
1557 return true;
1558}
1559
1560#endif // HAVE_LINUX_CCISS_IOCTL_H
1561
1562/////////////////////////////////////////////////////////////////////////////
1563/// AMCC/3ware RAID support
1564
1566: public /*implements*/ ata_device,
1567 public /*extends*/ linux_smart_device
1568{
1569public:
1576
1577 linux_escalade_device(smart_interface * intf, const char * dev_name,
1578 escalade_type_t escalade_type, int disknum);
1579
1580 virtual bool open() override;
1581
1582 virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) override;
1583
1584private:
1585 escalade_type_t m_escalade_type; ///< Controller type
1586 int m_disknum; ///< Disk number.
1587};
1588
1590 escalade_type_t escalade_type, int disknum)
1591: smart_device(intf, dev_name, "3ware", "3ware"),
1592 linux_smart_device(O_RDONLY | O_NONBLOCK),
1593 m_escalade_type(escalade_type), m_disknum(disknum)
1594{
1595 set_info().info_name = strprintf("%s [3ware_disk_%02d]", dev_name, disknum);
1596}
1597
1598/* This function will setup and fix device nodes for a 3ware controller. */
1599#define MAJOR_STRING_LENGTH 3
1600#define DEVICE_STRING_LENGTH 32
1601#define NODE_STRING_LENGTH 16
1602static int setup_3ware_nodes(const char *nodename, const char *driver_name)
1603{
1604 int tw_major = 0;
1605 int index = 0;
1606 char majorstring[MAJOR_STRING_LENGTH+1];
1607 char device_name[DEVICE_STRING_LENGTH+1];
1608 char nodestring[NODE_STRING_LENGTH];
1609 struct stat stat_buf;
1610 FILE *file;
1611 int retval = 0;
1612#ifdef HAVE_LIBSELINUX
1613 security_context_t orig_context = NULL;
1614 security_context_t node_context = NULL;
1615 int selinux_enabled = is_selinux_enabled();
1616 int selinux_enforced = security_getenforce();
1617#endif
1618
1619 /* First try to open up /proc/devices */
1620 if (!(file = fopen("/proc/devices", "r"))) {
1621 pout("Error opening /proc/devices to check/create 3ware device nodes\n");
1622 syserror("fopen");
1623 return 0; // don't fail here: user might not have /proc !
1624 }
1625
1626 /* Attempt to get device major number */
1627 while (EOF != fscanf(file, "%3s %32s", majorstring, device_name)) {
1628 majorstring[MAJOR_STRING_LENGTH]='\0';
1629 device_name[DEVICE_STRING_LENGTH]='\0';
1630 if (!strncmp(device_name, nodename, DEVICE_STRING_LENGTH)) {
1631 tw_major = atoi(majorstring);
1632 break;
1633 }
1634 }
1635 fclose(file);
1636
1637 /* See if we found a major device number */
1638 if (!tw_major) {
1639 pout("No major number for /dev/%s listed in /proc/devices. Is the %s driver loaded?\n", nodename, driver_name);
1640 return 2;
1641 }
1642#ifdef HAVE_LIBSELINUX
1643 /* Prepare a database of contexts for files in /dev
1644 * and save the current context */
1645 if (selinux_enabled) {
1646 if (matchpathcon_init_prefix(NULL, "/dev") < 0)
1647 pout("Error initializing contexts database for /dev");
1648 if (getfscreatecon(&orig_context) < 0) {
1649 pout("Error retrieving original SELinux fscreate context");
1650 if (selinux_enforced) {
1651 matchpathcon_fini();
1652 return 6;
1653 }
1654 }
1655 }
1656#endif
1657 /* Now check if nodes are correct */
1658 for (index=0; index<16; index++) {
1659 snprintf(nodestring, sizeof(nodestring), "/dev/%s%d", nodename, index);
1660#ifdef HAVE_LIBSELINUX
1661 /* Get context of the node and set it as the default */
1662 if (selinux_enabled) {
1663 if (matchpathcon(nodestring, S_IRUSR | S_IWUSR, &node_context) < 0) {
1664 pout("Could not retrieve context for %s", nodestring);
1665 if (selinux_enforced) {
1666 retval = 6;
1667 break;
1668 }
1669 }
1670 if (setfscreatecon(node_context) < 0) {
1671 pout ("Error setting default fscreate context");
1672 if (selinux_enforced) {
1673 retval = 6;
1674 break;
1675 }
1676 }
1677 }
1678#endif
1679 /* Try to stat the node */
1680 if ((stat(nodestring, &stat_buf))) {
1681 pout("Node %s does not exist and must be created. Check the udev rules.\n", nodestring);
1682 /* Create a new node if it doesn't exist */
1683 if (mknod(nodestring, S_IFCHR|0600, makedev(tw_major, index))) {
1684 pout("problem creating 3ware device nodes %s", nodestring);
1685 syserror("mknod");
1686 retval = 3;
1687 break;
1688 } else {
1689#ifdef HAVE_LIBSELINUX
1690 if (selinux_enabled && node_context) {
1691 freecon(node_context);
1692 node_context = NULL;
1693 }
1694#endif
1695 continue;
1696 }
1697 }
1698
1699 /* See if nodes major and minor numbers are correct */
1700 if ((tw_major != (int)(major(stat_buf.st_rdev))) ||
1701 (index != (int)(minor(stat_buf.st_rdev))) ||
1702 (!S_ISCHR(stat_buf.st_mode))) {
1703 pout("Node %s has wrong major/minor number and must be created anew."
1704 " Check the udev rules.\n", nodestring);
1705 /* Delete the old node */
1706 if (unlink(nodestring)) {
1707 pout("problem unlinking stale 3ware device node %s", nodestring);
1708 syserror("unlink");
1709 retval = 4;
1710 break;
1711 }
1712
1713 /* Make a new node */
1714 if (mknod(nodestring, S_IFCHR|0600, makedev(tw_major, index))) {
1715 pout("problem creating 3ware device nodes %s", nodestring);
1716 syserror("mknod");
1717 retval = 5;
1718 break;
1719 }
1720 }
1721#ifdef HAVE_LIBSELINUX
1722 if (selinux_enabled && node_context) {
1723 freecon(node_context);
1724 node_context = NULL;
1725 }
1726#endif
1727 }
1728
1729#ifdef HAVE_LIBSELINUX
1730 if (selinux_enabled) {
1731 if(setfscreatecon(orig_context) < 0) {
1732 pout("Error re-setting original fscreate context");
1733 if (selinux_enforced)
1734 retval = 6;
1735 }
1736 if(orig_context)
1737 freecon(orig_context);
1738 if(node_context)
1739 freecon(node_context);
1740 matchpathcon_fini();
1741 }
1742#endif
1743 return retval;
1744}
1745
1747{
1750 // the device nodes for these controllers are dynamically assigned,
1751 // so we need to check that they exist with the correct major
1752 // numbers and if not, create them
1753 const char * node = (m_escalade_type == AMCC_3WARE_9700_CHAR ? "twl" :
1755 "twe" );
1756 const char * driver = (m_escalade_type == AMCC_3WARE_9700_CHAR ? "3w-sas" :
1757 m_escalade_type == AMCC_3WARE_9000_CHAR ? "3w-9xxx" :
1758 "3w-xxxx" );
1759 if (setup_3ware_nodes(node, driver))
1760 return set_err((errno ? errno : ENXIO), "setup_3ware_nodes(\"%s\", \"%s\") failed", node, driver);
1761 }
1762 // Continue with default open
1763 return linux_smart_device::open();
1764}
1765
1766// TODO: Function no longer useful
1767//void printwarning(smart_command_set command);
1768
1769#ifndef SCSI_IOCTL_SEND_COMMAND
1770#define SCSI_IOCTL_SEND_COMMAND 1
1771#endif
1772
1773// PURPOSE
1774// This is an interface routine meant to isolate the OS dependent
1775// parts of the code, and to provide a debugging interface. Each
1776// different port and OS needs to provide it's own interface. This
1777// is the linux interface to the 3ware 3w-xxxx driver. It allows ATA
1778// commands to be passed through the SCSI driver.
1779// DETAILED DESCRIPTION OF ARGUMENTS
1780// fd: is the file descriptor provided by open()
1781// disknum is the disk number (0 to 15) in the RAID array
1782// escalade_type indicates the type of controller type, and if scsi or char interface is used
1783// command: defines the different operations.
1784// select: additional input data if needed (which log, which type of
1785// self-test).
1786// data: location to write output data, if needed (512 bytes).
1787// Note: not all commands use all arguments.
1788// RETURN VALUES
1789// -1 if the command failed
1790// 0 if the command succeeded,
1791// STATUS_CHECK routine:
1792// -1 if the command failed
1793// 0 if the command succeeded and disk SMART status is "OK"
1794// 1 if the command succeeded and disk SMART status is "FAILING"
1795
1796/* 512 is the max payload size: increase if needed */
1797#define BUFFER_LEN_678K ( sizeof(TW_Ioctl) ) // 1044 unpacked, 1041 packed
1798#define BUFFER_LEN_678K_CHAR ( sizeof(TW_New_Ioctl)+512-1 ) // 1539 unpacked, 1536 packed
1799#define BUFFER_LEN_9000 ( sizeof(TW_Ioctl_Buf_Apache)+512-1 ) // 2051 unpacked, 2048 packed
1800#define TW_IOCTL_BUFFER_SIZE ( MAX(MAX(BUFFER_LEN_678K, BUFFER_LEN_9000), BUFFER_LEN_678K_CHAR) )
1801
1803{
1804 if (!ata_cmd_is_ok(in,
1805 true, // data_out_support
1806 false, // TODO: multi_sector_support
1807 true) // ata_48bit_support
1808 )
1809 return false;
1810
1811 // Used by both the SCSI and char interfaces
1812 TW_Passthru *passthru=NULL;
1813 char ioctl_buffer[TW_IOCTL_BUFFER_SIZE];
1814
1815 // only used for SCSI device interface
1816 TW_Ioctl *tw_ioctl=NULL;
1817 TW_Output *tw_output=NULL;
1818
1819 // only used for 6000/7000/8000 char device interface
1820 TW_New_Ioctl *tw_ioctl_char=NULL;
1821
1822 // only used for 9000 character device interface
1823 TW_Ioctl_Buf_Apache *tw_ioctl_apache=NULL;
1824
1825 memset(ioctl_buffer, 0, TW_IOCTL_BUFFER_SIZE);
1826
1827 // TODO: Handle controller differences by different classes
1829 tw_ioctl_apache = (TW_Ioctl_Buf_Apache *)ioctl_buffer;
1831 tw_ioctl_apache->driver_command.buffer_length = 512; /* payload size */
1832 passthru = (TW_Passthru *)&(tw_ioctl_apache->firmware_command.command.oldcommand);
1833 }
1835 tw_ioctl_char = (TW_New_Ioctl *)ioctl_buffer;
1836 tw_ioctl_char->data_buffer_length = 512;
1837 passthru = (TW_Passthru *)&(tw_ioctl_char->firmware_command);
1838 }
1839 else if (m_escalade_type==AMCC_3WARE_678K) {
1840 tw_ioctl = (TW_Ioctl *)ioctl_buffer;
1841 tw_ioctl->cdb[0] = TW_IOCTL;
1842 tw_ioctl->opcode = TW_ATA_PASSTHRU;
1843 tw_ioctl->input_length = 512; // correct even for non-data commands
1844 tw_ioctl->output_length = 512; // correct even for non-data commands
1845 tw_output = (TW_Output *)tw_ioctl;
1846 passthru = (TW_Passthru *)&(tw_ioctl->input_data);
1847 }
1848 else {
1849 return set_err(ENOSYS,
1850 "Unrecognized escalade_type %d in linux_3ware_command_interface(disk %d)\n"
1851 "Please contact " PACKAGE_BUGREPORT "\n", (int)m_escalade_type, m_disknum);
1852 }
1853
1854 // Same for (almost) all commands - but some reset below
1855 passthru->byte0.opcode = TW_OP_ATA_PASSTHRU;
1856 passthru->request_id = 0xFF;
1857 passthru->unit = m_disknum;
1858 passthru->status = 0;
1859 passthru->flags = 0x1;
1860
1861 // Set registers
1862 {
1863 const ata_in_regs_48bit & r = in.in_regs;
1864 passthru->features = r.features_16;
1865 passthru->sector_count = r.sector_count_16;
1866 passthru->sector_num = r.lba_low_16;
1867 passthru->cylinder_lo = r.lba_mid_16;
1868 passthru->cylinder_hi = r.lba_high_16;
1869 passthru->drive_head = r.device;
1870 passthru->command = r.command;
1871 }
1872
1873 // Is this a command that reads or returns 512 bytes?
1874 // passthru->param values are:
1875 // 0x0 - non data command without TFR write check,
1876 // 0x8 - non data command with TFR write check,
1877 // 0xD - data command that returns data to host from device
1878 // 0xF - data command that writes data from host to device
1879 // passthru->size values are 0x5 for non-data and 0x07 for data
1880 bool readdata = false;
1881 if (in.direction == ata_cmd_in::data_in) {
1882 readdata=true;
1883 passthru->byte0.sgloff = 0x5;
1884 passthru->size = 0x7; // TODO: Other value for multi-sector ?
1885 passthru->param = 0xD;
1886 // For 64-bit to work correctly, up the size of the command packet
1887 // in dwords by 1 to account for the 64-bit single sgl 'address'
1888 // field. Note that this doesn't agree with the typedefs but it's
1889 // right (agree with kernel driver behavior/typedefs).
1891 && sizeof(long) == 8)
1892 passthru->size++;
1893 }
1894 else if (in.direction == ata_cmd_in::no_data) {
1895 // Non data command -- but doesn't use large sector
1896 // count register values.
1897 passthru->byte0.sgloff = 0x0;
1898 passthru->size = 0x5;
1899 passthru->param = 0x8;
1900 passthru->sector_count = 0x0;
1901 }
1902 else if (in.direction == ata_cmd_in::data_out) {
1904 memcpy(tw_ioctl_apache->data_buffer, in.buffer, in.size);
1906 memcpy(tw_ioctl_char->data_buffer, in.buffer, in.size);
1907 else {
1908 // COMMAND NOT SUPPORTED VIA SCSI IOCTL INTERFACE
1909 // memcpy(tw_output->output_data, data, 512);
1910 // printwarning(command); // TODO: Parameter no longer valid
1911 return set_err(ENOTSUP, "DATA OUT not supported for this 3ware controller type");
1912 }
1913 passthru->byte0.sgloff = 0x5;
1914 passthru->size = 0x7; // TODO: Other value for multi-sector ?
1915 passthru->param = 0xF; // PIO data write
1917 && sizeof(long) == 8)
1918 passthru->size++;
1919 }
1920 else
1921 return set_err(EINVAL);
1922
1923 // Now send the command down through an ioctl()
1924 int ioctlreturn;
1926 ioctlreturn=ioctl(get_fd(), TW_IOCTL_FIRMWARE_PASS_THROUGH, tw_ioctl_apache);
1928 ioctlreturn=ioctl(get_fd(), TW_CMD_PACKET_WITH_DATA, tw_ioctl_char);
1929 else
1930 ioctlreturn=ioctl(get_fd(), SCSI_IOCTL_SEND_COMMAND, tw_ioctl);
1931
1932 // Deal with the different error cases
1933 if (ioctlreturn) {
1938 && in.in_regs.lba_low) {
1939 // error here is probably a kernel driver whose version is too old
1940 // printwarning(command); // TODO: Parameter no longer valid
1941 return set_err(ENOTSUP, "Probably kernel driver too old");
1942 }
1943 return set_err(EIO);
1944 }
1945
1946 // The passthru structure is valid after return from an ioctl if:
1947 // - we are using the character interface OR
1948 // - we are using the SCSI interface and this is a NON-READ-DATA command
1949 // For SCSI interface, note that we set passthru to a different
1950 // value after ioctl().
1952 if (readdata)
1953 passthru=NULL;
1954 else
1955 passthru=(TW_Passthru *)&(tw_output->output_data);
1956 }
1957
1958 // See if the ATA command failed. Now that we have returned from
1959 // the ioctl() call, if passthru is valid, then:
1960 // - passthru->status contains the 3ware controller STATUS
1961 // - passthru->command contains the ATA STATUS register
1962 // - passthru->features contains the ATA ERROR register
1963 //
1964 // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS
1965 // If bit 0 (error bit) is set, then ATA ERROR register is valid.
1966 // While we *might* decode the ATA ERROR register, at the moment it
1967 // doesn't make much sense: we don't care in detail why the error
1968 // happened.
1969
1970 if (passthru && (passthru->status || (passthru->command & 0x21))) {
1971 return set_err(EIO);
1972 }
1973
1974 // If this is a read data command, copy data to output buffer
1975 if (readdata) {
1977 memcpy(in.buffer, tw_ioctl_apache->data_buffer, in.size);
1979 memcpy(in.buffer, tw_ioctl_char->data_buffer, in.size);
1980 else
1981 memcpy(in.buffer, tw_output->output_data, in.size);
1982 }
1983
1984 // Return register values
1985 if (passthru) {
1986 ata_out_regs_48bit & r = out.out_regs;
1987 r.error = passthru->features;
1988 r.sector_count_16 = passthru->sector_count;
1989 r.lba_low_16 = passthru->sector_num;
1990 r.lba_mid_16 = passthru->cylinder_lo;
1991 r.lba_high_16 = passthru->cylinder_hi;
1992 r.device = passthru->drive_head;
1993 r.status = passthru->command;
1994 }
1995
1996 // look for nonexistent devices/ports
1998 && !nonempty(in.buffer, in.size)) {
1999 return set_err(ENODEV, "No drive on port %d", m_disknum);
2000 }
2001
2002 return true;
2003}
2004
2005/////////////////////////////////////////////////////////////////////////////
2006/// Areca RAID support
2007
2008///////////////////////////////////////////////////////////////////
2009// SATA(ATA) device behind Areca RAID Controller
2011: public /*implements*/ areca_ata_device,
2012 public /*extends*/ linux_smart_device
2013{
2014public:
2015 linux_areca_ata_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
2016 virtual smart_device * autodetect_open() override;
2017 virtual bool arcmsr_lock() override;
2018 virtual bool arcmsr_unlock() override;
2019 virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io * iop) override;
2020};
2021
2022///////////////////////////////////////////////////////////////////
2023// SAS(SCSI) device behind Areca RAID Controller
2025: public /*implements*/ areca_scsi_device,
2026 public /*extends*/ linux_smart_device
2027{
2028public:
2029 linux_areca_scsi_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
2030 virtual smart_device * autodetect_open() override;
2031 virtual bool arcmsr_lock() override;
2032 virtual bool arcmsr_unlock() override;
2033 virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io * iop) override;
2034};
2035
2036// Looks in /proc/scsi to suggest correct areca devices
2038{
2039 const char* proc_format_string="host\tchan\tid\tlun\ttype\topens\tqdepth\tbusy\tonline\n";
2040
2041 // check data formwat
2042 FILE *fp=fopen("/proc/scsi/sg/device_hdr", "r");
2043 if (!fp) {
2044 pout("Unable to open /proc/scsi/sg/device_hdr for reading\n");
2045 return 1;
2046 }
2047
2048 // get line, compare to format
2049 char linebuf[256];
2050 linebuf[255]='\0';
2051 char *out = fgets(linebuf, 256, fp);
2052 fclose(fp);
2053 if (!out) {
2054 pout("Unable to read contents of /proc/scsi/sg/device_hdr\n");
2055 return 2;
2056 }
2057
2058 if (strcmp(linebuf, proc_format_string)) {
2059 // wrong format!
2060 // Fix this by comparing only tokens not white space!!
2061 pout("Unexpected format %s in /proc/scsi/sg/device_hdr\n", proc_format_string);
2062 return 3;
2063 }
2064
2065 // Format is understood, now search for correct device
2066 fp=fopen("/proc/scsi/sg/devices", "r");
2067 if (!fp) return 1;
2068 int host, chan, id, lun, type, opens, qdepth, busy, online;
2069 int dev=-1;
2070 // search all lines of /proc/scsi/sg/devices
2071 while (9 == fscanf(fp, "%d %d %d %d %d %d %d %d %d", &host, &chan, &id, &lun, &type, &opens, &qdepth, &busy, &online)) {
2072 dev++;
2073 if (id == 16 && type == 3) {
2074 // devices with id=16 and type=3 might be Areca controllers
2075 pout("Device /dev/sg%d appears to be an Areca controller.\n", dev);
2076 }
2077 }
2078 fclose(fp);
2079 return 0;
2080}
2081
2082// Areca RAID Controller(SATA Disk)
2083linux_areca_ata_device::linux_areca_ata_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
2084: smart_device(intf, dev_name, "areca", "areca"),
2085 linux_smart_device(O_RDWR | O_EXCL | O_NONBLOCK)
2086{
2087 set_disknum(disknum);
2088 set_encnum(encnum);
2089 set_info().info_name = strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name, disknum, encnum);
2090}
2091
2093{
2094 // autodetect device type
2096 if(is_ata < 0)
2097 {
2098 set_err(EIO);
2099 return this;
2100 }
2101
2102 if(is_ata == 1)
2103 {
2104 // SATA device
2105 return this;
2106 }
2107
2108 // SAS device
2110 close();
2111 delete this;
2112 newdev->open(); // TODO: Can possibly pass open fd
2113
2114 return newdev.release();
2115}
2116
2118{
2119 int ioctlreturn = 0;
2120
2121 if(!is_open()) {
2122 if(!open()){
2124 }
2125 }
2126
2127 ioctlreturn = do_normal_scsi_cmnd_io(get_fd(), iop, scsi_debugmode);
2128 if ( ioctlreturn || iop->scsi_status )
2129 {
2130 // errors found
2131 return -1;
2132 }
2133
2134 return ioctlreturn;
2135}
2136
2138{
2139 return true;
2140}
2141
2143{
2144 return true;
2145}
2146
2147// Areca RAID Controller(SAS Device)
2148linux_areca_scsi_device::linux_areca_scsi_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
2149: smart_device(intf, dev_name, "areca", "areca"),
2150 linux_smart_device(O_RDWR | O_EXCL | O_NONBLOCK)
2151{
2152 set_disknum(disknum);
2153 set_encnum(encnum);
2154 set_info().info_name = strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name, disknum, encnum);
2155}
2156
2158{
2159 return this;
2160}
2161
2163{
2164 int ioctlreturn = 0;
2165
2166 if(!is_open()) {
2167 if(!open()){
2169 }
2170 }
2171
2172 ioctlreturn = do_normal_scsi_cmnd_io(get_fd(), iop, scsi_debugmode);
2173 if ( ioctlreturn || iop->scsi_status )
2174 {
2175 // errors found
2176 return -1;
2177 }
2178
2179 return ioctlreturn;
2180}
2181
2183{
2184 return true;
2185}
2186
2188{
2189 return true;
2190}
2191
2192/////////////////////////////////////////////////////////////////////////////
2193/// Marvell support
2194
2196: public /*implements*/ ata_device_with_command_set,
2197 public /*extends*/ linux_smart_device
2198{
2199public:
2200 linux_marvell_device(smart_interface * intf, const char * dev_name, const char * req_type);
2201
2202protected:
2203 virtual int ata_command_interface(smart_command_set command, int select, char * data);
2204};
2205
2207 const char * dev_name, const char * req_type)
2208: smart_device(intf, dev_name, "marvell", req_type),
2209 linux_smart_device(O_RDONLY | O_NONBLOCK)
2210{
2211}
2212
2214{
2215 typedef struct {
2216 int inlen;
2217 int outlen;
2218 char cmd[540];
2219 } mvsata_scsi_cmd;
2220
2221 int copydata = 0;
2222 mvsata_scsi_cmd smart_command;
2223 unsigned char *buff = (unsigned char *)&smart_command.cmd[6];
2224 // See struct hd_drive_cmd_hdr in hdreg.h
2225 // buff[0]: ATA COMMAND CODE REGISTER
2226 // buff[1]: ATA SECTOR NUMBER REGISTER
2227 // buff[2]: ATA FEATURES REGISTER
2228 // buff[3]: ATA SECTOR COUNT REGISTER
2229
2230 // clear out buff. Large enough for HDIO_DRIVE_CMD (4+512 bytes)
2231 memset(&smart_command, 0, sizeof(smart_command));
2232 smart_command.inlen = 540;
2233 smart_command.outlen = 540;
2234 smart_command.cmd[0] = 0xC; //Vendor-specific code
2235 smart_command.cmd[4] = 6; //command length
2236
2237 buff[0] = ATA_SMART_CMD;
2238 switch (command){
2239 case CHECK_POWER_MODE:
2240 buff[0]=ATA_CHECK_POWER_MODE;
2241 break;
2242 case READ_VALUES:
2243 buff[2]=ATA_SMART_READ_VALUES;
2244 copydata=buff[3]=1;
2245 break;
2246 case READ_THRESHOLDS:
2248 copydata=buff[1]=buff[3]=1;
2249 break;
2250 case READ_LOG:
2252 buff[1]=select;
2253 copydata=buff[3]=1;
2254 break;
2255 case IDENTIFY:
2256 buff[0]=ATA_IDENTIFY_DEVICE;
2257 copydata=buff[3]=1;
2258 break;
2259 case PIDENTIFY:
2261 copydata=buff[3]=1;
2262 break;
2263 case ENABLE:
2264 buff[2]=ATA_SMART_ENABLE;
2265 buff[1]=1;
2266 break;
2267 case DISABLE:
2268 buff[2]=ATA_SMART_DISABLE;
2269 buff[1]=1;
2270 break;
2271 case STATUS:
2272 case STATUS_CHECK:
2273 // this command only says if SMART is working. It could be
2274 // replaced with STATUS_CHECK below.
2275 buff[2] = ATA_SMART_STATUS;
2276 break;
2277 case AUTO_OFFLINE:
2278 buff[2]=ATA_SMART_AUTO_OFFLINE;
2279 buff[3]=select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
2280 break;
2281 case AUTOSAVE:
2282 buff[2]=ATA_SMART_AUTOSAVE;
2283 buff[3]=select; // YET NOTE - THIS IS A NON-DATA COMMAND!!
2284 break;
2285 case IMMEDIATE_OFFLINE:
2287 buff[1]=select;
2288 break;
2289 default:
2290 pout("Unrecognized command %d in mvsata_os_specific_handler()\n", command);
2291 errno = EINVAL;
2292 return -1;
2293 }
2294 // There are two different types of ioctls(). The HDIO_DRIVE_TASK
2295 // one is this:
2296 // We are now doing the HDIO_DRIVE_CMD type ioctl.
2297 if (ioctl(get_fd(), SCSI_IOCTL_SEND_COMMAND, (void *)&smart_command))
2298 return -1;
2299
2300 if (command==CHECK_POWER_MODE) {
2301 // LEON -- CHECK THIS PLEASE. THIS SHOULD BE THE SECTOR COUNT
2302 // REGISTER, AND IT MIGHT BE buff[2] NOT buff[3]. Bruce
2303 data[0]=buff[3];
2304 return 0;
2305 }
2306
2307 // Always succeed on a SMART status, as a disk that failed returned
2308 // buff[4]=0xF4, buff[5]=0x2C, i.e. "Bad SMART status" (see below).
2309 if (command == STATUS)
2310 return 0;
2311 //Data returned is starting from 0 offset
2312 if (command == STATUS_CHECK)
2313 {
2314 // Cyl low and Cyl high unchanged means "Good SMART status"
2315 if (buff[4] == 0x4F && buff[5] == 0xC2)
2316 return 0;
2317 // These values mean "Bad SMART status"
2318 if (buff[4] == 0xF4 && buff[5] == 0x2C)
2319 return 1;
2320 // We haven't gotten output that makes sense; print out some debugging info
2321 syserror("Error SMART Status command failed");
2322 pout("Please get assistance from %s\n",PACKAGE_BUGREPORT);
2323 pout("Register values returned from SMART Status command are:\n");
2324 pout("CMD =0x%02x\n",(int)buff[0]);
2325 pout("FR =0x%02x\n",(int)buff[1]);
2326 pout("NS =0x%02x\n",(int)buff[2]);
2327 pout("SC =0x%02x\n",(int)buff[3]);
2328 pout("CL =0x%02x\n",(int)buff[4]);
2329 pout("CH =0x%02x\n",(int)buff[5]);
2330 pout("SEL=0x%02x\n",(int)buff[6]);
2331 return -1;
2332 }
2333
2334 if (copydata)
2335 memcpy(data, buff, 512);
2336 return 0;
2337}
2338
2339/////////////////////////////////////////////////////////////////////////////
2340/// Highpoint RAID support
2341
2343: public /*implements*/ ata_device_with_command_set,
2344 public /*extends*/ linux_smart_device
2345{
2346public:
2347 linux_highpoint_device(smart_interface * intf, const char * dev_name,
2348 unsigned char controller, unsigned char channel, unsigned char port);
2349
2350protected:
2351 virtual int ata_command_interface(smart_command_set command, int select, char * data);
2352
2353private:
2354 unsigned char m_hpt_data[3]; ///< controller/channel/port
2355};
2356
2358 unsigned char controller, unsigned char channel, unsigned char port)
2359: smart_device(intf, dev_name, "hpt", "hpt"),
2360 linux_smart_device(O_RDONLY | O_NONBLOCK)
2361{
2362 m_hpt_data[0] = controller; m_hpt_data[1] = channel; m_hpt_data[2] = port;
2363 set_info().info_name = strprintf("%s [hpt_disk_%u/%u/%u]", dev_name, m_hpt_data[0], m_hpt_data[1], m_hpt_data[2]);
2364}
2365
2366// this implementation is derived from ata_command_interface with a header
2367// packing for highpoint linux driver ioctl interface
2368//
2369// ioctl(fd,HPTIO_CTL,buff)
2370// ^^^^^^^^^
2371//
2372// structure of hpt_buff
2373// +----+----+----+----+--------------------.....---------------------+
2374// | 1 | 2 | 3 | 4 | 5 |
2375// +----+----+----+----+--------------------.....---------------------+
2376//
2377// 1: The target controller [ int ( 4 Bytes ) ]
2378// 2: The channel of the target controllee [ int ( 4 Bytes ) ]
2379// 3: HDIO_ ioctl call [ int ( 4 Bytes ) ]
2380// available from ${LINUX_KERNEL_SOURCE}/Documentation/ioctl/hdio
2381// 4: the pmport that disk attached, [ int ( 4 Bytes ) ]
2382// if no pmport device, set to 1 or leave blank
2383// 5: data [ void * ( var leangth ) ]
2384//
2385#define STRANGE_BUFFER_LENGTH (4+512*0xf8)
2386
2388{
2389 unsigned char hpt_buff[4*sizeof(int) + STRANGE_BUFFER_LENGTH];
2390 unsigned int *hpt = (unsigned int *)hpt_buff;
2391 unsigned char *buff = &hpt_buff[4*sizeof(int)];
2392 int copydata = 0;
2393 const int HDIO_DRIVE_CMD_OFFSET = 4;
2394
2395 memset(hpt_buff, 0, 4*sizeof(int) + STRANGE_BUFFER_LENGTH);
2396 hpt[0] = m_hpt_data[0]; // controller id
2397 hpt[1] = m_hpt_data[1]; // channel number
2398 hpt[3] = m_hpt_data[2]; // pmport number
2399
2400 buff[0]=ATA_SMART_CMD;
2401 switch (command){
2402 case CHECK_POWER_MODE:
2403 buff[0]=ATA_CHECK_POWER_MODE;
2404 copydata=1;
2405 break;
2406 case READ_VALUES:
2407 buff[2]=ATA_SMART_READ_VALUES;
2408 buff[3]=1;
2409 copydata=512;
2410 break;
2411 case READ_THRESHOLDS:
2413 buff[1]=buff[3]=1;
2414 copydata=512;
2415 break;
2416 case READ_LOG:
2418 buff[1]=select;
2419 buff[3]=1;
2420 copydata=512;
2421 break;
2422 case WRITE_LOG:
2423 break;
2424 case IDENTIFY:
2425 buff[0]=ATA_IDENTIFY_DEVICE;
2426 buff[3]=1;
2427 copydata=512;
2428 break;
2429 case PIDENTIFY:
2431 buff[3]=1;
2432 copydata=512;
2433 break;
2434 case ENABLE:
2435 buff[2]=ATA_SMART_ENABLE;
2436 buff[1]=1;
2437 break;
2438 case DISABLE:
2439 buff[2]=ATA_SMART_DISABLE;
2440 buff[1]=1;
2441 break;
2442 case STATUS:
2443 buff[2]=ATA_SMART_STATUS;
2444 break;
2445 case AUTO_OFFLINE:
2446 buff[2]=ATA_SMART_AUTO_OFFLINE;
2447 buff[3]=select;
2448 break;
2449 case AUTOSAVE:
2450 buff[2]=ATA_SMART_AUTOSAVE;
2451 buff[3]=select;
2452 break;
2453 case IMMEDIATE_OFFLINE:
2455 buff[1]=select;
2456 break;
2457 case STATUS_CHECK:
2458 buff[1]=ATA_SMART_STATUS;
2459 break;
2460 default:
2461 pout("Unrecognized command %d in linux_highpoint_command_interface()\n"
2462 "Please contact " PACKAGE_BUGREPORT "\n", command);
2463 errno=ENOSYS;
2464 return -1;
2465 }
2466
2467 if (command==WRITE_LOG) {
2468 unsigned char task[4*sizeof(int)+sizeof(ide_task_request_t)+512];
2469 unsigned int *hpt_tf = (unsigned int *)task;
2470 ide_task_request_t *reqtask = (ide_task_request_t *)(&task[4*sizeof(int)]);
2471 task_struct_t *taskfile = (task_struct_t *)reqtask->io_ports;
2472
2473 memset(task, 0, sizeof(task));
2474
2475 hpt_tf[0] = m_hpt_data[0]; // controller id
2476 hpt_tf[1] = m_hpt_data[1]; // channel number
2477 hpt_tf[3] = m_hpt_data[2]; // pmport number
2478 hpt_tf[2] = HDIO_DRIVE_TASKFILE; // real hd ioctl
2479
2480 taskfile->data = 0;
2482 taskfile->sector_count = 1;
2483 taskfile->sector_number = select;
2484 taskfile->low_cylinder = 0x4f;
2485 taskfile->high_cylinder = 0xc2;
2486 taskfile->device_head = 0;
2487 taskfile->command = ATA_SMART_CMD;
2488
2489 reqtask->data_phase = TASKFILE_OUT;
2490 reqtask->req_cmd = IDE_DRIVE_TASK_OUT;
2491 reqtask->out_size = 512;
2492 reqtask->in_size = 0;
2493
2494 memcpy(task+sizeof(ide_task_request_t)+4*sizeof(int), data, 512);
2495
2496 if (ioctl(get_fd(), HPTIO_CTL, task))
2497 return -1;
2498
2499 return 0;
2500 }
2501
2502 if (command==STATUS_CHECK){
2503 unsigned const char normal_lo=0x4f, normal_hi=0xc2;
2504 unsigned const char failed_lo=0xf4, failed_hi=0x2c;
2505 buff[4]=normal_lo;
2506 buff[5]=normal_hi;
2507
2508 hpt[2] = HDIO_DRIVE_TASK;
2509
2510 if (ioctl(get_fd(), HPTIO_CTL, hpt_buff))
2511 return -1;
2512
2513 if (buff[4]==normal_lo && buff[5]==normal_hi)
2514 return 0;
2515
2516 if (buff[4]==failed_lo && buff[5]==failed_hi)
2517 return 1;
2518
2519 syserror("Error SMART Status command failed");
2520 pout("Please get assistance from " PACKAGE_URL "\n");
2521 pout("Register values returned from SMART Status command are:\n");
2522 pout("CMD=0x%02x\n",(int)buff[0]);
2523 pout("FR =0x%02x\n",(int)buff[1]);
2524 pout("NS =0x%02x\n",(int)buff[2]);
2525 pout("SC =0x%02x\n",(int)buff[3]);
2526 pout("CL =0x%02x\n",(int)buff[4]);
2527 pout("CH =0x%02x\n",(int)buff[5]);
2528 pout("SEL=0x%02x\n",(int)buff[6]);
2529 return -1;
2530 }
2531
2532#if 1
2533 if (command==IDENTIFY || command==PIDENTIFY) {
2534 unsigned char deviceid[4*sizeof(int)+512*sizeof(char)];
2535 unsigned int *hpt_id = (unsigned int *)deviceid;
2536
2537 hpt_id[0] = m_hpt_data[0]; // controller id
2538 hpt_id[1] = m_hpt_data[1]; // channel number
2539 hpt_id[3] = m_hpt_data[2]; // pmport number
2540
2541 hpt_id[2] = HDIO_GET_IDENTITY;
2542 if (!ioctl(get_fd(), HPTIO_CTL, deviceid) && (deviceid[4*sizeof(int)] & 0x8000))
2544 }
2545#endif
2546
2547 hpt[2] = HDIO_DRIVE_CMD;
2548 if ((ioctl(get_fd(), HPTIO_CTL, hpt_buff)))
2549 return -1;
2550
2551 if (command==CHECK_POWER_MODE)
2552 buff[HDIO_DRIVE_CMD_OFFSET]=buff[2];
2553
2554 if (copydata)
2555 memcpy(data, buff+HDIO_DRIVE_CMD_OFFSET, copydata);
2556
2557 return 0;
2558}
2559
2560#if 0 // TODO: Migrate from 'smart_command_set' to 'ata_in_regs' OR remove the function
2561// Utility function for printing warnings
2562void printwarning(smart_command_set command){
2563 static int printed[4]={0,0,0,0};
2564 const char* message=
2565 "can not be passed through the 3ware 3w-xxxx driver. This can be fixed by\n"
2566 "applying a simple 3w-xxxx driver patch that can be found here:\n"
2567 PACKAGE_URL "\n"
2568 "Alternatively, upgrade your 3w-xxxx driver to version 1.02.00.037 or greater.\n\n";
2569
2570 if (command==AUTO_OFFLINE && !printed[0]) {
2571 printed[0]=1;
2572 pout("The SMART AUTO-OFFLINE ENABLE command (smartmontools -o on option/Directive)\n%s", message);
2573 }
2574 else if (command==AUTOSAVE && !printed[1]) {
2575 printed[1]=1;
2576 pout("The SMART AUTOSAVE ENABLE command (smartmontools -S on option/Directive)\n%s", message);
2577 }
2578 else if (command==STATUS_CHECK && !printed[2]) {
2579 printed[2]=1;
2580 pout("The SMART RETURN STATUS return value (smartmontools -H option/Directive)\n%s", message);
2581 }
2582 else if (command==WRITE_LOG && !printed[3]) {
2583 printed[3]=1;
2584 pout("The SMART WRITE LOG command (smartmontools -t selective) only supported via char /dev/tw[ae] interface\n");
2585 }
2586
2587 return;
2588}
2589#endif
2590
2591/////////////////////////////////////////////////////////////////////////////
2592/// SCSI open with autodetection support
2593
2595{
2596 // Open device
2597 if (!open())
2598 return this;
2599
2600 // No Autodetection if device type was specified by user
2601 bool sat_only = false;
2602 if (*get_req_type()) {
2603 // Detect SAT if device object was created by scan_smart_devices().
2604 if (!(m_scanning && !strcmp(get_req_type(), "sat")))
2605 return this;
2606 sat_only = true;
2607 }
2608
2609 // The code below is based on smartd.cpp:SCSIFilterKnown()
2610
2611 // Get INQUIRY
2612 unsigned char req_buff[64] = {0, };
2613 int req_len = 36;
2614 if (scsiStdInquiry(this, req_buff, req_len)) {
2615 // Marvell controllers fail on a 36 bytes StdInquiry, but 64 suffices
2616 // watch this spot ... other devices could lock up here
2617 req_len = 64;
2618 if (scsiStdInquiry(this, req_buff, req_len)) {
2619 // device doesn't like INQUIRY commands
2620 close();
2621 set_err(EIO, "INQUIRY failed");
2622 return this;
2623 }
2624 }
2625
2626 int avail_len = req_buff[4] + 5;
2627 int len = (avail_len < req_len ? avail_len : req_len);
2628 if (len < 36) {
2629 if (sat_only) {
2630 close();
2631 set_err(EIO, "INQUIRY too short for SAT");
2632 }
2633 return this;
2634 }
2635
2636 // Use INQUIRY to detect type
2637 if (!sat_only) {
2638
2639 // 3ware ?
2640 if (!memcmp(req_buff + 8, "3ware", 5) || !memcmp(req_buff + 8, "AMCC", 4)) {
2641 close();
2642 set_err(EINVAL, "AMCC/3ware controller, please try adding '-d 3ware,N',\n"
2643 "you may need to replace %s with /dev/twlN, /dev/twaN or /dev/tweN", get_dev_name());
2644 return this;
2645 }
2646
2647 // DELL?
2648 if (!memcmp(req_buff + 8, "DELL PERC", 12) || !memcmp(req_buff + 8, "MegaRAID", 8)
2649 || !memcmp(req_buff + 16, "PERC ", 5) || !memcmp(req_buff + 8, "LSI\0",4)
2650 ) {
2651 close();
2652 set_err(EINVAL, "DELL or MegaRaid controller, please try adding '-d megaraid,N'");
2653 return this;
2654 }
2655
2656 // Marvell ?
2657 if (len >= 42 && !memcmp(req_buff + 36, "MVSATA", 6)) {
2658 //pout("Device %s: using '-d marvell' for ATA disk with Marvell driver\n", get_dev_name());
2659 close();
2660 smart_device_auto_ptr newdev(
2662 );
2663 newdev->open(); // TODO: Can possibly pass open fd
2664 delete this;
2665 return newdev.release();
2666 }
2667 }
2668
2669 // SAT or USB ?
2670 {
2671 smart_device * newdev = smi()->autodetect_sat_device(this, req_buff, len);
2672 if (newdev)
2673 // NOTE: 'this' is now owned by '*newdev'
2674 return newdev;
2675 }
2676
2677 // Nothing special found
2678
2679 if (sat_only) {
2680 close();
2681 set_err(EIO, "Not a SAT device");
2682 }
2683 return this;
2684}
2685
2686/////////////////////////////////////////////////////////////////////////////
2687/// NVMe support
2688
2690: public /*implements*/ nvme_device,
2691 public /*extends*/ linux_smart_device
2692{
2693public:
2694 linux_nvme_device(smart_interface * intf, const char * dev_name,
2695 const char * req_type, unsigned nsid);
2696
2697 virtual bool open() override;
2698
2699 virtual bool nvme_pass_through(const nvme_cmd_in & in, nvme_cmd_out & out) override;
2700};
2701
2703 const char * req_type, unsigned nsid)
2704: smart_device(intf, dev_name, "nvme", req_type),
2706 linux_smart_device(O_RDONLY | O_NONBLOCK)
2707{
2708}
2709
2711{
2713 return false;
2714
2715 if (!get_nsid()) {
2716 // Use actual NSID (/dev/nvmeXnN) if available,
2717 // else use broadcast namespace (/dev/nvmeX)
2718 int nsid = ioctl(get_fd(), NVME_IOCTL_ID, (void*)0);
2719 set_nsid(nsid);
2720 }
2721
2722 return true;
2723}
2724
2726{
2728 memset(&pt, 0, sizeof(pt));
2729
2730 pt.opcode = in.opcode;
2731 pt.nsid = in.nsid;
2732 pt.addr = (uint64_t)in.buffer;
2733 pt.data_len = in.size;
2734 pt.cdw10 = in.cdw10;
2735 pt.cdw11 = in.cdw11;
2736 pt.cdw12 = in.cdw12;
2737 pt.cdw13 = in.cdw13;
2738 pt.cdw14 = in.cdw14;
2739 pt.cdw15 = in.cdw15;
2740 // Kernel default for NVMe admin commands is 60 seconds
2741 // pt.timeout_ms = 60 * 1000;
2742
2743 int status = ioctl(get_fd(), NVME_IOCTL_ADMIN_CMD, &pt);
2744
2745 if (status < 0)
2746 return set_err(errno, "NVME_IOCTL_ADMIN_CMD: %s", strerror(errno));
2747
2748 if (status > 0)
2749 return set_nvme_err(out, status);
2750
2751 out.result = pt.result;
2752 return true;
2753}
2754
2755
2756//////////////////////////////////////////////////////////////////////
2757// USB bridge ID detection
2758
2759// Read USB ID from /sys file
2760static bool read_id(const std::string & path, unsigned short & id)
2761{
2762 FILE * f = fopen(path.c_str(), "r");
2763 if (!f)
2764 return false;
2765 int n = -1;
2766 bool ok = (fscanf(f, "%hx%n", &id, &n) == 1 && n == 4);
2767 fclose(f);
2768 return ok;
2769}
2770
2771// Get USB bridge ID for "sdX" or "sgN"
2772static bool get_usb_id(const char * name, unsigned short & vendor_id,
2773 unsigned short & product_id, unsigned short & version)
2774{
2775 // Only "sdX" or "sgN" supported
2776 if (!(name[0] == 's' && (name[1] == 'd' || name[1] == 'g') && !strchr(name, '/')))
2777 return false;
2778
2779 // Start search at dir referenced by symlink
2780 // "/sys/block/sdX/device" or
2781 // "/sys/class/scsi_generic/sgN"
2782 // -> "/sys/devices/.../usb*/.../host*/target*/..."
2783 std::string dir = strprintf("/sys/%s/%s%s",
2784 (name[1] == 'd' ? "block" : "class/scsi_generic"), name,
2785 (name[1] == 'd' ? "/device" : ""));
2786
2787 // Stop search at "/sys/devices"
2788 struct stat st;
2789 if (stat("/sys/devices", &st))
2790 return false;
2791 ino_t stop_ino = st.st_ino;
2792
2793 // Search in parent directories until "idVendor" is found,
2794 // fail if "/sys/devices" reached or too many iterations
2795 int cnt = 0;
2796 do {
2797 dir += "/..";
2798 if (!(++cnt < 10 && !stat(dir.c_str(), &st) && st.st_ino != stop_ino))
2799 return false;
2800 } while (access((dir + "/idVendor").c_str(), 0));
2801
2802 if (scsi_debugmode > 1) {
2803 pout("Found idVendor in: %s\n", dir.c_str());
2804 char * p = realpath(dir.c_str(), (char *)0);
2805 if (p) {
2806 pout(" realpath: %s\n", p);
2807 free(p);
2808 }
2809 }
2810
2811 // Read IDs
2812 if (!( read_id(dir + "/idVendor", vendor_id)
2813 && read_id(dir + "/idProduct", product_id)
2814 && read_id(dir + "/bcdDevice", version) ))
2815 return false;
2816
2817 if (scsi_debugmode > 1)
2818 pout("USB ID = 0x%04x:0x%04x (0x%03x)\n", vendor_id, product_id, version);
2819 return true;
2820}
2821
2822//////////////////////////////////////////////////////////////////////
2823/// Linux interface
2824
2826: public /*implements*/ smart_interface
2827{
2828public:
2829 virtual std::string get_os_version_str() override;
2830
2831 virtual std::string get_app_examples(const char * appname) override;
2832
2833 virtual bool scan_smart_devices(smart_device_list & devlist,
2834 const smart_devtype_list & types, const char * pattern = 0) override;
2835
2836protected:
2837 virtual ata_device * get_ata_device(const char * name, const char * type) override;
2838
2839 virtual scsi_device * get_scsi_device(const char * name, const char * type) override;
2840
2841 virtual nvme_device * get_nvme_device(const char * name, const char * type,
2842 unsigned nsid) override;
2843
2844 virtual smart_device * autodetect_smart_device(const char * name) override;
2845
2846 virtual smart_device * get_custom_smart_device(const char * name, const char * type) override;
2847
2848 virtual std::string get_valid_custom_dev_types_str() override;
2849
2850private:
2851 static constexpr int devxy_to_n_max = 701; // "/dev/sdzz"
2852 static int devxy_to_n(const char * name, bool debug);
2853
2854 void get_dev_list(smart_device_list & devlist, const char * pattern,
2855 bool scan_scsi, bool (* p_dev_sdxy_seen)[devxy_to_n_max+1],
2856 bool scan_nvme, const char * req_type, bool autodetect);
2857
2858 bool get_dev_megasas(smart_device_list & devlist);
2859 smart_device * missing_option(const char * opt);
2860 int megasas_dcmd_cmd(int bus_no, uint32_t opcode, void *buf,
2861 size_t bufsize, uint8_t *mbox, size_t mboxlen, uint8_t *statusp);
2862 int megasas_pd_add_list(int bus_no, smart_device_list & devlist);
2863 bool get_dev_sssraid(smart_device_list & devlist);
2864 int sssraid_pd_add_list(int bus_no, smart_device_list & devlist);
2865 int sssraid_pdlist_cmd(int bus_no, uint16_t start_idx, void *buf, size_t bufsize, uint8_t *statusp);
2866};
2867
2869{
2870 struct utsname u;
2871 if (!uname(&u))
2872 return strprintf("%s-linux-%s", u.machine, u.release);
2873 else
2874 return SMARTMONTOOLS_BUILD_HOST;
2875}
2876
2877std::string linux_smart_interface::get_app_examples(const char * appname)
2878{
2879 if (!strcmp(appname, "smartctl"))
2880 return smartctl_examples;
2881 return "";
2882}
2883
2884// "/dev/sdXY" -> 0-devxy_to_n_max
2885// "/dev/disk/by-id/NAME" -> "../../sdXY" -> 0-devxy_to_n_max
2886// Other -> -1
2887int linux_smart_interface::devxy_to_n(const char * name, bool debug)
2888{
2889 const char * xy;
2890 char dest[256];
2891 if (str_starts_with(name, "/dev/sd")) {
2892 // Assume "/dev/sdXY"
2893 xy = name + sizeof("/dev/sd") - 1;
2894 }
2895 else {
2896 // Assume "/dev/disk/by-id/NAME", check link target
2897 int sz = readlink(name, dest, sizeof(dest)-1);
2898 if (!(0 < sz && sz < (int)sizeof(dest)))
2899 return -1;
2900 dest[sz] = 0;
2901 if (!str_starts_with(dest, "../../sd"))
2902 return -1;
2903 if (debug)
2904 pout("%s -> %s\n", name, dest);
2905 xy = dest + sizeof("../../sd") - 1;
2906 }
2907
2908 char x = xy[0];
2909 if (!('a' <= x && x <= 'z'))
2910 return -1;
2911 char y = xy[1];
2912 if (!y)
2913 // "[a-z]" -> 0-25
2914 return x - 'a';
2915
2916 if (!('a' <= y && y <= 'z' && !xy[2]))
2917 return -1;
2918 // "[a-z][a-z]" -> 26-701
2919 STATIC_ASSERT((('z' - 'a' + 1) * ('z' - 'a' + 1) + ('z' - 'a')) == devxy_to_n_max);
2920 return (x - 'a' + 1) * ('z' - 'a' + 1) + (y - 'a');
2921}
2922
2924 const char * pattern, bool scan_scsi, bool (* p_dev_sdxy_seen)[devxy_to_n_max+1],
2925 bool scan_nvme, const char * req_type, bool autodetect)
2926{
2927 bool debug = (ata_debugmode || scsi_debugmode || nvme_debugmode);
2928
2929 // Use glob to look for any directory entries matching the pattern
2930 glob_t globbuf;
2931 memset(&globbuf, 0, sizeof(globbuf));
2932 int retglob = glob(pattern, GLOB_ERR, NULL, &globbuf);
2933 if (retglob) {
2934 // glob failed: free memory and return
2935 globfree(&globbuf);
2936
2937 if (debug)
2938 pout("glob(3) error %d for pattern %s\n", retglob, pattern);
2939
2940 if (retglob == GLOB_NOSPACE)
2941 throw std::bad_alloc();
2942 return;
2943 }
2944
2945 // did we find too many paths?
2946 const int max_pathc = 1024;
2947 int n = (int)globbuf.gl_pathc;
2948 if (n > max_pathc) {
2949 pout("glob(3) found %d > MAX=%d devices matching pattern %s: ignoring %d paths\n",
2950 n, max_pathc, pattern, n - max_pathc);
2951 n = max_pathc;
2952 }
2953
2954 // now step through the list returned by glob.
2955 for (int i = 0; i < n; i++) {
2956 const char * name = globbuf.gl_pathv[i];
2957
2958 if (p_dev_sdxy_seen) {
2959 // Follow "/dev/disk/by-id/*" symlink and check for duplicate "/dev/sdXY"
2960 int dev_n = devxy_to_n(name, debug);
2961 if (!(0 <= dev_n && dev_n <= devxy_to_n_max))
2962 continue;
2963 if ((*p_dev_sdxy_seen)[dev_n]) {
2964 if (debug)
2965 pout("%s: duplicate, ignored\n", name);
2966 continue;
2967 }
2968 (*p_dev_sdxy_seen)[dev_n] = true;
2969 }
2970
2971 smart_device * dev;
2972 if (autodetect) {
2973 dev = autodetect_smart_device(name);
2974 if (!dev)
2975 continue;
2976 }
2977 else if (scan_scsi)
2978 dev = new linux_scsi_device(this, name, req_type, true /*scanning*/);
2979 else if (scan_nvme)
2980 dev = new linux_nvme_device(this, name, req_type, 0 /* use default nsid */);
2981 else
2982 dev = new linux_ata_device(this, name, req_type);
2983 devlist.push_back(dev);
2984 }
2985
2986 // free memory
2987 globfree(&globbuf);
2988}
2989
2990// getting devices from LSI SAS MegaRaid, if available
2992{
2993 /* Scanning of disks on MegaRaid device */
2994 /* Perform mknod of device ioctl node */
2995 int mjr, n1;
2996 char line[128];
2997 bool scan_megasas = false;
2998 FILE * fp = fopen("/proc/devices", "r");
2999 if (!fp)
3000 return false;
3001 while (fgets(line, sizeof(line), fp) != NULL) {
3002 n1=0;
3003 if (sscanf(line, "%d megaraid_sas_ioctl%n", &mjr, &n1) == 1 && n1 == 22) {
3004 scan_megasas = true;
3005 n1=mknod("/dev/megaraid_sas_ioctl_node", S_IFCHR|0600, makedev(mjr, 0));
3006 if(scsi_debugmode > 0)
3007 pout("Creating /dev/megaraid_sas_ioctl_node = %d\n", n1 >= 0 ? 0 : errno);
3008 if (n1 >= 0 || errno == EEXIST)
3009 break;
3010 }
3011 }
3012 fclose(fp);
3013
3014 if(!scan_megasas)
3015 return false;
3016
3017 // getting bus numbers with megasas devices
3018 // we are using sysfs to get list of all scsi hosts
3019 DIR * dp = opendir ("/sys/class/scsi_host/");
3020 if (dp != NULL)
3021 {
3022 struct dirent *ep;
3023 while ((ep = readdir (dp)) != NULL) {
3024 unsigned int host_no = 0;
3025 if (!sscanf(ep->d_name, "host%u", &host_no))
3026 continue;
3027 /* proc_name should be megaraid_sas */
3028 char sysfsdir[256];
3029 snprintf(sysfsdir, sizeof(sysfsdir) - 1,
3030 "/sys/class/scsi_host/host%u/proc_name", host_no);
3031 if((fp = fopen(sysfsdir, "r")) == NULL)
3032 continue;
3033 if(fgets(line, sizeof(line), fp) != NULL && !strncmp(line,"megaraid_sas",12)) {
3034 megasas_pd_add_list(host_no, devlist);
3035 }
3036 fclose(fp);
3037 }
3038 (void) closedir (dp);
3039 } else { /* sysfs not mounted ? */
3040 for(unsigned i = 0; i <=16; i++) // trying to add devices on first 16 buses
3041 megasas_pd_add_list(i, devlist);
3042 }
3043 return true;
3044}
3045
3046// getting devices from 3SNIC Raid, if available
3048{
3049 /* Scanning of disks on sssraid device */
3050 char line[128];
3051 FILE * fp = NULL;
3052
3053 // getting bus numbers with 3snic sas devices
3054 // we are using sysfs to get list of all scsi hosts
3055 DIR * dp = opendir ("/sys/class/scsi_host/");
3056 if (dp != NULL)
3057 {
3058 struct dirent *ep;
3059 while ((ep = readdir (dp)) != NULL) {
3060 unsigned int host_no = 0;
3061 if (!sscanf(ep->d_name, "host%u", &host_no))
3062 continue;
3063 /* proc_name should be sssraid */
3064 char sysfsdir[256];
3065 snprintf(sysfsdir, sizeof(sysfsdir) - 1,
3066 "/sys/class/scsi_host/host%u/proc_name", host_no);
3067 if((fp = fopen(sysfsdir, "r")) == NULL)
3068 continue;
3069 if(fgets(line, sizeof(line), fp) != NULL && !strncmp(line,"sssraid",7)) {
3070 sssraid_pd_add_list(host_no, devlist);
3071 }
3072 fclose(fp);
3073 }
3074 (void) closedir (dp);
3075 } else { /* sysfs not mounted ? */
3076 for(unsigned i = 0; i <=16; i++) // trying to add devices on first 16 buses
3077 sssraid_pd_add_list(i, devlist);
3078 }
3079 return true;
3080}
3081
3083 const smart_devtype_list & types, const char * pattern /*= 0*/)
3084{
3085 if (pattern)
3086 return set_err(EINVAL, "DEVICESCAN with pattern not implemented yet");
3087
3088 // Scan type list
3089 bool by_id = false;
3090 const char * type_ata = 0, * type_scsi = 0, * type_sat = 0, * type_nvme = 0;
3091 for (unsigned i = 0; i < types.size(); i++) {
3092 const char * type = types[i].c_str();
3093 if (!strcmp(type, "by-id"))
3094 by_id = true;
3095 else if (!strcmp(type, "ata"))
3096 type_ata = "ata";
3097 else if (!strcmp(type, "scsi"))
3098 type_scsi = "scsi";
3099 else if (!strcmp(type, "sat"))
3100 type_sat = "sat";
3101 else if (!strcmp(type, "nvme"))
3102 type_nvme = "nvme";
3103 else
3104 return set_err(EINVAL, "Invalid type '%s', valid arguments are: by-id, ata, scsi, sat, nvme",
3105 type);
3106 }
3107 // Use default if no type specified
3108 if (!(type_ata || type_scsi || type_sat || type_nvme)) {
3109 type_ata = type_scsi = type_sat = "";
3110#ifdef WITH_NVME_DEVICESCAN // TODO: Remove when NVMe support is no longer EXPERIMENTAL
3111 type_nvme = "";
3112#endif
3113 }
3114
3115 if (type_ata)
3116 get_dev_list(devlist, "/dev/hd[a-t]", false, 0, false, type_ata, false);
3117
3118 if (type_scsi || type_sat) {
3119 // "sat" detection will be later handled in linux_scsi_device::autodetect_open()
3120 const char * type_scsi_sat = ((type_scsi && type_sat) ? "" // detect both
3121 : (type_scsi ? type_scsi : type_sat));
3122 bool autodetect = !*type_scsi_sat; // If no type specified, detect USB also
3123
3124 bool dev_sdxy_seen[devxy_to_n_max+1] = {false, };
3125 bool (*p_dev_sdxy_seen)[devxy_to_n_max+1] = 0;
3126 if (by_id) {
3127 // Scan unique symlinks first
3128 get_dev_list(devlist, "/dev/disk/by-id/*", true, &dev_sdxy_seen, false,
3129 type_scsi_sat, autodetect);
3130 p_dev_sdxy_seen = &dev_sdxy_seen; // Check for duplicates below
3131 }
3132
3133 get_dev_list(devlist, "/dev/sd[a-z]", true, p_dev_sdxy_seen, false, type_scsi_sat, autodetect);
3134 get_dev_list(devlist, "/dev/sd[a-z][a-z]", true, p_dev_sdxy_seen, false, type_scsi_sat, autodetect);
3135
3136 // get device list from the megaraid device
3137 get_dev_megasas(devlist);
3138 // get device list from the sssraid device
3139 get_dev_sssraid(devlist);
3140 }
3141
3142 if (type_nvme) {
3143 get_dev_list(devlist, "/dev/nvme[0-9]", false, 0, true, type_nvme, false);
3144 get_dev_list(devlist, "/dev/nvme[1-9][0-9]", false, 0, true, type_nvme, false);
3145 }
3146
3147 return true;
3148}
3149
3150ata_device * linux_smart_interface::get_ata_device(const char * name, const char * type)
3151{
3152 return new linux_ata_device(this, name, type);
3153}
3154
3155scsi_device * linux_smart_interface::get_scsi_device(const char * name, const char * type)
3156{
3157 return new linux_scsi_device(this, name, type);
3158}
3159
3160nvme_device * linux_smart_interface::get_nvme_device(const char * name, const char * type,
3161 unsigned nsid)
3162{
3163 return new linux_nvme_device(this, name, type, nsid);
3164}
3165
3167{
3168 return set_err_np(EINVAL, "requires option '%s'", opt);
3169}
3170
3171int
3172linux_smart_interface::megasas_dcmd_cmd(int bus_no, uint32_t opcode, void *buf,
3173 size_t bufsize, uint8_t *mbox, size_t mboxlen, uint8_t *statusp)
3174{
3175 struct megasas_iocpacket ioc;
3176
3177 if ((mbox != NULL && (mboxlen == 0 || mboxlen > MFI_MBOX_SIZE)) ||
3178 (mbox == NULL && mboxlen != 0))
3179 {
3180 errno = EINVAL;
3181 return (-1);
3182 }
3183
3184 memset(&ioc, 0, sizeof(ioc));
3185 struct megasas_dcmd_frame * dcmd = &ioc.frame.dcmd;
3186 ioc.host_no = bus_no;
3187 if (mbox)
3188 memcpy(dcmd->mbox.w, mbox, mboxlen);
3190 dcmd->timeout = 0;
3191 dcmd->flags = 0;
3192 dcmd->data_xfer_len = bufsize;
3193 dcmd->opcode = opcode;
3194
3195 if (bufsize > 0) {
3196 dcmd->sge_count = 1;
3197 dcmd->data_xfer_len = bufsize;
3198 dcmd->sgl.sge32[0].phys_addr = (intptr_t)buf;
3199 dcmd->sgl.sge32[0].length = (uint32_t)bufsize;
3200 ioc.sge_count = 1;
3201 ioc.sgl_off = offsetof(struct megasas_dcmd_frame, sgl);
3202 ioc.sgl[0].iov_base = buf;
3203 ioc.sgl[0].iov_len = bufsize;
3204 }
3205
3206 int fd;
3207 if ((fd = ::open("/dev/megaraid_sas_ioctl_node", O_RDWR)) < 0) {
3208 return (errno);
3209 }
3210
3211 int r = ioctl(fd, MEGASAS_IOC_FIRMWARE, &ioc);
3212 ::close(fd);
3213 if (r < 0) {
3214 return (r);
3215 }
3216
3217 if (statusp != NULL)
3218 *statusp = dcmd->cmd_status;
3219 else if (dcmd->cmd_status != MFI_STAT_OK) {
3220 fprintf(stderr, "command %x returned error status %x\n",
3222 errno = EIO;
3223 return (-1);
3224 }
3225 return (0);
3226}
3227
3228int
3230{
3231 /*
3232 * Keep fetching the list in a loop until we have a large enough
3233 * buffer to hold the entire list.
3234 */
3235 megasas_pd_list * list = 0;
3236 for (unsigned list_size = 1024; ; ) {
3237 list = reinterpret_cast<megasas_pd_list *>(realloc(list, list_size));
3238 if (!list)
3239 throw std::bad_alloc();
3240 memset(list, 0, list_size);
3241 if (megasas_dcmd_cmd(bus_no, MFI_DCMD_PD_GET_LIST, list, list_size, NULL, 0,
3242 NULL) < 0)
3243 {
3244 free(list);
3245 return (-1);
3246 }
3247 if (list->size <= list_size)
3248 break;
3249 list_size = list->size;
3250 }
3251
3252 // adding all SCSI devices
3253 for (unsigned i = 0; i < list->count; i++) {
3254 if(list->addr[i].scsi_dev_type)
3255 continue; /* non disk device found */
3256 char line[128];
3257 snprintf(line, sizeof(line) - 1, "/dev/bus/%d", bus_no);
3258 smart_device * dev = new linux_megaraid_device(this, line, list->addr[i].device_id);
3259 devlist.push_back(dev);
3260 }
3261 free(list);
3262 return (0);
3263}
3264
3265int
3266linux_smart_interface::sssraid_pdlist_cmd(int bus_no, uint16_t start_idx_param, void *buf, size_t bufsize, uint8_t *statusp)
3267{
3268 struct sg_io_v4 io_hdr_v4{};
3269 unsigned char sense_buff[ADM_SCSI_CDB_SENSE_MAX_LEN] = { 0 };
3270 struct bsg_ioctl_cmd bsg_param{};
3271 u8 cmd_param[24] = { 0 };
3272
3273 io_hdr_v4.guard = 'Q';
3274 io_hdr_v4.protocol = BSG_PROTOCOL_SCSI;
3275 io_hdr_v4.subprotocol = BSG_SUB_PROTOCOL_SCSI_TRANSPORT;
3276 io_hdr_v4.response = (uintptr_t)sense_buff;
3277 io_hdr_v4.max_response_len = ADM_SCSI_CDB_SENSE_MAX_LEN;
3278 io_hdr_v4.request_len = sizeof(struct bsg_ioctl_cmd);
3279 io_hdr_v4.request = (uintptr_t)(&bsg_param);
3281
3282 if (bufsize >0) {
3283 io_hdr_v4.din_xferp = (uintptr_t)buf;
3284 io_hdr_v4.din_xfer_len = bufsize;
3285 }
3286
3287 bsg_param.msgcode = 0;
3288 bsg_param.ioctl_r64.opcode = ADM_RAID_READ;
3291 bsg_param.ioctl_r64.addr = (uintptr_t)buf;
3292 bsg_param.ioctl_r64.info_1.data_len = bufsize;
3293 bsg_param.ioctl_r64.data_len = bufsize;
3294 bsg_param.ioctl_r64.info_1.param_len = sizeof(struct cmd_pdlist_idx);
3295
3296 struct cmd_pdlist_idx *p_cmd_param = (struct cmd_pdlist_idx *)(&cmd_param);
3297 p_cmd_param->start_idx = start_idx_param;
3298 p_cmd_param->count = CMD_PDLIST_ONCE_NUM;
3299 memcpy((u32*)&bsg_param.ioctl_r64.cdw10, cmd_param, sizeof(struct cmd_pdlist_idx));
3300
3301 int fd;
3302 char line[128];
3303 snprintf(line, sizeof(line) - 1, "/dev/bsg/sssraid%d", bus_no);
3304 if ((fd = ::open(line, O_RDONLY)) < 0) {
3305 pout("open %s error %d\n", line, fd);
3306 return (errno);
3307 }
3308
3309 int r = ioctl(fd, SG_IO, &io_hdr_v4);
3310 ::close(fd);
3311 if (r < 0) {
3312 return (r);
3313 }
3314
3315 if (statusp != NULL) {
3316 *statusp = (io_hdr_v4.transport_status << 0x8) | io_hdr_v4.device_status;
3317 pout("statusp = 0x%x\n", *statusp);
3318 if (*statusp) {
3319 pout("controller returns an error - 0x%x", *statusp);
3320 return (-1);
3321 }
3322 }
3323 return (0);
3324}
3325
3326int
3328{
3329 unsigned disk_num = 0;
3330 struct cmd_pdlist_entry pdlist[CMD_PDS_MAX_NUM]{};
3331 while (disk_num < CMD_PDS_MAX_NUM) {
3332 struct cmd_show_pdlist list{};
3333 if (sssraid_pdlist_cmd(bus_no, disk_num, &list, sizeof(struct cmd_show_pdlist), NULL) < 0)
3334 {
3335 return (-1);
3336 }
3337 if (list.num == 0)
3338 break;
3339 memcpy(&pdlist[disk_num], list.disks, list.num * sizeof(struct cmd_pdlist_entry));
3340 disk_num += list.num;
3341 if (list.num < CMD_PDLIST_ONCE_NUM)
3342 break;
3343 }
3344
3345 // adding all SCSI devices
3346 for (unsigned i = 0; i < disk_num; i++) {
3347 if(!(pdlist[i].interface == ADM_DEVICE_TYPE_SATA || pdlist[i].interface == ADM_DEVICE_TYPE_SAS
3348 || pdlist[i].interface == ADM_DEVICE_TYPE_NVME))
3349 continue; /* non disk device found */
3350 char line[128];
3351 snprintf(line, sizeof(line) - 1, "/dev/bsg/sssraid%d", bus_no);
3352 smart_device * dev = new linux_sssraid_device(this, line, (unsigned int)pdlist[i].enc_id, (unsigned int)pdlist[i].slot_id);
3353 devlist.push_back(dev);
3354 }
3355 return (0);
3356}
3357
3358// Return kernel release as integer ("2.6.31" -> 206031)
3359static unsigned get_kernel_release()
3360{
3361 struct utsname u;
3362 if (uname(&u))
3363 return 0;
3364 unsigned x = 0, y = 0, z = 0;
3365 if (!(sscanf(u.release, "%u.%u.%u", &x, &y, &z) == 3
3366 && x < 100 && y < 100 && z < 1000 ))
3367 return 0;
3368 return x * 100000 + y * 1000 + z;
3369}
3370
3371// Check for SCSI host proc_name "hpsa" and HPSA raid_level
3372static bool is_hpsa_in_raid_mode(const char * name)
3373{
3374 char path[128];
3375 snprintf(path, sizeof(path), "/sys/block/%s/device", name);
3376 char * syshostpath = realpath(path, (char *)0);
3377 if (!syshostpath)
3378 return false;
3379
3380 char * syshost = strrchr(syshostpath, '/');
3381 if (!syshost) {
3382 free(syshostpath);
3383 return false;
3384 }
3385
3386 char * hostsep = strchr(++syshost, ':');
3387 if (hostsep)
3388 *hostsep = 0;
3389
3390 snprintf(path, sizeof(path), "/sys/class/scsi_host/host%s/proc_name", syshost);
3391 free(syshostpath);
3392 int fd = open(path, O_RDONLY);
3393 if (fd < 0)
3394 return false;
3395
3396 char proc_name[32];
3397 ssize_t n = read(fd, proc_name, sizeof(proc_name) - 1);
3398 close(fd);
3399 if (n < 4)
3400 return false;
3401
3402 proc_name[n] = 0;
3403 if (proc_name[n - 1] == '\n')
3404 proc_name[n - 1] = 0;
3405
3406 if (scsi_debugmode > 1)
3407 pout("%s -> %s: \"%s\"\n", name, path, proc_name);
3408
3409 if (strcmp(proc_name, "hpsa"))
3410 return false;
3411
3412 // See: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/scsi/hpsa.c?id=6417f03132a6952cd17ddd8eaddbac92b61b17e0#n693
3413 snprintf(path, sizeof(path), "/sys/block/%s/device/raid_level", name);
3414 fd = open(path, O_RDONLY);
3415 if (fd < 0)
3416 return false;
3417
3418 char raid_level[4];
3419 n = read(fd, raid_level, sizeof(raid_level) - 1);
3420 close(fd);
3421 if (n < 3)
3422 return false;
3423 raid_level[n] = 0;
3424
3425 if (strcmp(raid_level, "N/A"))
3426 return true;
3427
3428 return false;
3429}
3430
3431// Guess device type (ata or scsi) based on device name (Linux
3432// specific) SCSI device name in linux can be sd, sr, scd, st, nst,
3433// osst, nosst and sg.
3435{
3436 const char * test_name = name;
3437
3438 // Dereference symlinks
3439 struct stat st;
3440 std::string pathbuf;
3441 if (!lstat(name, &st) && S_ISLNK(st.st_mode)) {
3442 char * p = realpath(name, (char *)0);
3443 if (p) {
3444 pathbuf = p;
3445 free(p);
3446 test_name = pathbuf.c_str();
3447 }
3448 }
3449
3450 // Remove the leading /dev/... if it's there
3451 static const char dev_prefix[] = "/dev/";
3452 if (str_starts_with(test_name, dev_prefix))
3453 test_name += strlen(dev_prefix);
3454
3455 // form /dev/h* or h*
3456 if (str_starts_with(test_name, "h"))
3457 return new linux_ata_device(this, name, "");
3458
3459 // form /dev/ide/* or ide/*
3460 if (str_starts_with(test_name, "ide/"))
3461 return new linux_ata_device(this, name, "");
3462
3463 // form /dev/s* or s*
3464 if (str_starts_with(test_name, "s")) {
3465
3466 // Try to detect possible USB->(S)ATA bridge
3467 unsigned short vendor_id = 0, product_id = 0, version = 0;
3468 if (get_usb_id(test_name, vendor_id, product_id, version)) {
3469 const char * usbtype = get_usb_dev_type_by_id(vendor_id, product_id, version);
3470 if (!usbtype)
3471 return nullptr;
3472
3473 // Kernels before 2.6.29 do not support the sense data length
3474 // required for SAT ATA PASS-THROUGH(16)
3475 if (!strcmp(usbtype, "sat") && get_kernel_release() < 206029)
3476 usbtype = "sat,12";
3477
3478 // Return SAT/USB device for this type
3479 // (Note: linux_scsi_device::autodetect_open() will not be called in this case)
3480 return get_scsi_passthrough_device(usbtype, new linux_scsi_device(this, name, ""));
3481 }
3482
3483 // Fail if hpsa driver and device is using RAID
3484 if (is_hpsa_in_raid_mode(test_name))
3485 return missing_option("-d cciss,N");
3486
3487 // No USB bridge or hpsa driver found, assume regular SCSI device
3488 return new linux_scsi_device(this, name, "");
3489 }
3490
3491 // form /dev/scsi/* or scsi/*
3492 if (str_starts_with(test_name, "scsi/"))
3493 return new linux_scsi_device(this, name, "");
3494
3495 // form /dev/bsg/* or bsg/*
3496 if (str_starts_with(test_name, "bsg/"))
3497 return new linux_scsi_device(this, name, "");
3498
3499 // form /dev/ns* or ns*
3500 if (str_starts_with(test_name, "ns"))
3501 return new linux_scsi_device(this, name, "");
3502
3503 // form /dev/os* or os*
3504 if (str_starts_with(test_name, "os"))
3505 return new linux_scsi_device(this, name, "");
3506
3507 // form /dev/nos* or nos*
3508 if (str_starts_with(test_name, "nos"))
3509 return new linux_scsi_device(this, name, "");
3510
3511 // form /dev/nvme* or nvme*
3512 if (str_starts_with(test_name, "nvme"))
3513 return new linux_nvme_device(this, name, "", 0 /* use default nsid */);
3514
3515 // form /dev/tw[ael]* or tw[ael]*
3516 if (str_starts_with(test_name, "tw") && strchr("ael", test_name[2]))
3517 return missing_option("-d 3ware,N");
3518
3519 // form /dev/cciss/* or cciss/*
3520 if (str_starts_with(test_name, "cciss/"))
3521 return missing_option("-d cciss,N");
3522
3523 // we failed to recognize any of the forms
3524 return nullptr;
3525}
3526
3528{
3529 // Marvell ?
3530 // TODO: Remove after smartmontools 7.4
3531 if (!strcmp(type, "marvell"))
3532 return set_err_np(EINVAL,
3533 "The device type 'marvell' is deprecated and will be removed in a\n"
3534 "future version of smartmontools. If you still need this device type, please\n"
3535 "use '-d marvell,force' and inform " PACKAGE_BUGREPORT );
3536 if (!strcmp(type, "marvell,force"))
3537 return new linux_marvell_device(this, name, type);
3538
3539 // 3Ware ?
3540 int disknum = -1, n1 = -1, n2 = -1;
3541 if (sscanf(type, "3ware,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {
3542 if (n2 != (int)strlen(type))
3543 return set_err_np(EINVAL, "Option -d 3ware,N requires N to be a non-negative integer");
3544 if (!(0 <= disknum && disknum <= 127))
3545 return set_err_np(EINVAL, "Option -d 3ware,N (N=%d) must have 0 <= N <= 127", disknum);
3546
3547 if (!strncmp(name, "/dev/twl", 8))
3549 else if (!strncmp(name, "/dev/twa", 8))
3551 else if (!strncmp(name, "/dev/twe", 8))
3553 else
3554 return new linux_escalade_device(this, name, linux_escalade_device::AMCC_3WARE_678K, disknum);
3555 }
3556
3557 // Areca?
3558 disknum = n1 = n2 = -1;
3559 int encnum = 1;
3560 if (sscanf(type, "areca,%n%d/%d%n", &n1, &disknum, &encnum, &n2) >= 1 || n1 == 6) {
3561 if (!(1 <= disknum && disknum <= 128))
3562 return set_err_np(EINVAL, "Option -d areca,N/E (N=%d) must have 1 <= N <= 128", disknum);
3563 if (!(1 <= encnum && encnum <= 8))
3564 return set_err_np(EINVAL, "Option -d areca,N/E (E=%d) must have 1 <= E <= 8", encnum);
3565 return new linux_areca_ata_device(this, name, disknum, encnum);
3566 }
3567
3568 // Highpoint ?
3569 int controller = -1, channel = -1; disknum = 1;
3570 n1 = n2 = -1; int n3 = -1;
3571 if (sscanf(type, "hpt,%n%d/%d%n/%d%n", &n1, &controller, &channel, &n2, &disknum, &n3) >= 2 || n1 == 4) {
3572 int len = strlen(type);
3573 if (!(n2 == len || n3 == len))
3574 return set_err_np(EINVAL, "Option '-d hpt,L/M/N' supports 2-3 items");
3575 if (!(1 <= controller && controller <= 8))
3576 return set_err_np(EINVAL, "Option '-d hpt,L/M/N' invalid controller id L supplied");
3577 if (!(1 <= channel && channel <= 128))
3578 return set_err_np(EINVAL, "Option '-d hpt,L/M/N' invalid channel number M supplied");
3579 if (!(1 <= disknum && disknum <= 15))
3580 return set_err_np(EINVAL, "Option '-d hpt,L/M/N' invalid pmport number N supplied");
3581 return new linux_highpoint_device(this, name, controller, channel, disknum);
3582 }
3583
3584#ifdef HAVE_LINUX_CCISS_IOCTL_H
3585 // CCISS ?
3586 disknum = n1 = n2 = -1;
3587 if (sscanf(type, "cciss,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {
3588 if (n2 != (int)strlen(type))
3589 return set_err_np(EINVAL, "Option -d cciss,N requires N to be a non-negative integer");
3590 if (!(0 <= disknum && disknum <= 127))
3591 return set_err_np(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 127", disknum);
3592 return get_sat_device("sat,auto", new linux_cciss_device(this, name, disknum));
3593 }
3594#endif // HAVE_LINUX_CCISS_IOCTL_H
3595
3596 // MegaRAID ?
3597 if (sscanf(type, "megaraid,%d", &disknum) == 1) {
3598 return new linux_megaraid_device(this, name, disknum);
3599 }
3600
3601 // SSSRAID
3602 unsigned eid = -1, sid = -1;
3603 if (sscanf(type, "sssraid,%u,%u", &eid, &sid) == 2) {
3604 return get_sat_device("sat,auto", new linux_sssraid_device(this, name, eid, sid));
3605 }
3606
3607 //aacraid?
3608 unsigned host, chan, device;
3609 if (sscanf(type, "aacraid,%u,%u,%u", &host, &chan, &device) == 3) {
3610 //return new linux_aacraid_device(this,name,channel,device);
3611 return get_sat_device("sat,auto",
3612 new linux_aacraid_device(this, name, host, chan, device));
3613
3614 }
3615
3616 return nullptr;
3617}
3618
3620{
3621 return "areca,N/E, 3ware,N, hpt,L/M/N, megaraid,N, aacraid,H,L,ID, sssraid,E,S"
3622#ifdef HAVE_LINUX_CCISS_IOCTL_H
3623 ", cciss,N"
3624#endif
3625 ;
3626}
3627
3628} // namespace
3629
3630/////////////////////////////////////////////////////////////////////////////
3631/// Initialize platform interface and register with smi()
3632
3634{
3635 static os_linux::linux_smart_interface the_interface;
3636 smart_interface::set(&the_interface);
3637}
#define SRB_DataIn
Definition: aacraid.h:43
#define SRB_DataOut
Definition: aacraid.h:44
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: aacraid.h:41
#define FSACTL_SEND_RAW_SRB
Definition: aacraid.h:39
#define SRB_NoDataXfer
Definition: aacraid.h:45
unsigned char ata_debugmode
Definition: atacmds.cpp:33
#define ATA_SMART_AUTO_OFFLINE
Definition: atacmds.h:94
#define ATA_IDENTIFY_DEVICE
Definition: atacmds.h:53
#define ATA_SMART_WRITE_LOG_SECTOR
Definition: atacmds.h:87
#define ATA_IDENTIFY_PACKET_DEVICE
Definition: atacmds.h:54
#define ATA_SMART_STATUS
Definition: atacmds.h:91
#define ATA_SMART_READ_VALUES
Definition: atacmds.h:81
#define ATA_SMART_READ_THRESHOLDS
Definition: atacmds.h:82
#define ATA_SMART_READ_LOG_SECTOR
Definition: atacmds.h:86
#define ATA_SMART_CMD
Definition: atacmds.h:56
#define ATA_SMART_IMMEDIATE_OFFLINE
Definition: atacmds.h:85
smart_command_set
Definition: atacmds.h:29
@ PIDENTIFY
Definition: atacmds.h:43
@ CHECK_POWER_MODE
Definition: atacmds.h:45
@ IDENTIFY
Definition: atacmds.h:42
@ STATUS_CHECK
Definition: atacmds.h:37
@ IMMEDIATE_OFFLINE
Definition: atacmds.h:34
@ AUTO_OFFLINE
Definition: atacmds.h:35
@ ENABLE
Definition: atacmds.h:31
@ WRITE_LOG
Definition: atacmds.h:47
@ READ_VALUES
Definition: atacmds.h:39
@ AUTOSAVE
Definition: atacmds.h:33
@ STATUS
Definition: atacmds.h:36
@ READ_THRESHOLDS
Definition: atacmds.h:40
@ DISABLE
Definition: atacmds.h:32
@ READ_LOG
Definition: atacmds.h:41
#define ATA_SMART_ENABLE
Definition: atacmds.h:89
#define ATA_SMART_AUTOSAVE
Definition: atacmds.h:83
#define ATA_SMART_DISABLE
Definition: atacmds.h:90
#define ATA_CHECK_POWER_MODE
Definition: atacmds.h:52
int cciss_io_interface(int device, int target, struct scsi_cmnd_io *iop, int report)
Smart pointer class for device pointers.
device_type * release()
Return the pointer and release ownership.
Adapter class to implement new ATA pass through old interface.
ATA device access.
bool ata_cmd_is_ok(const ata_cmd_in &in, bool data_out_support=false, bool multi_sector_support=false, bool ata_48bit_support=false)
Check command input parameters (old version).
virtual int arcmsr_get_dev_type()
Definition: dev_areca.cpp:342
void set_disknum(int disknum)
Definition: dev_areca.h:119
void set_encnum(int encnum)
Definition: dev_areca.h:122
NVMe device access.
unsigned get_nsid() const
Get namespace id.
bool set_nvme_err(nvme_cmd_out &out, unsigned status, const char *msg=0)
Set last error number and message if pass-through returns NVMe error status.
void set_nsid(unsigned nsid)
Set namespace id.
PMC AacRAID support.
Definition: os_linux.cpp:836
virtual bool scsi_pass_through(scsi_cmnd_io *iop) override
SCSI pass through.
Definition: os_linux.cpp:921
linux_aacraid_device(smart_interface *intf, const char *dev_name, unsigned int host, unsigned int channel, unsigned int device)
Definition: os_linux.cpp:859
virtual bool open() override
Open device, return false on error.
Definition: os_linux.cpp:873
linux_areca_ata_device(smart_interface *intf, const char *dev_name, int disknum, int encnum=1)
Definition: os_linux.cpp:2083
virtual smart_device * autodetect_open() override
Open device with autodetection support.
Definition: os_linux.cpp:2092
virtual bool arcmsr_lock() override
Definition: os_linux.cpp:2137
virtual bool arcmsr_unlock() override
Definition: os_linux.cpp:2142
virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io *iop) override
Definition: os_linux.cpp:2117
virtual smart_device * autodetect_open() override
Open device with autodetection support.
Definition: os_linux.cpp:2157
virtual int arcmsr_do_scsi_io(struct scsi_cmnd_io *iop) override
Definition: os_linux.cpp:2162
virtual bool arcmsr_lock() override
Definition: os_linux.cpp:2182
virtual bool arcmsr_unlock() override
Definition: os_linux.cpp:2187
linux_areca_scsi_device(smart_interface *intf, const char *dev_name, int disknum, int encnum=1)
Definition: os_linux.cpp:2148
Linux ATA support.
Definition: os_linux.cpp:213
linux_ata_device(smart_interface *intf, const char *dev_name, const char *req_type)
Definition: os_linux.cpp:221
virtual int ata_command_interface(smart_command_set command, int select, char *data) override
Old ATA interface called by ata_pass_through()
Definition: os_linux.cpp:249
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out) override
ATA pass through.
Definition: os_linux.cpp:1802
virtual bool open() override
Open device, return false on error.
Definition: os_linux.cpp:1746
linux_escalade_device(smart_interface *intf, const char *dev_name, escalade_type_t escalade_type, int disknum)
Definition: os_linux.cpp:1589
escalade_type_t m_escalade_type
Controller type.
Definition: os_linux.cpp:1585
Highpoint RAID support.
Definition: os_linux.cpp:2345
unsigned char m_hpt_data[3]
controller/channel/port
Definition: os_linux.cpp:2354
linux_highpoint_device(smart_interface *intf, const char *dev_name, unsigned char controller, unsigned char channel, unsigned char port)
Definition: os_linux.cpp:2357
virtual int ata_command_interface(smart_command_set command, int select, char *data)
Old ATA interface called by ata_pass_through()
Definition: os_linux.cpp:2387
virtual int ata_command_interface(smart_command_set command, int select, char *data)
Old ATA interface called by ata_pass_through()
Definition: os_linux.cpp:2213
linux_marvell_device(smart_interface *intf, const char *dev_name, const char *req_type)
Definition: os_linux.cpp:2206
LSI MegaRAID support.
Definition: os_linux.cpp:1072
bool megasas_cmd(int cdbLen, void *cdb, int dataLen, void *data, int senseLen, void *sense, int report, int direction)
Definition: os_linux.cpp:1281
bool(linux_megaraid_device::* pt_cmd)(int cdblen, void *cdb, int dataLen, void *data, int senseLen, void *sense, int report, int direction)
Definition: os_linux.cpp:1091
virtual bool close() override
Close device, return false on error.
Definition: os_linux.cpp:1217
virtual bool open() override
Open device, return false on error.
Definition: os_linux.cpp:1157
linux_megaraid_device(smart_interface *intf, const char *name, unsigned int tgt)
Definition: os_linux.cpp:1099
virtual smart_device * autodetect_open() override
Open device with autodetection support.
Definition: os_linux.cpp:1116
virtual bool scsi_pass_through(scsi_cmnd_io *iop) override
SCSI pass through.
Definition: os_linux.cpp:1226
bool megadev_cmd(int cdbLen, void *cdb, int dataLen, void *data, int senseLen, void *sense, int report, int direction)
Definition: os_linux.cpp:1342
linux_nvme_device(smart_interface *intf, const char *dev_name, const char *req_type, unsigned nsid)
Definition: os_linux.cpp:2702
virtual bool nvme_pass_through(const nvme_cmd_in &in, nvme_cmd_out &out) override
NVMe pass through.
Definition: os_linux.cpp:2725
virtual bool open() override
Open device, return false on error.
Definition: os_linux.cpp:2710
Standard SCSI support.
Definition: os_linux.cpp:799
bool m_scanning
true if created within scan_smart_devices
Definition: os_linux.cpp:809
virtual smart_device * autodetect_open() override
SCSI open with autodetection support.
Definition: os_linux.cpp:2594
linux_scsi_device(smart_interface *intf, const char *dev_name, const char *req_type, bool scanning=false)
Definition: os_linux.cpp:812
virtual bool scsi_pass_through(scsi_cmnd_io *iop) override
SCSI pass through.
Definition: os_linux.cpp:822
Shared open/close routines.
Definition: os_linux.cpp:104
virtual bool open() override
Open device, return false on error.
Definition: os_linux.cpp:145
int m_flags
Flags for open()
Definition: os_linux.cpp:130
virtual bool is_open() const override
Return true if device is open.
Definition: os_linux.cpp:140
int m_retry_flags
Flags to retry open(), -1 if no retry.
Definition: os_linux.cpp:131
virtual bool close() override
Close device, return false on error.
Definition: os_linux.cpp:177
linux_smart_device(int flags, int retry_flags=-1)
Definition: os_linux.cpp:106
int m_fd
filedesc, -1 if not open.
Definition: os_linux.cpp:129
int get_fd() const
Return filedesc for derived classes.
Definition: os_linux.cpp:122
virtual nvme_device * get_nvme_device(const char *name, const char *type, unsigned nsid) override
Return standard NVMe device.
Definition: os_linux.cpp:3160
virtual ata_device * get_ata_device(const char *name, const char *type) override
Return standard ATA device.
Definition: os_linux.cpp:3150
static int devxy_to_n(const char *name, bool debug)
Definition: os_linux.cpp:2887
int sssraid_pdlist_cmd(int bus_no, uint16_t start_idx, void *buf, size_t bufsize, uint8_t *statusp)
Definition: os_linux.cpp:3266
virtual std::string get_valid_custom_dev_types_str() override
Return valid 'type' args accepted by above.
Definition: os_linux.cpp:3619
int megasas_pd_add_list(int bus_no, smart_device_list &devlist)
Definition: os_linux.cpp:3229
virtual bool scan_smart_devices(smart_device_list &devlist, const smart_devtype_list &types, const char *pattern=0) override
Fill 'devlist' with devices of all 'types' with device names specified by some optional 'pattern'.
Definition: os_linux.cpp:3082
virtual scsi_device * get_scsi_device(const char *name, const char *type) override
Return standard SCSI device.
Definition: os_linux.cpp:3155
virtual std::string get_app_examples(const char *appname) override
Return example string for program 'appname'.
Definition: os_linux.cpp:2877
int sssraid_pd_add_list(int bus_no, smart_device_list &devlist)
Definition: os_linux.cpp:3327
virtual smart_device * autodetect_smart_device(const char *name) override
Autodetect device if no device type specified.
Definition: os_linux.cpp:3434
virtual std::string get_os_version_str() override
Return info string about build host and/or OS version.
Definition: os_linux.cpp:2868
bool get_dev_megasas(smart_device_list &devlist)
Definition: os_linux.cpp:2991
virtual smart_device * get_custom_smart_device(const char *name, const char *type) override
Return device for platform specific 'type'.
Definition: os_linux.cpp:3527
int megasas_dcmd_cmd(int bus_no, uint32_t opcode, void *buf, size_t bufsize, uint8_t *mbox, size_t mboxlen, uint8_t *statusp)
Definition: os_linux.cpp:3172
void get_dev_list(smart_device_list &devlist, const char *pattern, bool scan_scsi, bool(*p_dev_sdxy_seen)[devxy_to_n_max+1], bool scan_nvme, const char *req_type, bool autodetect)
Definition: os_linux.cpp:2923
smart_device * missing_option(const char *opt)
Definition: os_linux.cpp:3166
bool get_dev_sssraid(smart_device_list &devlist)
Definition: os_linux.cpp:3047
static constexpr int devxy_to_n_max
Definition: os_linux.cpp:2851
bool scsi_cmd(scsi_cmnd_io *iop)
Definition: os_linux.cpp:1447
virtual bool scsi_pass_through(scsi_cmnd_io *iop) override
SCSI pass through.
Definition: os_linux.cpp:1415
linux_sssraid_device(smart_interface *intf, const char *name, unsigned int eid, unsigned int sid)
Definition: os_linux.cpp:1405
SCSI device access.
List of devices for DEVICESCAN.
void push_back(smart_device *dev)
Base class for all devices.
Definition: dev_interface.h:33
smart_interface * smi()
Get interface which produced this object.
const char * get_req_type() const
Get type requested by user, empty if none.
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
bool is_ata() const
Return true if ATA device.
Definition: dev_interface.h:86
device_info & set_info()
R/W access to device info struct.
const char * get_dev_name() const
Get device (path)name.
The platform interface abstraction.
static void set(smart_interface *intf)
Set interface to use, must be called from init().
virtual const char * get_usb_dev_type_by_id(int vendor_id, int product_id, int version=-1)
Get type name for USB device with known VENDOR:PRODUCT ID.
Definition: scsiata.cpp:1518
virtual ata_device * get_sat_device(const char *type, scsi_device *scsidev)
Return ATA->SCSI filter for a SAT or USB 'type'.
Definition: scsiata.cpp:1405
static void init()
Initialize platform interface and register with smi().
Definition: dev_legacy.cpp:334
bool decltype(nullptr) set_err_np(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
virtual smart_device * get_scsi_passthrough_device(const char *type, scsi_device *scsidev)
Return ATA->SCSI of NVMe->SCSI filter for a SAT, SNT or USB 'type'.
virtual ata_device * autodetect_sat_device(scsi_device *scsidev, const unsigned char *inqdata, unsigned inqsize)
Try to detect a SAT device behind a SCSI interface.
Definition: scsiata.cpp:1486
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
std::vector< std::string > smart_devtype_list
List of types for DEVICESCAN.
#define NVME_IOCTL_ID
#define NVME_IOCTL_ADMIN_CMD
#define MFI_CMD_DCMD
Definition: megaraid.h:120
u8 cmd
Definition: megaraid.h:1
u16 flags
Definition: megaraid.h:14
#define u32
Definition: megaraid.h:17
#define MEGA_MBOXCMD_PASSTHRU
Definition: megaraid.h:36
u16 host_no
Definition: megaraid.h:0
mega_passthru pthru
Definition: megaraid.h:14
uint8_t opcode
Definition: megaraid.h:0
u8 lun
Definition: megaraid.h:7
#define MEGAIOCCMD
Definition: megaraid.h:28
#define MFI_FRAME_DIR_WRITE
Definition: megaraid.h:130
#define MEGASAS_IOC_FIRMWARE
Definition: megaraid.h:117
uint32_t inlen
Definition: megaraid.h:0
u8 cdb[16]
Definition: megaraid.h:21
#define MFI_STAT_OK
Definition: megaraid.h:122
#define MFI_FRAME_DIR_NONE
Definition: megaraid.h:129
#define MKADAP(adapno)
Definition: megaraid.h:31
#define MFI_DCMD_PD_GET_LIST
Definition: megaraid.h:123
union megasas_sgl sgl
Definition: megaraid.h:22
#define MAX_REQ_SENSE_LEN
Definition: megaraid.h:38
struct megasas_dcmd_frame dcmd
Definition: megaraid.h:10
ptr_t data
Definition: megaraid.h:15
megacmd_t mbox
Definition: megaraid.h:13
#define MFI_FRAME_DIR_READ
Definition: megaraid.h:131
uint32_t outlen
Definition: megaraid.h:1
#define MFI_CMD_PD_SCSI_IO
Definition: megaraid.h:119
#define u8
Definition: megaraid.h:15
#define MFI_MBOX_SIZE
Definition: megaraid.h:127
static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io *iop, int report, enum lk_sg_io_ifc_t sg_io_ifc)
Definition: os_linux.cpp:515
static int do_normal_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io *iop, int report)
Definition: os_linux.cpp:746
@ SG_IO_UNSUPP
Definition: os_linux.cpp:503
@ SG_IO_USE_DETECT
Definition: os_linux.cpp:502
@ SG_IO_USE_V4
Definition: os_linux.cpp:505
@ SG_IO_USE_V3
Definition: os_linux.cpp:504
static bool get_usb_id(const char *name, unsigned short &vendor_id, unsigned short &product_id, unsigned short &version)
Definition: os_linux.cpp:2772
static unsigned get_kernel_release()
Definition: os_linux.cpp:3359
static bool read_id(const std::string &path, unsigned short &id)
Definition: os_linux.cpp:2760
static int setup_3ware_nodes(const char *nodename, const char *driver_name)
Definition: os_linux.cpp:1602
static const char smartctl_examples[]
Definition: os_linux.cpp:186
static int find_areca_in_proc()
Definition: os_linux.cpp:2037
static bool is_hpsa_in_raid_mode(const char *name)
Definition: os_linux.cpp:3372
static enum lk_sg_io_ifc_t sg_io_interface
Definition: os_linux.cpp:508
uint8_t id
uint32_t nsid
unsigned char nvme_debugmode
Definition: nvmecmds.cpp:27
unsigned char failuretest_permissive
Definition: smartctl.cpp:1457
void printwarning(int msgNo, const char *extra)
Definition: os_freebsd.cpp:89
#define TW_IOCTL_BUFFER_SIZE
Definition: os_freebsd.cpp:118
const char * os_linux_cpp_cvsid
Definition: os_linux.cpp:93
#define LSCSI_DID_ERROR
Definition: os_linux.cpp:494
unsigned char failuretest_permissive
Definition: smartctl.cpp:1457
#define LSCSI_DRIVER_TIMEOUT
Definition: os_linux.cpp:495
#define LSCSI_DID_BUS_BUSY
Definition: os_linux.cpp:497
#define LSCSI_DRIVER_MASK
Definition: os_linux.cpp:492
#define LSCSI_DID_TIME_OUT
Definition: os_linux.cpp:496
#define MAJOR_STRING_LENGTH
Definition: os_linux.cpp:1599
#define LSCSI_DRIVER_SENSE
Definition: os_linux.cpp:493
#define LSCSI_DID_NO_CONNECT
Definition: os_linux.cpp:498
#define ENOTSUP
Definition: os_linux.cpp:88
#define SRB_STATUS_AUTOSENSE_VALID
#define SRB_STATUS_ERROR
#define DEVICE_STRING_LENGTH
Definition: os_linux.cpp:1600
#define SRB_STATUS_SELECTION_TIMEOUT
#define STRANGE_BUFFER_LENGTH
Definition: os_linux.cpp:2385
#define SRB_STATUS_NO_DEVICE
#define SRB_STATUS_SUCCESS
#define BUFFER_LENGTH
Definition: os_linux.cpp:247
#define SCSI_IOCTL_SEND_COMMAND
Definition: os_linux.cpp:1770
#define NODE_STRING_LENGTH
Definition: os_linux.cpp:1601
#define TW_OP_ATA_PASSTHRU
Definition: os_linux.h:40
struct ide_task_request_s ide_task_request_t
#define HPTIO_CTL
Definition: os_linux.h:373
#define OS_LINUX_H_CVSID
Definition: os_linux.h:27
#define TW_ATA_PASSTHRU
Definition: os_linux.h:86
#define TASKFILE_OUT
Definition: os_linux.h:363
#define HDIO_DRIVE_TASKFILE
Definition: os_linux.h:370
#define HDIO_GET_IDENTITY
Definition: os_linux.h:371
#define TW_IOCTL_FIRMWARE_PASS_THROUGH
Definition: os_linux.h:121
#define HDIO_DRIVE_TASK
Definition: os_linux.h:369
#define TW_CMD_PACKET_WITH_DATA
Definition: os_linux.h:228
#define IDE_DRIVE_TASK_OUT
Definition: os_linux.h:367
#define TW_IOCTL
Definition: os_linux.h:85
#define HDIO_DRIVE_CMD
Definition: os_linux.h:368
bool is_scsi_cdb(const uint8_t *cdbp, int clen)
Definition: scsicmds.cpp:391
int scsiStdInquiry(scsi_device *device, uint8_t *pBuf, int bufLen)
Definition: scsicmds.cpp:1163
void dStrHex(const uint8_t *up, int len, int no_ascii)
Definition: scsicmds.cpp:368
unsigned char scsi_debugmode
Definition: scsicmds.cpp:45
const char * scsi_get_opcode_name(const uint8_t *cdbp)
Definition: scsicmds.cpp:511
#define SAT_ATA_PASSTHROUGH_12
Definition: scsicmds.h:101
#define DXFER_NONE
Definition: scsicmds.h:108
#define DXFER_FROM_DEVICE
Definition: scsicmds.h:109
#define SAT_ATA_PASSTHROUGH_16
Definition: scsicmds.h:104
#define DXFER_TO_DEVICE
Definition: scsicmds.h:110
#define SCSI_STATUS_CHECK_CONDITION
Definition: scsicmds.h:320
void pout(const char *fmt,...)
Definition: smartd.cpp:1347
#define DEFAULT_CONMMAND_TIMEOUT_MS
Definition: sssraid.h:25
#define BSG_APPEND_TIMEOUT_MS
Definition: sssraid.h:24
@ ADM_DEVICE_TYPE_SAS
Definition: sssraid.h:36
@ ADM_DEVICE_TYPE_SATA
Definition: sssraid.h:38
@ ADM_DEVICE_TYPE_NVME
Definition: sssraid.h:40
#define ADM_RAID_SET
Definition: sssraid.h:28
#define ADM_RAID_WRITE
Definition: sssraid.h:29
#define ADM_BSG_MSGCODE_SCSI_PTHRU
Definition: sssraid.h:26
#define ADM_CMD_SHOW_PDLIST
Definition: sssraid.h:22
#define ADM_SCSI_CDB_SENSE_MAX_LEN
Definition: sssraid.h:20
#define CMD_PDS_MAX_NUM
Definition: sssraid.h:60
#define CMD_PDLIST_ONCE_NUM
Definition: sssraid.h:61
#define ADM_CMD_SCSI_PASSTHROUGH
Definition: sssraid.h:23
#define ADM_RAID_READ
Definition: sssraid.h:30
#define STATIC_ASSERT(x)
Definition: static_assert.h:24
union TAG_TW_Command_Full_9000::@63 command
TW_Command_9000 oldcommand
Definition: os_linux.h:208
TW_Command_Full_9000 firmware_command
Definition: os_linux.h:217
char data_buffer[1]
Definition: os_linux.h:218
TW_Ioctl_Driver_Command_9000 driver_command
Definition: os_linux.h:215
unsigned char input_data[499]
Definition: os_linux.h:106
unsigned char opcode
Definition: os_linux.h:95
int input_length
Definition: os_linux.h:92
unsigned char cdb[16]
Definition: os_linux.h:94
int output_length
Definition: os_linux.h:93
unsigned int data_buffer_length
Definition: os_linux.h:272
TW_Command firmware_command
Definition: os_linux.h:274
char data_buffer[1]
Definition: os_linux.h:275
char output_data[512]
Definition: os_linux.h:116
unsigned char drive_head
Definition: os_linux.h:74
struct TAG_TW_Passthru::@51 byte0
unsigned char flags
Definition: os_linux.h:67
unsigned char sgloff
Definition: os_linux.h:61
unsigned short cylinder_hi
Definition: os_linux.h:73
unsigned char command
Definition: os_linux.h:75
unsigned short cylinder_lo
Definition: os_linux.h:72
unsigned short features
Definition: os_linux.h:69
unsigned char status
Definition: os_linux.h:66
unsigned char opcode
Definition: os_linux.h:60
unsigned char unit
Definition: os_linux.h:65
unsigned short sector_num
Definition: os_linux.h:71
unsigned short sector_count
Definition: os_linux.h:70
unsigned char size
Definition: os_linux.h:63
unsigned short param
Definition: os_linux.h:68
unsigned char request_id
Definition: os_linux.h:64
uint32_t hi32
Definition: aacraid.h:49
uint32_t lo32
Definition: aacraid.h:48
ATA pass through input parameters.
enum ata_cmd_in::@29 direction
I/O direction.
void * buffer
Pointer to data buffer.
ata_in_regs_48bit in_regs
Input registers.
unsigned size
Size of buffer.
ATA pass through output parameters.
ata_out_regs_48bit out_regs
Output registers.
ATA Input registers for 48-bit commands.
ata_reg_alias_16 lba_high_16
ata_reg_alias_16 sector_count_16
ata_reg_alias_16 features_16
ata_reg_alias_16 lba_low_16
ata_reg_alias_16 lba_mid_16
ata_register device
ata_register lba_low
ata_register features
ata_register command
ATA Output registers for 48-bit commands.
ata_reg_alias_16 lba_mid_16
ata_reg_alias_16 sector_count_16
ata_reg_alias_16 lba_low_16
ata_reg_alias_16 lba_high_16
ata_register error
ata_register device
ata_register status
struct sssraid_passthru_common_cmd ioctl_r64
Definition: sssraid.h:193
struct sssraid_ioq_passthru_cmd ioctl_pthru
Definition: sssraid.h:194
Definition: sssraid.h:51
u16 start_idx
Definition: sssraid.h:46
struct multi_disk_location loc
Definition: sssraid.h:79
struct cmd_pdlist_entry disks[CMD_PDLIST_ONCE_NUM]
Definition: sssraid.h:67
task_ioreg_t sector_number
Definition: os_linux.h:321
task_ioreg_t low_cylinder
Definition: os_linux.h:322
task_ioreg_t feature
Definition: os_linux.h:319
task_ioreg_t high_cylinder
Definition: os_linux.h:323
task_ioreg_t data
Definition: os_linux.h:318
task_ioreg_t command
Definition: os_linux.h:325
task_ioreg_t device_head
Definition: os_linux.h:324
task_ioreg_t sector_count
Definition: os_linux.h:320
unsigned long in_size
Definition: os_linux.h:358
task_ioreg_t io_ports[8]
Definition: os_linux.h:351
unsigned long out_size
Definition: os_linux.h:357
union megasas_dcmd_frame::@38 mbox
union megasas_sgl sgl
Definition: megaraid.h:228
struct megasas_pthru_frame pthru
Definition: megaraid.h:242
struct iovec sgl[MAX_IOCTL_SGE]
Definition: megaraid.h:246
struct megasas_dcmd_frame dcmd
Definition: megaraid.h:243
union megasas_iocpacket::@40 frame
struct megasas_pd_address addr[MAX_SYS_PDS]
Definition: megaraid.h:262
NVMe pass through input parameters.
unsigned cdw10
unsigned cdw13
unsigned cdw11
unsigned char opcode
Opcode (CDW0 07:00)
unsigned size
Size of buffer.
unsigned cdw14
unsigned cdw15
Cmd specific.
unsigned nsid
Namespace ID.
unsigned cdw12
void * buffer
Pointer to data buffer.
NVMe pass through output parameters.
unsigned result
Command specific result (DW0)
uint8_t * sensep
Definition: scsicmds.h:123
uint8_t * dxferp
Definition: scsicmds.h:121
int dxfer_dir
Definition: scsicmds.h:119
size_t cmnd_len
Definition: scsicmds.h:118
size_t resp_sense_len
Definition: scsicmds.h:127
size_t dxfer_len
Definition: scsicmds.h:122
size_t max_sense_len
Definition: scsicmds.h:125
uint8_t scsi_status
Definition: scsicmds.h:128
uint8_t * cmnd
Definition: scsicmds.h:117
unsigned timeout
Definition: scsicmds.h:126
std::string info_name
Informal name.
Definition: dev_interface.h:46
std::string dev_type
Actual device type.
Definition: dev_interface.h:47
struct sssraid_ioq_passthru_cmd::@129::@138 info_1
struct sssraid_ioq_passthru_cmd::@127::@137 info_0
struct sssraid_ioq_passthru_cmd::@133::@140 info_3
struct sssraid_ioq_passthru_cmd::@135::@141 info_4
struct sssraid_passthru_common_cmd::@123::@126 info_1
struct sssraid_passthru_common_cmd::@121::@125 info_0
uint32_t inlen
Definition: megaraid.h:92
mega_passthru pthru
Definition: megaraid.h:106
uint8_t opcode
Definition: megaraid.h:97
uint32_t outlen
Definition: megaraid.h:93
megacmd_t mbox
Definition: megaraid.h:105
ptr_t data
Definition: megaraid.h:107
uint16_t adapno
Definition: megaraid.h:99
uint32_t srb_status
Definition: aacraid.h:141
uint32_t sense_data_size
Definition: aacraid.h:144
uint8_t sense_data[30]
Definition: aacraid.h:145
uint32_t scsi_status
Definition: aacraid.h:142
uint32_t id
Definition: aacraid.h:114
uint8_t cdb[16]
Definition: aacraid.h:121
uint32_t function
Definition: aacraid.h:112
uint32_t cdb_size
Definition: aacraid.h:120
uint32_t timeout
Definition: aacraid.h:116
user_sgmap64 sg64
Definition: aacraid.h:122
uint32_t retry_limit
Definition: aacraid.h:119
uint32_t count
Definition: aacraid.h:118
uint32_t flags
Definition: aacraid.h:117
uint32_t channel
Definition: aacraid.h:113
uint32_t lun
Definition: aacraid.h:115
uint32_t length
Definition: aacraid.h:54
address64 addr64
Definition: aacraid.h:53
user_sgentry64 sg64[1]
Definition: aacraid.h:64
uint32_t count
Definition: aacraid.h:63
struct megasas_sge32 sge32[1]
Definition: megaraid.h:152
uint8_t * pointer
Definition: megaraid.h:77
void syserror(const char *message)
Definition: utility.cpp:409
std::string strprintf(const char *fmt,...)
Definition: utility.cpp:799
bool nonempty(const void *data, int size)
Definition: utility.cpp:682
bool str_starts_with(const char *str, const char *prefix)
Definition: utility.h:52