]> git.proxmox.com Git - mirror_smartmontools-debian.git/blame - os_freebsd.cpp
Imported Upstream version 5.42+svn3561
[mirror_smartmontools-debian.git] / os_freebsd.cpp
CommitLineData
832b75ed
GG
1/*
2 * os_freebsd.c
3 *
4 * Home page of code is: http://smartmontools.sourceforge.net
5 *
a23d5117 6 * Copyright (C) 2003-10 Eduard Martinescu <smartmontools-support@lists.sourceforge.net>
832b75ed
GG
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * You should have received a copy of the GNU General Public License
14 * (for example COPYING); if not, write to the Free
15 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16 */
17
18#include <stdio.h>
19#include <sys/types.h>
20#include <dirent.h>
21#include <fcntl.h>
22#include <err.h>
cfbba5b9 23#include <errno.h>
832b75ed
GG
24#include <camlib.h>
25#include <cam/scsi/scsi_message.h>
2127e193 26#include <cam/scsi/scsi_pass.h>
1953ff6d
GG
27#if defined(__DragonFly__)
28#include <sys/nata.h>
29#else
832b75ed 30#include <sys/ata.h>
1953ff6d 31#endif
832b75ed
GG
32#include <sys/stat.h>
33#include <unistd.h>
832b75ed 34#include <glob.h>
832b75ed 35#include <stddef.h>
2127e193
GI
36#include <paths.h>
37#include <sys/utsname.h>
832b75ed
GG
38
39#include "config.h"
40#include "int64.h"
41#include "atacmds.h"
42#include "scsicmds.h"
a37e7145 43#include "cciss.h"
832b75ed
GG
44#include "utility.h"
45#include "os_freebsd.h"
46
2127e193
GI
47#include "dev_interface.h"
48#include "dev_ata_cmd_set.h"
49
50#define USBDEV "/dev/usb"
54965743
GI
51#if defined(__FreeBSD_version)
52
53// This way we define one variable for the GNU/kFreeBSD and FreeBSD
54#define FREEBSDVER __FreeBSD_version
55#else
56#define FREEBSDVER __FreeBSD_kernel_version
57#endif
58
59#if (FREEBSDVER >= 800000)
60#include <libusb20_desc.h>
61#include <libusb20.h>
cfbba5b9
GI
62#elif defined(__DragonFly__)
63#include <bus/usb/usb.h>
64#include <bus/usb/usbhid.h>
54965743
GI
65#else
66#include <dev/usb/usb.h>
67#include <dev/usb/usbhid.h>
68#endif
832b75ed 69
eb07ddf2
GI
70#define CONTROLLER_3WARE_9000_CHAR 0x01
71#define CONTROLLER_3WARE_678K_CHAR 0x02
a37e7145 72
eb07ddf2
GI
73#ifndef PATHINQ_SETTINGS_SIZE
74#define PATHINQ_SETTINGS_SIZE 128
75#endif
832b75ed 76
f4e463df 77const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp 3542 2012-05-18 18:18:45Z samm2 $" \
eb07ddf2 78ATACMDS_H_CVSID CCISS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_FREEBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
54965743 79
832b75ed
GG
80#define NO_RETURN 0
81#define BAD_SMART 1
82#define NO_DISK_3WARE 2
83#define BAD_KERNEL 3
84#define MAX_MSG 3
85
86// Utility function for printing warnings
87void printwarning(int msgNo, const char* extra) {
88 static int printed[] = {0,0,0,0};
89 static const char* message[]={
90 "The SMART RETURN STATUS return value (smartmontools -H option/Directive)\n can not be retrieved with this version of ATAng, please do not rely on this value\nYou should update to at least 5.2\n",
54965743 91
832b75ed 92 "Error SMART Status command failed\nPlease get assistance from \n" PACKAGE_HOMEPAGE "\nRegister values returned from SMART Status command are:\n",
54965743 93
832b75ed 94 "You must specify a DISK # for 3ware drives with -d 3ware,<n> where <n> begins with 1 for first disk drive\n",
54965743 95
832b75ed
GG
96 "ATA support is not provided for this kernel version. Please ugrade to a recent 5-CURRENT kernel (post 09/01/2003 or so)\n"
97 };
98
99 if (msgNo >= 0 && msgNo <= MAX_MSG) {
100 if (!printed[msgNo]) {
101 printed[msgNo] = 1;
102 pout("%s", message[msgNo]);
103 if (extra)
104 pout("%s",extra);
105 }
106 }
107 return;
108}
109
2127e193 110// Interface to ATA devices behind 3ware escalade RAID controller cards. See os_linux.c
832b75ed 111
2127e193
GI
112#define BUFFER_LEN_678K_CHAR ( sizeof(struct twe_usercommand) ) // 520
113#define BUFFER_LEN_9000_CHAR ( sizeof(TW_OSLI_IOCTL_NO_DATA_BUF) + sizeof(TWE_Command) ) // 2048
114#define TW_IOCTL_BUFFER_SIZE ( MAX(BUFFER_LEN_678K_CHAR, BUFFER_LEN_9000_CHAR) )
4d59bff9 115
2127e193
GI
116#ifndef ATA_DEVICE
117#define ATA_DEVICE "/dev/ata"
832b75ed 118#endif
832b75ed 119
d008864d
GI
120#define ARGUSED(x) ((void)(x))
121
2127e193
GI
122// global variable holding byte count of allocated memory
123long long bytes;
832b75ed 124
2127e193 125/////////////////////////////////////////////////////////////////////////////
832b75ed 126
2127e193 127namespace os_freebsd { // No need to publish anything, name provided for Doxygen
832b75ed 128
2127e193
GI
129/////////////////////////////////////////////////////////////////////////////
130/// Implement shared open/close routines with old functions.
832b75ed 131
2127e193
GI
132class freebsd_smart_device
133: virtual public /*implements*/ smart_device
134{
135public:
136 explicit freebsd_smart_device(const char * mode)
137 : smart_device(never_called),
138 m_fd(-1), m_mode(mode) { }
832b75ed 139
2127e193 140 virtual ~freebsd_smart_device() throw();
832b75ed 141
2127e193 142 virtual bool is_open() const;
832b75ed 143
2127e193 144 virtual bool open();
832b75ed 145
2127e193 146 virtual bool close();
832b75ed 147
2127e193
GI
148protected:
149 /// Return filedesc for derived classes.
150 int get_fd() const
151 { return m_fd; }
832b75ed 152
eb07ddf2
GI
153 void set_fd(int fd)
154 { m_fd = fd; }
155
2127e193
GI
156private:
157 int m_fd; ///< filedesc, -1 if not open.
158 const char * m_mode; ///< Mode string for deviceopen().
159};
832b75ed 160
54965743
GI
161#ifdef __GLIBC__
162static inline void * reallocf(void *ptr, size_t size) {
163 void *rv = realloc(ptr, size);
f4ebf3d1 164 if((rv == NULL) && (size != 0))
54965743
GI
165 free(ptr);
166 return rv;
167 }
168#endif
2127e193
GI
169
170freebsd_smart_device::~freebsd_smart_device() throw()
a37e7145 171{
2127e193
GI
172 if (m_fd >= 0)
173 os_freebsd::freebsd_smart_device::close();
a37e7145
GG
174}
175
2127e193
GI
176// migration from the old_style
177unsigned char m_controller_type;
178unsigned char m_controller_port;
832b75ed 179
2127e193
GI
180// examples for smartctl
181static const char smartctl_examples[] =
54965743 182 "=================================================== SMARTCTL EXAMPLES =====\n\n"
2127e193
GI
183 " smartctl -a /dev/ad0 (Prints all SMART information)\n\n"
184 " smartctl --smart=on --offlineauto=on --saveauto=on /dev/ad0\n"
185 " (Enables SMART on first disk)\n\n"
186 " smartctl -t long /dev/ad0 (Executes extended disk self-test)\n\n"
187 " smartctl --attributes --log=selftest --quietmode=errorsonly /dev/ad0\n"
188 " (Prints Self-Test & Attribute errors)\n"
189 " (Prints Self-Test & Attribute errors)\n\n"
190 " smartctl -a --device=3ware,2 /dev/twa0\n"
191 " smartctl -a --device=3ware,2 /dev/twe0\n"
192 " (Prints all SMART information for ATA disk on\n"
193 " third port of first 3ware RAID controller)\n"
54965743
GI
194 " smartctl -a --device=cciss,0 /dev/ciss0\n"
195 " (Prints all SMART information for first disk \n"
196 " on Common Interface for SCSI-3 Support driver)\n"
f4e463df
GI
197 " smartctl -a --device=areca,3/1 /dev/arcmsr0\n"
198 " (Prints all SMART information for 3rd disk in the 1st enclosure \n"
d008864d 199 " on first ARECA RAID controller)\n"
54965743 200
2127e193 201 ;
832b75ed 202
2127e193
GI
203bool freebsd_smart_device::is_open() const
204{
205 return (m_fd >= 0);
206}
832b75ed 207
832b75ed 208
2127e193
GI
209bool freebsd_smart_device::open()
210{
2127e193 211 const char *dev = get_dev_name();
eb07ddf2
GI
212 if ((m_fd = ::open(dev,O_RDONLY))<0) {
213 set_err(errno);
2127e193
GI
214 return false;
215 }
216 return true;
217}
218
219bool freebsd_smart_device::close()
220{
2127e193 221 int failed = 0;
2127e193 222 // close device, if open
eb07ddf2
GI
223 if (is_open())
224 failed=::close(get_fd());
225
226 set_fd(-1);
54965743 227
54965743 228 if(failed) return false;
eb07ddf2 229 else return true;
2127e193
GI
230}
231
232/////////////////////////////////////////////////////////////////////////////
a23d5117 233/// Implement standard ATA support
2127e193
GI
234
235class freebsd_ata_device
a23d5117 236: public /*implements*/ ata_device,
2127e193
GI
237 public /*extends*/ freebsd_smart_device
238{
239public:
240 freebsd_ata_device(smart_interface * intf, const char * dev_name, const char * req_type);
a23d5117 241 virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
2127e193 242
2127e193 243protected:
d008864d 244 virtual int do_cmd(struct ata_ioc_request* request, bool is_48bit_cmd);
2127e193
GI
245};
246
247freebsd_ata_device::freebsd_ata_device(smart_interface * intf, const char * dev_name, const char * req_type)
248: smart_device(intf, dev_name, "ata", req_type),
249 freebsd_smart_device("ATA")
250{
251}
252
d008864d 253int freebsd_ata_device::do_cmd( struct ata_ioc_request* request, bool is_48bit_cmd)
eb07ddf2
GI
254{
255 int fd = get_fd();
d008864d 256 ARGUSED(is_48bit_cmd); // no support for 48 bit commands in the IOCATAREQUEST
eb07ddf2
GI
257 return ioctl(fd, IOCATAREQUEST, request);
258}
259
a23d5117
GI
260
261
262bool freebsd_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
263{
d008864d
GI
264 bool ata_48bit = false; // no ata_48bit_support via IOCATAREQUEST
265 if(!strcmp("atacam",get_dev_type())) // enable for atacam interface
266 ata_48bit = true;
267
7f0798ef
GI
268 if (!ata_cmd_is_ok(in,
269 true, // data_out_support
270 true, // multi_sector_support
d008864d 271 ata_48bit)
7f0798ef 272 )
a23d5117
GI
273 return false;
274
275 struct ata_ioc_request request;
276 bzero(&request,sizeof(struct ata_ioc_request));
277
278 request.timeout=SCSI_TIMEOUT_DEFAULT;
279 request.u.ata.command=in.in_regs.command;
280 request.u.ata.feature=in.in_regs.features;
281
282 request.u.ata.count = in.in_regs.sector_count_16;
283 request.u.ata.lba = in.in_regs.lba_48;
284
285 switch (in.direction) {
286 case ata_cmd_in::no_data:
287 request.flags=ATA_CMD_CONTROL;
288 break;
289 case ata_cmd_in::data_in:
d008864d 290 request.flags=ATA_CMD_READ | ATA_CMD_CONTROL;
a23d5117
GI
291 request.data=(char *)in.buffer;
292 request.count=in.size;
293 break;
294 case ata_cmd_in::data_out:
d008864d 295 request.flags=ATA_CMD_WRITE | ATA_CMD_CONTROL;
a23d5117
GI
296 request.data=(char *)in.buffer;
297 request.count=in.size;
298 break;
299 default:
300 return set_err(ENOSYS);
301 }
d008864d
GI
302
303 clear_err();
a23d5117 304 errno = 0;
d008864d 305 if (do_cmd(&request, in.in_regs.is_48bit_cmd()))
a23d5117
GI
306 return set_err(errno);
307 if (request.error)
308 return set_err(EIO, "request failed, error code 0x%02x", request.error);
309
310 out.out_regs.error = request.error;
311 out.out_regs.sector_count_16 = request.u.ata.count;
312 out.out_regs.lba_48 = request.u.ata.lba;
313
314
315 // Command specific processing
316 if (in.in_regs.command == ATA_SMART_CMD
317 && in.in_regs.features == ATA_SMART_STATUS
318 && in.out_needed.lba_high)
319 {
320 unsigned const char normal_lo=0x4f, normal_hi=0xc2;
321 unsigned const char failed_lo=0xf4, failed_hi=0x2c;
322
a23d5117
GI
323 // Cyl low and Cyl high unchanged means "Good SMART status"
324 if (!(out.out_regs.lba_mid==normal_lo && out.out_regs.lba_high==normal_hi)
325 // These values mean "Bad SMART status"
326 && !(out.out_regs.lba_mid==failed_lo && out.out_regs.lba_high==failed_hi))
327
328 {
329 // We haven't gotten output that makes sense; print out some debugging info
330 char buf[512];
331 sprintf(buf,"CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
332 (int)request.u.ata.command,
333 (int)request.u.ata.feature,
334 (int)request.u.ata.count,
335 (int)((request.u.ata.lba) & 0xff),
336 (int)((request.u.ata.lba>>8) & 0xff),
337 (int)((request.u.ata.lba>>16) & 0xff),
338 (int)request.error);
339 printwarning(BAD_SMART,buf);
340 out.out_regs.lba_high = failed_hi;
341 out.out_regs.lba_mid = failed_lo;
342 }
343 }
344
345 return true;
346}
347
eb07ddf2
GI
348#if FREEBSDVER > 800100
349class freebsd_atacam_device : public freebsd_ata_device
350{
351public:
352 freebsd_atacam_device(smart_interface * intf, const char * dev_name, const char * req_type)
353 : smart_device(intf, dev_name, "atacam", req_type), freebsd_ata_device(intf, dev_name, req_type)
354 {}
355
356 virtual bool open();
357 virtual bool close();
358
359protected:
360 int m_fd;
361 struct cam_device *m_camdev;
362
d008864d 363 virtual int do_cmd( struct ata_ioc_request* request , bool is_48bit_cmd);
eb07ddf2
GI
364};
365
366bool freebsd_atacam_device::open(){
367 const char *dev = get_dev_name();
368
369 if ((m_camdev = cam_open_device(dev, O_RDWR)) == NULL) {
370 set_err(errno);
371 return false;
372 }
373 set_fd(m_camdev->fd);
374 return true;
375}
376
377bool freebsd_atacam_device::close(){
378 cam_close_device(m_camdev);
379 set_fd(-1);
380 return true;
381}
382
d008864d 383int freebsd_atacam_device::do_cmd( struct ata_ioc_request* request, bool is_48bit_cmd)
eb07ddf2
GI
384{
385 union ccb ccb;
386 int camflags;
387
388 memset(&ccb, 0, sizeof(ccb));
389
390 if (request->count == 0)
391 camflags = CAM_DIR_NONE;
d008864d 392 else if (request->flags & ATA_CMD_READ)
eb07ddf2
GI
393 camflags = CAM_DIR_IN;
394 else
395 camflags = CAM_DIR_OUT;
d008864d
GI
396 if(is_48bit_cmd)
397 camflags |= CAM_ATAIO_48BIT;
eb07ddf2
GI
398
399 cam_fill_ataio(&ccb.ataio,
400 0,
401 NULL,
402 camflags,
403 MSG_SIMPLE_Q_TAG,
404 (u_int8_t*)request->data,
405 request->count,
406 request->timeout * 1000); // timeout in seconds
407
d008864d 408 ccb.ataio.cmd.flags = CAM_ATAIO_NEEDRESULT;
eb07ddf2 409 // ata_28bit_cmd
eb07ddf2
GI
410 ccb.ataio.cmd.command = request->u.ata.command;
411 ccb.ataio.cmd.features = request->u.ata.feature;
412 ccb.ataio.cmd.lba_low = request->u.ata.lba;
413 ccb.ataio.cmd.lba_mid = request->u.ata.lba >> 8;
414 ccb.ataio.cmd.lba_high = request->u.ata.lba >> 16;
d008864d
GI
415 // ata_48bit cmd
416 ccb.ataio.cmd.lba_low_exp = request->u.ata.lba >> 24;
417 ccb.ataio.cmd.lba_mid_exp = request->u.ata.lba >> 32;
418 ccb.ataio.cmd.lba_high_exp = request->u.ata.lba >> 40;
eb07ddf2
GI
419 ccb.ataio.cmd.device = 0x40 | ((request->u.ata.lba >> 24) & 0x0f);
420 ccb.ataio.cmd.sector_count = request->u.ata.count;
d008864d 421 ccb.ataio.cmd.sector_count_exp = request->u.ata.count >> 8;;
eb07ddf2
GI
422
423 ccb.ccb_h.flags |= CAM_DEV_QFRZDIS;
424
425 if (cam_send_ccb(m_camdev, &ccb) < 0) {
426 err(1, "cam_send_ccb");
427 return -1;
428 }
429
cfbba5b9
GI
430 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
431 cam_error_print(m_camdev, &ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
432 return -1;
433 }
eb07ddf2 434
d008864d
GI
435 request->u.ata.lba =
436 ((u_int64_t)(ccb.ataio.res.lba_low)) |
437 ((u_int64_t)(ccb.ataio.res.lba_mid) << 8) |
438 ((u_int64_t)(ccb.ataio.res.lba_high) << 16) |
439 ((u_int64_t)(ccb.ataio.res.lba_low_exp) << 24) |
440 ((u_int64_t)(ccb.ataio.res.lba_mid_exp) << 32) |
441 ((u_int64_t)(ccb.ataio.res.lba_high_exp) << 40);
442
443 request->u.ata.count = ccb.ataio.res.sector_count | (ccb.ataio.res.sector_count_exp << 8);
444 request->error = ccb.ataio.res.error;
445
cfbba5b9 446 return 0;
eb07ddf2
GI
447}
448
449#endif
450
2127e193
GI
451/////////////////////////////////////////////////////////////////////////////
452/// Implement AMCC/3ware RAID support with old functions
453
454class freebsd_escalade_device
455: public /*implements*/ ata_device_with_command_set,
456 public /*extends*/ freebsd_smart_device
457{
458public:
459 freebsd_escalade_device(smart_interface * intf, const char * dev_name,
460 int escalade_type, int disknum);
461
462protected:
463 virtual int ata_command_interface(smart_command_set command, int select, char * data);
eb07ddf2 464 virtual bool open();
2127e193
GI
465
466private:
467 int m_escalade_type; ///< Type string for escalade_command_interface().
468 int m_disknum; ///< Disk number.
469};
470
471freebsd_escalade_device::freebsd_escalade_device(smart_interface * intf, const char * dev_name,
472 int escalade_type, int disknum)
473: smart_device(intf, dev_name, "3ware", "3ware"),
474 freebsd_smart_device(
475 escalade_type==CONTROLLER_3WARE_9000_CHAR ? "ATA_3WARE_9000" :
476 escalade_type==CONTROLLER_3WARE_678K_CHAR ? "ATA_3WARE_678K" :
477 /* CONTROLLER_3WARE_678K */ "ATA" ),
478 m_escalade_type(escalade_type), m_disknum(disknum)
479{
480 set_info().info_name = strprintf("%s [3ware_disk_%02d]", dev_name, disknum);
481}
482
eb07ddf2
GI
483bool freebsd_escalade_device::open()
484{
485 const char *dev = get_dev_name();
486 int fd;
487
488 if ((fd = ::open(dev,O_RDWR))<0) {
489 set_err(errno);
490 return false;
491 }
492 set_fd(fd);
493 return true;
494}
495
2127e193
GI
496int freebsd_escalade_device::ata_command_interface(smart_command_set command, int select, char * data)
497{
54965743
GI
498 // to hold true file descriptor
499 int fd = get_fd();
2127e193
GI
500
501 // return value and buffer for ioctl()
502 int ioctlreturn, readdata=0;
503 struct twe_usercommand* cmd_twe = NULL;
504 TW_OSLI_IOCTL_NO_DATA_BUF* cmd_twa = NULL;
505 TWE_Command_ATA* ata = NULL;
506
507 // Used by both the SCSI and char interfaces
508 char ioctl_buffer[TW_IOCTL_BUFFER_SIZE];
509
510 if (m_disknum < 0) {
511 printwarning(NO_DISK_3WARE,NULL);
512 return -1;
513 }
514
2127e193
GI
515 memset(ioctl_buffer, 0, TW_IOCTL_BUFFER_SIZE);
516
517 if (m_escalade_type==CONTROLLER_3WARE_9000_CHAR) {
518 cmd_twa = (TW_OSLI_IOCTL_NO_DATA_BUF*)ioctl_buffer;
519 cmd_twa->pdata = ((TW_OSLI_IOCTL_WITH_PAYLOAD*)cmd_twa)->payload.data_buf;
520 cmd_twa->driver_pkt.buffer_length = 512;
521 ata = (TWE_Command_ATA*)&cmd_twa->cmd_pkt.command.cmd_pkt_7k;
522 } else if (m_escalade_type==CONTROLLER_3WARE_678K_CHAR) {
523 cmd_twe = (struct twe_usercommand*)ioctl_buffer;
524 ata = &cmd_twe->tu_command.ata;
525 } else {
526 pout("Unrecognized escalade_type %d in freebsd_3ware_command_interface(disk %d)\n"
54965743 527 "Please contact " PACKAGE_BUGREPORT "\n", m_escalade_type, m_disknum);
2127e193
GI
528 errno=ENOSYS;
529 return -1;
530 }
531
532 ata->opcode = TWE_OP_ATA_PASSTHROUGH;
533
534 // Same for (almost) all commands - but some reset below
535 ata->request_id = 0xFF;
536 ata->unit = m_disknum;
537 ata->status = 0;
538 ata->flags = 0x1;
539 ata->drive_head = 0x0;
540 ata->sector_num = 0;
541
542 // All SMART commands use this CL/CH signature. These are magic
543 // values from the ATA specifications.
544 ata->cylinder_lo = 0x4F;
545 ata->cylinder_hi = 0xC2;
54965743 546
2127e193
GI
547 // SMART ATA COMMAND REGISTER value
548 ata->command = ATA_SMART_CMD;
54965743 549
2127e193
GI
550 // Is this a command that reads or returns 512 bytes?
551 // passthru->param values are:
552 // 0x0 - non data command without TFR write check,
553 // 0x8 - non data command with TFR write check,
554 // 0xD - data command that returns data to host from device
555 // 0xF - data command that writes data from host to device
556 // passthru->size values are 0x5 for non-data and 0x07 for data
557 if (command == READ_VALUES ||
558 command == READ_THRESHOLDS ||
559 command == READ_LOG ||
560 command == IDENTIFY ||
54965743
GI
561 command == WRITE_LOG )
562 {
2127e193
GI
563 readdata=1;
564 if (m_escalade_type==CONTROLLER_3WARE_678K_CHAR) {
565 cmd_twe->tu_data = data;
566 cmd_twe->tu_size = 512;
567 }
568 ata->sgl_offset = 0x5;
569 ata->size = 0x5;
570 ata->param = 0xD;
571 ata->sector_count = 0x1;
572 // For 64-bit to work correctly, up the size of the command packet
573 // in dwords by 1 to account for the 64-bit single sgl 'address'
574 // field. Note that this doesn't agree with the typedefs but it's
575 // right (agree with kernel driver behavior/typedefs).
576 //if (sizeof(long)==8)
577 // ata->size++;
578 }
579 else {
580 // Non data command -- but doesn't use large sector
581 // count register values.
582 ata->sgl_offset = 0x0;
583 ata->size = 0x5;
584 ata->param = 0x8;
585 ata->sector_count = 0x0;
586 }
54965743 587
2127e193
GI
588 // Now set ATA registers depending upon command
589 switch (command){
590 case CHECK_POWER_MODE:
591 ata->command = ATA_CHECK_POWER_MODE;
592 ata->features = 0;
593 ata->cylinder_lo = 0;
594 ata->cylinder_hi = 0;
595 break;
596 case READ_VALUES:
597 ata->features = ATA_SMART_READ_VALUES;
598 break;
599 case READ_THRESHOLDS:
600 ata->features = ATA_SMART_READ_THRESHOLDS;
601 break;
602 case READ_LOG:
603 ata->features = ATA_SMART_READ_LOG_SECTOR;
604 // log number to return
605 ata->sector_num = select;
606 break;
607 case WRITE_LOG:
608 readdata=0;
609 ata->features = ATA_SMART_WRITE_LOG_SECTOR;
610 ata->sector_count = 1;
611 ata->sector_num = select;
612 ata->param = 0xF; // PIO data write
613 break;
614 case IDENTIFY:
615 // ATA IDENTIFY DEVICE
616 ata->command = ATA_IDENTIFY_DEVICE;
617 ata->features = 0;
618 ata->cylinder_lo = 0;
619 ata->cylinder_hi = 0;
620 break;
621 case PIDENTIFY:
622 // 3WARE controller can NOT have packet device internally
623 pout("WARNING - NO DEVICE FOUND ON 3WARE CONTROLLER (disk %d)\n", m_disknum);
624 errno=ENODEV;
625 return -1;
626 case ENABLE:
627 ata->features = ATA_SMART_ENABLE;
628 break;
629 case DISABLE:
630 ata->features = ATA_SMART_DISABLE;
631 break;
632 case AUTO_OFFLINE:
633 ata->features = ATA_SMART_AUTO_OFFLINE;
634 // Enable or disable?
635 ata->sector_count = select;
636 break;
637 case AUTOSAVE:
638 ata->features = ATA_SMART_AUTOSAVE;
639 // Enable or disable?
640 ata->sector_count = select;
641 break;
642 case IMMEDIATE_OFFLINE:
643 ata->features = ATA_SMART_IMMEDIATE_OFFLINE;
644 // What test type to run?
645 ata->sector_num = select;
646 break;
647 case STATUS_CHECK:
648 ata->features = ATA_SMART_STATUS;
649 break;
650 case STATUS:
651 // This is JUST to see if SMART is enabled, by giving SMART status
652 // command. But it doesn't say if status was good, or failing.
653 // See below for the difference.
654 ata->features = ATA_SMART_STATUS;
655 break;
656 default:
657 pout("Unrecognized command %d in freebsd_3ware_command_interface(disk %d)\n"
658 "Please contact " PACKAGE_BUGREPORT "\n", command, m_disknum);
659 errno=ENOSYS;
660 return -1;
661 }
662
663 // Now send the command down through an ioctl()
664 if (m_escalade_type==CONTROLLER_3WARE_9000_CHAR) {
eb07ddf2 665 ioctlreturn=ioctl(fd,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH,cmd_twa);
2127e193 666 } else {
eb07ddf2 667 ioctlreturn=ioctl(fd,TWEIO_COMMAND,cmd_twe);
2127e193
GI
668 }
669
670 // Deal with the different error cases
671 if (ioctlreturn) {
672 if (!errno)
673 errno=EIO;
674 return -1;
675 }
54965743 676
2127e193
GI
677 // See if the ATA command failed. Now that we have returned from
678 // the ioctl() call, if passthru is valid, then:
679 // - ata->status contains the 3ware controller STATUS
680 // - ata->command contains the ATA STATUS register
681 // - ata->features contains the ATA ERROR register
682 //
683 // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS
684 // If bit 0 (error bit) is set, then ATA ERROR register is valid.
685 // While we *might* decode the ATA ERROR register, at the moment it
686 // doesn't make much sense: we don't care in detail why the error
687 // happened.
54965743 688
2127e193
GI
689 if (ata->status || (ata->command & 0x21)) {
690 pout("Command failed, ata.status=(0x%2.2x), ata.command=(0x%2.2x), ata.flags=(0x%2.2x)\n",ata->status,ata->command,ata->flags);
691 errno=EIO;
692 return -1;
693 }
54965743 694
2127e193
GI
695 // If this is a read data command, copy data to output buffer
696 if (readdata) {
697 if (m_escalade_type==CONTROLLER_3WARE_9000_CHAR)
698 memcpy(data, cmd_twa->pdata, 512);
699 }
700
701 // For STATUS_CHECK, we need to check register values
702 if (command==STATUS_CHECK) {
54965743 703
2127e193
GI
704 // To find out if the SMART RETURN STATUS is good or failing, we
705 // need to examine the values of the Cylinder Low and Cylinder
706 // High Registers.
54965743 707
2127e193
GI
708 unsigned short cyl_lo=ata->cylinder_lo;
709 unsigned short cyl_hi=ata->cylinder_hi;
54965743 710
2127e193
GI
711 // If values in Cyl-LO and Cyl-HI are unchanged, SMART status is good.
712 if (cyl_lo==0x4F && cyl_hi==0xC2)
713 return 0;
54965743 714
2127e193
GI
715 // If values in Cyl-LO and Cyl-HI are as follows, SMART status is FAIL
716 if (cyl_lo==0xF4 && cyl_hi==0x2C)
717 return 1;
54965743 718
2127e193
GI
719 errno=EIO;
720 return -1;
721 }
54965743 722
2127e193
GI
723 // copy sector count register (one byte!) to return data
724 if (command==CHECK_POWER_MODE)
725 *data=*(char *)&(ata->sector_count);
54965743 726
2127e193 727 // look for nonexistent devices/ports
a23d5117 728 if (command==IDENTIFY && !nonempty(data, 512)) {
2127e193
GI
729 errno=ENODEV;
730 return -1;
731 }
54965743 732
2127e193
GI
733 return 0;
734}
735
736
737/////////////////////////////////////////////////////////////////////////////
738/// Implement Highpoint RAID support with old functions
739
740class freebsd_highpoint_device
741: public /*implements*/ ata_device_with_command_set,
742 public /*extends*/ freebsd_smart_device
743{
744public:
745 freebsd_highpoint_device(smart_interface * intf, const char * dev_name,
746 unsigned char controller, unsigned char channel, unsigned char port);
747
748protected:
749 virtual int ata_command_interface(smart_command_set command, int select, char * data);
eb07ddf2 750 virtual bool open();
2127e193
GI
751
752private:
753 unsigned char m_hpt_data[3]; ///< controller/channel/port
754};
755
756
757freebsd_highpoint_device::freebsd_highpoint_device(smart_interface * intf, const char * dev_name,
758 unsigned char controller, unsigned char channel, unsigned char port)
759: smart_device(intf, dev_name, "hpt", "hpt"),
760 freebsd_smart_device("ATA")
761{
762 m_hpt_data[0] = controller; m_hpt_data[1] = channel; m_hpt_data[2] = port;
763 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]);
764}
765
eb07ddf2
GI
766bool freebsd_highpoint_device::open()
767{
768 const char *dev = get_dev_name();
769 int fd;
770
771 if ((fd = ::open(dev,O_RDWR))<0) {
772 set_err(errno);
773 return false;
774 }
775 set_fd(fd);
776 return true;
777}
778
2127e193
GI
779int freebsd_highpoint_device::ata_command_interface(smart_command_set command, int select, char * data)
780{
54965743 781 int fd=get_fd();
2127e193 782 int ids[2];
2127e193
GI
783 HPT_IOCTL_PARAM param;
784 HPT_CHANNEL_INFO_V2 info;
785 unsigned char* buff[512 + 2 * sizeof(HPT_PASS_THROUGH_HEADER)];
786 PHPT_PASS_THROUGH_HEADER pide_pt_hdr, pide_pt_hdr_out;
787
2127e193
GI
788 // get internal deviceid
789 ids[0] = m_hpt_data[0] - 1;
790 ids[1] = m_hpt_data[1] - 1;
791
792 memset(&param, 0, sizeof(HPT_IOCTL_PARAM));
793
794 param.magic = HPT_IOCTL_MAGIC;
795 param.ctrl_code = HPT_IOCTL_GET_CHANNEL_INFO_V2;
796 param.in = (unsigned char *)ids;
797 param.in_size = sizeof(unsigned int) * 2;
798 param.out = (unsigned char *)&info;
799 param.out_size = sizeof(HPT_CHANNEL_INFO_V2);
800
801 if (m_hpt_data[2]==1) {
802 param.ctrl_code = HPT_IOCTL_GET_CHANNEL_INFO;
803 param.out_size = sizeof(HPT_CHANNEL_INFO);
804 }
eb07ddf2 805 if (ioctl(fd, HPT_DO_IOCONTROL, &param)!=0 ||
2127e193
GI
806 info.devices[m_hpt_data[2]-1]==0) {
807 return -1;
808 }
809
810 // perform smart action
811 memset(buff, 0, 512 + 2 * sizeof(HPT_PASS_THROUGH_HEADER));
812 pide_pt_hdr = (PHPT_PASS_THROUGH_HEADER)buff;
813
814 pide_pt_hdr->lbamid = 0x4f;
815 pide_pt_hdr->lbahigh = 0xc2;
816 pide_pt_hdr->command = ATA_SMART_CMD;
817 pide_pt_hdr->id = info.devices[m_hpt_data[2] - 1];
818
819 switch (command){
820 case READ_VALUES:
821 pide_pt_hdr->feature=ATA_SMART_READ_VALUES;
822 pide_pt_hdr->protocol=HPT_READ;
823 break;
824 case READ_THRESHOLDS:
825 pide_pt_hdr->feature=ATA_SMART_READ_THRESHOLDS;
826 pide_pt_hdr->protocol=HPT_READ;
827 break;
828 case READ_LOG:
829 pide_pt_hdr->feature=ATA_SMART_READ_LOG_SECTOR;
830 pide_pt_hdr->lbalow=select;
831 pide_pt_hdr->protocol=HPT_READ;
832 break;
833 case IDENTIFY:
834 pide_pt_hdr->command=ATA_IDENTIFY_DEVICE;
835 pide_pt_hdr->protocol=HPT_READ;
836 break;
837 case ENABLE:
838 pide_pt_hdr->feature=ATA_SMART_ENABLE;
839 break;
840 case DISABLE:
841 pide_pt_hdr->feature=ATA_SMART_DISABLE;
842 break;
843 case AUTO_OFFLINE:
844 pide_pt_hdr->feature=ATA_SMART_AUTO_OFFLINE;
845 pide_pt_hdr->sectorcount=select;
846 break;
847 case AUTOSAVE:
848 pide_pt_hdr->feature=ATA_SMART_AUTOSAVE;
849 pide_pt_hdr->sectorcount=select;
850 break;
851 case IMMEDIATE_OFFLINE:
852 pide_pt_hdr->feature=ATA_SMART_IMMEDIATE_OFFLINE;
853 pide_pt_hdr->lbalow=select;
854 break;
855 case STATUS_CHECK:
856 case STATUS:
857 pide_pt_hdr->feature=ATA_SMART_STATUS;
858 break;
859 case CHECK_POWER_MODE:
860 pide_pt_hdr->command=ATA_CHECK_POWER_MODE;
861 break;
862 case WRITE_LOG:
863 memcpy(buff+sizeof(HPT_PASS_THROUGH_HEADER), data, 512);
864 pide_pt_hdr->feature=ATA_SMART_WRITE_LOG_SECTOR;
865 pide_pt_hdr->lbalow=select;
866 pide_pt_hdr->protocol=HPT_WRITE;
867 break;
868 default:
869 pout("Unrecognized command %d in highpoint_command_interface()\n"
870 "Please contact " PACKAGE_BUGREPORT "\n", command);
871 errno=ENOSYS;
872 return -1;
873 }
874 if (pide_pt_hdr->protocol!=0) {
875 pide_pt_hdr->sectors = 1;
876 pide_pt_hdr->sectorcount = 1;
877 }
878
879 memset(&param, 0, sizeof(HPT_IOCTL_PARAM));
880
881 param.magic = HPT_IOCTL_MAGIC;
882 param.ctrl_code = HPT_IOCTL_IDE_PASS_THROUGH;
883 param.in = (unsigned char *)buff;
884 param.in_size = sizeof(HPT_PASS_THROUGH_HEADER) + (pide_pt_hdr->protocol==HPT_READ ? 0 : pide_pt_hdr->sectors * 512);
885 param.out = (unsigned char *)buff+param.in_size;
886 param.out_size = sizeof(HPT_PASS_THROUGH_HEADER) + (pide_pt_hdr->protocol==HPT_READ ? pide_pt_hdr->sectors * 512 : 0);
887
888 pide_pt_hdr_out = (PHPT_PASS_THROUGH_HEADER)param.out;
889
eb07ddf2 890 if ((ioctl(fd, HPT_DO_IOCONTROL, &param)!=0) ||
2127e193
GI
891 (pide_pt_hdr_out->command & 1)) {
892 return -1;
893 }
894
54965743
GI
895 if (command==STATUS_CHECK)
896 {
2127e193
GI
897 unsigned const char normal_lo=0x4f, normal_hi=0xc2;
898 unsigned const char failed_lo=0xf4, failed_hi=0x2c;
899 unsigned char low,high;
900
901 high = pide_pt_hdr_out->lbahigh;
902 low = pide_pt_hdr_out->lbamid;
903
904 // Cyl low and Cyl high unchanged means "Good SMART status"
905 if (low==normal_lo && high==normal_hi)
906 return 0;
907
908 // These values mean "Bad SMART status"
909 if (low==failed_lo && high==failed_hi)
910 return 1;
911
912 // We haven't gotten output that makes sense; print out some debugging info
913 char buf[512];
914 sprintf(buf,"CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
915 (int)pide_pt_hdr_out->command,
916 (int)pide_pt_hdr_out->feature,
917 (int)pide_pt_hdr_out->sectorcount,
918 (int)pide_pt_hdr_out->lbalow,
919 (int)pide_pt_hdr_out->lbamid,
920 (int)pide_pt_hdr_out->lbahigh,
921 (int)pide_pt_hdr_out->sectors);
922 printwarning(BAD_SMART,buf);
923 }
924 else if (command==CHECK_POWER_MODE)
925 data[0] = pide_pt_hdr_out->sectorcount & 0xff;
926 else if (pide_pt_hdr->protocol==HPT_READ)
54965743
GI
927 memcpy(data, (unsigned char *)buff + 2 * sizeof(HPT_PASS_THROUGH_HEADER),
928 pide_pt_hdr->sectors * 512);
2127e193
GI
929 return 0;
930}
931
932
933/////////////////////////////////////////////////////////////////////////////
e165493d 934/// Standard SCSI support
2127e193
GI
935
936class freebsd_scsi_device
937: public /*implements*/ scsi_device,
938 public /*extends*/ freebsd_smart_device
939{
940public:
941 freebsd_scsi_device(smart_interface * intf, const char * dev_name, const char * req_type);
942
943 virtual smart_device * autodetect_open();
944
945 virtual bool scsi_pass_through(scsi_cmnd_io * iop);
eb07ddf2
GI
946
947 virtual bool open();
948
949 virtual bool close();
950
951private:
952 int m_fd;
953 struct cam_device *m_camdev;
2127e193
GI
954};
955
eb07ddf2
GI
956bool freebsd_scsi_device::open(){
957 const char *dev = get_dev_name();
958
959 if ((m_camdev = cam_open_device(dev, O_RDWR)) == NULL) {
960 set_err(errno);
961 return false;
962 }
963 set_fd(m_camdev->fd);
964 return true;
965}
966
967bool freebsd_scsi_device::close(){
968 cam_close_device(m_camdev);
969 set_fd(-1);
970 return true;
971}
972
2127e193
GI
973freebsd_scsi_device::freebsd_scsi_device(smart_interface * intf,
974 const char * dev_name, const char * req_type)
975: smart_device(intf, dev_name, "scsi", req_type),
976 freebsd_smart_device("SCSI")
977{
978}
979
eb07ddf2
GI
980
981bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
2127e193 982{
cfbba5b9 983 int report=scsi_debugmode;
2127e193 984 union ccb *ccb;
54965743
GI
985
986 if (report > 0) {
987 unsigned int k;
988 const unsigned char * ucp = iop->cmnd;
989 const char * np;
990
991 np = scsi_get_opcode_name(ucp[0]);
992 pout(" [%s: ", np ? np : "<unknown opcode>");
993 for (k = 0; k < iop->cmnd_len; ++k)
994 pout("%02x ", ucp[k]);
995 if ((report > 1) &&
996 (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
997 int trunc = (iop->dxfer_len > 256) ? 1 : 0;
998
999 pout("]\n Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
1000 (trunc ? " [only first 256 bytes shown]" : ""));
1001 dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
1002 }
1003 else
1004 pout("]");
1005 }
2127e193 1006
eb07ddf2
GI
1007 if(m_camdev==NULL) {
1008 warnx("error: camdev=0!");
54965743 1009 return -ENOTTY;
2127e193
GI
1010 }
1011
eb07ddf2 1012 if (!(ccb = cam_getccb(m_camdev))) {
2127e193
GI
1013 warnx("error allocating ccb");
1014 return -ENOMEM;
1015 }
d008864d
GI
1016 // mfi SAT layer is known to be buggy
1017 if(!strcmp("mfi",m_camdev->sim_name)) {
1018 if (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12 || iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16) {
1019 // Controller does not return ATA output registers in SAT sense data
1020 if (iop->cmnd[2] & (1 << 5)) // chk_cond
1021 return set_err(ENOSYS, "ATA return descriptor not supported by controller firmware");
1022 }
1023 // SMART WRITE LOG SECTOR causing media errors
1024 if ((iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16 && iop->cmnd[14] == ATA_SMART_CMD
1025 && iop->cmnd[3]==0 && iop->cmnd[4] == ATA_SMART_WRITE_LOG_SECTOR) ||
1026 (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12 && iop->cmnd[9] == ATA_SMART_CMD &&
1027 iop->cmnd[3] == ATA_SMART_WRITE_LOG_SECTOR))
1028 return set_err(ENOSYS, "SMART WRITE LOG SECTOR command is not supported by controller firmware");
1029 }
2127e193
GI
1030
1031 // clear out structure, except for header that was filled in for us
1032 bzero(&(&ccb->ccb_h)[1],
54965743 1033 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
2127e193
GI
1034
1035 cam_fill_csio(&ccb->csio,
54965743
GI
1036 /*retrires*/ 1,
1037 /*cbfcnp*/ NULL,
1038 /* flags */ (iop->dxfer_dir == DXFER_NONE ? CAM_DIR_NONE :(iop->dxfer_dir == DXFER_FROM_DEVICE ? CAM_DIR_IN : CAM_DIR_OUT)),
1039 /* tagaction */ MSG_SIMPLE_Q_TAG,
1040 /* dataptr */ iop->dxferp,
1041 /* datalen */ iop->dxfer_len,
1042 /* senselen */ iop->max_sense_len,
1043 /* cdblen */ iop->cmnd_len,
1044 /* timout (converted to seconds) */ iop->timeout*1000);
2127e193
GI
1045 memcpy(ccb->csio.cdb_io.cdb_bytes,iop->cmnd,iop->cmnd_len);
1046
eb07ddf2 1047 if (cam_send_ccb(m_camdev,ccb) < 0) {
2127e193 1048 warn("error sending SCSI ccb");
eb07ddf2 1049 cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
2127e193
GI
1050 cam_freeccb(ccb);
1051 return -EIO;
1052 }
1053
54965743 1054 if (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR)) {
eb07ddf2 1055 cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
2127e193
GI
1056 cam_freeccb(ccb);
1057 return -EIO;
1058 }
1059
1060 if (iop->sensep) {
d008864d
GI
1061 iop->resp_sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
1062 memcpy(iop->sensep,&(ccb->csio.sense_data),iop->resp_sense_len);
2127e193
GI
1063 }
1064
1065 iop->scsi_status = ccb->csio.scsi_status;
1066
1067 cam_freeccb(ccb);
54965743 1068
2127e193
GI
1069 if (report > 0) {
1070 int trunc;
1071
1072 pout(" status=0\n");
1073 trunc = (iop->dxfer_len > 256) ? 1 : 0;
54965743 1074
2127e193 1075 pout(" Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
54965743 1076 (trunc ? " [only first 256 bytes shown]" : ""));
2127e193
GI
1077 dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
1078 }
54965743 1079
2127e193
GI
1080 return true;
1081}
1082
1083
d008864d
GI
1084/////////////////////////////////////////////////////////////////////////////
1085/// Areca RAID support
1086
1087class freebsd_areca_device
1088: public /*implements*/ ata_device,
1089 public /*extends*/ freebsd_smart_device
1090{
1091public:
f4e463df 1092 freebsd_areca_device(smart_interface * intf, const char * dev_name, int disknum, int encnum = 1);
d008864d
GI
1093
1094protected:
1095 virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
1096
1097private:
1098 int m_disknum; ///< Disk number.
1099};
1100
1101
1102// PURPOSE
1103// This is an interface routine meant to isolate the OS dependent
1104// parts of the code, and to provide a debugging interface. Each
1105// different port and OS needs to provide it's own interface. This
1106// is the linux interface to the Areca "arcmsr" driver. It allows ATA
1107// commands to be passed through the SCSI driver.
1108// DETAILED DESCRIPTION OF ARGUMENTS
1109// fd: is the file descriptor provided by open()
1110// disknum is the disk number (0 to 15) in the RAID array
1111// command: defines the different operations.
1112// select: additional input data if needed (which log, which type of
1113// self-test).
1114// data: location to write output data, if needed (512 bytes).
1115// Note: not all commands use all arguments.
1116// RETURN VALUES
1117// -1 if the command failed
1118// 0 if the command succeeded,
1119// STATUS_CHECK routine:
1120// -1 if the command failed
1121// 0 if the command succeeded and disk SMART status is "OK"
1122// 1 if the command succeeded and disk SMART status is "FAILING"
1123
1124
1125/*FunctionCode*/
1126#define FUNCTION_READ_RQBUFFER 0x0801
1127#define FUNCTION_WRITE_WQBUFFER 0x0802
1128#define FUNCTION_CLEAR_RQBUFFER 0x0803
1129#define FUNCTION_CLEAR_WQBUFFER 0x0804
1130
1131/* ARECA IO CONTROL CODE*/
1132#define ARCMSR_IOCTL_READ_RQBUFFER _IOWR('F', FUNCTION_READ_RQBUFFER, sSRB_BUFFER)
1133#define ARCMSR_IOCTL_WRITE_WQBUFFER _IOWR('F', FUNCTION_WRITE_WQBUFFER, sSRB_BUFFER)
1134#define ARCMSR_IOCTL_CLEAR_RQBUFFER _IOWR('F', FUNCTION_CLEAR_RQBUFFER, sSRB_BUFFER)
1135#define ARCMSR_IOCTL_CLEAR_WQBUFFER _IOWR('F', FUNCTION_CLEAR_WQBUFFER, sSRB_BUFFER)
1136#define ARECA_SIG_STR "ARCMSR"
1137
1138
1139
1140// The SRB_IO_CONTROL & SRB_BUFFER structures are used to communicate(to/from) to areca driver
1141typedef struct _SRB_IO_CONTROL
1142{
1143 unsigned int HeaderLength;
1144 unsigned char Signature[8];
1145 unsigned int Timeout;
1146 unsigned int ControlCode;
1147 unsigned int ReturnCode;
1148 unsigned int Length;
1149} sSRB_IO_CONTROL;
1150
1151typedef struct _SRB_BUFFER
1152{
1153 sSRB_IO_CONTROL srbioctl;
1154 unsigned char ioctldatabuffer[1032]; // the buffer to put the command data to/from firmware
1155} sSRB_BUFFER;
1156
1157
1158// For debugging areca code
1159
1160static void areca_dumpdata(unsigned char *block, int len)
1161{
1162 int ln = (len / 16) + 1; // total line#
1163 unsigned char c;
1164 int pos = 0;
1165
1166 printf(" Address = %p, Length = (0x%x)%d\n", block, len, len);
1167 printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F ASCII \n");
1168 printf("=====================================================================\n");
1169
1170 for ( int l = 0; l < ln && len; l++ )
1171 {
1172 // printf the line# and the HEX data
1173 // if a line data length < 16 then append the space to the tail of line to reach 16 chars
1174 printf("%02X | ", l);
1175 for ( pos = 0; pos < 16 && len; pos++, len-- )
1176 {
1177 c = block[l*16+pos];
1178 printf("%02X ", c);
1179 }
1180
1181 if ( pos < 16 )
1182 {
1183 for ( int loop = pos; loop < 16; loop++ )
1184 {
1185 printf(" ");
1186 }
1187 }
1188
1189 // print ASCII char
1190 for ( int loop = 0; loop < pos; loop++ )
1191 {
1192 c = block[l*16+loop];
1193 if ( c >= 0x20 && c <= 0x7F )
1194 {
1195 printf("%c", c);
1196 }
1197 else
1198 {
1199 printf(".");
1200 }
1201 }
1202 printf("\n");
1203 }
1204 printf("=====================================================================\n");
1205}
1206
1207
1208static int arcmsr_command_handler(int fd, unsigned long arcmsr_cmd, unsigned char *data, int data_len, void *ext_data /* reserved for further use */)
1209{
1210 ARGUSED(ext_data);
1211
1212 int ioctlreturn = 0;
1213 sSRB_BUFFER sBuf;
1214
1215 unsigned char *areca_return_packet;
1216 int total = 0;
1217 int expected = -1;
1218 unsigned char return_buff[2048];
1219 unsigned char *ptr = &return_buff[0];
1220 memset(return_buff, 0, sizeof(return_buff));
1221
1222 memset((unsigned char *)&sBuf, 0, sizeof(sBuf));
1223
1224
1225 sBuf.srbioctl.HeaderLength = sizeof(sSRB_IO_CONTROL);
1226 memcpy(sBuf.srbioctl.Signature, ARECA_SIG_STR, strlen(ARECA_SIG_STR));
1227 sBuf.srbioctl.Timeout = 10000;
1228 sBuf.srbioctl.ControlCode = ARCMSR_IOCTL_READ_RQBUFFER;
1229
1230 switch ( arcmsr_cmd )
1231 {
1232 // command for writing data to driver
1233 case ARCMSR_IOCTL_WRITE_WQBUFFER:
1234 if ( data && data_len )
1235 {
1236 sBuf.srbioctl.Length = data_len;
1237 memcpy((unsigned char *)sBuf.ioctldatabuffer, (unsigned char *)data, data_len);
1238 }
1239 // commands for clearing related buffer of driver
1240 case ARCMSR_IOCTL_CLEAR_RQBUFFER:
1241 case ARCMSR_IOCTL_CLEAR_WQBUFFER:
1242 break;
1243 // command for reading data from driver
1244 case ARCMSR_IOCTL_READ_RQBUFFER:
1245 break;
1246 default:
1247 // unknown arcmsr commands
1248 return -1;
1249 }
1250
1251
1252 while ( 1 )
1253 {
1254 ioctlreturn = ioctl(fd,arcmsr_cmd,&sBuf);
1255 if ( ioctlreturn )
1256 {
1257 // errors found
1258 break;
1259 }
1260
1261 if ( arcmsr_cmd != ARCMSR_IOCTL_READ_RQBUFFER )
1262 {
1263 // if succeeded, just returns the length of outgoing data
1264 return data_len;
1265 }
1266
1267 if ( sBuf.srbioctl.Length )
1268 {
1269 if(ata_debugmode)
1270 areca_dumpdata(&sBuf.ioctldatabuffer[0], sBuf.srbioctl.Length);
1271 memcpy(ptr, &sBuf.ioctldatabuffer[0], sBuf.srbioctl.Length);
1272 ptr += sBuf.srbioctl.Length;
1273 total += sBuf.srbioctl.Length;
1274 // the returned bytes enough to compute payload length ?
1275 if ( expected < 0 && total >= 5 )
1276 {
1277 areca_return_packet = (unsigned char *)&return_buff[0];
1278 if ( areca_return_packet[0] == 0x5E &&
1279 areca_return_packet[1] == 0x01 &&
1280 areca_return_packet[2] == 0x61 )
1281 {
1282 // valid header, let's compute the returned payload length,
1283 // we expected the total length is
1284 // payload + 3 bytes header + 2 bytes length + 1 byte checksum
1285 expected = areca_return_packet[4] * 256 + areca_return_packet[3] + 6;
1286 }
1287 }
1288
1289 if ( total >= 7 && total >= expected )
1290 {
1291 //printf("total bytes received = %d, expected length = %d\n", total, expected);
1292
1293 // ------ Okay! we received enough --------
1294 break;
1295 }
1296 }
1297 }
1298
1299 // Deal with the different error cases
1300 if ( ioctlreturn )
1301 {
1302 pout("ioctl write buffer failed code = %x\n", ioctlreturn);
1303 return -2;
1304 }
1305
1306
1307 if ( data )
1308 {
1309 memcpy(data, return_buff, total);
1310 }
1311
1312 return total;
1313}
1314
1315
f4e463df 1316freebsd_areca_device::freebsd_areca_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
d008864d
GI
1317: smart_device(intf, dev_name, "areca", "areca"),
1318 freebsd_smart_device("ATA"),
f4e463df
GI
1319 m_disknum(disknum),
1320 m_encnum(encnum)
d008864d 1321{
f4e463df 1322 set_info().info_name = strprintf("%s [areca_disk#%02d_enc#%02d]", dev_name, disknum, encnum);
d008864d
GI
1323}
1324
1325// Areca RAID Controller
1326// int freebsd_areca_device::ata_command_interface(smart_command_set command, int select, char * data)
1327bool freebsd_areca_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
1328{
1329if (!ata_cmd_is_ok(in,
1330 true, // data_out_support
1331 false, // TODO: multi_sector_support
1332 true) // ata_48bit_support
1333 )
1334 return false;
1335
1336 // ATA input registers
1337 typedef struct _ATA_INPUT_REGISTERS
1338 {
1339 unsigned char features;
1340 unsigned char sector_count;
1341 unsigned char sector_number;
1342 unsigned char cylinder_low;
1343 unsigned char cylinder_high;
1344 unsigned char device_head;
1345 unsigned char command;
1346 unsigned char reserved[8];
1347 unsigned char data[512]; // [in/out] buffer for outgoing/incoming data
1348 } sATA_INPUT_REGISTERS;
1349
1350 // ATA output registers
1351 // Note: The output registers is re-sorted for areca internal use only
1352 typedef struct _ATA_OUTPUT_REGISTERS
1353 {
1354 unsigned char error;
1355 unsigned char status;
1356 unsigned char sector_count;
1357 unsigned char sector_number;
1358 unsigned char cylinder_low;
1359 unsigned char cylinder_high;
1360 }sATA_OUTPUT_REGISTERS;
1361
1362 // Areca packet format for outgoing:
1363 // B[0~2] : 3 bytes header, fixed value 0x5E, 0x01, 0x61
1364 // B[3~4] : 2 bytes command length + variant data length, little endian
1365 // B[5] : 1 bytes areca defined command code, ATA passthrough command code is 0x1c
1366 // B[6~last-1] : variant bytes payload data
1367 // B[last] : 1 byte checksum, simply sum(B[3] ~ B[last -1])
1368 //
1369 //
1370 // header 3 bytes length 2 bytes cmd 1 byte payload data x bytes cs 1 byte
1371 // +--------------------------------------------------------------------------------+
1372 // + 0x5E 0x01 0x61 | 0x00 0x00 | 0x1c | .................... | 0x00 |
1373 // +--------------------------------------------------------------------------------+
1374 //
1375
1376 //Areca packet format for incoming:
1377 // B[0~2] : 3 bytes header, fixed value 0x5E, 0x01, 0x61
1378 // B[3~4] : 2 bytes payload length, little endian
1379 // B[5~last-1] : variant bytes returned payload data
1380 // B[last] : 1 byte checksum, simply sum(B[3] ~ B[last -1])
1381 //
1382 //
1383 // header 3 bytes length 2 bytes payload data x bytes cs 1 byte
1384 // +-------------------------------------------------------------------+
1385 // + 0x5E 0x01 0x61 | 0x00 0x00 | .................... | 0x00 |
1386 // +-------------------------------------------------------------------+
1387 unsigned char areca_packet[640];
1388 int areca_packet_len = sizeof(areca_packet);
1389 unsigned char cs = 0;
1390
1391 sATA_INPUT_REGISTERS *ata_cmd;
1392
1393 // For debugging
1394 memset(areca_packet, 0, areca_packet_len);
1395
1396 // ----- BEGIN TO SETUP HEADERS -------
1397 areca_packet[0] = 0x5E;
1398 areca_packet[1] = 0x01;
1399 areca_packet[2] = 0x61;
1400 areca_packet[3] = (unsigned char)((areca_packet_len - 6) & 0xff);
1401 areca_packet[4] = (unsigned char)(((areca_packet_len - 6) >> 8) & 0xff);
1402 areca_packet[5] = 0x1c; // areca defined code for ATA passthrough command
1403
1404 // ----- BEGIN TO SETUP PAYLOAD DATA -----
1405 memcpy(&areca_packet[7], "SmrT", 4); // areca defined password
1406 ata_cmd = (sATA_INPUT_REGISTERS *)&areca_packet[12];
1407
1408 // Set registers
1409 {
1410 const ata_in_regs_48bit & r = in.in_regs;
1411 ata_cmd->features = r.features_16;
1412 ata_cmd->sector_count = r.sector_count_16;
1413 ata_cmd->sector_number = r.lba_low_16;
1414 ata_cmd->cylinder_low = r.lba_mid_16;
1415 ata_cmd->cylinder_high = r.lba_high_16;
1416 ata_cmd->device_head = r.device;
1417 ata_cmd->command = r.command;
1418 }
1419 bool readdata = false;
1420 if (in.direction == ata_cmd_in::data_in) {
1421 readdata = true;
1422 // the command will read data
1423 areca_packet[6] = 0x13;
1424 }
1425 else if ( in.direction == ata_cmd_in::no_data )
1426 {
1427 // the commands will return no data
1428 areca_packet[6] = 0x15;
1429 }
1430 else if (in.direction == ata_cmd_in::data_out)
1431 {
1432 // the commands will write data
1433 memcpy(ata_cmd->data, in.buffer, in.size);
1434 areca_packet[6] = 0x14;
1435 }
1436 else {
1437 // COMMAND NOT SUPPORTED VIA ARECA IOCTL INTERFACE
1438 return set_err(ENOTSUP, "DATA OUT not supported for this Areca controller type");
1439 }
1440
f4e463df
GI
1441 areca_packet[11] = m_disknum - 1; // disk #
1442 areca_packet[19] = m_encnum - 1; // enc#
d008864d
GI
1443
1444 // ----- BEGIN TO SETUP CHECKSUM -----
1445 for ( int loop = 3; loop < areca_packet_len - 1; loop++ )
1446 {
1447 cs += areca_packet[loop];
1448 }
1449 areca_packet[areca_packet_len-1] = cs;
1450
1451 // ----- BEGIN TO SEND TO ARECA DRIVER ------
1452 int expected = 0;
1453 unsigned char return_buff[2048];
1454 memset(return_buff, 0, sizeof(return_buff));
1455
1456 expected = arcmsr_command_handler(get_fd(), ARCMSR_IOCTL_CLEAR_RQBUFFER, NULL, 0, NULL);
1457 if (expected==-3) {
1458 return set_err(EIO);
1459 }
1460
1461 expected = arcmsr_command_handler(get_fd(), ARCMSR_IOCTL_CLEAR_WQBUFFER, NULL, 0, NULL);
1462 expected = arcmsr_command_handler(get_fd(), ARCMSR_IOCTL_WRITE_WQBUFFER, areca_packet, areca_packet_len, NULL);
1463 if ( expected > 0 )
1464 {
1465 expected = arcmsr_command_handler(get_fd(), ARCMSR_IOCTL_READ_RQBUFFER, return_buff, sizeof(return_buff), NULL);
1466 }
1467 if ( expected < 0 )
1468 {
1469 return -1;
1470 }
1471
1472 // ----- VERIFY THE CHECKSUM -----
1473 cs = 0;
1474 for ( int loop = 3; loop < expected - 1; loop++ )
1475 {
1476 cs += return_buff[loop];
1477 }
1478
1479 if ( return_buff[expected - 1] != cs )
1480 {
1481 return set_err(EIO);
1482 }
1483
1484 sATA_OUTPUT_REGISTERS *ata_out = (sATA_OUTPUT_REGISTERS *)&return_buff[5] ;
1485 if ( ata_out->status )
1486 {
1487 if ( in.in_regs.command == ATA_IDENTIFY_DEVICE
1488 && !nonempty((unsigned char *)in.buffer, in.size))
1489 {
1490 return set_err(ENODEV, "No drive on port %d", m_disknum);
1491 }
1492 }
1493
1494 // returns with data
1495 if (readdata)
1496 {
1497 memcpy(in.buffer, &return_buff[7], in.size);
1498 }
1499
1500 // Return register values
1501 {
1502 ata_out_regs_48bit & r = out.out_regs;
1503 r.error = ata_out->error;
1504 r.sector_count_16 = ata_out->sector_count;
1505 r.lba_low_16 = ata_out->sector_number;
1506 r.lba_mid_16 = ata_out->cylinder_low;
1507 r.lba_high_16 = ata_out->cylinder_high;
1508 r.status = ata_out->status;
1509 }
1510 return true;
1511}
1512
1513
1514
2127e193
GI
1515/////////////////////////////////////////////////////////////////////////////
1516/// Implement CCISS RAID support with old functions
1517
1518class freebsd_cciss_device
1519: public /*implements*/ scsi_device,
1520 public /*extends*/ freebsd_smart_device
1521{
1522public:
1523 freebsd_cciss_device(smart_interface * intf, const char * name, unsigned char disknum);
1524
1525 virtual bool scsi_pass_through(scsi_cmnd_io * iop);
eb07ddf2 1526 virtual bool open();
2127e193
GI
1527
1528private:
1529 unsigned char m_disknum; ///< Disk number.
1530};
1531
eb07ddf2
GI
1532bool freebsd_cciss_device::open()
1533{
1534 const char *dev = get_dev_name();
1535 int fd;
eb07ddf2
GI
1536 if ((fd = ::open(dev,O_RDWR))<0) {
1537 set_err(errno);
1538 return false;
1539 }
1540 set_fd(fd);
1541 return true;
1542}
2127e193
GI
1543
1544freebsd_cciss_device::freebsd_cciss_device(smart_interface * intf,
1545 const char * dev_name, unsigned char disknum)
1546: smart_device(intf, dev_name, "cciss", "cciss"),
1547 freebsd_smart_device("SCSI"),
1548 m_disknum(disknum)
1549{
1550 set_info().info_name = strprintf("%s [cciss_disk_%02d]", dev_name, disknum);
1551}
1552
1553bool freebsd_cciss_device::scsi_pass_through(scsi_cmnd_io * iop)
1554{
cfbba5b9 1555 int status = cciss_io_interface(get_fd(), m_disknum, iop, scsi_debugmode);
eb07ddf2
GI
1556 if (status < 0)
1557 return set_err(-status);
1558 return true;
eb07ddf2 1559 // not reached
2127e193
GI
1560 return true;
1561}
1562
1563
1564/////////////////////////////////////////////////////////////////////////////
1565/// SCSI open with autodetection support
1566
1567smart_device * freebsd_scsi_device::autodetect_open()
1568{
1569 // Open device
1570 if (!open())
1571 return this;
1572
1573 // No Autodetection if device type was specified by user
1574 if (*get_req_type())
1575 return this;
1576
1577 // The code below is based on smartd.cpp:SCSIFilterKnown()
1578
1579 // Get INQUIRY
1580 unsigned char req_buff[64] = {0, };
1581 int req_len = 36;
1582 if (scsiStdInquiry(this, req_buff, req_len)) {
1583 // Marvell controllers fail on a 36 bytes StdInquiry, but 64 suffices
1584 // watch this spot ... other devices could lock up here
1585 req_len = 64;
1586 if (scsiStdInquiry(this, req_buff, req_len)) {
1587 // device doesn't like INQUIRY commands
1588 close();
1589 set_err(EIO, "INQUIRY failed");
1590 return this;
1591 }
1592 }
1593
1594 int avail_len = req_buff[4] + 5;
1595 int len = (avail_len < req_len ? avail_len : req_len);
1596 if (len < 36)
54965743 1597 return this;
2127e193
GI
1598
1599 // Use INQUIRY to detect type
2127e193 1600
bed94269
GI
1601 // 3ware ?
1602 if (!memcmp(req_buff + 8, "3ware", 5) || !memcmp(req_buff + 8, "AMCC", 4)) {
1603 close();
1604 set_err(EINVAL, "AMCC/3ware controller, please try adding '-d 3ware,N',\n"
1605 "you may need to replace %s with /dev/twaN or /dev/tweN", get_dev_name());
1606 return this;
1607 }
1608
d008864d 1609 // SAT or USB, skip MFI controllers because of bugs
bed94269
GI
1610 {
1611 smart_device * newdev = smi()->autodetect_sat_device(this, req_buff, len);
d008864d 1612 if (newdev) {
2127e193 1613 // NOTE: 'this' is now owned by '*newdev'
d008864d
GI
1614 if(!strcmp("mfi",m_camdev->sim_name)) {
1615 newdev->close();
1616 newdev->set_err(ENOSYS, "SATA device detected,\n"
1617 "MegaRAID SAT layer is reportedly buggy, use '-d sat' to try anyhow");
1618 }
2127e193 1619 return newdev;
d008864d 1620 }
2127e193 1621 }
2127e193
GI
1622
1623 // Nothing special found
1624 return this;
1625}
1626
1627
1628/////////////////////////////////////////////////////////////////////////////
1629/// Implement platform interface with old functions.
1630
1631class freebsd_smart_interface
1632: public /*implements*/ smart_interface
1633{
1634public:
54965743 1635 virtual std::string get_os_version_str();
2127e193 1636
54965743 1637 virtual std::string get_app_examples(const char * appname);
2127e193
GI
1638
1639 virtual bool scan_smart_devices(smart_device_list & devlist, const char * type,
1640 const char * pattern = 0);
1641
1642protected:
1643 virtual ata_device * get_ata_device(const char * name, const char * type);
1644
eb07ddf2
GI
1645#if FREEBSDVER > 800100
1646 virtual ata_device * get_atacam_device(const char * name, const char * type);
1647#endif
1648
2127e193
GI
1649 virtual scsi_device * get_scsi_device(const char * name, const char * type);
1650
1651 virtual smart_device * autodetect_smart_device(const char * name);
1652
1653 virtual smart_device * get_custom_smart_device(const char * name, const char * type);
1654
54965743 1655 virtual std::string get_valid_custom_dev_types_str();
2127e193
GI
1656};
1657
1658
1659//////////////////////////////////////////////////////////////////////
54965743
GI
1660
1661std::string freebsd_smart_interface::get_os_version_str()
2127e193 1662{
54965743
GI
1663 struct utsname osname;
1664 uname(&osname);
1665 return strprintf("%s %s %s", osname.sysname, osname.release, osname.machine);
2127e193
GI
1666}
1667
54965743 1668std::string freebsd_smart_interface::get_app_examples(const char * appname)
2127e193
GI
1669{
1670 if (!strcmp(appname, "smartctl"))
1671 return smartctl_examples;
54965743 1672 return "";
2127e193
GI
1673}
1674
1675ata_device * freebsd_smart_interface::get_ata_device(const char * name, const char * type)
1676{
1677 return new freebsd_ata_device(this, name, type);
1678}
1679
eb07ddf2
GI
1680#if FREEBSDVER > 800100
1681ata_device * freebsd_smart_interface::get_atacam_device(const char * name, const char * type)
2127e193 1682{
eb07ddf2 1683 return new freebsd_atacam_device(this, name, type);
2127e193 1684}
eb07ddf2 1685#endif
832b75ed 1686
eb07ddf2
GI
1687scsi_device * freebsd_smart_interface::get_scsi_device(const char * name, const char * type)
1688{
1689 return new freebsd_scsi_device(this, name, type);
832b75ed
GG
1690}
1691
54965743
GI
1692// we are using CAM subsystem XPT enumerator to found all CAM (scsi/usb/ada/...)
1693// devices on system despite of it's names
2127e193
GI
1694//
1695// If any errors occur, leave errno set as it was returned by the
1696// system call, and return <0.
1697//
eb07ddf2
GI
1698// arguments:
1699// names: resulting array
1700// show_all - export duplicate device name or not
1701//
2127e193
GI
1702// Return values:
1703// -1: error
1704// >=0: number of discovered devices
832b75ed 1705
cfbba5b9
GI
1706bool get_dev_names_cam(std::vector<std::string> & names, bool show_all)
1707{
1708 int fd;
2127e193
GI
1709 if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) {
1710 if (errno == ENOENT) /* There are no CAM device on this computer */
1711 return 0;
cfbba5b9 1712 int serrno = errno;
2127e193 1713 pout("%s control device couldn't opened: %s\n", XPT_DEVICE, strerror(errno));
cfbba5b9
GI
1714 errno = serrno;
1715 return false;
832b75ed 1716 }
2127e193 1717
cfbba5b9 1718 union ccb ccb;
2127e193
GI
1719 bzero(&ccb, sizeof(union ccb));
1720
1721 ccb.ccb_h.path_id = CAM_XPT_PATH_ID;
1722 ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
1723 ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
1724
1725 ccb.ccb_h.func_code = XPT_DEV_MATCH;
cfbba5b9 1726 int bufsize = sizeof(struct dev_match_result) * MAX_NUM_DEV;
2127e193 1727 ccb.cdm.match_buf_len = bufsize;
cfbba5b9 1728 // TODO: Use local buffer instead of malloc() if possible
2127e193 1729 ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);
a7e8ffec
GI
1730 bzero(ccb.cdm.matches,bufsize); // clear ccb.cdm.matches structure
1731
2127e193 1732 if (ccb.cdm.matches == NULL) {
cfbba5b9
GI
1733 close(fd);
1734 throw std::bad_alloc();
2127e193
GI
1735 }
1736 ccb.cdm.num_matches = 0;
2127e193
GI
1737 ccb.cdm.num_patterns = 0;
1738 ccb.cdm.pattern_buf_len = 0;
1739
1740 /*
1741 * We do the ioctl multiple times if necessary, in case there are
1742 * more than MAX_NUM_DEV nodes in the EDT.
1743 */
cfbba5b9
GI
1744 int skip_device = 0, skip_bus = 0, changed = 0; // TODO: bool
1745 std::string devname;
2127e193
GI
1746 do {
1747 if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
cfbba5b9 1748 int serrno = errno;
2127e193 1749 pout("error sending CAMIOCOMMAND ioctl: %s\n", strerror(errno));
cfbba5b9
GI
1750 free(ccb.cdm.matches);
1751 close(fd);
1752 errno = serrno;
1753 return false;
832b75ed 1754 }
2127e193
GI
1755
1756 if ((ccb.ccb_h.status != CAM_REQ_CMP)
54965743
GI
1757 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)
1758 && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {
2127e193 1759 pout("got CAM error %#x, CDM error %d\n", ccb.ccb_h.status, ccb.cdm.status);
cfbba5b9
GI
1760 free(ccb.cdm.matches);
1761 close(fd);
1762 errno = ENXIO;
1763 return false;
832b75ed 1764 }
2127e193 1765
cfbba5b9 1766 for (unsigned i = 0; i < ccb.cdm.num_matches; i++) {
2127e193
GI
1767 struct bus_match_result *bus_result;
1768 struct device_match_result *dev_result;
1769 struct periph_match_result *periph_result;
1770
1771 if (ccb.cdm.matches[i].type == DEV_MATCH_BUS) {
1772 bus_result = &ccb.cdm.matches[i].result.bus_result;
1773
d008864d 1774 if (strcmp(bus_result->dev_name,"xpt") == 0) /* skip XPT bus at all */
54965743 1775 skip_bus = 1;
2127e193
GI
1776 else
1777 skip_bus = 0;
1778 changed = 1;
1779 } else if (ccb.cdm.matches[i].type == DEV_MATCH_DEVICE) {
1780 dev_result = &ccb.cdm.matches[i].result.device_result;
1781
1782 if (dev_result->flags & DEV_RESULT_UNCONFIGURED || skip_bus == 1)
1783 skip_device = 1;
1784 else
1785 skip_device = 0;
eb07ddf2 1786
54965743
GI
1787 // /* Shall we skip non T_DIRECT devices ? */
1788 // if (dev_result->inq_data.device != T_DIRECT)
1789 // skip_device = 1;
2127e193 1790 changed = 1;
eb07ddf2
GI
1791 } else if (ccb.cdm.matches[i].type == DEV_MATCH_PERIPH &&
1792 (skip_device == 0 || show_all)) {
2127e193 1793 /* One device may be populated as many peripherals (pass0 & da0 for example).
54965743 1794 * We are searching for latest name
2127e193
GI
1795 */
1796 periph_result = &ccb.cdm.matches[i].result.periph_result;
cfbba5b9 1797 devname = strprintf("%s%s%d", _PATH_DEV, periph_result->periph_name, periph_result->unit_number);
2127e193
GI
1798 changed = 0;
1799 };
cfbba5b9
GI
1800 if ((changed == 1 || show_all) && !devname.empty()) {
1801 names.push_back(devname);
1802 devname.erase();
2127e193
GI
1803 changed = 0;
1804 };
1805 }
1806
cfbba5b9 1807 } while ((ccb.ccb_h.status == CAM_REQ_CMP) && (ccb.cdm.status == CAM_DEV_MATCH_MORE));
2127e193 1808
cfbba5b9
GI
1809 if (!devname.empty())
1810 names.push_back(devname);
2127e193 1811
2127e193 1812 free(ccb.cdm.matches);
cfbba5b9
GI
1813 close(fd);
1814 return true;
832b75ed 1815}
832b75ed 1816
2127e193
GI
1817// we are using ATA subsystem enumerator to found all ATA devices on system
1818// despite of it's names
1819//
1820// If any errors occur, leave errno set as it was returned by the
1821// system call, and return <0.
832b75ed 1822
2127e193
GI
1823// Return values:
1824// -1: error
1825// >=0: number of discovered devices
1826int get_dev_names_ata(char*** names) {
1827 struct ata_ioc_devices devices;
1828 int fd=-1,maxchannel,serrno=-1,n=0;
1829 char **mp = NULL;
1830
1831 *names=NULL;
1832
1833 if ((fd = open(ATA_DEVICE, O_RDWR)) < 0) {
1834 if (errno == ENOENT) /* There are no ATA device on this computer */
1835 return 0;
1836 serrno = errno;
1837 pout("%s control device can't be opened: %s\n", ATA_DEVICE, strerror(errno));
1838 n = -1;
1839 goto end;
1840 };
54965743 1841
2127e193
GI
1842 if (ioctl(fd, IOCATAGMAXCHANNEL, &maxchannel) < 0) {
1843 serrno = errno;
1844 pout("ioctl(IOCATAGMAXCHANNEL) on /dev/ata failed: %s\n", strerror(errno));
1845 n = -1;
1846 goto end;
1847 };
1848
1849 // allocate space for up to MAX_NUM_DEV number of ATA devices
1850 mp = (char **)calloc(MAX_NUM_DEV, sizeof(char*));
1851 if (mp == NULL) {
1852 serrno=errno;
1853 pout("Out of memory constructing scan device list (on line %d)\n", __LINE__);
1854 n = -1;
1855 goto end;
1856 };
1857
1858 for (devices.channel = 0; devices.channel < maxchannel && n < MAX_NUM_DEV; devices.channel++) {
1859 int j;
54965743 1860
2127e193
GI
1861 if (ioctl(fd, IOCATADEVICES, &devices) < 0) {
1862 if (errno == ENXIO)
1863 continue; /* such channel not exist */
1864 pout("ioctl(IOCATADEVICES) on %s channel %d failed: %s\n", ATA_DEVICE, devices.channel, strerror(errno));
1865 n = -1;
1866 goto end;
1867 };
1868 for (j=0;j<=1 && n<MAX_NUM_DEV;j++) {
1869 if (devices.name[j][0] != '\0') {
1870 asprintf(mp+n, "%s%s", _PATH_DEV, devices.name[j]);
1871 if (mp[n] == NULL) {
1872 pout("Out of memory constructing scan ATA device list (on line %d)\n", __LINE__);
1873 n = -1;
1874 goto end;
1875 };
1876 bytes+=1+strlen(mp[n]);
1877 n++;
1878 };
1879 };
1880 };
1881 mp = (char **)reallocf(mp,n*(sizeof (char*))); // shrink to correct size
f4ebf3d1
GI
1882 if (mp == NULL && n > 0 ) { // reallocf never fail for size=0, but may return NULL
1883 serrno=errno;
1884 pout("Out of memory constructing scan device list (on line %d)\n", __LINE__);
1885 n = -1;
1886 goto end;
1887 };
2127e193 1888 bytes += (n)*(sizeof(char*)); // and set allocated byte count
54965743 1889
2127e193
GI
1890end:
1891 if (fd>=0)
1892 close(fd);
1893 if (n <= 0) {
1894 free(mp);
1895 mp = NULL;
832b75ed 1896 }
832b75ed 1897
2127e193 1898 *names=mp;
832b75ed 1899
2127e193
GI
1900 if (serrno>-1)
1901 errno=serrno;
1902 return n;
1903}
832b75ed 1904
2127e193
GI
1905
1906
1907bool freebsd_smart_interface::scan_smart_devices(smart_device_list & devlist,
1908 const char * type, const char * pattern /*= 0*/)
1909{
1910 if (pattern) {
1911 set_err(EINVAL, "DEVICESCAN with pattern not implemented yet");
1912 return false;
832b75ed
GG
1913 }
1914
2127e193
GI
1915 // Make namelists
1916 char * * atanames = 0; int numata = 0;
1917 if (!type || !strcmp(type, "ata")) {
1918 numata = get_dev_names_ata(&atanames);
1919 if (numata < 0) {
1920 set_err(ENOMEM);
1921 return false;
832b75ed 1922 }
2127e193
GI
1923 }
1924
cfbba5b9 1925 std::vector<std::string> scsinames;
eb07ddf2 1926 if (!type || !strcmp(type, "scsi")) { // do not export duplicated names
cfbba5b9
GI
1927 if (!get_dev_names_cam(scsinames, false)) {
1928 set_err(errno);
2127e193 1929 return false;
832b75ed 1930 }
832b75ed
GG
1931 }
1932
2127e193
GI
1933 // Add to devlist
1934 int i;
1935 if (type==NULL)
1936 type="";
1937 for (i = 0; i < numata; i++) {
1938 ata_device * atadev = get_ata_device(atanames[i], type);
1939 if (atadev)
bed94269 1940 devlist.push_back(atadev);
a7e8ffec 1941 free(atanames[i]);
2127e193 1942 }
a7e8ffec 1943 if(numata) free(atanames);
832b75ed 1944
cfbba5b9 1945 for (i = 0; i < (int)scsinames.size(); i++) {
54965743 1946 if(!*type) { // try USB autodetection if no type specified
cfbba5b9 1947 smart_device * smartdev = autodetect_smart_device(scsinames[i].c_str());
54965743 1948 if(smartdev)
bed94269 1949 devlist.push_back(smartdev);
54965743
GI
1950 }
1951 else {
cfbba5b9 1952 scsi_device * scsidev = get_scsi_device(scsinames[i].c_str(), type);
54965743 1953 if (scsidev)
bed94269 1954 devlist.push_back(scsidev);
54965743 1955 }
832b75ed 1956 }
2127e193 1957 return true;
832b75ed
GG
1958}
1959
2127e193 1960
54965743 1961#if (FREEBSDVER < 800000) // without this build fail on FreeBSD 8
2127e193 1962static char done[USB_MAX_DEVICES];
2127e193
GI
1963
1964static int usbdevinfo(int f, int a, int rec, int busno, unsigned short & vendor_id,
54965743
GI
1965 unsigned short & product_id, unsigned short & version)
1966{
832b75ed 1967
54965743
GI
1968 struct usb_device_info di;
1969 int e, p, i;
1970 char devname[256];
832b75ed 1971
54965743
GI
1972 snprintf(devname, sizeof(devname),"umass%d",busno);
1973
1974 di.udi_addr = a;
1975 e = ioctl(f, USB_DEVICEINFO, &di);
1976 if (e) {
1977 if (errno != ENXIO)
1978 printf("addr %d: I/O error\n", a);
1979 return 0;
1980 }
1981 done[a] = 1;
1982
1983 // list devices
1984 for (i = 0; i < USB_MAX_DEVNAMES; i++) {
1985 if (di.udi_devnames[i][0]) {
1986 if(strcmp(di.udi_devnames[i],devname)==0) {
1987 // device found!
1988 vendor_id = di.udi_vendorNo;
1989 product_id = di.udi_productNo;
1990 version = di.udi_releaseNo;
1991 return 1;
1992 // FIXME
1993 }
1994 }
1995 }
1996 if (!rec)
1997 return 0;
1998 for (p = 0; p < di.udi_nports; p++) {
1999 int s = di.udi_ports[p];
2000 if (s >= USB_MAX_DEVICES) {
2001 continue;
2002 }
2003 if (s == 0)
2004 printf("addr 0 should never happen!\n");
2005 else {
2006 if(usbdevinfo(f, s, 1, busno, vendor_id, product_id, version)) return 1;
2007 }
2008 }
2009 return 0;
2010}
2011#endif
832b75ed 2012
832b75ed 2013
2127e193 2014static int usbdevlist(int busno,unsigned short & vendor_id,
54965743 2015 unsigned short & product_id, unsigned short & version)
2127e193 2016{
54965743
GI
2017#if (FREEBSDVER >= 800000) // libusb2 interface
2018 struct libusb20_device *pdev = NULL;
2019 struct libusb20_backend *pbe;
2020 uint32_t matches = 0;
2021 char buf[128]; // do not change!
2022 char devname[128];
2023 uint8_t n;
2024 struct LIBUSB20_DEVICE_DESC_DECODED *pdesc;
2025
2026 pbe = libusb20_be_alloc_default();
2027
2028 while ((pdev = libusb20_be_device_foreach(pbe, pdev))) {
2029 matches++;
2030
2031 if (libusb20_dev_open(pdev, 0)) {
2032 warnx("libusb20_dev_open: could not open device");
2033 return 0;
2127e193 2034 }
54965743
GI
2035
2036 pdesc=libusb20_dev_get_device_desc(pdev);
2037
2038 snprintf(devname, sizeof(devname),"umass%d:",busno);
2039 for (n = 0; n != 255; n++) {
2040 if (libusb20_dev_get_iface_desc(pdev, n, buf, sizeof(buf)))
2041 break;
2042 if (buf[0] == 0)
2043 continue;
2044 if(strncmp(buf,devname,strlen(devname))==0){
2045 // found!
2046 vendor_id = pdesc->idVendor;
2047 product_id = pdesc->idProduct;
2048 version = pdesc->bcdDevice;
2049 libusb20_dev_close(pdev);
2050 libusb20_be_free(pbe);
2051 return 1;
2052 }
2053 }
2054
2055 libusb20_dev_close(pdev);
2056 }
2057
2058 if (matches == 0) {
2059 printf("No device match or lack of permissions.\n");
2060 }
2061
2062 libusb20_be_free(pbe);
2063
2064 return false;
2065#else // freebsd < 8.0 USB stack, ioctl interface
2066
2067 int i, f, a, rc;
2068 char buf[50];
2069 int ncont;
2070
2071 for (ncont = 0, i = 0; i < 10; i++) {
2072 snprintf(buf, sizeof(buf), "%s%d", USBDEV, i);
2073 f = open(buf, O_RDONLY);
2074 if (f >= 0) {
2075 memset(done, 0, sizeof done);
2076 for (a = 1; a < USB_MAX_DEVICES; a++) {
2077 if (!done[a]) {
2078 rc = usbdevinfo(f, a, 1, busno,vendor_id, product_id, version);
2079 if(rc) return 1;
2080 }
2081
2082 }
2083 close(f);
2084 } else {
2085 if (errno == ENOENT || errno == ENXIO)
2086 continue;
2087 warn("%s", buf);
2088 }
2089 ncont++;
2090 }
2091 return 0;
2092#endif
2127e193
GI
2093}
2094
2127e193
GI
2095smart_device * freebsd_smart_interface::autodetect_smart_device(const char * name)
2096{
2127e193 2097 unsigned short vendor_id = 0, product_id = 0, version = 0;
eb07ddf2
GI
2098 struct cam_device *cam_dev;
2099 union ccb ccb;
2100 int bus=-1;
a7e8ffec 2101 int i,c;
eb07ddf2 2102 int len;
d008864d 2103 const char * test_name = name;
54965743 2104
eb07ddf2
GI
2105 // if dev_name null, or string length zero
2106 if (!name || !(len = strlen(name)))
d008864d
GI
2107 return 0;
2108
2109 // Dereference symlinks
2110 struct stat st;
2111 std::string pathbuf;
2112 if (!lstat(name, &st) && S_ISLNK(st.st_mode)) {
2113 char * p = realpath(name, (char *)0);
2114 if (p) {
2115 pathbuf = p;
2116 free(p);
2117 test_name = pathbuf.c_str();
2118 }
2119 }
eb07ddf2
GI
2120
2121 // check ATA bus
2122 char * * atanames = 0; int numata = 0;
2123 numata = get_dev_names_ata(&atanames);
2124 if (numata > 0) {
2125 // check ATA/ATAPI devices
2126 for (i = 0; i < numata; i++) {
d008864d 2127 if(!strcmp(atanames[i],test_name)) {
a7e8ffec
GI
2128 for (c = i; c < numata; c++) free(atanames[c]);
2129 free(atanames);
d008864d 2130 return new freebsd_ata_device(this, test_name, "");
eb07ddf2 2131 }
a7e8ffec 2132 else free(atanames[i]);
832b75ed 2133 }
a7e8ffec 2134 if(numata) free(atanames);
832b75ed 2135 }
eb07ddf2
GI
2136 else {
2137 if (numata < 0)
2138 pout("Unable to get ATA device list\n");
2139 }
2140
2141 // check CAM
cfbba5b9
GI
2142 std::vector<std::string> scsinames;
2143 if (!get_dev_names_cam(scsinames, true))
2144 pout("Unable to get CAM device list\n");
2145 else if (!scsinames.empty()) {
eb07ddf2 2146 // check all devices on CAM bus
cfbba5b9 2147 for (i = 0; i < (int)scsinames.size(); i++) {
d008864d 2148 if(strcmp(scsinames[i].c_str(), test_name)==0)
eb07ddf2 2149 { // our disk device is CAM
d008864d 2150 if ((cam_dev = cam_open_device(test_name, O_RDWR)) == NULL) {
eb07ddf2
GI
2151 // open failure
2152 set_err(errno);
d008864d 2153 return 0;
eb07ddf2 2154 }
eb07ddf2
GI
2155 // zero the payload
2156 bzero(&(&ccb.ccb_h)[1], PATHINQ_SETTINGS_SIZE);
2157 ccb.ccb_h.func_code = XPT_PATH_INQ; // send PATH_INQ to the device
2158 if (ioctl(cam_dev->fd, CAMIOCOMMAND, &ccb) == -1) {
2159 warn("Get Transfer Settings CCB failed\n"
2160 "%s", strerror(errno));
2161 cam_close_device(cam_dev);
2162 return 0;
2163 }
2164 // now check if we are working with USB device, see umass.c
2165 if(strcmp(ccb.cpi.dev_name,"umass-sim") == 0) { // USB device found
2166 usbdevlist(bus,vendor_id, product_id, version);
2167 int bus=ccb.cpi.unit_number; // unit_number will match umass number
2168 cam_close_device(cam_dev);
2169 if(usbdevlist(bus,vendor_id, product_id, version)){
2170 const char * usbtype = get_usb_dev_type_by_id(vendor_id, product_id, version);
f4ebf3d1 2171 if (usbtype)
d008864d 2172 return get_sat_device(usbtype, new freebsd_scsi_device(this, test_name, ""));
eb07ddf2 2173 }
d008864d 2174 return 0;
eb07ddf2
GI
2175 }
2176#if FREEBSDVER > 800100
2177 // check if we have ATA device connected to CAM (ada)
2178 if(ccb.cpi.protocol == PROTO_ATA){
2179 cam_close_device(cam_dev);
d008864d 2180 return new freebsd_atacam_device(this, test_name, "");
eb07ddf2
GI
2181 }
2182#endif
2183 // close cam device, we don`t need it anymore
2184 cam_close_device(cam_dev);
2185 // handle as usual scsi
d008864d 2186 return new freebsd_scsi_device(this, test_name, "");
eb07ddf2
GI
2187 }
2188 }
eb07ddf2 2189 }
d008864d
GI
2190 // device is LSI raid supported by mfi driver
2191 if(!strncmp("/dev/mfid", test_name, strlen("/dev/mfid")))
2192 set_err(EINVAL, "To monitor disks on LSI RAID load mfip.ko module and run 'smartctl -a /dev/passX' to show SMART information");
eb07ddf2 2193 // device type unknown
2127e193
GI
2194 return 0;
2195}
2196
2197
2198smart_device * freebsd_smart_interface::get_custom_smart_device(const char * name, const char * type)
2199{
2200 // 3Ware ?
eb07ddf2
GI
2201 static const char * fbsd_dev_twe_ctrl = "/dev/twe";
2202 static const char * fbsd_dev_twa_ctrl = "/dev/twa";
2203 int disknum = -1, n1 = -1, n2 = -1, contr = -1;
2204
2127e193
GI
2205 if (sscanf(type, "3ware,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {
2206 if (n2 != (int)strlen(type)) {
2207 set_err(EINVAL, "Option -d 3ware,N requires N to be a non-negative integer");
2208 return 0;
2209 }
2210 if (!(0 <= disknum && disknum <= 127)) {
2211 set_err(EINVAL, "Option -d 3ware,N (N=%d) must have 0 <= N <= 127", disknum);
2212 return 0;
2213 }
eb07ddf2
GI
2214
2215 // guess 3ware device type based on device name
2216 if (!strncmp(fbsd_dev_twa_ctrl, name, strlen(fbsd_dev_twa_ctrl))){
2217 contr=CONTROLLER_3WARE_9000_CHAR;
2218 }
2219 if (!strncmp(fbsd_dev_twe_ctrl, name, strlen(fbsd_dev_twe_ctrl))){
2220 contr=CONTROLLER_3WARE_678K_CHAR;
2221 }
2222
2223 if(contr == -1){
2224 set_err(EINVAL, "3ware controller type unknown, use %sX or %sX devices",
2225 fbsd_dev_twe_ctrl, fbsd_dev_twa_ctrl);
2226 return 0;
2227 }
54965743 2228 return new freebsd_escalade_device(this, name, contr, disknum);
2127e193
GI
2229 }
2230
2231 // Highpoint ?
2232 int controller = -1, channel = -1; disknum = 1;
2233 n1 = n2 = -1; int n3 = -1;
2234 if (sscanf(type, "hpt,%n%d/%d%n/%d%n", &n1, &controller, &channel, &n2, &disknum, &n3) >= 2 || n1 == 4) {
2235 int len = strlen(type);
2236 if (!(n2 == len || n3 == len)) {
2237 set_err(EINVAL, "Option '-d hpt,L/M/N' supports 2-3 items");
2238 return 0;
2239 }
2240 if (!(1 <= controller && controller <= 8)) {
2241 set_err(EINVAL, "Option '-d hpt,L/M/N' invalid controller id L supplied");
2242 return 0;
2243 }
d008864d 2244 if (!(1 <= channel && channel <= 16)) {
2127e193
GI
2245 set_err(EINVAL, "Option '-d hpt,L/M/N' invalid channel number M supplied");
2246 return 0;
2247 }
2248 if (!(1 <= disknum && disknum <= 15)) {
2249 set_err(EINVAL, "Option '-d hpt,L/M/N' invalid pmport number N supplied");
2250 return 0;
2251 }
2252 return new freebsd_highpoint_device(this, name, controller, channel, disknum);
832b75ed
GG
2253 }
2254
2127e193
GI
2255 // CCISS ?
2256 disknum = n1 = n2 = -1;
2257 if (sscanf(type, "cciss,%n%d%n", &n1, &disknum, &n2) == 1 || n1 == 6) {
2258 if (n2 != (int)strlen(type)) {
2259 set_err(EINVAL, "Option -d cciss,N requires N to be a non-negative integer");
2260 return 0;
2261 }
e9583e0c
GI
2262 if (!(0 <= disknum && disknum <= 127)) {
2263 set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 127", disknum);
2127e193
GI
2264 return 0;
2265 }
2266 return new freebsd_cciss_device(this, name, disknum);
832b75ed 2267 }
eb07ddf2
GI
2268#if FREEBSDVER > 800100
2269 // adaX devices ?
2270 if(!strcmp(type,"atacam"))
2271 return new freebsd_atacam_device(this, name, "");
2272#endif
d008864d
GI
2273 // Areca?
2274 disknum = n1 = n2 = -1;
f4e463df
GI
2275 int encnum = 1;
2276 if (sscanf(type, "areca,%n%d/%d%n", &n1, &disknum, &encnum, &n2) >= 1 || n1 == 6) {
2277 if (!(1 <= disknum && disknum <= 128)) {
2278 set_err(EINVAL, "Option -d areca,N/E (N=%d) must have 1 <= N <= 128", disknum);
d008864d
GI
2279 return 0;
2280 }
f4e463df
GI
2281 if (!(1 <= encnum && encnum <= 8)) {
2282 set_err(EINVAL, "Option -d areca,N/E (E=%d) must have 1 <= E <= 8", encnum);
d008864d
GI
2283 return 0;
2284 }
2285 return new freebsd_areca_device(this, name, disknum);
2286 }
832b75ed 2287
2127e193 2288 return 0;
832b75ed
GG
2289}
2290
54965743 2291std::string freebsd_smart_interface::get_valid_custom_dev_types_str()
2127e193 2292{
f4e463df 2293 return "3ware,N, hpt,L/M/N, cciss,N, areca,N/E"
eb07ddf2
GI
2294#if FREEBSDVER > 800100
2295 ", atacam"
2296#endif
2297 ;
2127e193
GI
2298}
2299
2127e193
GI
2300} // namespace
2301
2127e193
GI
2302/////////////////////////////////////////////////////////////////////////////
2303/// Initialize platform interface and register with smi()
2304
2305void smart_interface::init()
2306{
2307 static os_freebsd::freebsd_smart_interface the_interface;
2308 smart_interface::set(&the_interface);
832b75ed 2309}