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.c,v 1.49 2006/04/12 14:54:28 ballen4705 Exp $";
43 const char *os_XXXX_c_cvsid
="$Id: os_freebsd.c,v 1.49 2006/04/12 14:54:28 ballen4705 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
= 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 ata_command_interface(int fd
, smart_command_set command
, int select
, char *data
) {
258 #if !defined(ATAREQUEST) && !defined(IOCATAREQUEST)
259 // sorry, but without ATAng, we can't do anything here
260 printwarning(BAD_KERNEL
,NULL
);
264 struct freebsd_dev_channel
* con
;
265 int retval
, copydata
=0;
267 struct ata_ioc_request request
;
269 struct ata_cmd iocmd
;
271 unsigned char buff
[512];
273 // check that "file descriptor" is valid
274 if (isnotopen(&fd
,&con
))
280 bzero(&request
,sizeof(struct ata_ioc_request
));
282 bzero(&iocmd
,sizeof(struct ata_cmd
));
286 #ifndef IOCATAREQUEST
287 iocmd
.cmd
=ATAREQUEST
;
288 iocmd
.channel
=con
->channel
;
289 iocmd
.device
=con
->device
;
290 #define request iocmd.u.request
293 request
.u
.ata
.command
=ATA_SMART_CMD
;
297 request
.u
.ata
.feature
=ATA_SMART_READ_VALUES
;
298 request
.u
.ata
.lba
=0xc24f<<8;
299 request
.flags
=ATA_CMD_READ
;
304 case READ_THRESHOLDS
:
305 request
.u
.ata
.feature
=ATA_SMART_READ_THRESHOLDS
;
306 request
.u
.ata
.count
=1;
307 request
.u
.ata
.lba
=1|(0xc24f<<8);
308 request
.flags
=ATA_CMD_READ
;
314 request
.u
.ata
.feature
=ATA_SMART_READ_LOG_SECTOR
;
315 request
.u
.ata
.lba
=select
|(0xc24f<<8);
316 request
.u
.ata
.count
=1;
317 request
.flags
=ATA_CMD_READ
;
323 request
.u
.ata
.command
=ATA_IDENTIFY_DEVICE
;
324 request
.flags
=ATA_CMD_READ
;
330 request
.u
.ata
.command
=ATA_IDENTIFY_PACKET_DEVICE
;
331 request
.flags
=ATA_CMD_READ
;
337 request
.u
.ata
.feature
=ATA_SMART_ENABLE
;
338 request
.u
.ata
.lba
=0xc24f<<8;
339 request
.flags
=ATA_CMD_CONTROL
;
342 request
.u
.ata
.feature
=ATA_SMART_DISABLE
;
343 request
.u
.ata
.lba
=0xc24f<<8;
344 request
.flags
=ATA_CMD_CONTROL
;
347 // NOTE: According to ATAPI 4 and UP, this command is obsolete
348 request
.u
.ata
.feature
=ATA_SMART_AUTO_OFFLINE
;
349 request
.u
.ata
.lba
=select
|(0xc24f<<8);
350 request
.flags
=ATA_CMD_CONTROL
;
353 request
.u
.ata
.feature
=ATA_SMART_AUTOSAVE
;
354 request
.u
.ata
.count
=0xf1; // to enable autosave
355 request
.u
.ata
.lba
=0xc24f<<8;
356 request
.flags
=ATA_CMD_CONTROL
;
358 case IMMEDIATE_OFFLINE
:
359 request
.u
.ata
.feature
=ATA_SMART_IMMEDIATE_OFFLINE
;
360 request
.u
.ata
.lba
= select
|(0xc24f<<8); // put test in sector
361 request
.flags
=ATA_CMD_CONTROL
;
363 case STATUS_CHECK
: // same command, no HDIO in FreeBSD
365 // this command only says if SMART is working. It could be
366 // replaced with STATUS_CHECK below.
367 request
.u
.ata
.feature
=ATA_SMART_STATUS
;
368 request
.u
.ata
.lba
=0xc24f<<8;
369 request
.flags
=ATA_CMD_CONTROL
;
372 pout("Unrecognized command %d in ata_command_interface()\n"
373 "Please contact " PACKAGE_BUGREPORT
"\n", command
);
378 if (command
==STATUS_CHECK
){
379 unsigned const char normal_lo
=0x4f, normal_hi
=0xc2;
380 unsigned const char failed_lo
=0xf4, failed_hi
=0x2c;
381 unsigned char low
,high
;
384 if ((retval
=ioctl(con
->device
, IOCATAREQUEST
, &request
)) || request
.error
)
386 if ((retval
=ioctl(con
->atacommand
, IOCATA
, &iocmd
)) || request
.error
)
390 #if __FreeBSD_version < 502000
391 printwarning(NO_RETURN
,NULL
);
394 high
= (request
.u
.ata
.lba
>> 16) & 0xff;
395 low
= (request
.u
.ata
.lba
>> 8) & 0xff;
397 // Cyl low and Cyl high unchanged means "Good SMART status"
398 if (low
==normal_lo
&& high
==normal_hi
)
401 // These values mean "Bad SMART status"
402 if (low
==failed_lo
&& high
==failed_hi
)
405 // We haven't gotten output that makes sense; print out some debugging info
407 sprintf(buf
,"CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
408 (int)request
.u
.ata
.command
,
409 (int)request
.u
.ata
.feature
,
410 (int)request
.u
.ata
.count
,
411 (int)((request
.u
.ata
.lba
) & 0xff),
412 (int)((request
.u
.ata
.lba
>>8) & 0xff),
413 (int)((request
.u
.ata
.lba
>>16) & 0xff),
415 printwarning(BAD_SMART
,buf
);
420 if ((retval
=ioctl(con
->device
, IOCATAREQUEST
, &request
)) || request
.error
)
422 if ((retval
=ioctl(con
->atacommand
, IOCATA
, &iocmd
)) || request
.error
)
429 memcpy(data
, buff
, 512);
436 // Interface to SCSI devices. See os_linux.c
437 int do_scsi_cmnd_io(int fd
, struct scsi_cmnd_io
* iop
, int report
)
439 struct freebsd_dev_channel
* con
= NULL
;
440 struct cam_device
* cam_dev
= NULL
;
446 const unsigned char * ucp
= iop
->cmnd
;
449 np
= scsi_get_opcode_name(ucp
[0]);
450 pout(" [%s: ", np
? np
: "<unknown opcode>");
451 for (k
= 0; k
< iop
->cmnd_len
; ++k
)
452 pout("%02x ", ucp
[k
]);
454 (DXFER_TO_DEVICE
== iop
->dxfer_dir
) && (iop
->dxferp
)) {
455 int trunc
= (iop
->dxfer_len
> 256) ? 1 : 0;
457 pout("]\n Outgoing data, len=%d%s:\n", (int)iop
->dxfer_len
,
458 (trunc
? " [only first 256 bytes shown]" : ""));
459 dStrHex(iop
->dxferp
, (trunc
? 256 : iop
->dxfer_len
) , 1);
465 // check that "file descriptor" is valid
466 if (isnotopen(&fd
,&con
))
470 if (!(cam_dev
= cam_open_spec_device(con
->devname
,con
->unitnum
,O_RDWR
,NULL
))) {
471 warnx("%s",cam_errbuf
);
475 if (!(ccb
= cam_getccb(cam_dev
))) {
476 warnx("error allocating ccb");
480 // clear out structure, except for header that was filled in for us
481 bzero(&(&ccb
->ccb_h
)[1],
482 sizeof(struct ccb_scsiio
) - sizeof(struct ccb_hdr
));
484 cam_fill_csio(&ccb
->csio
,
487 /* flags */ (iop
->dxfer_dir
== DXFER_NONE
? CAM_DIR_NONE
:(iop
->dxfer_dir
== DXFER_FROM_DEVICE
? CAM_DIR_IN
: CAM_DIR_OUT
)),
488 /* tagaction */ MSG_SIMPLE_Q_TAG
,
489 /* dataptr */ iop
->dxferp
,
490 /* datalen */ iop
->dxfer_len
,
491 /* senselen */ iop
->max_sense_len
,
492 /* cdblen */ iop
->cmnd_len
,
493 /* timout (converted to seconds) */ iop
->timeout
*1000);
494 memcpy(ccb
->csio
.cdb_io
.cdb_bytes
,iop
->cmnd
,iop
->cmnd_len
);
496 if (cam_send_ccb(cam_dev
,ccb
) < 0) {
497 warn("error sending SCSI ccb");
498 #if __FreeBSD_version > 500000
499 cam_error_print(cam_dev
,ccb
,CAM_ESF_ALL
,CAM_EPF_ALL
,stderr
);
505 if ((ccb
->ccb_h
.status
& CAM_STATUS_MASK
) != CAM_REQ_CMP
) {
506 #if __FreeBSD_version > 500000
507 cam_error_print(cam_dev
,ccb
,CAM_ESF_ALL
,CAM_EPF_ALL
,stderr
);
514 memcpy(iop
->sensep
,&(ccb
->csio
.sense_data
),sizeof(struct scsi_sense_data
));
515 iop
->resp_sense_len
= sizeof(struct scsi_sense_data
);
518 iop
->scsi_status
= ccb
->csio
.scsi_status
;
523 cam_close_device(cam_dev
);
529 trunc
= (iop
->dxfer_len
> 256) ? 1 : 0;
531 pout(" Incoming data, len=%d%s:\n", (int)iop
->dxfer_len
,
532 (trunc
? " [only first 256 bytes shown]" : ""));
533 dStrHex(iop
->dxferp
, (trunc
? 256 : iop
->dxfer_len
) , 1);
538 // Interface to ATA devices behind 3ware escalade RAID controller cards. See os_linux.c
540 #define BUFFER_LEN_678K_CHAR ( sizeof(struct twe_usercommand) ) // 520
541 #define BUFFER_LEN_9000_CHAR ( sizeof(TW_OSLI_IOCTL_NO_DATA_BUF) + sizeof(TWE_Command) ) // 2048
542 #define TW_IOCTL_BUFFER_SIZE ( MAX(BUFFER_LEN_678K_CHAR, BUFFER_LEN_9000_CHAR) )
544 int escalade_command_interface(int fd
, int disknum
, int escalade_type
, smart_command_set command
, int select
, char *data
) {
545 // to hold true file descriptor
546 struct freebsd_dev_channel
* con
;
548 // return value and buffer for ioctl()
549 int ioctlreturn
, readdata
=0;
550 struct twe_usercommand
* cmd_twe
= NULL
;
551 TW_OSLI_IOCTL_NO_DATA_BUF
* cmd_twa
= NULL
;
552 TWE_Command_ATA
* ata
= NULL
;
554 // Used by both the SCSI and char interfaces
555 char ioctl_buffer
[TW_IOCTL_BUFFER_SIZE
];
558 printwarning(NO_DISK_3WARE
,NULL
);
562 // check that "file descriptor" is valid
563 if (isnotopen(&fd
,&con
))
566 memset(ioctl_buffer
, 0, TW_IOCTL_BUFFER_SIZE
);
568 if (escalade_type
==CONTROLLER_3WARE_9000_CHAR
) {
569 cmd_twa
= (TW_OSLI_IOCTL_NO_DATA_BUF
*)ioctl_buffer
;
570 cmd_twa
->pdata
= ((TW_OSLI_IOCTL_WITH_PAYLOAD
*)cmd_twa
)->payload
.data_buf
;
571 cmd_twa
->driver_pkt
.buffer_length
= 512;
572 ata
= (TWE_Command_ATA
*)&cmd_twa
->cmd_pkt
.command
.cmd_pkt_7k
;
573 } else if (escalade_type
==CONTROLLER_3WARE_678K_CHAR
) {
574 cmd_twe
= (struct twe_usercommand
*)ioctl_buffer
;
575 ata
= &cmd_twe
->tu_command
.ata
;
577 pout("Unrecognized escalade_type %d in freebsd_3ware_command_interface(disk %d)\n"
578 "Please contact " PACKAGE_BUGREPORT
"\n", escalade_type
, disknum
);
583 ata
->opcode
= TWE_OP_ATA_PASSTHROUGH
;
585 // Same for (almost) all commands - but some reset below
586 ata
->request_id
= 0xFF;
591 ata
->drive_head
= 0x0;
594 // All SMART commands use this CL/CH signature. These are magic
595 // values from the ATA specifications.
596 ata
->cylinder_lo
= 0x4F;
597 ata
->cylinder_hi
= 0xC2;
599 // SMART ATA COMMAND REGISTER value
600 ata
->command
= ATA_SMART_CMD
;
602 // Is this a command that reads or returns 512 bytes?
603 // passthru->param values are:
604 // 0x0 - non data command without TFR write check,
605 // 0x8 - non data command with TFR write check,
606 // 0xD - data command that returns data to host from device
607 // 0xF - data command that writes data from host to device
608 // passthru->size values are 0x5 for non-data and 0x07 for data
609 if (command
== READ_VALUES
||
610 command
== READ_THRESHOLDS
||
611 command
== READ_LOG
||
612 command
== IDENTIFY
||
613 command
== WRITE_LOG
) {
615 if (escalade_type
==CONTROLLER_3WARE_678K_CHAR
) {
616 cmd_twe
->tu_data
= data
;
617 cmd_twe
->tu_size
= 512;
619 ata
->sgl_offset
= 0x5;
622 ata
->sector_count
= 0x1;
623 // For 64-bit to work correctly, up the size of the command packet
624 // in dwords by 1 to account for the 64-bit single sgl 'address'
625 // field. Note that this doesn't agree with the typedefs but it's
626 // right (agree with kernel driver behavior/typedefs).
627 //if (sizeof(long)==8)
631 // Non data command -- but doesn't use large sector
632 // count register values.
633 ata
->sgl_offset
= 0x0;
636 ata
->sector_count
= 0x0;
639 // Now set ATA registers depending upon command
641 case CHECK_POWER_MODE
:
642 ata
->command
= ATA_CHECK_POWER_MODE
;
644 ata
->cylinder_lo
= 0;
645 ata
->cylinder_hi
= 0;
648 ata
->features
= ATA_SMART_READ_VALUES
;
650 case READ_THRESHOLDS
:
651 ata
->features
= ATA_SMART_READ_THRESHOLDS
;
654 ata
->features
= ATA_SMART_READ_LOG_SECTOR
;
655 // log number to return
656 ata
->sector_num
= select
;
660 ata
->features
= ATA_SMART_WRITE_LOG_SECTOR
;
661 ata
->sector_count
= 1;
662 ata
->sector_num
= select
;
663 ata
->param
= 0xF; // PIO data write
666 // ATA IDENTIFY DEVICE
667 ata
->command
= ATA_IDENTIFY_DEVICE
;
669 ata
->cylinder_lo
= 0;
670 ata
->cylinder_hi
= 0;
673 // 3WARE controller can NOT have packet device internally
674 pout("WARNING - NO DEVICE FOUND ON 3WARE CONTROLLER (disk %d)\n", disknum
);
678 ata
->features
= ATA_SMART_ENABLE
;
681 ata
->features
= ATA_SMART_DISABLE
;
684 ata
->features
= ATA_SMART_AUTO_OFFLINE
;
685 // Enable or disable?
686 ata
->sector_count
= select
;
689 ata
->features
= ATA_SMART_AUTOSAVE
;
690 // Enable or disable?
691 ata
->sector_count
= select
;
693 case IMMEDIATE_OFFLINE
:
694 ata
->features
= ATA_SMART_IMMEDIATE_OFFLINE
;
695 // What test type to run?
696 ata
->sector_num
= select
;
699 ata
->features
= ATA_SMART_STATUS
;
702 // This is JUST to see if SMART is enabled, by giving SMART status
703 // command. But it doesn't say if status was good, or failing.
704 // See below for the difference.
705 ata
->features
= ATA_SMART_STATUS
;
708 pout("Unrecognized command %d in freebsd_3ware_command_interface(disk %d)\n"
709 "Please contact " PACKAGE_BUGREPORT
"\n", command
, disknum
);
714 // Now send the command down through an ioctl()
715 if (escalade_type
==CONTROLLER_3WARE_9000_CHAR
) {
717 ioctlreturn
=ioctl(con
->device
,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH
,cmd_twa
);
719 ioctlreturn
=ioctl(con
->atacommand
,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH
,cmd_twa
);
723 ioctlreturn
=ioctl(con
->device
,TWEIO_COMMAND
,cmd_twe
);
725 ioctlreturn
=ioctl(con
->atacommand
,TWEIO_COMMAND
,cmd_twe
);
729 // Deal with the different error cases
736 // See if the ATA command failed. Now that we have returned from
737 // the ioctl() call, if passthru is valid, then:
738 // - ata->status contains the 3ware controller STATUS
739 // - ata->command contains the ATA STATUS register
740 // - ata->features contains the ATA ERROR register
742 // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS
743 // If bit 0 (error bit) is set, then ATA ERROR register is valid.
744 // While we *might* decode the ATA ERROR register, at the moment it
745 // doesn't make much sense: we don't care in detail why the error
748 if (ata
->status
|| (ata
->command
& 0x21)) {
749 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
);
754 // If this is a read data command, copy data to output buffer
756 if (escalade_type
==CONTROLLER_3WARE_9000_CHAR
)
757 memcpy(data
, cmd_twa
->pdata
, 512);
760 // For STATUS_CHECK, we need to check register values
761 if (command
==STATUS_CHECK
) {
763 // To find out if the SMART RETURN STATUS is good or failing, we
764 // need to examine the values of the Cylinder Low and Cylinder
767 unsigned short cyl_lo
=ata
->cylinder_lo
;
768 unsigned short cyl_hi
=ata
->cylinder_hi
;
770 // If values in Cyl-LO and Cyl-HI are unchanged, SMART status is good.
771 if (cyl_lo
==0x4F && cyl_hi
==0xC2)
774 // If values in Cyl-LO and Cyl-HI are as follows, SMART status is FAIL
775 if (cyl_lo
==0xF4 && cyl_hi
==0x2C)
782 // copy sector count register (one byte!) to return data
783 if (command
==CHECK_POWER_MODE
)
784 *data
=*(char *)&(ata
->sector_count
);
786 // look for nonexistent devices/ports
787 if (command
==IDENTIFY
&& !nonempty((unsigned char *)data
, 512)) {
795 static int get_tw_channel_unit (const char* name
, int* unit
, int* dev
) {
798 /* device node sanity check */
799 for (p
= name
+ 3; *p
; p
++)
800 if (*p
< '0' || *p
> '9')
802 if (strlen(name
) > 4 && *(name
+ 3) == '0')
808 /* no need for unit number */
815 #ifndef IOCATAREQUEST
816 static int get_ata_channel_unit ( const char* name
, int* unit
, int* dev
) {
822 // there is no direct correlation between name 'ad0, ad1, ...' and
823 // channel/unit number. So we need to iterate through the possible
824 // channels and check each unit to see if we match names
825 struct ata_cmd iocmd
;
828 bzero(&iocmd
, sizeof(struct ata_cmd
));
830 if ((fd
= open("/dev/ata", O_RDWR
)) < 0)
833 iocmd
.cmd
= ATAGMAXCHANNEL
;
834 if (ioctl(fd
, IOCATA
, &iocmd
) < 0) {
838 maxunit
= iocmd
.u
.maxchan
;
839 for (*unit
= 0; *unit
< maxunit
; (*unit
)++) {
840 iocmd
.channel
= *unit
;
842 iocmd
.cmd
= ATAGPARM
;
843 if (ioctl(fd
, IOCATA
, &iocmd
) < 0) {
847 if (iocmd
.u
.param
.type
[0] && !strcmp(name
,iocmd
.u
.param
.name
[0])) {
851 if (iocmd
.u
.param
.type
[1] && !strcmp(name
,iocmd
.u
.param
.name
[1])) {
857 if (*unit
== maxunit
)
865 // Guess device type (ata or scsi) based on device name (FreeBSD
866 // specific) SCSI device name in FreeBSD can be sd, sr, scd, st, nst,
867 // osst, nosst and sg.
868 static const char * fbsd_dev_prefix
= "/dev/";
869 static const char * fbsd_dev_ata_disk_prefix
= "ad";
870 static const char * fbsd_dev_scsi_disk_plus
= "da";
871 static const char * fbsd_dev_scsi_tape1
= "sa";
872 static const char * fbsd_dev_scsi_tape2
= "nsa";
873 static const char * fbsd_dev_scsi_tape3
= "esa";
874 static const char * fbsd_dev_twe_ctrl
= "twe";
875 static const char * fbsd_dev_twa_ctrl
= "twa";
877 static int parse_ata_chan_dev(const char * dev_name
, struct freebsd_dev_channel
*chan
) {
879 int dev_prefix_len
= strlen(fbsd_dev_prefix
);
881 // if dev_name null, or string length zero
882 if (!dev_name
|| !(len
= strlen(dev_name
)))
883 return CONTROLLER_UNKNOWN
;
885 // Remove the leading /dev/... if it's there
886 if (!strncmp(fbsd_dev_prefix
, dev_name
, dev_prefix_len
)) {
887 if (len
<= dev_prefix_len
)
888 // if nothing else in the string, unrecognized
889 return CONTROLLER_UNKNOWN
;
890 // else advance pointer to following characters
891 dev_name
+= dev_prefix_len
;
893 // form /dev/ad* or ad*
894 if (!strncmp(fbsd_dev_ata_disk_prefix
, dev_name
,
895 strlen(fbsd_dev_ata_disk_prefix
))) {
896 #ifndef IOCATAREQUEST
898 if (get_ata_channel_unit(dev_name
,&(chan
->channel
),&(chan
->device
))<0) {
899 return CONTROLLER_UNKNOWN
;
903 return CONTROLLER_ATA
;
906 // form /dev/da* or da*
907 if (!strncmp(fbsd_dev_scsi_disk_plus
, dev_name
,
908 strlen(fbsd_dev_scsi_disk_plus
)))
911 // form /dev/sa* or sa*
912 if (!strncmp(fbsd_dev_scsi_tape1
, dev_name
,
913 strlen(fbsd_dev_scsi_tape1
)))
916 // form /dev/nsa* or nsa*
917 if (!strncmp(fbsd_dev_scsi_tape2
, dev_name
,
918 strlen(fbsd_dev_scsi_tape2
)))
921 // form /dev/esa* or esa*
922 if (!strncmp(fbsd_dev_scsi_tape3
, dev_name
,
923 strlen(fbsd_dev_scsi_tape3
)))
926 if (!strncmp(fbsd_dev_twa_ctrl
,dev_name
,
927 strlen(fbsd_dev_twa_ctrl
))) {
929 if (get_tw_channel_unit(dev_name
,&(chan
->channel
),&(chan
->device
))<0) {
930 return CONTROLLER_UNKNOWN
;
933 else if (get_tw_channel_unit(dev_name
,NULL
,NULL
)<0) {
934 return CONTROLLER_UNKNOWN
;
936 return CONTROLLER_3WARE_9000_CHAR
;
939 if (!strncmp(fbsd_dev_twe_ctrl
,dev_name
,
940 strlen(fbsd_dev_twe_ctrl
))) {
942 if (get_tw_channel_unit(dev_name
,&(chan
->channel
),&(chan
->device
))<0) {
943 return CONTROLLER_UNKNOWN
;
946 else if (get_tw_channel_unit(dev_name
,NULL
,NULL
)<0) {
947 return CONTROLLER_UNKNOWN
;
949 return CONTROLLER_3WARE_678K_CHAR
;
952 // we failed to recognize any of the forms
953 return CONTROLLER_UNKNOWN
;
957 if (!(chan
->devname
= calloc(1,DEV_IDLEN
+1)))
958 return CONTROLLER_UNKNOWN
;
960 if (cam_get_device(dev_name
,chan
->devname
,DEV_IDLEN
,&(chan
->unitnum
)) == -1)
961 return CONTROLLER_UNKNOWN
;
963 return CONTROLLER_SCSI
;
967 int guess_device_type (const char* dev_name
) {
968 return parse_ata_chan_dev(dev_name
,NULL
);
971 // global variable holding byte count of allocated memory
972 extern long long bytes
;
974 // we are going to take advantage of the fact that FreeBSD's devfs will only
975 // have device entries for devices that exist. So if we get the equivilent of
976 // ls /dev/ad?, we have all the ATA devices on the system
978 // If any errors occur, leave errno set as it was returned by the
979 // system call, and return <0.
983 // -2 to -5 errors in glob
985 int get_dev_names(char*** names
, const char* prefix
) {
991 char pattern1
[128],pattern2
[128];
993 bzero(&globbuf
,sizeof(globbuf
));
994 // in case of non-clean exit
997 // handle 0-99 possible devices, will still be limited by MAX_NUM_DEV
998 sprintf(pattern1
,"/dev/%s[0-9]",prefix
);
999 sprintf(pattern2
,"/dev/%s[0-9][0-9]",prefix
);
1001 // Use glob to look for any directory entries matching the patterns
1002 // first call inits with first pattern match, second call appends
1003 // to first list. Turn on NOCHECK for second call. This results in no
1004 // error if no more matches found, however it does append the actual
1005 // pattern to the list of paths....
1006 if ((retglob
=glob(pattern1
, GLOB_ERR
, NULL
, &globbuf
)) ||
1007 (retglob
=glob(pattern2
, GLOB_ERR
|GLOB_APPEND
|GLOB_NOCHECK
,NULL
,&globbuf
))) {
1010 if (retglob
==GLOB_NOSPACE
)
1011 pout("glob(3) ran out of memory matching patterns (%s),(%s)\n",
1012 pattern1
, pattern2
);
1013 else if (retglob
==GLOB_ABORTED
)
1014 pout("glob(3) aborted matching patterns (%s),(%s)\n",
1015 pattern1
, pattern2
);
1016 else if (retglob
==GLOB_NOMATCH
) {
1017 pout("glob(3) found no matches for patterns (%s),(%s)\n",
1018 pattern1
, pattern2
);
1022 pout("Unexplained error in glob(3) of patterns (%s),(%s)\n",
1023 pattern1
, pattern2
);
1025 // Free memory and return
1031 // did we find too many paths?
1032 // did we find too many paths?
1033 lim
= globbuf
.gl_pathc
< MAX_NUM_DEV
? globbuf
.gl_pathc
: MAX_NUM_DEV
;
1034 if (lim
< globbuf
.gl_pathc
)
1035 pout("glob(3) found %d > MAX=%d devices matching patterns (%s),(%s): ignoring %d paths\n",
1036 globbuf
.gl_pathc
, MAX_NUM_DEV
, pattern1
,pattern2
,
1037 globbuf
.gl_pathc
-MAX_NUM_DEV
);
1039 // allocate space for up to lim number of ATA devices
1040 if (!(mp
= (char **)calloc(lim
, sizeof(char*)))){
1041 pout("Out of memory constructing scan device list\n");
1045 // now step through the list returned by glob. No link checking needed
1047 for (i
=0; i
<globbuf
.gl_pathc
; i
++){
1048 // becuase of the NO_CHECK on second call to glob,
1049 // the pattern itself will be added to path list..
1050 // so ignore any paths that have the ']' from pattern
1051 if (strchr(globbuf
.gl_pathv
[i
],']') == NULL
)
1052 mp
[n
++] = CustomStrDup(globbuf
.gl_pathv
[i
], 1, __LINE__
, filenameandversion
);
1056 mp
= realloc(mp
,n
*(sizeof(char*))); // shrink to correct size
1057 bytes
+= (n
)*(sizeof(char*)); // and set allocated byte count
1062 int make_device_names (char*** devlist
, const char* name
) {
1063 if (!strcmp(name
,"SCSI"))
1064 return get_dev_names(devlist
,"da");
1065 else if (!strcmp(name
,"ATA"))
1066 return get_dev_names(devlist
,"ad");