4 * Home page of code is: http://smartmontools.sourceforge.net
6 * Copyright (C) 2003-6 Eduard Martinescu <smartmontools-support@lists.sourceforge.net>
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)
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.
19 #include <sys/types.h>
24 #include <cam/scsi/scsi_message.h>
39 #include "os_freebsd.h"
41 static const char *filenameandversion
="$Id: os_freebsd.cpp,v 1.51 2006/09/17 03:17:53 dpgilbert Exp $";
43 const char *os_XXXX_c_cvsid
="$Id: os_freebsd.cpp,v 1.51 2006/09/17 03:17:53 dpgilbert Exp $" \
44 ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_FREEBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID
;
46 // to hold onto exit code for atexit routine
47 extern int exitstatus
;
49 // Private table of open devices: guaranteed zero on startup since
50 // part of static data.
51 struct freebsd_dev_channel
*devicetable
[FREEBSD_MAXDEV
];
53 // forward declaration
54 static int parse_ata_chan_dev(const char * dev_name
, struct freebsd_dev_channel
*ch
);
56 // print examples for smartctl
57 void print_smartctl_examples(){
58 printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
59 #ifdef HAVE_GETOPT_LONG
61 " smartctl -a /dev/ad0 (Prints all SMART information)\n\n"
62 " smartctl --smart=on --offlineauto=on --saveauto=on /dev/ad0\n"
63 " (Enables SMART on first disk)\n\n"
64 " smartctl -t long /dev/ad0 (Executes extended disk self-test)\n\n"
65 " smartctl --attributes --log=selftest --quietmode=errorsonly /dev/ad0\n"
66 " (Prints Self-Test & Attribute errors)\n"
67 " (Prints Self-Test & Attribute errors)\n\n"
68 " smartctl -a --device=3ware,2 /dev/twa0\n"
69 " smartctl -a --device=3ware,2 /dev/twe0\n"
70 " (Prints all SMART information for ATA disk on\n"
71 " third port of first 3ware RAID controller)\n"
75 " smartctl -a /dev/ad0 (Prints all SMART information)\n"
76 " smartctl -s on -o on -S on /dev/ad0 (Enables SMART on first disk)\n"
77 " smartctl -t long /dev/ad0 (Executes extended disk self-test)\n"
78 " smartctl -A -l selftest -q errorsonly /dev/ad0\n"
79 " (Prints Self-Test & Attribute errors)\n"
80 " smartctl -a -d 3ware,2 /dev/twa0\n"
81 " smartctl -a -d 3ware,2 /dev/twe0\n"
87 // Like open(). Return positive integer handle, used by functions below only. mode=="ATA" or "SCSI".
88 int deviceopen (const char* dev
, char* mode __unused
) {
89 struct freebsd_dev_channel
*fdchan
;
92 // Search table for a free entry
93 for (i
=0; i
<FREEBSD_MAXDEV
; i
++)
97 // If no free entry found, return error. We have max allowed number
98 // of "file descriptors" already allocated.
99 if (i
==FREEBSD_MAXDEV
) {
104 fdchan
= (struct freebsd_dev_channel
*)calloc(1,sizeof(struct freebsd_dev_channel
));
105 if (fdchan
== NULL
) {
106 // errno already set by call to malloc()
110 parse_ok
= parse_ata_chan_dev (dev
,fdchan
);
111 if (parse_ok
== CONTROLLER_UNKNOWN
) {
114 return -1; // can't handle what we don't know
117 if (parse_ok
== CONTROLLER_ATA
) {
119 if ((fdchan
->device
= open(dev
,O_RDONLY
))<0) {
121 if ((fdchan
->atacommand
= open("/dev/ata",O_RDWR
))<0) {
123 int myerror
= errno
; //preserve across free call
130 if (parse_ok
== CONTROLLER_3WARE_678K_CHAR
) {
132 sprintf(buf
,"/dev/twe%d",fdchan
->device
);
134 if ((fdchan
->device
= open(buf
,O_RDWR
))<0) {
136 if ((fdchan
->atacommand
= open(buf
,O_RDWR
))<0) {
138 int myerror
= errno
; // preserver across free call
145 if (parse_ok
== CONTROLLER_3WARE_9000_CHAR
) {
147 sprintf(buf
,"/dev/twa%d",fdchan
->device
);
149 if ((fdchan
->device
= open(buf
,O_RDWR
))<0) {
151 if ((fdchan
->atacommand
= open(buf
,O_RDWR
))<0) {
153 int myerror
= errno
; // preserver across free call
160 if (parse_ok
== CONTROLLER_SCSI
) {
161 // this is really a NO-OP, as the parse takes care
162 // of filling in correct details
165 // return pointer to "file descriptor" table entry, properly offset.
166 devicetable
[i
]=fdchan
;
167 return i
+FREEBSD_FDOFFSET
;
170 // Returns 1 if device not available/open/found else 0. Also shifts fd into valid range.
171 static int isnotopen(int *fd
, struct freebsd_dev_channel
** fdchan
) {
172 // put valid "file descriptor" into range 0...FREEBSD_MAXDEV-1
173 *fd
-= FREEBSD_FDOFFSET
;
175 // check for validity of "file descriptor".
176 if (*fd
<0 || *fd
>=FREEBSD_MAXDEV
|| !((*fdchan
)=devicetable
[*fd
])) {
184 // Like close(). Acts on handles returned by above function.
185 int deviceclose (int fd
) {
186 struct freebsd_dev_channel
*fdchan
;
189 // check for valid file descriptor
190 if (isnotopen(&fd
, &fdchan
))
194 // did we allocate a SCSI device name?
196 free(fdchan
->devname
);
198 // close device, if open
201 failed
=close(fdchan
->device
);
203 if (fdchan
->atacommand
)
204 failed
=close(fdchan
->atacommand
);
207 if (fdchan
->scsicontrol
)
208 failed
=close(fdchan
->scsicontrol
);
210 // if close succeeded, then remove from device list
211 // Eduard, should we also remove it from list if close() fails? I'm
212 // not sure. Here I only remove it from list if close() worked.
215 devicetable
[fd
]=NULL
;
223 #define NO_DISK_3WARE 2
227 // Utility function for printing warnings
228 void printwarning(int msgNo
, const char* extra
) {
229 static int printed
[] = {0,0,0,0};
230 static const char* message
[]={
231 "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",
233 "Error SMART Status command failed\nPlease get assistance from \n" PACKAGE_HOMEPAGE
"\nRegister values returned from SMART Status command are:\n",
235 "You must specify a DISK # for 3ware drives with -d 3ware,<n> where <n> begins with 1 for first disk drive\n",
237 "ATA support is not provided for this kernel version. Please ugrade to a recent 5-CURRENT kernel (post 09/01/2003 or so)\n"
240 if (msgNo
>= 0 && msgNo
<= MAX_MSG
) {
241 if (!printed
[msgNo
]) {
243 pout("%s", message
[msgNo
]);
252 // Interface to ATA devices. See os_linux.c
253 int marvell_command_interface(int fd __unused
, smart_command_set command __unused
, int select __unused
, char *data __unused
) {
257 int highpoint_command_interface(int fd __unused
, smart_command_set command __unused
, int select __unused
, char *data __unused
)
262 int ata_command_interface(int fd
, smart_command_set command
, int select
, char *data
) {
263 #if !defined(ATAREQUEST) && !defined(IOCATAREQUEST)
264 // sorry, but without ATAng, we can't do anything here
265 printwarning(BAD_KERNEL
,NULL
);
269 struct freebsd_dev_channel
* con
;
270 int retval
, copydata
=0;
272 struct ata_ioc_request request
;
274 struct ata_cmd iocmd
;
276 unsigned char buff
[512];
278 // check that "file descriptor" is valid
279 if (isnotopen(&fd
,&con
))
285 bzero(&request
,sizeof(struct ata_ioc_request
));
287 bzero(&iocmd
,sizeof(struct ata_cmd
));
291 #ifndef IOCATAREQUEST
292 iocmd
.cmd
=ATAREQUEST
;
293 iocmd
.channel
=con
->channel
;
294 iocmd
.device
=con
->device
;
295 #define request iocmd.u.request
298 request
.u
.ata
.command
=ATA_SMART_CMD
;
302 request
.u
.ata
.feature
=ATA_SMART_READ_VALUES
;
303 request
.u
.ata
.lba
=0xc24f<<8;
304 request
.flags
=ATA_CMD_READ
;
305 request
.data
=(char *)buff
;
309 case READ_THRESHOLDS
:
310 request
.u
.ata
.feature
=ATA_SMART_READ_THRESHOLDS
;
311 request
.u
.ata
.count
=1;
312 request
.u
.ata
.lba
=1|(0xc24f<<8);
313 request
.flags
=ATA_CMD_READ
;
314 request
.data
=(char *)buff
;
319 request
.u
.ata
.feature
=ATA_SMART_READ_LOG_SECTOR
;
320 request
.u
.ata
.lba
=select
|(0xc24f<<8);
321 request
.u
.ata
.count
=1;
322 request
.flags
=ATA_CMD_READ
;
323 request
.data
=(char *)buff
;
328 request
.u
.ata
.command
=ATA_IDENTIFY_DEVICE
;
329 request
.flags
=ATA_CMD_READ
;
330 request
.data
=(char *)buff
;
335 request
.u
.ata
.command
=ATA_IDENTIFY_PACKET_DEVICE
;
336 request
.flags
=ATA_CMD_READ
;
337 request
.data
=(char *)buff
;
342 request
.u
.ata
.feature
=ATA_SMART_ENABLE
;
343 request
.u
.ata
.lba
=0xc24f<<8;
344 request
.flags
=ATA_CMD_CONTROL
;
347 request
.u
.ata
.feature
=ATA_SMART_DISABLE
;
348 request
.u
.ata
.lba
=0xc24f<<8;
349 request
.flags
=ATA_CMD_CONTROL
;
352 // NOTE: According to ATAPI 4 and UP, this command is obsolete
353 request
.u
.ata
.feature
=ATA_SMART_AUTO_OFFLINE
;
354 request
.u
.ata
.lba
=select
|(0xc24f<<8);
355 request
.flags
=ATA_CMD_CONTROL
;
358 request
.u
.ata
.feature
=ATA_SMART_AUTOSAVE
;
359 request
.u
.ata
.count
=0xf1; // to enable autosave
360 request
.u
.ata
.lba
=0xc24f<<8;
361 request
.flags
=ATA_CMD_CONTROL
;
363 case IMMEDIATE_OFFLINE
:
364 request
.u
.ata
.feature
=ATA_SMART_IMMEDIATE_OFFLINE
;
365 request
.u
.ata
.lba
= select
|(0xc24f<<8); // put test in sector
366 request
.flags
=ATA_CMD_CONTROL
;
368 case STATUS_CHECK
: // same command, no HDIO in FreeBSD
370 // this command only says if SMART is working. It could be
371 // replaced with STATUS_CHECK below.
372 request
.u
.ata
.feature
=ATA_SMART_STATUS
;
373 request
.u
.ata
.lba
=0xc24f<<8;
374 request
.flags
=ATA_CMD_CONTROL
;
377 pout("Unrecognized command %d in ata_command_interface()\n"
378 "Please contact " PACKAGE_BUGREPORT
"\n", command
);
383 if (command
==STATUS_CHECK
){
384 unsigned const char normal_lo
=0x4f, normal_hi
=0xc2;
385 unsigned const char failed_lo
=0xf4, failed_hi
=0x2c;
386 unsigned char low
,high
;
389 if ((retval
=ioctl(con
->device
, IOCATAREQUEST
, &request
)) || request
.error
)
391 if ((retval
=ioctl(con
->atacommand
, IOCATA
, &iocmd
)) || request
.error
)
395 #if __FreeBSD_version < 502000
396 printwarning(NO_RETURN
,NULL
);
399 high
= (request
.u
.ata
.lba
>> 16) & 0xff;
400 low
= (request
.u
.ata
.lba
>> 8) & 0xff;
402 // Cyl low and Cyl high unchanged means "Good SMART status"
403 if (low
==normal_lo
&& high
==normal_hi
)
406 // These values mean "Bad SMART status"
407 if (low
==failed_lo
&& high
==failed_hi
)
410 // We haven't gotten output that makes sense; print out some debugging info
412 sprintf(buf
,"CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
413 (int)request
.u
.ata
.command
,
414 (int)request
.u
.ata
.feature
,
415 (int)request
.u
.ata
.count
,
416 (int)((request
.u
.ata
.lba
) & 0xff),
417 (int)((request
.u
.ata
.lba
>>8) & 0xff),
418 (int)((request
.u
.ata
.lba
>>16) & 0xff),
420 printwarning(BAD_SMART
,buf
);
425 if ((retval
=ioctl(con
->device
, IOCATAREQUEST
, &request
)) || request
.error
)
427 if ((retval
=ioctl(con
->atacommand
, IOCATA
, &iocmd
)) || request
.error
)
434 memcpy(data
, buff
, 512);
441 // Interface to SCSI devices. See os_linux.c
442 int do_scsi_cmnd_io(int fd
, struct scsi_cmnd_io
* iop
, int report
)
444 struct freebsd_dev_channel
* con
= NULL
;
445 struct cam_device
* cam_dev
= NULL
;
451 const unsigned char * ucp
= iop
->cmnd
;
454 np
= scsi_get_opcode_name(ucp
[0]);
455 pout(" [%s: ", np
? np
: "<unknown opcode>");
456 for (k
= 0; k
< iop
->cmnd_len
; ++k
)
457 pout("%02x ", ucp
[k
]);
459 (DXFER_TO_DEVICE
== iop
->dxfer_dir
) && (iop
->dxferp
)) {
460 int trunc
= (iop
->dxfer_len
> 256) ? 1 : 0;
462 pout("]\n Outgoing data, len=%d%s:\n", (int)iop
->dxfer_len
,
463 (trunc
? " [only first 256 bytes shown]" : ""));
464 dStrHex(iop
->dxferp
, (trunc
? 256 : iop
->dxfer_len
) , 1);
470 // check that "file descriptor" is valid
471 if (isnotopen(&fd
,&con
))
475 if (!(cam_dev
= cam_open_spec_device(con
->devname
,con
->unitnum
,O_RDWR
,NULL
))) {
476 warnx("%s",cam_errbuf
);
480 if (!(ccb
= cam_getccb(cam_dev
))) {
481 warnx("error allocating ccb");
485 // clear out structure, except for header that was filled in for us
486 bzero(&(&ccb
->ccb_h
)[1],
487 sizeof(struct ccb_scsiio
) - sizeof(struct ccb_hdr
));
489 cam_fill_csio(&ccb
->csio
,
492 /* flags */ (iop
->dxfer_dir
== DXFER_NONE
? CAM_DIR_NONE
:(iop
->dxfer_dir
== DXFER_FROM_DEVICE
? CAM_DIR_IN
: CAM_DIR_OUT
)),
493 /* tagaction */ MSG_SIMPLE_Q_TAG
,
494 /* dataptr */ iop
->dxferp
,
495 /* datalen */ iop
->dxfer_len
,
496 /* senselen */ iop
->max_sense_len
,
497 /* cdblen */ iop
->cmnd_len
,
498 /* timout (converted to seconds) */ iop
->timeout
*1000);
499 memcpy(ccb
->csio
.cdb_io
.cdb_bytes
,iop
->cmnd
,iop
->cmnd_len
);
501 if (cam_send_ccb(cam_dev
,ccb
) < 0) {
502 warn("error sending SCSI ccb");
503 #if __FreeBSD_version > 500000
504 cam_error_print(cam_dev
,ccb
,CAM_ESF_ALL
,CAM_EPF_ALL
,stderr
);
510 if ((ccb
->ccb_h
.status
& CAM_STATUS_MASK
) != CAM_REQ_CMP
) {
511 #if __FreeBSD_version > 500000
512 cam_error_print(cam_dev
,ccb
,CAM_ESF_ALL
,CAM_EPF_ALL
,stderr
);
519 memcpy(iop
->sensep
,&(ccb
->csio
.sense_data
),sizeof(struct scsi_sense_data
));
520 iop
->resp_sense_len
= sizeof(struct scsi_sense_data
);
523 iop
->scsi_status
= ccb
->csio
.scsi_status
;
528 cam_close_device(cam_dev
);
534 trunc
= (iop
->dxfer_len
> 256) ? 1 : 0;
536 pout(" Incoming data, len=%d%s:\n", (int)iop
->dxfer_len
,
537 (trunc
? " [only first 256 bytes shown]" : ""));
538 dStrHex(iop
->dxferp
, (trunc
? 256 : iop
->dxfer_len
) , 1);
543 // Interface to ATA devices behind 3ware escalade RAID controller cards. See os_linux.c
545 #define BUFFER_LEN_678K_CHAR ( sizeof(struct twe_usercommand) ) // 520
546 #define BUFFER_LEN_9000_CHAR ( sizeof(TW_OSLI_IOCTL_NO_DATA_BUF) + sizeof(TWE_Command) ) // 2048
547 #define TW_IOCTL_BUFFER_SIZE ( MAX(BUFFER_LEN_678K_CHAR, BUFFER_LEN_9000_CHAR) )
549 int escalade_command_interface(int fd
, int disknum
, int escalade_type
, smart_command_set command
, int select
, char *data
) {
550 // to hold true file descriptor
551 struct freebsd_dev_channel
* con
;
553 // return value and buffer for ioctl()
554 int ioctlreturn
, readdata
=0;
555 struct twe_usercommand
* cmd_twe
= NULL
;
556 TW_OSLI_IOCTL_NO_DATA_BUF
* cmd_twa
= NULL
;
557 TWE_Command_ATA
* ata
= NULL
;
559 // Used by both the SCSI and char interfaces
560 char ioctl_buffer
[TW_IOCTL_BUFFER_SIZE
];
563 printwarning(NO_DISK_3WARE
,NULL
);
567 // check that "file descriptor" is valid
568 if (isnotopen(&fd
,&con
))
571 memset(ioctl_buffer
, 0, TW_IOCTL_BUFFER_SIZE
);
573 if (escalade_type
==CONTROLLER_3WARE_9000_CHAR
) {
574 cmd_twa
= (TW_OSLI_IOCTL_NO_DATA_BUF
*)ioctl_buffer
;
575 cmd_twa
->pdata
= ((TW_OSLI_IOCTL_WITH_PAYLOAD
*)cmd_twa
)->payload
.data_buf
;
576 cmd_twa
->driver_pkt
.buffer_length
= 512;
577 ata
= (TWE_Command_ATA
*)&cmd_twa
->cmd_pkt
.command
.cmd_pkt_7k
;
578 } else if (escalade_type
==CONTROLLER_3WARE_678K_CHAR
) {
579 cmd_twe
= (struct twe_usercommand
*)ioctl_buffer
;
580 ata
= &cmd_twe
->tu_command
.ata
;
582 pout("Unrecognized escalade_type %d in freebsd_3ware_command_interface(disk %d)\n"
583 "Please contact " PACKAGE_BUGREPORT
"\n", escalade_type
, disknum
);
588 ata
->opcode
= TWE_OP_ATA_PASSTHROUGH
;
590 // Same for (almost) all commands - but some reset below
591 ata
->request_id
= 0xFF;
596 ata
->drive_head
= 0x0;
599 // All SMART commands use this CL/CH signature. These are magic
600 // values from the ATA specifications.
601 ata
->cylinder_lo
= 0x4F;
602 ata
->cylinder_hi
= 0xC2;
604 // SMART ATA COMMAND REGISTER value
605 ata
->command
= ATA_SMART_CMD
;
607 // Is this a command that reads or returns 512 bytes?
608 // passthru->param values are:
609 // 0x0 - non data command without TFR write check,
610 // 0x8 - non data command with TFR write check,
611 // 0xD - data command that returns data to host from device
612 // 0xF - data command that writes data from host to device
613 // passthru->size values are 0x5 for non-data and 0x07 for data
614 if (command
== READ_VALUES
||
615 command
== READ_THRESHOLDS
||
616 command
== READ_LOG
||
617 command
== IDENTIFY
||
618 command
== WRITE_LOG
) {
620 if (escalade_type
==CONTROLLER_3WARE_678K_CHAR
) {
621 cmd_twe
->tu_data
= data
;
622 cmd_twe
->tu_size
= 512;
624 ata
->sgl_offset
= 0x5;
627 ata
->sector_count
= 0x1;
628 // For 64-bit to work correctly, up the size of the command packet
629 // in dwords by 1 to account for the 64-bit single sgl 'address'
630 // field. Note that this doesn't agree with the typedefs but it's
631 // right (agree with kernel driver behavior/typedefs).
632 //if (sizeof(long)==8)
636 // Non data command -- but doesn't use large sector
637 // count register values.
638 ata
->sgl_offset
= 0x0;
641 ata
->sector_count
= 0x0;
644 // Now set ATA registers depending upon command
646 case CHECK_POWER_MODE
:
647 ata
->command
= ATA_CHECK_POWER_MODE
;
649 ata
->cylinder_lo
= 0;
650 ata
->cylinder_hi
= 0;
653 ata
->features
= ATA_SMART_READ_VALUES
;
655 case READ_THRESHOLDS
:
656 ata
->features
= ATA_SMART_READ_THRESHOLDS
;
659 ata
->features
= ATA_SMART_READ_LOG_SECTOR
;
660 // log number to return
661 ata
->sector_num
= select
;
665 ata
->features
= ATA_SMART_WRITE_LOG_SECTOR
;
666 ata
->sector_count
= 1;
667 ata
->sector_num
= select
;
668 ata
->param
= 0xF; // PIO data write
671 // ATA IDENTIFY DEVICE
672 ata
->command
= ATA_IDENTIFY_DEVICE
;
674 ata
->cylinder_lo
= 0;
675 ata
->cylinder_hi
= 0;
678 // 3WARE controller can NOT have packet device internally
679 pout("WARNING - NO DEVICE FOUND ON 3WARE CONTROLLER (disk %d)\n", disknum
);
683 ata
->features
= ATA_SMART_ENABLE
;
686 ata
->features
= ATA_SMART_DISABLE
;
689 ata
->features
= ATA_SMART_AUTO_OFFLINE
;
690 // Enable or disable?
691 ata
->sector_count
= select
;
694 ata
->features
= ATA_SMART_AUTOSAVE
;
695 // Enable or disable?
696 ata
->sector_count
= select
;
698 case IMMEDIATE_OFFLINE
:
699 ata
->features
= ATA_SMART_IMMEDIATE_OFFLINE
;
700 // What test type to run?
701 ata
->sector_num
= select
;
704 ata
->features
= ATA_SMART_STATUS
;
707 // This is JUST to see if SMART is enabled, by giving SMART status
708 // command. But it doesn't say if status was good, or failing.
709 // See below for the difference.
710 ata
->features
= ATA_SMART_STATUS
;
713 pout("Unrecognized command %d in freebsd_3ware_command_interface(disk %d)\n"
714 "Please contact " PACKAGE_BUGREPORT
"\n", command
, disknum
);
719 // Now send the command down through an ioctl()
720 if (escalade_type
==CONTROLLER_3WARE_9000_CHAR
) {
722 ioctlreturn
=ioctl(con
->device
,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH
,cmd_twa
);
724 ioctlreturn
=ioctl(con
->atacommand
,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH
,cmd_twa
);
728 ioctlreturn
=ioctl(con
->device
,TWEIO_COMMAND
,cmd_twe
);
730 ioctlreturn
=ioctl(con
->atacommand
,TWEIO_COMMAND
,cmd_twe
);
734 // Deal with the different error cases
741 // See if the ATA command failed. Now that we have returned from
742 // the ioctl() call, if passthru is valid, then:
743 // - ata->status contains the 3ware controller STATUS
744 // - ata->command contains the ATA STATUS register
745 // - ata->features contains the ATA ERROR register
747 // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS
748 // If bit 0 (error bit) is set, then ATA ERROR register is valid.
749 // While we *might* decode the ATA ERROR register, at the moment it
750 // doesn't make much sense: we don't care in detail why the error
753 if (ata
->status
|| (ata
->command
& 0x21)) {
754 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
);
759 // If this is a read data command, copy data to output buffer
761 if (escalade_type
==CONTROLLER_3WARE_9000_CHAR
)
762 memcpy(data
, cmd_twa
->pdata
, 512);
765 // For STATUS_CHECK, we need to check register values
766 if (command
==STATUS_CHECK
) {
768 // To find out if the SMART RETURN STATUS is good or failing, we
769 // need to examine the values of the Cylinder Low and Cylinder
772 unsigned short cyl_lo
=ata
->cylinder_lo
;
773 unsigned short cyl_hi
=ata
->cylinder_hi
;
775 // If values in Cyl-LO and Cyl-HI are unchanged, SMART status is good.
776 if (cyl_lo
==0x4F && cyl_hi
==0xC2)
779 // If values in Cyl-LO and Cyl-HI are as follows, SMART status is FAIL
780 if (cyl_lo
==0xF4 && cyl_hi
==0x2C)
787 // copy sector count register (one byte!) to return data
788 if (command
==CHECK_POWER_MODE
)
789 *data
=*(char *)&(ata
->sector_count
);
791 // look for nonexistent devices/ports
792 if (command
==IDENTIFY
&& !nonempty((unsigned char *)data
, 512)) {
800 static int get_tw_channel_unit (const char* name
, int* unit
, int* dev
) {
803 /* device node sanity check */
804 for (p
= name
+ 3; *p
; p
++)
805 if (*p
< '0' || *p
> '9')
807 if (strlen(name
) > 4 && *(name
+ 3) == '0')
813 /* no need for unit number */
820 #ifndef IOCATAREQUEST
821 static int get_ata_channel_unit ( const char* name
, int* unit
, int* dev
) {
827 // there is no direct correlation between name 'ad0, ad1, ...' and
828 // channel/unit number. So we need to iterate through the possible
829 // channels and check each unit to see if we match names
830 struct ata_cmd iocmd
;
833 bzero(&iocmd
, sizeof(struct ata_cmd
));
835 if ((fd
= open("/dev/ata", O_RDWR
)) < 0)
838 iocmd
.cmd
= ATAGMAXCHANNEL
;
839 if (ioctl(fd
, IOCATA
, &iocmd
) < 0) {
843 maxunit
= iocmd
.u
.maxchan
;
844 for (*unit
= 0; *unit
< maxunit
; (*unit
)++) {
845 iocmd
.channel
= *unit
;
847 iocmd
.cmd
= ATAGPARM
;
848 if (ioctl(fd
, IOCATA
, &iocmd
) < 0) {
852 if (iocmd
.u
.param
.type
[0] && !strcmp(name
,iocmd
.u
.param
.name
[0])) {
856 if (iocmd
.u
.param
.type
[1] && !strcmp(name
,iocmd
.u
.param
.name
[1])) {
862 if (*unit
== maxunit
)
870 // Guess device type (ata or scsi) based on device name (FreeBSD
871 // specific) SCSI device name in FreeBSD can be sd, sr, scd, st, nst,
872 // osst, nosst and sg.
873 static const char * fbsd_dev_prefix
= "/dev/";
874 static const char * fbsd_dev_ata_disk_prefix
= "ad";
875 static const char * fbsd_dev_scsi_disk_plus
= "da";
876 static const char * fbsd_dev_scsi_tape1
= "sa";
877 static const char * fbsd_dev_scsi_tape2
= "nsa";
878 static const char * fbsd_dev_scsi_tape3
= "esa";
879 static const char * fbsd_dev_twe_ctrl
= "twe";
880 static const char * fbsd_dev_twa_ctrl
= "twa";
882 static int parse_ata_chan_dev(const char * dev_name
, struct freebsd_dev_channel
*chan
) {
884 int dev_prefix_len
= strlen(fbsd_dev_prefix
);
886 // if dev_name null, or string length zero
887 if (!dev_name
|| !(len
= strlen(dev_name
)))
888 return CONTROLLER_UNKNOWN
;
890 // Remove the leading /dev/... if it's there
891 if (!strncmp(fbsd_dev_prefix
, dev_name
, dev_prefix_len
)) {
892 if (len
<= dev_prefix_len
)
893 // if nothing else in the string, unrecognized
894 return CONTROLLER_UNKNOWN
;
895 // else advance pointer to following characters
896 dev_name
+= dev_prefix_len
;
898 // form /dev/ad* or ad*
899 if (!strncmp(fbsd_dev_ata_disk_prefix
, dev_name
,
900 strlen(fbsd_dev_ata_disk_prefix
))) {
901 #ifndef IOCATAREQUEST
903 if (get_ata_channel_unit(dev_name
,&(chan
->channel
),&(chan
->device
))<0) {
904 return CONTROLLER_UNKNOWN
;
908 return CONTROLLER_ATA
;
911 // form /dev/da* or da*
912 if (!strncmp(fbsd_dev_scsi_disk_plus
, dev_name
,
913 strlen(fbsd_dev_scsi_disk_plus
)))
916 // form /dev/sa* or sa*
917 if (!strncmp(fbsd_dev_scsi_tape1
, dev_name
,
918 strlen(fbsd_dev_scsi_tape1
)))
921 // form /dev/nsa* or nsa*
922 if (!strncmp(fbsd_dev_scsi_tape2
, dev_name
,
923 strlen(fbsd_dev_scsi_tape2
)))
926 // form /dev/esa* or esa*
927 if (!strncmp(fbsd_dev_scsi_tape3
, dev_name
,
928 strlen(fbsd_dev_scsi_tape3
)))
931 if (!strncmp(fbsd_dev_twa_ctrl
,dev_name
,
932 strlen(fbsd_dev_twa_ctrl
))) {
934 if (get_tw_channel_unit(dev_name
,&(chan
->channel
),&(chan
->device
))<0) {
935 return CONTROLLER_UNKNOWN
;
938 else if (get_tw_channel_unit(dev_name
,NULL
,NULL
)<0) {
939 return CONTROLLER_UNKNOWN
;
941 return CONTROLLER_3WARE_9000_CHAR
;
944 if (!strncmp(fbsd_dev_twe_ctrl
,dev_name
,
945 strlen(fbsd_dev_twe_ctrl
))) {
947 if (get_tw_channel_unit(dev_name
,&(chan
->channel
),&(chan
->device
))<0) {
948 return CONTROLLER_UNKNOWN
;
951 else if (get_tw_channel_unit(dev_name
,NULL
,NULL
)<0) {
952 return CONTROLLER_UNKNOWN
;
954 return CONTROLLER_3WARE_678K_CHAR
;
957 // we failed to recognize any of the forms
958 return CONTROLLER_UNKNOWN
;
962 if (!(chan
->devname
= (char *)calloc(1,DEV_IDLEN
+1)))
963 return CONTROLLER_UNKNOWN
;
965 if (cam_get_device(dev_name
,chan
->devname
,DEV_IDLEN
,&(chan
->unitnum
)) == -1)
966 return CONTROLLER_UNKNOWN
;
968 return CONTROLLER_SCSI
;
972 int guess_device_type (const char* dev_name
) {
973 return parse_ata_chan_dev(dev_name
,NULL
);
976 // global variable holding byte count of allocated memory
977 extern long long bytes
;
979 // we are going to take advantage of the fact that FreeBSD's devfs will only
980 // have device entries for devices that exist. So if we get the equivilent of
981 // ls /dev/ad?, we have all the ATA devices on the system
983 // If any errors occur, leave errno set as it was returned by the
984 // system call, and return <0.
988 // -2 to -5 errors in glob
990 int get_dev_names(char*** names
, const char* prefix
) {
996 char pattern1
[128],pattern2
[128];
998 bzero(&globbuf
,sizeof(globbuf
));
999 // in case of non-clean exit
1002 // handle 0-99 possible devices, will still be limited by MAX_NUM_DEV
1003 sprintf(pattern1
,"/dev/%s[0-9]",prefix
);
1004 sprintf(pattern2
,"/dev/%s[0-9][0-9]",prefix
);
1006 // Use glob to look for any directory entries matching the patterns
1007 // first call inits with first pattern match, second call appends
1008 // to first list. Turn on NOCHECK for second call. This results in no
1009 // error if no more matches found, however it does append the actual
1010 // pattern to the list of paths....
1011 if ((retglob
=glob(pattern1
, GLOB_ERR
, NULL
, &globbuf
)) ||
1012 (retglob
=glob(pattern2
, GLOB_ERR
|GLOB_APPEND
|GLOB_NOCHECK
,NULL
,&globbuf
))) {
1015 if (retglob
==GLOB_NOSPACE
)
1016 pout("glob(3) ran out of memory matching patterns (%s),(%s)\n",
1017 pattern1
, pattern2
);
1018 else if (retglob
==GLOB_ABORTED
)
1019 pout("glob(3) aborted matching patterns (%s),(%s)\n",
1020 pattern1
, pattern2
);
1021 else if (retglob
==GLOB_NOMATCH
) {
1022 pout("glob(3) found no matches for patterns (%s),(%s)\n",
1023 pattern1
, pattern2
);
1027 pout("Unexplained error in glob(3) of patterns (%s),(%s)\n",
1028 pattern1
, pattern2
);
1030 // Free memory and return
1036 // did we find too many paths?
1037 // did we find too many paths?
1038 lim
= globbuf
.gl_pathc
< MAX_NUM_DEV
? globbuf
.gl_pathc
: MAX_NUM_DEV
;
1039 if (lim
< globbuf
.gl_pathc
)
1040 pout("glob(3) found %d > MAX=%d devices matching patterns (%s),(%s): ignoring %d paths\n",
1041 globbuf
.gl_pathc
, MAX_NUM_DEV
, pattern1
,pattern2
,
1042 globbuf
.gl_pathc
-MAX_NUM_DEV
);
1044 // allocate space for up to lim number of ATA devices
1045 if (!(mp
= (char **)calloc(lim
, sizeof(char*)))){
1046 pout("Out of memory constructing scan device list\n");
1050 // now step through the list returned by glob. No link checking needed
1052 for (i
=0; i
<globbuf
.gl_pathc
; i
++){
1053 // becuase of the NO_CHECK on second call to glob,
1054 // the pattern itself will be added to path list..
1055 // so ignore any paths that have the ']' from pattern
1056 if (strchr(globbuf
.gl_pathv
[i
],']') == NULL
)
1057 mp
[n
++] = CustomStrDup(globbuf
.gl_pathv
[i
], 1, __LINE__
, filenameandversion
);
1061 mp
= (char **)realloc(mp
,n
*(sizeof(char*))); // shrink to correct size
1062 bytes
+= (n
)*(sizeof(char*)); // and set allocated byte count
1067 int make_device_names (char*** devlist
, const char* name
) {
1068 if (!strcmp(name
,"SCSI"))
1069 return get_dev_names(devlist
,"da");
1070 else if (!strcmp(name
,"ATA"))
1071 return get_dev_names(devlist
,"ad");