]> git.proxmox.com Git - mirror_smartmontools-debian.git/blame - os_freebsd.cpp
drop 40_fix-sata-hsm-violation.diff - pull from upstream
[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 *
6 * Copyright (C) 2003-6 Eduard Martinescu <smartmontools-support@lists.sourceforge.net>
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>
23#include <camlib.h>
24#include <cam/scsi/scsi_message.h>
25#include <sys/ata.h>
26#include <sys/stat.h>
27#include <unistd.h>
28#include <fcntl.h>
29#include <glob.h>
30#include <fcntl.h>
31#include <stddef.h>
32
33
34#include "config.h"
35#include "int64.h"
36#include "atacmds.h"
37#include "scsicmds.h"
a37e7145 38#include "cciss.h"
832b75ed 39#include "utility.h"
a37e7145 40#include "extern.h"
832b75ed
GG
41#include "os_freebsd.h"
42
a37e7145 43static const char *filenameandversion="$Id: os_freebsd.cpp,v 1.54 2007/09/06 08:48:55 ballen4705 Exp $";
832b75ed 44
a37e7145 45const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp,v 1.54 2007/09/06 08:48:55 ballen4705 Exp $" \
832b75ed
GG
46ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_FREEBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
47
48// to hold onto exit code for atexit routine
49extern int exitstatus;
50
a37e7145
GG
51extern smartmonctrl * con;
52
832b75ed
GG
53// Private table of open devices: guaranteed zero on startup since
54// part of static data.
55struct freebsd_dev_channel *devicetable[FREEBSD_MAXDEV];
56
57// forward declaration
58static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel *ch);
59
60// print examples for smartctl
61void print_smartctl_examples(){
62 printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
63#ifdef HAVE_GETOPT_LONG
64 printf(
65 " smartctl -a /dev/ad0 (Prints all SMART information)\n\n"
66 " smartctl --smart=on --offlineauto=on --saveauto=on /dev/ad0\n"
67 " (Enables SMART on first disk)\n\n"
68 " smartctl -t long /dev/ad0 (Executes extended disk self-test)\n\n"
69 " smartctl --attributes --log=selftest --quietmode=errorsonly /dev/ad0\n"
70 " (Prints Self-Test & Attribute errors)\n"
71 " (Prints Self-Test & Attribute errors)\n\n"
72 " smartctl -a --device=3ware,2 /dev/twa0\n"
73 " smartctl -a --device=3ware,2 /dev/twe0\n"
74 " (Prints all SMART information for ATA disk on\n"
75 " third port of first 3ware RAID controller)\n"
76 );
77#else
78 printf(
79 " smartctl -a /dev/ad0 (Prints all SMART information)\n"
80 " smartctl -s on -o on -S on /dev/ad0 (Enables SMART on first disk)\n"
81 " smartctl -t long /dev/ad0 (Executes extended disk self-test)\n"
82 " smartctl -A -l selftest -q errorsonly /dev/ad0\n"
83 " (Prints Self-Test & Attribute errors)\n"
84 " smartctl -a -d 3ware,2 /dev/twa0\n"
85 " smartctl -a -d 3ware,2 /dev/twe0\n"
86 );
87#endif
88 return;
89}
90
91// Like open(). Return positive integer handle, used by functions below only. mode=="ATA" or "SCSI".
a37e7145 92int deviceopen (const char* dev, __unused char* mode) {
832b75ed
GG
93 struct freebsd_dev_channel *fdchan;
94 int parse_ok, i;
95
96 // Search table for a free entry
97 for (i=0; i<FREEBSD_MAXDEV; i++)
98 if (!devicetable[i])
99 break;
100
101 // If no free entry found, return error. We have max allowed number
102 // of "file descriptors" already allocated.
103 if (i==FREEBSD_MAXDEV) {
104 errno=EMFILE;
105 return -1;
106 }
107
4d59bff9 108 fdchan = (struct freebsd_dev_channel *)calloc(1,sizeof(struct freebsd_dev_channel));
832b75ed
GG
109 if (fdchan == NULL) {
110 // errno already set by call to malloc()
111 return -1;
112 }
113
114 parse_ok = parse_ata_chan_dev (dev,fdchan);
115 if (parse_ok == CONTROLLER_UNKNOWN) {
116 free(fdchan);
117 errno = ENOTTY;
118 return -1; // can't handle what we don't know
119 }
120
121 if (parse_ok == CONTROLLER_ATA) {
122#ifdef IOCATAREQUEST
123 if ((fdchan->device = open(dev,O_RDONLY))<0) {
124#else
125 if ((fdchan->atacommand = open("/dev/ata",O_RDWR))<0) {
126#endif
127 int myerror = errno; //preserve across free call
128 free (fdchan);
129 errno = myerror;
130 return -1;
131 }
132 }
133
134 if (parse_ok == CONTROLLER_3WARE_678K_CHAR) {
135 char buf[512];
136 sprintf(buf,"/dev/twe%d",fdchan->device);
137#ifdef IOCATAREQUEST
138 if ((fdchan->device = open(buf,O_RDWR))<0) {
139#else
140 if ((fdchan->atacommand = open(buf,O_RDWR))<0) {
141#endif
142 int myerror = errno; // preserver across free call
143 free(fdchan);
144 errno=myerror;
145 return -1;
146 }
147 }
148
149 if (parse_ok == CONTROLLER_3WARE_9000_CHAR) {
150 char buf[512];
151 sprintf(buf,"/dev/twa%d",fdchan->device);
152#ifdef IOCATAREQUEST
153 if ((fdchan->device = open(buf,O_RDWR))<0) {
154#else
155 if ((fdchan->atacommand = open(buf,O_RDWR))<0) {
156#endif
157 int myerror = errno; // preserver across free call
158 free(fdchan);
159 errno=myerror;
160 return -1;
161 }
162 }
163
a37e7145
GG
164 if (parse_ok == CONTROLLER_CCISS) {
165 if ((fdchan->device = open(dev,O_RDWR))<0) {
166 int myerror = errno; // preserver across free call
167 free(fdchan);
168 errno=myerror;
169 return -1;
170 }
171 }
172
832b75ed
GG
173 if (parse_ok == CONTROLLER_SCSI) {
174 // this is really a NO-OP, as the parse takes care
175 // of filling in correct details
176 }
177
178 // return pointer to "file descriptor" table entry, properly offset.
179 devicetable[i]=fdchan;
180 return i+FREEBSD_FDOFFSET;
181}
182
183// Returns 1 if device not available/open/found else 0. Also shifts fd into valid range.
184static int isnotopen(int *fd, struct freebsd_dev_channel** fdchan) {
185 // put valid "file descriptor" into range 0...FREEBSD_MAXDEV-1
186 *fd -= FREEBSD_FDOFFSET;
187
188 // check for validity of "file descriptor".
189 if (*fd<0 || *fd>=FREEBSD_MAXDEV || !((*fdchan)=devicetable[*fd])) {
190 errno = ENODEV;
191 return 1;
192 }
193
194 return 0;
195}
196
197// Like close(). Acts on handles returned by above function.
198int deviceclose (int fd) {
199 struct freebsd_dev_channel *fdchan;
200 int failed = 0;
201
202 // check for valid file descriptor
203 if (isnotopen(&fd, &fdchan))
204 return -1;
205
206
207 // did we allocate a SCSI device name?
208 if (fdchan->devname)
209 free(fdchan->devname);
210
211 // close device, if open
212#ifdef IOCATAREQUEST
213 if (fdchan->device)
214 failed=close(fdchan->device);
215#else
216 if (fdchan->atacommand)
217 failed=close(fdchan->atacommand);
218#endif
219
220 if (fdchan->scsicontrol)
221 failed=close(fdchan->scsicontrol);
222
223 // if close succeeded, then remove from device list
224 // Eduard, should we also remove it from list if close() fails? I'm
225 // not sure. Here I only remove it from list if close() worked.
226 if (!failed) {
227 free(fdchan);
228 devicetable[fd]=NULL;
229 }
230
231 return failed;
232}
233
234#define NO_RETURN 0
235#define BAD_SMART 1
236#define NO_DISK_3WARE 2
237#define BAD_KERNEL 3
238#define MAX_MSG 3
239
240// Utility function for printing warnings
241void printwarning(int msgNo, const char* extra) {
242 static int printed[] = {0,0,0,0};
243 static const char* message[]={
244 "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",
245
246 "Error SMART Status command failed\nPlease get assistance from \n" PACKAGE_HOMEPAGE "\nRegister values returned from SMART Status command are:\n",
247
248 "You must specify a DISK # for 3ware drives with -d 3ware,<n> where <n> begins with 1 for first disk drive\n",
249
250 "ATA support is not provided for this kernel version. Please ugrade to a recent 5-CURRENT kernel (post 09/01/2003 or so)\n"
251 };
252
253 if (msgNo >= 0 && msgNo <= MAX_MSG) {
254 if (!printed[msgNo]) {
255 printed[msgNo] = 1;
256 pout("%s", message[msgNo]);
257 if (extra)
258 pout("%s",extra);
259 }
260 }
261 return;
262}
263
832b75ed 264// Interface to ATA devices. See os_linux.c
a37e7145
GG
265
266int marvell_command_interface(__unused int fd, __unused smart_command_set command, __unused int select, __unused char *data) {
267 return -1;
832b75ed
GG
268}
269
a37e7145 270int highpoint_command_interface(__unused int fd, __unused smart_command_set command, __unused int select, __unused char *data) {
4d59bff9
GG
271{
272 return -1;
273}
274
832b75ed
GG
275int ata_command_interface(int fd, smart_command_set command, int select, char *data) {
276#if !defined(ATAREQUEST) && !defined(IOCATAREQUEST)
277 // sorry, but without ATAng, we can't do anything here
278 printwarning(BAD_KERNEL,NULL);
279 errno = ENOSYS;
280 return -1;
281#else
282 struct freebsd_dev_channel* con;
283 int retval, copydata=0;
284#ifdef IOCATAREQUEST
285 struct ata_ioc_request request;
286#else
287 struct ata_cmd iocmd;
288#endif
289 unsigned char buff[512];
290
291 // check that "file descriptor" is valid
292 if (isnotopen(&fd,&con))
293 return -1;
294
295 bzero(buff,512);
296
297#ifdef IOCATAREQUEST
298 bzero(&request,sizeof(struct ata_ioc_request));
299#else
300 bzero(&iocmd,sizeof(struct ata_cmd));
301#endif
302 bzero(buff,512);
303
304#ifndef IOCATAREQUEST
305 iocmd.cmd=ATAREQUEST;
306 iocmd.channel=con->channel;
307 iocmd.device=con->device;
308#define request iocmd.u.request
309#endif
310
311 request.u.ata.command=ATA_SMART_CMD;
312 request.timeout=600;
313 switch (command){
314 case READ_VALUES:
315 request.u.ata.feature=ATA_SMART_READ_VALUES;
316 request.u.ata.lba=0xc24f<<8;
317 request.flags=ATA_CMD_READ;
4d59bff9 318 request.data=(char *)buff;
832b75ed
GG
319 request.count=512;
320 copydata=1;
321 break;
322 case READ_THRESHOLDS:
323 request.u.ata.feature=ATA_SMART_READ_THRESHOLDS;
324 request.u.ata.count=1;
325 request.u.ata.lba=1|(0xc24f<<8);
326 request.flags=ATA_CMD_READ;
4d59bff9 327 request.data=(char *)buff;
832b75ed
GG
328 request.count=512;
329 copydata=1;
330 break;
331 case READ_LOG:
332 request.u.ata.feature=ATA_SMART_READ_LOG_SECTOR;
333 request.u.ata.lba=select|(0xc24f<<8);
334 request.u.ata.count=1;
335 request.flags=ATA_CMD_READ;
4d59bff9 336 request.data=(char *)buff;
832b75ed
GG
337 request.count=512;
338 copydata=1;
339 break;
340 case IDENTIFY:
341 request.u.ata.command=ATA_IDENTIFY_DEVICE;
342 request.flags=ATA_CMD_READ;
4d59bff9 343 request.data=(char *)buff;
832b75ed
GG
344 request.count=512;
345 copydata=1;
346 break;
347 case PIDENTIFY:
348 request.u.ata.command=ATA_IDENTIFY_PACKET_DEVICE;
349 request.flags=ATA_CMD_READ;
4d59bff9 350 request.data=(char *)buff;
832b75ed
GG
351 request.count=512;
352 copydata=1;
353 break;
354 case ENABLE:
355 request.u.ata.feature=ATA_SMART_ENABLE;
356 request.u.ata.lba=0xc24f<<8;
357 request.flags=ATA_CMD_CONTROL;
358 break;
359 case DISABLE:
360 request.u.ata.feature=ATA_SMART_DISABLE;
361 request.u.ata.lba=0xc24f<<8;
362 request.flags=ATA_CMD_CONTROL;
363 break;
364 case AUTO_OFFLINE:
365 // NOTE: According to ATAPI 4 and UP, this command is obsolete
366 request.u.ata.feature=ATA_SMART_AUTO_OFFLINE;
367 request.u.ata.lba=select|(0xc24f<<8);
368 request.flags=ATA_CMD_CONTROL;
369 break;
370 case AUTOSAVE:
371 request.u.ata.feature=ATA_SMART_AUTOSAVE;
372 request.u.ata.count=0xf1; // to enable autosave
373 request.u.ata.lba=0xc24f<<8;
374 request.flags=ATA_CMD_CONTROL;
375 break;
376 case IMMEDIATE_OFFLINE:
377 request.u.ata.feature=ATA_SMART_IMMEDIATE_OFFLINE;
378 request.u.ata.lba = select|(0xc24f<<8); // put test in sector
379 request.flags=ATA_CMD_CONTROL;
380 break;
381 case STATUS_CHECK: // same command, no HDIO in FreeBSD
382 case STATUS:
383 // this command only says if SMART is working. It could be
384 // replaced with STATUS_CHECK below.
385 request.u.ata.feature=ATA_SMART_STATUS;
386 request.u.ata.lba=0xc24f<<8;
387 request.flags=ATA_CMD_CONTROL;
388 break;
389 default:
390 pout("Unrecognized command %d in ata_command_interface()\n"
391 "Please contact " PACKAGE_BUGREPORT "\n", command);
392 errno=ENOSYS;
393 return -1;
394 }
395
396 if (command==STATUS_CHECK){
397 unsigned const char normal_lo=0x4f, normal_hi=0xc2;
398 unsigned const char failed_lo=0xf4, failed_hi=0x2c;
399 unsigned char low,high;
400
401#ifdef IOCATAREQUEST
402 if ((retval=ioctl(con->device, IOCATAREQUEST, &request)) || request.error)
403#else
404 if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)) || request.error)
405#endif
406 return -1;
407
408#if __FreeBSD_version < 502000
409 printwarning(NO_RETURN,NULL);
410#endif
411
412 high = (request.u.ata.lba >> 16) & 0xff;
413 low = (request.u.ata.lba >> 8) & 0xff;
414
415 // Cyl low and Cyl high unchanged means "Good SMART status"
416 if (low==normal_lo && high==normal_hi)
417 return 0;
418
419 // These values mean "Bad SMART status"
420 if (low==failed_lo && high==failed_hi)
421 return 1;
422
423 // We haven't gotten output that makes sense; print out some debugging info
424 char buf[512];
425 sprintf(buf,"CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
426 (int)request.u.ata.command,
427 (int)request.u.ata.feature,
428 (int)request.u.ata.count,
429 (int)((request.u.ata.lba) & 0xff),
430 (int)((request.u.ata.lba>>8) & 0xff),
431 (int)((request.u.ata.lba>>16) & 0xff),
432 (int)request.error);
433 printwarning(BAD_SMART,buf);
434 return 0;
435 }
436
437#ifdef IOCATAREQUEST
438 if ((retval=ioctl(con->device, IOCATAREQUEST, &request)) || request.error)
439#else
440 if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)) || request.error)
441#endif
442 {
443 return -1;
444 }
445 //
446 if (copydata)
447 memcpy(data, buff, 512);
448
449 return 0;
450#endif
451}
452
453
454// Interface to SCSI devices. See os_linux.c
a37e7145 455int do_normal_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
832b75ed
GG
456{
457 struct freebsd_dev_channel* con = NULL;
458 struct cam_device* cam_dev = NULL;
459 union ccb *ccb;
460
461
462 if (report > 0) {
463 unsigned int k;
464 const unsigned char * ucp = iop->cmnd;
465 const char * np;
466
467 np = scsi_get_opcode_name(ucp[0]);
468 pout(" [%s: ", np ? np : "<unknown opcode>");
469 for (k = 0; k < iop->cmnd_len; ++k)
470 pout("%02x ", ucp[k]);
471 if ((report > 1) &&
472 (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
473 int trunc = (iop->dxfer_len > 256) ? 1 : 0;
474
475 pout("]\n Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
476 (trunc ? " [only first 256 bytes shown]" : ""));
477 dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
478 }
479 else
480 pout("]");
481 }
482
483 // check that "file descriptor" is valid
484 if (isnotopen(&fd,&con))
485 return -ENOTTY;
486
487
488 if (!(cam_dev = cam_open_spec_device(con->devname,con->unitnum,O_RDWR,NULL))) {
489 warnx("%s",cam_errbuf);
490 return -1;
491 }
492
493 if (!(ccb = cam_getccb(cam_dev))) {
494 warnx("error allocating ccb");
495 return -ENOMEM;
496 }
497
498 // clear out structure, except for header that was filled in for us
499 bzero(&(&ccb->ccb_h)[1],
500 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
501
502 cam_fill_csio(&ccb->csio,
503 /*retrires*/ 1,
504 /*cbfcnp*/ NULL,
505 /* flags */ (iop->dxfer_dir == DXFER_NONE ? CAM_DIR_NONE :(iop->dxfer_dir == DXFER_FROM_DEVICE ? CAM_DIR_IN : CAM_DIR_OUT)),
506 /* tagaction */ MSG_SIMPLE_Q_TAG,
507 /* dataptr */ iop->dxferp,
508 /* datalen */ iop->dxfer_len,
509 /* senselen */ iop->max_sense_len,
510 /* cdblen */ iop->cmnd_len,
511 /* timout (converted to seconds) */ iop->timeout*1000);
512 memcpy(ccb->csio.cdb_io.cdb_bytes,iop->cmnd,iop->cmnd_len);
513
514 if (cam_send_ccb(cam_dev,ccb) < 0) {
515 warn("error sending SCSI ccb");
516 #if __FreeBSD_version > 500000
517 cam_error_print(cam_dev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
518 #endif
519 cam_freeccb(ccb);
520 return -1;
521 }
522
523 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
524 #if __FreeBSD_version > 500000
525 cam_error_print(cam_dev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
526 #endif
527 cam_freeccb(ccb);
528 return -1;
529 }
530
531 if (iop->sensep) {
532 memcpy(iop->sensep,&(ccb->csio.sense_data),sizeof(struct scsi_sense_data));
533 iop->resp_sense_len = sizeof(struct scsi_sense_data);
534 }
535
536 iop->scsi_status = ccb->csio.scsi_status;
537
538 cam_freeccb(ccb);
539
540 if (cam_dev)
541 cam_close_device(cam_dev);
542
543 if (report > 0) {
544 int trunc;
545
546 pout(" status=0\n");
547 trunc = (iop->dxfer_len > 256) ? 1 : 0;
548
549 pout(" Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
550 (trunc ? " [only first 256 bytes shown]" : ""));
551 dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
552 }
553 return 0;
554}
555
a37e7145
GG
556/* Check and call the right interface. Maybe when the do_generic_scsi_cmd_io interface is better
557 we can take off this crude way of calling the right interface */
558int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
559{
560struct freebsd_dev_channel *fdchan;
561 switch(con->controller_type)
562 {
563 case CONTROLLER_CCISS:
564 // check that "file descriptor" is valid
565 if (isnotopen(&dev_fd,&fdchan))
566 return -ENOTTY;
567#ifdef HAVE_DEV_CISS_CISSIO_H
568 return cciss_io_interface(fdchan->device, con->controller_port-1, iop, report);
569#else
570 {
571 static int warned = 0;
572 if (!warned) {
573 pout("CCISS support is not available in this build of smartmontools,\n"
574 "/usr/src/sys/dev/ciss/cissio.h was not available at build time.\n\n");
575 warned = 1;
576 }
577 }
578 errno = ENOSYS;
579 return -1;
580#endif
581 // not reached
582 break;
583 default:
584 return do_normal_scsi_cmnd_io(dev_fd, iop, report);
585 // not reached
586 break;
587 }
588}
589
832b75ed
GG
590// Interface to ATA devices behind 3ware escalade RAID controller cards. See os_linux.c
591
592#define BUFFER_LEN_678K_CHAR ( sizeof(struct twe_usercommand) ) // 520
593#define BUFFER_LEN_9000_CHAR ( sizeof(TW_OSLI_IOCTL_NO_DATA_BUF) + sizeof(TWE_Command) ) // 2048
594#define TW_IOCTL_BUFFER_SIZE ( MAX(BUFFER_LEN_678K_CHAR, BUFFER_LEN_9000_CHAR) )
595
596int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data) {
597 // to hold true file descriptor
598 struct freebsd_dev_channel* con;
599
600 // return value and buffer for ioctl()
601 int ioctlreturn, readdata=0;
602 struct twe_usercommand* cmd_twe = NULL;
603 TW_OSLI_IOCTL_NO_DATA_BUF* cmd_twa = NULL;
604 TWE_Command_ATA* ata = NULL;
605
606 // Used by both the SCSI and char interfaces
607 char ioctl_buffer[TW_IOCTL_BUFFER_SIZE];
608
609 if (disknum < 0) {
610 printwarning(NO_DISK_3WARE,NULL);
611 return -1;
612 }
613
614 // check that "file descriptor" is valid
615 if (isnotopen(&fd,&con))
616 return -1;
617
618 memset(ioctl_buffer, 0, TW_IOCTL_BUFFER_SIZE);
619
620 if (escalade_type==CONTROLLER_3WARE_9000_CHAR) {
621 cmd_twa = (TW_OSLI_IOCTL_NO_DATA_BUF*)ioctl_buffer;
622 cmd_twa->pdata = ((TW_OSLI_IOCTL_WITH_PAYLOAD*)cmd_twa)->payload.data_buf;
623 cmd_twa->driver_pkt.buffer_length = 512;
624 ata = (TWE_Command_ATA*)&cmd_twa->cmd_pkt.command.cmd_pkt_7k;
625 } else if (escalade_type==CONTROLLER_3WARE_678K_CHAR) {
626 cmd_twe = (struct twe_usercommand*)ioctl_buffer;
627 ata = &cmd_twe->tu_command.ata;
628 } else {
629 pout("Unrecognized escalade_type %d in freebsd_3ware_command_interface(disk %d)\n"
630 "Please contact " PACKAGE_BUGREPORT "\n", escalade_type, disknum);
631 errno=ENOSYS;
632 return -1;
633 }
634
635 ata->opcode = TWE_OP_ATA_PASSTHROUGH;
636
637 // Same for (almost) all commands - but some reset below
638 ata->request_id = 0xFF;
a37e7145 639 ata->unit = disknum;
832b75ed
GG
640 ata->status = 0;
641 ata->flags = 0x1;
642 ata->drive_head = 0x0;
643 ata->sector_num = 0;
644
645 // All SMART commands use this CL/CH signature. These are magic
646 // values from the ATA specifications.
647 ata->cylinder_lo = 0x4F;
648 ata->cylinder_hi = 0xC2;
649
650 // SMART ATA COMMAND REGISTER value
651 ata->command = ATA_SMART_CMD;
652
653 // Is this a command that reads or returns 512 bytes?
654 // passthru->param values are:
655 // 0x0 - non data command without TFR write check,
656 // 0x8 - non data command with TFR write check,
657 // 0xD - data command that returns data to host from device
658 // 0xF - data command that writes data from host to device
659 // passthru->size values are 0x5 for non-data and 0x07 for data
660 if (command == READ_VALUES ||
661 command == READ_THRESHOLDS ||
662 command == READ_LOG ||
663 command == IDENTIFY ||
664 command == WRITE_LOG ) {
665 readdata=1;
666 if (escalade_type==CONTROLLER_3WARE_678K_CHAR) {
667 cmd_twe->tu_data = data;
668 cmd_twe->tu_size = 512;
669 }
670 ata->sgl_offset = 0x5;
671 ata->size = 0x5;
672 ata->param = 0xD;
673 ata->sector_count = 0x1;
674 // For 64-bit to work correctly, up the size of the command packet
675 // in dwords by 1 to account for the 64-bit single sgl 'address'
676 // field. Note that this doesn't agree with the typedefs but it's
677 // right (agree with kernel driver behavior/typedefs).
678 //if (sizeof(long)==8)
679 // ata->size++;
680 }
681 else {
682 // Non data command -- but doesn't use large sector
683 // count register values.
684 ata->sgl_offset = 0x0;
685 ata->size = 0x5;
686 ata->param = 0x8;
687 ata->sector_count = 0x0;
688 }
689
690 // Now set ATA registers depending upon command
691 switch (command){
692 case CHECK_POWER_MODE:
693 ata->command = ATA_CHECK_POWER_MODE;
694 ata->features = 0;
695 ata->cylinder_lo = 0;
696 ata->cylinder_hi = 0;
697 break;
698 case READ_VALUES:
699 ata->features = ATA_SMART_READ_VALUES;
700 break;
701 case READ_THRESHOLDS:
702 ata->features = ATA_SMART_READ_THRESHOLDS;
703 break;
704 case READ_LOG:
705 ata->features = ATA_SMART_READ_LOG_SECTOR;
706 // log number to return
707 ata->sector_num = select;
708 break;
709 case WRITE_LOG:
710 readdata=0;
711 ata->features = ATA_SMART_WRITE_LOG_SECTOR;
712 ata->sector_count = 1;
713 ata->sector_num = select;
714 ata->param = 0xF; // PIO data write
715 break;
716 case IDENTIFY:
717 // ATA IDENTIFY DEVICE
718 ata->command = ATA_IDENTIFY_DEVICE;
719 ata->features = 0;
720 ata->cylinder_lo = 0;
721 ata->cylinder_hi = 0;
722 break;
723 case PIDENTIFY:
724 // 3WARE controller can NOT have packet device internally
725 pout("WARNING - NO DEVICE FOUND ON 3WARE CONTROLLER (disk %d)\n", disknum);
726 errno=ENODEV;
727 return -1;
728 case ENABLE:
729 ata->features = ATA_SMART_ENABLE;
730 break;
731 case DISABLE:
732 ata->features = ATA_SMART_DISABLE;
733 break;
734 case AUTO_OFFLINE:
735 ata->features = ATA_SMART_AUTO_OFFLINE;
736 // Enable or disable?
737 ata->sector_count = select;
738 break;
739 case AUTOSAVE:
740 ata->features = ATA_SMART_AUTOSAVE;
741 // Enable or disable?
742 ata->sector_count = select;
743 break;
744 case IMMEDIATE_OFFLINE:
745 ata->features = ATA_SMART_IMMEDIATE_OFFLINE;
746 // What test type to run?
747 ata->sector_num = select;
748 break;
749 case STATUS_CHECK:
750 ata->features = ATA_SMART_STATUS;
751 break;
752 case STATUS:
753 // This is JUST to see if SMART is enabled, by giving SMART status
754 // command. But it doesn't say if status was good, or failing.
755 // See below for the difference.
756 ata->features = ATA_SMART_STATUS;
757 break;
758 default:
759 pout("Unrecognized command %d in freebsd_3ware_command_interface(disk %d)\n"
760 "Please contact " PACKAGE_BUGREPORT "\n", command, disknum);
761 errno=ENOSYS;
762 return -1;
763 }
764
765 // Now send the command down through an ioctl()
766 if (escalade_type==CONTROLLER_3WARE_9000_CHAR) {
767#ifdef IOCATAREQUEST
768 ioctlreturn=ioctl(con->device,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH,cmd_twa);
769#else
770 ioctlreturn=ioctl(con->atacommand,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH,cmd_twa);
771#endif
772 } else {
773#ifdef IOCATAREQUEST
774 ioctlreturn=ioctl(con->device,TWEIO_COMMAND,cmd_twe);
775#else
776 ioctlreturn=ioctl(con->atacommand,TWEIO_COMMAND,cmd_twe);
777#endif
778 }
779
780 // Deal with the different error cases
781 if (ioctlreturn) {
782 if (!errno)
783 errno=EIO;
784 return -1;
785 }
786
787 // See if the ATA command failed. Now that we have returned from
788 // the ioctl() call, if passthru is valid, then:
789 // - ata->status contains the 3ware controller STATUS
790 // - ata->command contains the ATA STATUS register
791 // - ata->features contains the ATA ERROR register
792 //
793 // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS
794 // If bit 0 (error bit) is set, then ATA ERROR register is valid.
795 // While we *might* decode the ATA ERROR register, at the moment it
796 // doesn't make much sense: we don't care in detail why the error
797 // happened.
798
799 if (ata->status || (ata->command & 0x21)) {
800 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);
801 errno=EIO;
802 return -1;
803 }
804
805 // If this is a read data command, copy data to output buffer
806 if (readdata) {
807 if (escalade_type==CONTROLLER_3WARE_9000_CHAR)
808 memcpy(data, cmd_twa->pdata, 512);
809 }
810
811 // For STATUS_CHECK, we need to check register values
812 if (command==STATUS_CHECK) {
813
814 // To find out if the SMART RETURN STATUS is good or failing, we
815 // need to examine the values of the Cylinder Low and Cylinder
816 // High Registers.
817
818 unsigned short cyl_lo=ata->cylinder_lo;
819 unsigned short cyl_hi=ata->cylinder_hi;
820
821 // If values in Cyl-LO and Cyl-HI are unchanged, SMART status is good.
822 if (cyl_lo==0x4F && cyl_hi==0xC2)
823 return 0;
824
825 // If values in Cyl-LO and Cyl-HI are as follows, SMART status is FAIL
826 if (cyl_lo==0xF4 && cyl_hi==0x2C)
827 return 1;
828
829 errno=EIO;
830 return -1;
831 }
832
833 // copy sector count register (one byte!) to return data
834 if (command==CHECK_POWER_MODE)
835 *data=*(char *)&(ata->sector_count);
836
837 // look for nonexistent devices/ports
838 if (command==IDENTIFY && !nonempty((unsigned char *)data, 512)) {
839 errno=ENODEV;
840 return -1;
841 }
842
843 return 0;
844}
845
846static int get_tw_channel_unit (const char* name, int* unit, int* dev) {
847 const char *p;
848
849 /* device node sanity check */
850 for (p = name + 3; *p; p++)
851 if (*p < '0' || *p > '9')
852 return -1;
853 if (strlen(name) > 4 && *(name + 3) == '0')
854 return -1;
855
856 if (dev != NULL)
857 *dev=atoi(name + 3);
858
859 /* no need for unit number */
860 if (unit != NULL)
861 *unit=0;
862 return 0;
863}
864
865
866#ifndef IOCATAREQUEST
867static int get_ata_channel_unit ( const char* name, int* unit, int* dev) {
868#ifndef ATAREQUEST
869 *dev=0;
870 *unit=0;
871return 0;
872#else
873 // there is no direct correlation between name 'ad0, ad1, ...' and
874 // channel/unit number. So we need to iterate through the possible
875 // channels and check each unit to see if we match names
876 struct ata_cmd iocmd;
877 int fd,maxunit;
878
879 bzero(&iocmd, sizeof(struct ata_cmd));
880
881 if ((fd = open("/dev/ata", O_RDWR)) < 0)
882 return -errno;
883
884 iocmd.cmd = ATAGMAXCHANNEL;
885 if (ioctl(fd, IOCATA, &iocmd) < 0) {
886 return -errno;
887 close(fd);
888 }
889 maxunit = iocmd.u.maxchan;
890 for (*unit = 0; *unit < maxunit; (*unit)++) {
891 iocmd.channel = *unit;
892 iocmd.device = -1;
893 iocmd.cmd = ATAGPARM;
894 if (ioctl(fd, IOCATA, &iocmd) < 0) {
895 close(fd);
896 return -errno;
897 }
898 if (iocmd.u.param.type[0] && !strcmp(name,iocmd.u.param.name[0])) {
899 *dev = 0;
900 break;
901 }
902 if (iocmd.u.param.type[1] && !strcmp(name,iocmd.u.param.name[1])) {
903 *dev = 1;
904 break;
905 }
906 }
907 close(fd);
908 if (*unit == maxunit)
909 return -1;
910 else
911 return 0;
912#endif
913}
914#endif
915
916// Guess device type (ata or scsi) based on device name (FreeBSD
917// specific) SCSI device name in FreeBSD can be sd, sr, scd, st, nst,
918// osst, nosst and sg.
919static const char * fbsd_dev_prefix = "/dev/";
920static const char * fbsd_dev_ata_disk_prefix = "ad";
921static const char * fbsd_dev_scsi_disk_plus = "da";
922static const char * fbsd_dev_scsi_tape1 = "sa";
923static const char * fbsd_dev_scsi_tape2 = "nsa";
924static const char * fbsd_dev_scsi_tape3 = "esa";
925static const char * fbsd_dev_twe_ctrl = "twe";
926static const char * fbsd_dev_twa_ctrl = "twa";
a37e7145 927static const char * fbsd_dev_cciss = "ciss";
832b75ed
GG
928
929static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel *chan) {
930 int len;
931 int dev_prefix_len = strlen(fbsd_dev_prefix);
932
933 // if dev_name null, or string length zero
934 if (!dev_name || !(len = strlen(dev_name)))
935 return CONTROLLER_UNKNOWN;
936
937 // Remove the leading /dev/... if it's there
938 if (!strncmp(fbsd_dev_prefix, dev_name, dev_prefix_len)) {
939 if (len <= dev_prefix_len)
940 // if nothing else in the string, unrecognized
941 return CONTROLLER_UNKNOWN;
942 // else advance pointer to following characters
943 dev_name += dev_prefix_len;
944 }
945 // form /dev/ad* or ad*
946 if (!strncmp(fbsd_dev_ata_disk_prefix, dev_name,
947 strlen(fbsd_dev_ata_disk_prefix))) {
948#ifndef IOCATAREQUEST
949 if (chan != NULL) {
950 if (get_ata_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {
951 return CONTROLLER_UNKNOWN;
952 }
953 }
954#endif
955 return CONTROLLER_ATA;
956 }
957
958 // form /dev/da* or da*
959 if (!strncmp(fbsd_dev_scsi_disk_plus, dev_name,
960 strlen(fbsd_dev_scsi_disk_plus)))
961 goto handlescsi;
962
963 // form /dev/sa* or sa*
964 if (!strncmp(fbsd_dev_scsi_tape1, dev_name,
965 strlen(fbsd_dev_scsi_tape1)))
966 goto handlescsi;
967
968 // form /dev/nsa* or nsa*
969 if (!strncmp(fbsd_dev_scsi_tape2, dev_name,
970 strlen(fbsd_dev_scsi_tape2)))
971 goto handlescsi;
972
973 // form /dev/esa* or esa*
974 if (!strncmp(fbsd_dev_scsi_tape3, dev_name,
975 strlen(fbsd_dev_scsi_tape3)))
976 goto handlescsi;
977
978 if (!strncmp(fbsd_dev_twa_ctrl,dev_name,
979 strlen(fbsd_dev_twa_ctrl))) {
980 if (chan != NULL) {
981 if (get_tw_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {
982 return CONTROLLER_UNKNOWN;
983 }
984 }
985 else if (get_tw_channel_unit(dev_name,NULL,NULL)<0) {
986 return CONTROLLER_UNKNOWN;
987 }
988 return CONTROLLER_3WARE_9000_CHAR;
989 }
990
991 if (!strncmp(fbsd_dev_twe_ctrl,dev_name,
992 strlen(fbsd_dev_twe_ctrl))) {
993 if (chan != NULL) {
994 if (get_tw_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {
995 return CONTROLLER_UNKNOWN;
996 }
997 }
998 else if (get_tw_channel_unit(dev_name,NULL,NULL)<0) {
999 return CONTROLLER_UNKNOWN;
1000 }
1001 return CONTROLLER_3WARE_678K_CHAR;
1002 }
a37e7145
GG
1003 // form /dev/ciss*
1004 if (!strncmp(fbsd_dev_cciss, dev_name,
1005 strlen(fbsd_dev_cciss)))
1006 return CONTROLLER_CCISS;
832b75ed
GG
1007
1008 // we failed to recognize any of the forms
1009 return CONTROLLER_UNKNOWN;
1010
1011 handlescsi:
1012 if (chan != NULL) {
4d59bff9 1013 if (!(chan->devname = (char *)calloc(1,DEV_IDLEN+1)))
832b75ed
GG
1014 return CONTROLLER_UNKNOWN;
1015
1016 if (cam_get_device(dev_name,chan->devname,DEV_IDLEN,&(chan->unitnum)) == -1)
1017 return CONTROLLER_UNKNOWN;
1018 }
1019 return CONTROLLER_SCSI;
1020
1021}
1022
1023int guess_device_type (const char* dev_name) {
1024 return parse_ata_chan_dev(dev_name,NULL);
1025}
1026
1027// global variable holding byte count of allocated memory
1028extern long long bytes;
1029
1030// we are going to take advantage of the fact that FreeBSD's devfs will only
1031// have device entries for devices that exist. So if we get the equivilent of
1032// ls /dev/ad?, we have all the ATA devices on the system
1033//
1034// If any errors occur, leave errno set as it was returned by the
1035// system call, and return <0.
1036
1037// Return values:
1038// -1 out of memory
1039// -2 to -5 errors in glob
1040
1041int get_dev_names(char*** names, const char* prefix) {
1042 int n = 0;
1043 char** mp;
1044 int retglob,lim;
1045 glob_t globbuf;
1046 int i;
1047 char pattern1[128],pattern2[128];
1048
1049 bzero(&globbuf,sizeof(globbuf));
1050 // in case of non-clean exit
1051 *names=NULL;
1052
1053 // handle 0-99 possible devices, will still be limited by MAX_NUM_DEV
1054 sprintf(pattern1,"/dev/%s[0-9]",prefix);
1055 sprintf(pattern2,"/dev/%s[0-9][0-9]",prefix);
1056
1057 // Use glob to look for any directory entries matching the patterns
1058 // first call inits with first pattern match, second call appends
a37e7145
GG
1059 // to first list. GLOB_NOCHECK results in no error if no more matches
1060 // found, however it does append the actual pattern to the list of
1061 // paths....
1062 if ((retglob=glob(pattern1, GLOB_ERR|GLOB_NOCHECK, NULL, &globbuf)) ||
832b75ed
GG
1063 (retglob=glob(pattern2, GLOB_ERR|GLOB_APPEND|GLOB_NOCHECK,NULL,&globbuf))) {
1064 int retval = -1;
1065 // glob failed
1066 if (retglob==GLOB_NOSPACE)
1067 pout("glob(3) ran out of memory matching patterns (%s),(%s)\n",
1068 pattern1, pattern2);
1069 else if (retglob==GLOB_ABORTED)
1070 pout("glob(3) aborted matching patterns (%s),(%s)\n",
1071 pattern1, pattern2);
1072 else if (retglob==GLOB_NOMATCH) {
1073 pout("glob(3) found no matches for patterns (%s),(%s)\n",
1074 pattern1, pattern2);
1075 retval = 0;
1076 }
1077 else if (retglob)
1078 pout("Unexplained error in glob(3) of patterns (%s),(%s)\n",
1079 pattern1, pattern2);
1080
1081 // Free memory and return
1082 globfree(&globbuf);
1083
1084 return retval;
1085 }
1086
832b75ed
GG
1087 // did we find too many paths?
1088 lim = globbuf.gl_pathc < MAX_NUM_DEV ? globbuf.gl_pathc : MAX_NUM_DEV;
1089 if (lim < globbuf.gl_pathc)
1090 pout("glob(3) found %d > MAX=%d devices matching patterns (%s),(%s): ignoring %d paths\n",
1091 globbuf.gl_pathc, MAX_NUM_DEV, pattern1,pattern2,
1092 globbuf.gl_pathc-MAX_NUM_DEV);
1093
1094 // allocate space for up to lim number of ATA devices
1095 if (!(mp = (char **)calloc(lim, sizeof(char*)))){
1096 pout("Out of memory constructing scan device list\n");
1097 return -1;
1098 }
1099
1100 // now step through the list returned by glob. No link checking needed
1101 // in FreeBSD
1102 for (i=0; i<globbuf.gl_pathc; i++){
a37e7145 1103 // because of the NO_CHECK in calls to glob,
832b75ed
GG
1104 // the pattern itself will be added to path list..
1105 // so ignore any paths that have the ']' from pattern
1106 if (strchr(globbuf.gl_pathv[i],']') == NULL)
1107 mp[n++] = CustomStrDup(globbuf.gl_pathv[i], 1, __LINE__, filenameandversion);
1108 }
1109
1110 globfree(&globbuf);
4d59bff9 1111 mp = (char **)realloc(mp,n*(sizeof(char*))); // shrink to correct size
832b75ed
GG
1112 bytes += (n)*(sizeof(char*)); // and set allocated byte count
1113 *names=mp;
1114 return n;
1115}
1116
1117int make_device_names (char*** devlist, const char* name) {
1118 if (!strcmp(name,"SCSI"))
1119 return get_dev_names(devlist,"da");
1120 else if (!strcmp(name,"ATA"))
1121 return get_dev_names(devlist,"ad");
1122 else
1123 return 0;
1124}